1285809Sscottl/*******************************************************************************
2285809Sscottl*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3285809Sscottl*
4285809Sscottl*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5285809Sscottl*that the following conditions are met:
6285809Sscottl*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7285809Sscottl*following disclaimer.
8285809Sscottl*2. Redistributions in binary form must reproduce the above copyright notice,
9285809Sscottl*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10285809Sscottl*with the distribution.
11285809Sscottl*
12285809Sscottl*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13285809Sscottl*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14285809Sscottl*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15285809Sscottl*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16285809Sscottl*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17285809Sscottl*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18285809Sscottl*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19285809Sscottl*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20285809Sscottl
21285809Sscottl********************************************************************************/
22285809Sscottl#include <sys/cdefs.h>
23285809Sscottl__FBSDID("$FreeBSD$");
24285809Sscottl#include <dev/pms/config.h>
25285809Sscottl
26285809Sscottl#include <dev/pms/freebsd/driver/common/osenv.h>
27285809Sscottl#include <dev/pms/freebsd/driver/common/ostypes.h>
28285809Sscottl#include <dev/pms/freebsd/driver/common/osdebug.h>
29285809Sscottl
30285809Sscottl#include <dev/pms/RefTisa/tisa/api/titypes.h>
31285809Sscottl
32285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/sa.h>
33285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
34285809Sscottl#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
35285809Sscottl
36285809Sscottl#include <dev/pms/RefTisa/sat/api/sm.h>
37285809Sscottl#include <dev/pms/RefTisa/sat/api/smapi.h>
38285809Sscottl#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
39285809Sscottl
40285809Sscottl#include <dev/pms/RefTisa/sat/src/smdefs.h>
41285809Sscottl#include <dev/pms/RefTisa/sat/src/smproto.h>
42285809Sscottl#include <dev/pms/RefTisa/sat/src/smtypes.h>
43285809Sscottl
44285809Sscottl/* start smapi defined APIs */
45285809SscottlosGLOBAL bit32
46285809SscottlsmRegisterDevice(
47285809Sscottl                 smRoot_t                       *smRoot,
48285809Sscottl                 agsaDevHandle_t                *agDevHandle,
49285809Sscottl                 smDeviceHandle_t               *smDeviceHandle,
50285809Sscottl                 agsaDevHandle_t                *agExpDevHandle,
51285809Sscottl                 bit32                          phyID,
52285809Sscottl                 bit32                          DeviceType
53285809Sscottl                )
54285809Sscottl{
55285809Sscottl  smDeviceData_t            *oneDeviceData = agNULL;
56285809Sscottl
57285809Sscottl  SM_DBG2(("smRegisterDevice: start\n"));
58285809Sscottl
59285809Sscottl  if (smDeviceHandle == agNULL)
60285809Sscottl  {
61285809Sscottl    SM_DBG1(("smRegisterDevice: smDeviceHandle is NULL!!!\n"));
62285809Sscottl    return SM_RC_FAILURE;
63285809Sscottl  }
64285809Sscottl
65285809Sscottl  if (agDevHandle == agNULL)
66285809Sscottl  {
67285809Sscottl    SM_DBG1(("smRegisterDevice: agDevHandle is NULL!!!\n"));
68285809Sscottl    return SM_RC_FAILURE;
69285809Sscottl  }
70285809Sscottl
71285809Sscottl  oneDeviceData = smAddToSharedcontext(smRoot, agDevHandle, smDeviceHandle, agExpDevHandle, phyID);
72285809Sscottl  if (oneDeviceData != agNULL)
73285809Sscottl  {
74285809Sscottl    oneDeviceData->satDeviceType = DeviceType;
75285809Sscottl    return SM_RC_SUCCESS;
76285809Sscottl  }
77285809Sscottl  else
78285809Sscottl  {
79285809Sscottl    return SM_RC_FAILURE;
80285809Sscottl  }
81285809Sscottl
82285809Sscottl}
83285809Sscottl
84285809SscottlosGLOBAL bit32
85285809SscottlsmDeregisterDevice(
86285809Sscottl                   smRoot_t                     *smRoot,
87285809Sscottl                   agsaDevHandle_t              *agDevHandle,
88285809Sscottl                   smDeviceHandle_t             *smDeviceHandle
89285809Sscottl                  )
90285809Sscottl{
91285809Sscottl  bit32                     status = SM_RC_FAILURE;
92285809Sscottl
93285809Sscottl  SM_DBG2(("smDeregisterDevice: start\n"));
94285809Sscottl
95285809Sscottl  if (smDeviceHandle == agNULL)
96285809Sscottl  {
97285809Sscottl    SM_DBG1(("smDeregisterDevice: smDeviceHandle is NULL!!!\n"));
98285809Sscottl    return SM_RC_FAILURE;
99285809Sscottl  }
100285809Sscottl
101285809Sscottl  if (agDevHandle == agNULL)
102285809Sscottl  {
103285809Sscottl    SM_DBG1(("smDeregisterDevice: agDevHandle is NULL!!!\n"));
104285809Sscottl    return SM_RC_FAILURE;
105285809Sscottl  }
106285809Sscottl
107285809Sscottl  status = smRemoveFromSharedcontext(smRoot, agDevHandle, smDeviceHandle);
108285809Sscottl
109285809Sscottl  return status;
110285809Sscottl}
111285809Sscottl
112285809SscottlosGLOBAL bit32
113285809SscottlsmIOAbort(
114285809Sscottl           smRoot_t                     *smRoot,
115285809Sscottl           smIORequest_t                *tasktag
116285809Sscottl         )
117285809Sscottl
118285809Sscottl{
119285809Sscottl  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
120285809Sscottl  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
121285809Sscottl  agsaRoot_t                *agRoot;
122285809Sscottl  smIORequestBody_t         *smIORequestBody = agNULL;
123285809Sscottl  smIORequestBody_t         *smIONewRequestBody = agNULL;
124285809Sscottl  agsaIORequest_t           *agIORequest = agNULL; /* IO to be aborted */
125285809Sscottl  bit32                     status = SM_RC_FAILURE;
126285809Sscottl  agsaIORequest_t           *agAbortIORequest;  /* abort IO itself */
127285809Sscottl  smIORequestBody_t         *smAbortIORequestBody;
128285809Sscottl#if 1
129285809Sscottl  bit32                     PhysUpper32;
130285809Sscottl  bit32                     PhysLower32;
131285809Sscottl  bit32                     memAllocStatus;
132285809Sscottl  void                      *osMemHandle;
133285809Sscottl#endif
134285809Sscottl  smSatIOContext_t            *satIOContext;
135285809Sscottl  smSatInternalIo_t           *satIntIo;
136285809Sscottl  smSatIOContext_t            *satAbortIOContext;
137285809Sscottl
138285809Sscottl  SM_DBG1(("smIOAbort: start\n"));
139285809Sscottl  SM_DBG2(("smIOAbort: tasktag %p\n", tasktag));
140285809Sscottl  /*
141285809Sscottl    alloc smIORequestBody for abort itself
142285809Sscottl    call saSATAAbort()
143285809Sscottl  */
144285809Sscottl
145285809Sscottl  agRoot = smAllShared->agRoot;
146285809Sscottl  smIORequestBody =  (smIORequestBody_t *)tasktag->smData;
147285809Sscottl
148285809Sscottl  if (smIORequestBody == agNULL)
149285809Sscottl  {
150285809Sscottl    SM_DBG1(("smIOAbort: smIORequestBody is NULL!!!\n"));
151285809Sscottl    return SM_RC_FAILURE;
152285809Sscottl  }
153285809Sscottl
154285809Sscottl  /* needs to distinguish internally generated or externally generated */
155285809Sscottl  satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
156285809Sscottl  satIntIo     = satIOContext->satIntIoContext;
157285809Sscottl  if (satIntIo == agNULL)
158285809Sscottl  {
159285809Sscottl    SM_DBG2(("smIOAbort: External, OS generated\n"));
160285809Sscottl    agIORequest     = &(smIORequestBody->agIORequest);
161285809Sscottl  }
162285809Sscottl  else
163285809Sscottl  {
164285809Sscottl    SM_DBG2(("smIOAbort: Internal, SM generated\n"));
165285809Sscottl    smIONewRequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
166285809Sscottl    agIORequest     = &(smIONewRequestBody->agIORequest);
167285809Sscottl  }
168285809Sscottl
169285809Sscottl  /*
170285809Sscottl    allocate smAbortIORequestBody for abort request itself
171285809Sscottl  */
172285809Sscottl
173285809Sscottl#if 1
174285809Sscottl  /* allocating agIORequest for abort itself */
175285809Sscottl  memAllocStatus = tdsmAllocMemory(
176285809Sscottl                                   smRoot,
177285809Sscottl                                   &osMemHandle,
178285809Sscottl                                   (void **)&smAbortIORequestBody,
179285809Sscottl                                   &PhysUpper32,
180285809Sscottl                                   &PhysLower32,
181285809Sscottl                                   8,
182285809Sscottl                                   sizeof(smIORequestBody_t),
183285809Sscottl                                   agTRUE
184285809Sscottl                                   );
185285809Sscottl  if (memAllocStatus != SM_RC_SUCCESS)
186285809Sscottl  {
187285809Sscottl    /* let os process IO */
188285809Sscottl    SM_DBG1(("smIOAbort: tdsmAllocMemory failed...!!!\n"));
189285809Sscottl    return SM_RC_FAILURE;
190285809Sscottl  }
191285809Sscottl
192285809Sscottl  if (smAbortIORequestBody == agNULL)
193285809Sscottl  {
194285809Sscottl    /* let os process IO */
195285809Sscottl    SM_DBG1(("smIOAbort: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n"));
196285809Sscottl    return SM_RC_FAILURE;
197285809Sscottl  }
198285809Sscottl
199285809Sscottl  smIOReInit(smRoot, smAbortIORequestBody);
200285809Sscottl
201285809Sscottl  /* setup task management structure */
202285809Sscottl  smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
203285809Sscottl  satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext);
204285809Sscottl  satAbortIOContext->smRequestBody = smAbortIORequestBody;
205285809Sscottl
206285809Sscottl  smAbortIORequestBody->smDevHandle = smIORequestBody->smDevHandle;
207285809Sscottl
208285809Sscottl  /* initialize agIORequest */
209285809Sscottl  agAbortIORequest = &(smAbortIORequestBody->agIORequest);
210285809Sscottl  agAbortIORequest->osData = (void *) smAbortIORequestBody;
211285809Sscottl  agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
212285809Sscottl
213285809Sscottl  /* remember IO to be aborted */
214285809Sscottl  smAbortIORequestBody->smIOToBeAbortedRequest = tasktag;
215285809Sscottl
216285809Sscottl  status = saSATAAbort(agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, smaSATAAbortCB);
217285809Sscottl
218285809Sscottl  SM_DBG2(("smIOAbort: return status=0x%x\n", status));
219285809Sscottl
220285809Sscottl#endif /* 1 */
221285809Sscottl
222285809Sscottl
223285809Sscottl  if (status == AGSA_RC_SUCCESS)
224285809Sscottl  {
225285809Sscottl    return SM_RC_SUCCESS;
226285809Sscottl  }
227285809Sscottl  else
228285809Sscottl  {
229285809Sscottl    SM_DBG1(("smIOAbort: failed to call saSATAAbort, status=%d!!!\n", status));
230285809Sscottl    tdsmFreeMemory(smRoot,
231285809Sscottl               smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle,
232285809Sscottl               sizeof(smIORequestBody_t)
233285809Sscottl               );
234285809Sscottl    return SM_RC_FAILURE;
235285809Sscottl  }
236285809Sscottl}
237285809Sscottl
238285809SscottlosGLOBAL bit32
239285809SscottlsmIOAbortAll(
240285809Sscottl             smRoot_t                     *smRoot,
241285809Sscottl             smDeviceHandle_t             *smDeviceHandle
242285809Sscottl            )
243285809Sscottl{
244285809Sscottl  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
245285809Sscottl  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
246285809Sscottl  agsaRoot_t                *agRoot;
247285809Sscottl  bit32                     status = SM_RC_FAILURE;
248285809Sscottl  agsaIORequest_t           *agAbortIORequest;
249285809Sscottl  smIORequestBody_t         *smAbortIORequestBody;
250285809Sscottl  smSatIOContext_t          *satAbortIOContext;
251285809Sscottl  smDeviceData_t            *oneDeviceData = agNULL;
252285809Sscottl  agsaDevHandle_t           *agDevHandle;
253285809Sscottl
254285809Sscottl  bit32                     PhysUpper32;
255285809Sscottl  bit32                     PhysLower32;
256285809Sscottl  bit32                     memAllocStatus;
257285809Sscottl  void                      *osMemHandle;
258285809Sscottl
259285809Sscottl
260285809Sscottl  SM_DBG2(("smIOAbortAll: start\n"));
261285809Sscottl
262285809Sscottl  agRoot = smAllShared->agRoot;
263285809Sscottl
264285809Sscottl  if (smDeviceHandle == agNULL)
265285809Sscottl  {
266285809Sscottl    SM_DBG1(("smIOAbortAll: smDeviceHandle is NULL!!!\n"));
267285809Sscottl    return SM_RC_FAILURE;
268285809Sscottl  }
269285809Sscottl
270285809Sscottl  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
271285809Sscottl  if (oneDeviceData == agNULL)
272285809Sscottl  {
273285809Sscottl    SM_DBG1(("smIOAbortAll: oneDeviceData is NULL!!!\n"));
274285809Sscottl    return SM_RC_FAILURE;
275285809Sscottl  }
276285809Sscottl  if (oneDeviceData->valid == agFALSE)
277285809Sscottl  {
278285809Sscottl    SM_DBG1(("smIOAbortAll: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
279285809Sscottl    return SM_RC_FAILURE;
280285809Sscottl  }
281285809Sscottl
282285809Sscottl  agDevHandle     = oneDeviceData->agDevHandle;
283285809Sscottl  if (agDevHandle == agNULL)
284285809Sscottl  {
285285809Sscottl    SM_DBG1(("smIOAbortAll: agDevHandle is NULL!!!\n"));
286285809Sscottl    return SM_RC_FAILURE;
287285809Sscottl  }
288285809Sscottl/*
289285809Sscottl  smAbortIORequestBody = smDequeueIO(smRoot);
290285809Sscottl  if (smAbortIORequestBody == agNULL)
291285809Sscottl  {
292285809Sscottl    SM_DBG1(("smIOAbortAll: empty freeIOList!!!\n"));
293285809Sscottl    return SM_RC_FAILURE;
294285809Sscottl  }
295285809Sscottl*/
296285809Sscottl  /* allocating agIORequest for abort itself */
297285809Sscottl  memAllocStatus = tdsmAllocMemory(
298285809Sscottl                                   smRoot,
299285809Sscottl                                   &osMemHandle,
300285809Sscottl                                   (void **)&smAbortIORequestBody,
301285809Sscottl                                   &PhysUpper32,
302285809Sscottl                                   &PhysLower32,
303285809Sscottl                                   8,
304285809Sscottl                                   sizeof(smIORequestBody_t),
305285809Sscottl                                   agTRUE
306285809Sscottl                                   );
307285809Sscottl  if (memAllocStatus != SM_RC_SUCCESS)
308285809Sscottl  {
309285809Sscottl     /* let os process IO */
310285809Sscottl     SM_DBG1(("smIOAbortAll: tdsmAllocMemory failed...!!!\n"));
311285809Sscottl     return SM_RC_FAILURE;
312285809Sscottl  }
313285809Sscottl
314285809Sscottl  if (smAbortIORequestBody == agNULL)
315285809Sscottl  {
316285809Sscottl    /* let os process IO */
317285809Sscottl    SM_DBG1(("smIOAbortAll: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n"));
318285809Sscottl    return SM_RC_FAILURE;
319285809Sscottl  }
320285809Sscottl
321285809Sscottl  smIOReInit(smRoot, smAbortIORequestBody);
322285809Sscottl
323285809Sscottl  /* setup task management structure */
324285809Sscottl  smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
325285809Sscottl
326285809Sscottl  satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext);
327285809Sscottl  satAbortIOContext->smRequestBody = smAbortIORequestBody;
328285809Sscottl  smAbortIORequestBody->smDevHandle = smDeviceHandle;
329285809Sscottl
330285809Sscottl  /* initialize agIORequest */
331285809Sscottl  agAbortIORequest = &(smAbortIORequestBody->agIORequest);
332285809Sscottl  agAbortIORequest->osData = (void *) smAbortIORequestBody;
333285809Sscottl  agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
334285809Sscottl
335285809Sscottl  oneDeviceData->OSAbortAll = agTRUE;
336285809Sscottl  /* abort all */
337285809Sscottl  status = saSATAAbort(agRoot, agAbortIORequest, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, 1, agNULL, smaSATAAbortCB);
338285809Sscottl  if (status != AGSA_RC_SUCCESS)
339285809Sscottl  {
340285809Sscottl    SM_DBG1(("smIOAbortAll: failed to call saSATAAbort, status=%d!!!\n", status));
341285809Sscottl    tdsmFreeMemory(smRoot,
342285809Sscottl                   smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle,
343285809Sscottl                   sizeof(smIORequestBody_t)
344285809Sscottl                   );
345285809Sscottl  }
346285809Sscottl
347285809Sscottl  return status;
348285809Sscottl}
349285809Sscottl
350285809SscottlosGLOBAL bit32
351285809SscottlsmSuperIOStart(
352285809Sscottl               smRoot_t                         *smRoot,
353285809Sscottl               smIORequest_t                    *smIORequest,
354285809Sscottl               smDeviceHandle_t                 *smDeviceHandle,
355285809Sscottl               smSuperScsiInitiatorRequest_t    *smSCSIRequest,
356285809Sscottl               bit32                            AddrHi,
357285809Sscottl               bit32                            AddrLo,
358285809Sscottl               bit32                            interruptContext
359285809Sscottl              )
360285809Sscottl{
361285809Sscottl  smDeviceData_t            *oneDeviceData = agNULL;
362285809Sscottl  smIORequestBody_t         *smIORequestBody = agNULL;
363285809Sscottl  smSatIOContext_t            *satIOContext = agNULL;
364285809Sscottl  bit32                     status = SM_RC_FAILURE;
365285809Sscottl
366285809Sscottl  SM_DBG2(("smSuperIOStart: start\n"));
367285809Sscottl
368285809Sscottl  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
369285809Sscottl  if (oneDeviceData == agNULL)
370285809Sscottl  {
371285809Sscottl    SM_DBG1(("smSuperIOStart: oneDeviceData is NULL!!!\n"));
372285809Sscottl    return SM_RC_FAILURE;
373285809Sscottl  }
374285809Sscottl  if (oneDeviceData->valid == agFALSE)
375285809Sscottl  {
376285809Sscottl    SM_DBG1(("smSuperIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
377285809Sscottl    return SM_RC_FAILURE;
378285809Sscottl  }
379285809Sscottl  smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
380285809Sscottl
381285809Sscottl  if (smIORequestBody == agNULL)
382285809Sscottl  {
383285809Sscottl    SM_DBG1(("smSuperIOStart: smIORequestBody is NULL!!!\n"));
384285809Sscottl    return SM_RC_FAILURE;
385285809Sscottl  }
386285809Sscottl
387285809Sscottl  smIOReInit(smRoot, smIORequestBody);
388285809Sscottl
389285809Sscottl  SM_DBG3(("smSuperIOStart: io ID %d!!!\n", smIORequestBody->id ));
390285809Sscottl
391285809Sscottl  oneDeviceData->sasAddressHi = AddrHi;
392285809Sscottl  oneDeviceData->sasAddressLo = AddrLo;
393285809Sscottl
394285809Sscottl  smIORequestBody->smIORequest = smIORequest;
395285809Sscottl  smIORequestBody->smDevHandle = smDeviceHandle;
396285809Sscottl
397285809Sscottl  satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
398285809Sscottl
399285809Sscottl  /*
400285809Sscottl   * Need to initialize all the fields within satIOContext except
401285809Sscottl   * reqType and satCompleteCB which will be set later in SM.
402285809Sscottl   */
403285809Sscottl  smIORequestBody->transport.SATA.smSenseData.senseData = agNULL;
404285809Sscottl  smIORequestBody->transport.SATA.smSenseData.senseLen = 0;
405285809Sscottl  satIOContext->pSatDevData   = oneDeviceData;
406285809Sscottl  satIOContext->pFis          =
407285809Sscottl    &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
408285809Sscottl  satIOContext->pScsiCmnd     = &smSCSIRequest->scsiCmnd;
409285809Sscottl  satIOContext->pSense        = &smIORequestBody->transport.SATA.sensePayload;
410285809Sscottl  satIOContext->pSmSenseData  = &smIORequestBody->transport.SATA.smSenseData;
411285809Sscottl  satIOContext->pSmSenseData->senseData = satIOContext->pSense;
412285809Sscottl  /*    satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */
413285809Sscottl  satIOContext->smRequestBody = smIORequestBody;
414285809Sscottl  satIOContext->interruptContext = interruptContext;
415285809Sscottl  satIOContext->psmDeviceHandle = smDeviceHandle;
416285809Sscottl  satIOContext->smScsiXchg = smSCSIRequest;
417285809Sscottl  satIOContext->superIOFlag = agTRUE;
418285809Sscottl//  satIOContext->superIOFlag = agFALSE;
419285809Sscottl
420285809Sscottl  satIOContext->satIntIoContext  = agNULL;
421285809Sscottl  satIOContext->satOrgIOContext  = agNULL;
422285809Sscottl  /*    satIOContext->tiIORequest      = tiIORequest; */
423285809Sscottl
424285809Sscottl  /* save context if we need to abort later */
425285809Sscottl  /*smIORequest->smData = smIORequestBody;*/
426285809Sscottl
427285809Sscottl  /* followings are used only for internal IO */
428285809Sscottl  satIOContext->currentLBA = 0;
429285809Sscottl  satIOContext->OrgTL = 0;
430285809Sscottl
431285809Sscottl  status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, (smScsiInitiatorRequest_t *)smSCSIRequest, satIOContext);
432285809Sscottl
433285809Sscottl  return status;
434285809Sscottl}
435285809Sscottl
436285809Sscottl/*
437285809SscottlosGLOBAL bit32
438285809SscottltiINIIOStart(
439285809Sscottl             tiRoot_t                  *tiRoot,
440285809Sscottl             tiIORequest_t             *tiIORequest,
441285809Sscottl             tiDeviceHandle_t          *tiDeviceHandle,
442285809Sscottl             tiScsiInitiatorRequest_t  *tiScsiRequest,
443285809Sscottl             void                      *tiRequestBody,
444285809Sscottl             bit32                     interruptContext
445285809Sscottl             )
446285809Sscottl
447285809SscottlGLOBAL bit32  satIOStart(
448285809Sscottl                   tiRoot_t                  *tiRoot,
449285809Sscottl                   tiIORequest_t             *tiIORequest,
450285809Sscottl                   tiDeviceHandle_t          *tiDeviceHandle,
451285809Sscottl                   tiScsiInitiatorRequest_t  *tiScsiRequest,
452285809Sscottl                   smSatIOContext_t            *satIOContext
453285809Sscottl                  )
454285809SscottlsmIOStart(
455285809Sscottl          smRoot_t      *smRoot,
456285809Sscottl          smIORequest_t     *smIORequest,
457285809Sscottl          smDeviceHandle_t    *smDeviceHandle,
458285809Sscottl          smScsiInitiatorRequest_t  *smSCSIRequest,
459285809Sscottl          smIORequestBody_t             *smRequestBody,
460285809Sscottl          bit32       interruptContext
461285809Sscottl         )
462285809Sscottl
463285809Sscottl
464285809Sscottl*/
465285809SscottlFORCEINLINE bit32
466285809SscottlsmIOStart(
467285809Sscottl          smRoot_t                      *smRoot,
468285809Sscottl          smIORequest_t                 *smIORequest,
469285809Sscottl          smDeviceHandle_t              *smDeviceHandle,
470285809Sscottl          smScsiInitiatorRequest_t      *smSCSIRequest,
471285809Sscottl          bit32                         interruptContext
472285809Sscottl         )
473285809Sscottl{
474285809Sscottl  smDeviceData_t            *oneDeviceData = agNULL;
475285809Sscottl  smIORequestBody_t         *smIORequestBody = agNULL;
476285809Sscottl  smSatIOContext_t          *satIOContext = agNULL;
477285809Sscottl  bit32                     status = SM_RC_FAILURE;
478285809Sscottl
479285809Sscottl  SM_DBG2(("smIOStart: start\n"));
480285809Sscottl
481285809Sscottl  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
482285809Sscottl  if (oneDeviceData == agNULL)
483285809Sscottl  {
484285809Sscottl    SM_DBG1(("smIOStart: oneDeviceData is NULL!!!\n"));
485285809Sscottl    return SM_RC_FAILURE;
486285809Sscottl  }
487285809Sscottl  if (oneDeviceData->valid == agFALSE)
488285809Sscottl  {
489285809Sscottl    SM_DBG1(("smIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
490285809Sscottl    return SM_RC_FAILURE;
491285809Sscottl  }
492285809Sscottl  smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
493285809Sscottl
494285809Sscottl  if (smIORequestBody == agNULL)
495285809Sscottl  {
496285809Sscottl    SM_DBG1(("smIOStart: smIORequestBody is NULL!!!\n"));
497285809Sscottl    return SM_RC_FAILURE;
498285809Sscottl  }
499285809Sscottl
500285809Sscottl  smIOReInit(smRoot, smIORequestBody);
501285809Sscottl
502285809Sscottl  SM_DBG3(("smIOStart: io ID %d!!!\n", smIORequestBody->id ));
503285809Sscottl
504285809Sscottl  smIORequestBody->smIORequest = smIORequest;
505285809Sscottl  smIORequestBody->smDevHandle = smDeviceHandle;
506285809Sscottl
507285809Sscottl  satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
508285809Sscottl
509285809Sscottl  /*
510285809Sscottl   * Need to initialize all the fields within satIOContext except
511285809Sscottl   * reqType and satCompleteCB which will be set later in SM.
512285809Sscottl   */
513285809Sscottl  smIORequestBody->transport.SATA.smSenseData.senseData = agNULL;
514285809Sscottl  smIORequestBody->transport.SATA.smSenseData.senseLen = 0;
515285809Sscottl  satIOContext->pSatDevData   = oneDeviceData;
516285809Sscottl  satIOContext->pFis          =
517285809Sscottl    &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
518285809Sscottl  satIOContext->pScsiCmnd     = &smSCSIRequest->scsiCmnd;
519285809Sscottl  satIOContext->pSense        = &smIORequestBody->transport.SATA.sensePayload;
520285809Sscottl  satIOContext->pSmSenseData  = &smIORequestBody->transport.SATA.smSenseData;
521285809Sscottl  satIOContext->pSmSenseData->senseData = satIOContext->pSense;
522285809Sscottl  /*    satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */
523285809Sscottl  satIOContext->smRequestBody = smIORequestBody;
524285809Sscottl  satIOContext->interruptContext = interruptContext;
525285809Sscottl  satIOContext->psmDeviceHandle = smDeviceHandle;
526285809Sscottl  satIOContext->smScsiXchg = smSCSIRequest;
527285809Sscottl  satIOContext->superIOFlag = agFALSE;
528285809Sscottl
529285809Sscottl  satIOContext->satIntIoContext  = agNULL;
530285809Sscottl  satIOContext->satOrgIOContext  = agNULL;
531285809Sscottl  satIOContext->currentLBA = 0;
532285809Sscottl  satIOContext->OrgTL = 0;
533285809Sscottl
534285809Sscottl  status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
535285809Sscottl
536285809Sscottl  return status;
537285809Sscottl
538285809Sscottl}
539285809Sscottl
540285809Sscottl
541285809Sscottl
542285809SscottlosGLOBAL bit32
543285809SscottlsmTaskManagement(
544285809Sscottl                 smRoot_t                       *smRoot,
545285809Sscottl                 smDeviceHandle_t               *smDeviceHandle,
546285809Sscottl                 bit32                          task,
547285809Sscottl                 smLUN_t                        *lun,
548285809Sscottl                 smIORequest_t                  *taskTag, /* io to be aborted */
549285809Sscottl                 smIORequest_t                  *currentTaskTag /* task management */
550285809Sscottl                )
551285809Sscottl{
552285809Sscottl  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
553285809Sscottl  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
554285809Sscottl  agsaRoot_t                *agRoot = smAllShared->agRoot;
555285809Sscottl  smDeviceData_t            *oneDeviceData = agNULL;
556285809Sscottl  smIORequestBody_t         *smIORequestBody = agNULL;
557285809Sscottl  bit32                     status;
558285809Sscottl  agsaContext_t             *agContext = agNULL;
559285809Sscottl  smSatIOContext_t          *satIOContext;
560285809Sscottl
561285809Sscottl  SM_DBG1(("smTaskManagement: start\n"));
562285809Sscottl  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
563285809Sscottl
564285809Sscottl  if (task == SM_LOGICAL_UNIT_RESET || task == SM_TARGET_WARM_RESET || task == SM_ABORT_TASK)
565285809Sscottl  {
566285809Sscottl    if (task == AG_LOGICAL_UNIT_RESET)
567285809Sscottl    {
568285809Sscottl      if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
569285809Sscottl            lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
570285809Sscottl      {
571285809Sscottl        SM_DBG1(("smTaskManagement: *** REJECT *** LUN not zero, did %d!!!\n",
572285809Sscottl                oneDeviceData->id));
573285809Sscottl        return SM_RC_FAILURE;
574285809Sscottl      }
575285809Sscottl    }
576285809Sscottl
577285809Sscottl    oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
578285809Sscottl    oneDeviceData->satAbortAfterReset = agFALSE;
579285809Sscottl
580285809Sscottl    saSetDeviceState(agRoot,
581285809Sscottl                     agNULL,
582285809Sscottl                     tdsmRotateQnumber(smRoot, smDeviceHandle),
583285809Sscottl                     oneDeviceData->agDevHandle,
584285809Sscottl                     SA_DS_IN_RECOVERY
585285809Sscottl                     );
586285809Sscottl
587285809Sscottl    if (oneDeviceData->directlyAttached == agFALSE)
588285809Sscottl    {
589285809Sscottl      /* expander attached */
590285809Sscottl      SM_DBG1(("smTaskManagement: LUN reset or device reset expander attached!!!\n"));
591285809Sscottl      status = smPhyControlSend(smRoot,
592285809Sscottl                                oneDeviceData,
593285809Sscottl                                SMP_PHY_CONTROL_HARD_RESET,
594285809Sscottl                                currentTaskTag,
595285809Sscottl                                tdsmRotateQnumber(smRoot, smDeviceHandle)
596285809Sscottl                               );
597285809Sscottl      return status;
598285809Sscottl    }
599285809Sscottl    else
600285809Sscottl    {
601285809Sscottl      SM_DBG1(("smTaskManagement: LUN reset or device reset directly attached\n"));
602285809Sscottl
603285809Sscottl      smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot);
604285809Sscottl
605285809Sscottl      if (smIORequestBody == agNULL)
606285809Sscottl      {
607285809Sscottl        SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n"));
608285809Sscottl        return SM_RC_FAILURE;
609285809Sscottl      }
610285809Sscottl
611285809Sscottl      smIOReInit(smRoot, smIORequestBody);
612285809Sscottl
613285809Sscottl      satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
614285809Sscottl      satIOContext->smRequestBody = smIORequestBody;
615285809Sscottl      smIORequestBody->smDevHandle = smDeviceHandle;
616285809Sscottl
617285809Sscottl      agContext = &(oneDeviceData->agDeviceResetContext);
618285809Sscottl      agContext->osData = currentTaskTag;
619285809Sscottl
620285809Sscottl      status = saLocalPhyControl(agRoot,
621285809Sscottl                                 agContext,
622285809Sscottl                                 tdsmRotateQnumber(smRoot, smDeviceHandle) &0xFFFF,
623285809Sscottl                                 oneDeviceData->phyID,
624285809Sscottl                                 AGSA_PHY_HARD_RESET,
625285809Sscottl                                 smLocalPhyControlCB
626285809Sscottl                                 );
627285809Sscottl
628285809Sscottl      if ( status == AGSA_RC_SUCCESS)
629285809Sscottl      {
630285809Sscottl        return SM_RC_SUCCESS;
631285809Sscottl      }
632285809Sscottl      else if (status == AGSA_RC_BUSY)
633285809Sscottl      {
634285809Sscottl        return SM_RC_BUSY;
635285809Sscottl      }
636285809Sscottl      else if (status == AGSA_RC_FAILURE)
637285809Sscottl      {
638285809Sscottl        return SM_RC_FAILURE;
639285809Sscottl      }
640285809Sscottl      else
641285809Sscottl      {
642285809Sscottl        SM_DBG1(("smTaskManagement: unknown status %d\n",status));
643285809Sscottl        return SM_RC_FAILURE;
644285809Sscottl      }
645285809Sscottl    }
646285809Sscottl  }
647285809Sscottl  else
648285809Sscottl  {
649285809Sscottl    /* smsatsmTaskManagement() which is satTM() */
650285809Sscottl    smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot);
651285809Sscottl
652285809Sscottl    if (smIORequestBody == agNULL)
653285809Sscottl    {
654285809Sscottl      SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n"));
655285809Sscottl      return SM_RC_FAILURE;
656285809Sscottl    }
657285809Sscottl
658285809Sscottl    smIOReInit(smRoot, smIORequestBody);
659285809Sscottl    /*currentTaskTag->smData = smIORequestBody;*/
660285809Sscottl
661285809Sscottl    status = smsatTaskManagement(smRoot,
662285809Sscottl                                 smDeviceHandle,
663285809Sscottl                                 task,
664285809Sscottl                                 lun,
665285809Sscottl                                 taskTag,
666285809Sscottl                                 currentTaskTag,
667285809Sscottl                                 smIORequestBody
668285809Sscottl                                );
669285809Sscottl
670285809Sscottl    return status;
671285809Sscottl  }
672285809Sscottl  return SM_RC_SUCCESS;
673285809Sscottl}
674285809Sscottl
675285809Sscottl
676285809Sscottl
677285809Sscottl/********************************************************* end smapi defined APIS */
678285809Sscottl/* counterpart is
679285809Sscottl   smEnqueueIO(smRoot_t       *smRoot,
680285809Sscottl               smSatIOContext_t       *satIOContext)
681285809Sscottl*/
682285809SscottlosGLOBAL smIORequestBody_t *
683285809SscottlsmDequeueIO(smRoot_t          *smRoot)
684285809Sscottl{
685285809Sscottl  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
686285809Sscottl  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
687285809Sscottl  smIORequestBody_t         *smIORequestBody = agNULL;
688285809Sscottl  smList_t                  *IOListList;
689285809Sscottl
690285809Sscottl  SM_DBG2(("smDequeueIO: start\n"));
691285809Sscottl
692285809Sscottl  tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
693285809Sscottl  if (SMLIST_EMPTY(&(smAllShared->freeIOList)))
694285809Sscottl  {
695285809Sscottl    SM_DBG1(("smDequeueIO: empty freeIOList!!!\n"));
696285809Sscottl    tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
697285809Sscottl    return agNULL;
698285809Sscottl  }
699285809Sscottl
700285809Sscottl  SMLIST_DEQUEUE_FROM_HEAD(&IOListList, &(smAllShared->freeIOList));
701285809Sscottl  smIORequestBody = SMLIST_OBJECT_BASE(smIORequestBody_t, satIoBodyLink, IOListList);
702285809Sscottl  SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink));
703285809Sscottl  SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->mainIOList));
704285809Sscottl  tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
705285809Sscottl
706285809Sscottl  if (smIORequestBody->InUse == agTRUE)
707285809Sscottl  {
708285809Sscottl    SM_DBG1(("smDequeueIO: wrong. already in USE ID %d!!!!\n", smIORequestBody->id));
709285809Sscottl  }
710285809Sscottl  smIOReInit(smRoot, smIORequestBody);
711285809Sscottl
712285809Sscottl
713285809Sscottl  SM_DBG2(("smDequeueIO: io ID %d!\n", smIORequestBody->id));
714285809Sscottl
715285809Sscottl  /* debugging */
716285809Sscottl  if (smIORequestBody->satIoBodyLink.flink == agNULL)
717285809Sscottl  {
718285809Sscottl    SM_DBG1(("smDequeueIO: io ID %d, flink is NULL!!!\n", smIORequestBody->id));
719285809Sscottl  }
720285809Sscottl  if (smIORequestBody->satIoBodyLink.blink == agNULL)
721285809Sscottl  {
722285809Sscottl    SM_DBG1(("smDequeueIO: io ID %d, blink is NULL!!!\n", smIORequestBody->id));
723285809Sscottl  }
724285809Sscottl
725285809Sscottl  return smIORequestBody;
726285809Sscottl}
727285809Sscottl
728285809Sscottl//start here
729285809Sscottl//compare with ossaSATAAbortCB()
730285809Sscottl//qqq1
731285809SscottlosGLOBAL void
732285809SscottlsmsatAbort(
733285809Sscottl           smRoot_t          *smRoot,
734285809Sscottl           agsaRoot_t        *agRoot,
735285809Sscottl           smSatIOContext_t  *satIOContext
736285809Sscottl    )
737285809Sscottl{
738285809Sscottl  smIORequestBody_t         *smIORequestBody = agNULL; /* abort itself */
739285809Sscottl  smIORequestBody_t         *smToBeAbortedIORequestBody; /* io to be aborted */
740285809Sscottl  agsaIORequest_t           *agToBeAbortedIORequest; /* io to be aborted */
741285809Sscottl  agsaIORequest_t           *agAbortIORequest;  /* abort io itself */
742285809Sscottl  smSatIOContext_t          *satAbortIOContext;
743285809Sscottl  bit32                      PhysUpper32;
744285809Sscottl  bit32                      PhysLower32;
745285809Sscottl  bit32                      memAllocStatus;
746285809Sscottl  void                       *osMemHandle;
747285809Sscottl
748285809Sscottl
749285809Sscottl  SM_DBG2(("smsatAbort: start\n"));
750285809Sscottl
751285809Sscottl  if (satIOContext == agNULL)
752285809Sscottl  {
753285809Sscottl    SM_DBG1(("smsatAbort: satIOContext is NULL, wrong!!!\n"));
754285809Sscottl    return;
755285809Sscottl  }
756285809Sscottl
757285809Sscottl  smToBeAbortedIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
758285809Sscottl  agToBeAbortedIORequest = (agsaIORequest_t *)&(smToBeAbortedIORequestBody->agIORequest);
759285809Sscottl  /*
760285809Sscottl  smIORequestBody = smDequeueIO(smRoot);
761285809Sscottl
762285809Sscottl  if (smIORequestBody == agNULL)
763285809Sscottl  {
764285809Sscottl    SM_DBG1(("smsatAbort: empty freeIOList!!!\n"));
765285809Sscottl    return;
766285809Sscottl  }
767285809Sscottl   */
768285809Sscottl  /* allocating agIORequest for abort itself */
769285809Sscottl  memAllocStatus = tdsmAllocMemory(
770285809Sscottl                                   smRoot,
771285809Sscottl                                   &osMemHandle,
772285809Sscottl                                   (void **)&smIORequestBody,
773285809Sscottl                                   &PhysUpper32,
774285809Sscottl                                   &PhysLower32,
775285809Sscottl                                   8,
776285809Sscottl                                   sizeof(smIORequestBody_t),
777285809Sscottl                                   agTRUE
778285809Sscottl                                   );
779285809Sscottl  if (memAllocStatus != tiSuccess)
780285809Sscottl  {
781285809Sscottl    /* let os process IO */
782285809Sscottl    SM_DBG1(("smsatAbort: ostiAllocMemory failed...\n"));
783285809Sscottl    return;
784285809Sscottl  }
785285809Sscottl
786285809Sscottl  if (smIORequestBody == agNULL)
787285809Sscottl  {
788285809Sscottl    /* let os process IO */
789285809Sscottl    SM_DBG1(("smsatAbort: ostiAllocMemory returned NULL smIORequestBody\n"));
790285809Sscottl    return;
791285809Sscottl  }
792285809Sscottl  smIOReInit(smRoot, smIORequestBody);
793285809Sscottl
794285809Sscottl  smIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
795285809Sscottl  smIORequestBody->smDevHandle = smToBeAbortedIORequestBody->smDevHandle;
796285809Sscottl  /* initialize agIORequest */
797285809Sscottl  satAbortIOContext = &(smIORequestBody->transport.SATA.satIOContext);
798285809Sscottl  satAbortIOContext->smRequestBody = smIORequestBody;
799285809Sscottl
800285809Sscottl  agAbortIORequest = &(smIORequestBody->agIORequest);
801285809Sscottl  agAbortIORequest->osData = (void *) smIORequestBody;
802285809Sscottl  agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
803285809Sscottl
804285809Sscottl  /*
805285809Sscottl   * Issue abort
806285809Sscottl   */
807285809Sscottl                                                                                                                                                                 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, smaSATAAbortCB);
808285809Sscottl
809285809Sscottl
810285809Sscottl  SM_DBG1(("satAbort: end!!!\n"));
811285809Sscottl
812285809Sscottl  return;
813285809Sscottl}
814285809Sscottl
815285809SscottlosGLOBAL bit32
816285809SscottlsmsatStartCheckPowerMode(
817285809Sscottl                         smRoot_t                  *smRoot,
818285809Sscottl                         smIORequest_t             *currentTaskTag,
819285809Sscottl                         smDeviceHandle_t          *smDeviceHandle,
820285809Sscottl                         smScsiInitiatorRequest_t  *smScsiRequest,
821285809Sscottl                         smSatIOContext_t            *satIOContext
822285809Sscottl                        )
823285809Sscottl{
824285809Sscottl  smSatInternalIo_t           *satIntIo = agNULL;
825285809Sscottl  smDeviceData_t            *oneDeviceData = agNULL;
826285809Sscottl  smSatIOContext_t            *satNewIOContext;
827285809Sscottl  bit32                     status;
828285809Sscottl
829285809Sscottl  SM_DBG1(("smsatStartCheckPowerMode: start\n"));
830285809Sscottl
831285809Sscottl  oneDeviceData = satIOContext->pSatDevData;
832285809Sscottl
833285809Sscottl  SM_DBG6(("smsatStartCheckPowerMode: before alloc\n"));
834285809Sscottl
835285809Sscottl  /* allocate any fis for seting SRT bit in device control */
836285809Sscottl  satIntIo = smsatAllocIntIoResource( smRoot,
837285809Sscottl                                      currentTaskTag,
838285809Sscottl                                      oneDeviceData,
839285809Sscottl                                      0,
840285809Sscottl                                      satIntIo);
841285809Sscottl
842285809Sscottl  SM_DBG6(("smsatStartCheckPowerMode: before after\n"));
843285809Sscottl
844285809Sscottl  if (satIntIo == agNULL)
845285809Sscottl  {
846285809Sscottl    SM_DBG1(("smsatStartCheckPowerMode: can't alloacate!!!\n"));
847285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
848285809Sscottl    return SM_RC_FAILURE;
849285809Sscottl  }
850285809Sscottl
851285809Sscottl  satNewIOContext = smsatPrepareNewIO(satIntIo,
852285809Sscottl                                      currentTaskTag,
853285809Sscottl                                      oneDeviceData,
854285809Sscottl                                      agNULL,
855285809Sscottl                                      satIOContext);
856285809Sscottl
857285809Sscottl  SM_DBG6(("smsatStartCheckPowerMode: TD satIOContext %p \n", satIOContext));
858285809Sscottl  SM_DBG6(("smsatStartCheckPowerMode: SM satNewIOContext %p \n", satNewIOContext));
859285809Sscottl  SM_DBG6(("smsatStartCheckPowerMode: TD smScsiXchg %p \n", satIOContext->smScsiXchg));
860285809Sscottl  SM_DBG6(("smsatStartCheckPowerMode: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg));
861285809Sscottl
862285809Sscottl
863285809Sscottl
864285809Sscottl  SM_DBG2(("smsatStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
865285809Sscottl
866285809Sscottl  status = smsatCheckPowerMode(smRoot,
867285809Sscottl                               &satIntIo->satIntSmIORequest, /* New smIORequest */
868285809Sscottl                               smDeviceHandle,
869285809Sscottl                               satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *smScsiRequest, */
870285809Sscottl                               satNewIOContext);
871285809Sscottl
872285809Sscottl  if (status != SM_RC_SUCCESS)
873285809Sscottl  {
874285809Sscottl    SM_DBG1(("smsatStartCheckPowerMode: failed in sending!!!\n"));
875285809Sscottl
876285809Sscottl    smsatFreeIntIoResource( smRoot,
877285809Sscottl                            oneDeviceData,
878285809Sscottl                            satIntIo);
879285809Sscottl
880285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
881285809Sscottl
882285809Sscottl    return SM_RC_FAILURE;
883285809Sscottl  }
884285809Sscottl
885285809Sscottl
886285809Sscottl  SM_DBG6(("smsatStartCheckPowerMode: end\n"));
887285809Sscottl
888285809Sscottl  return status;
889285809Sscottl}
890285809Sscottl
891285809SscottlosGLOBAL bit32
892285809SscottlsmsatStartResetDevice(
893285809Sscottl                       smRoot_t                  *smRoot,
894285809Sscottl                       smIORequest_t             *currentTaskTag,
895285809Sscottl                       smDeviceHandle_t          *smDeviceHandle,
896285809Sscottl                       smScsiInitiatorRequest_t  *smScsiRequest,
897285809Sscottl                       smSatIOContext_t            *satIOContext
898285809Sscottl                     )
899285809Sscottl{
900285809Sscottl  smSatInternalIo_t           *satIntIo = agNULL;
901285809Sscottl  smDeviceData_t            *oneDeviceData = agNULL;
902285809Sscottl  smSatIOContext_t            *satNewIOContext;
903285809Sscottl  bit32                     status;
904285809Sscottl
905285809Sscottl  SM_DBG1(("smsatStartResetDevice: start\n"));
906285809Sscottl
907285809Sscottl  oneDeviceData = satIOContext->pSatDevData;
908285809Sscottl
909285809Sscottl  SM_DBG6(("smsatStartResetDevice: before alloc\n"));
910285809Sscottl
911285809Sscottl  /* allocate any fis for seting SRT bit in device control */
912285809Sscottl  satIntIo = smsatAllocIntIoResource( smRoot,
913285809Sscottl                                      currentTaskTag,
914285809Sscottl                                      oneDeviceData,
915285809Sscottl                                      0,
916285809Sscottl                                      satIntIo);
917285809Sscottl
918285809Sscottl  SM_DBG6(("smsatStartResetDevice: before after\n"));
919285809Sscottl
920285809Sscottl  if (satIntIo == agNULL)
921285809Sscottl  {
922285809Sscottl    SM_DBG1(("smsatStartResetDevice: can't alloacate!!!\n"));
923285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
924285809Sscottl    return SM_RC_FAILURE;
925285809Sscottl  }
926285809Sscottl
927285809Sscottl  satNewIOContext = smsatPrepareNewIO(satIntIo,
928285809Sscottl                                      currentTaskTag,
929285809Sscottl                                      oneDeviceData,
930285809Sscottl                                      agNULL,
931285809Sscottl                                      satIOContext);
932285809Sscottl
933285809Sscottl  SM_DBG6(("smsatStartResetDevice: TD satIOContext %p \n", satIOContext));
934285809Sscottl  SM_DBG6(("smsatStartResetDevice: SM satNewIOContext %p \n", satNewIOContext));
935285809Sscottl  SM_DBG6(("smsatStartResetDevice: TD smScsiXchg %p \n", satIOContext->smScsiXchg));
936285809Sscottl  SM_DBG6(("smsatStartResetDevice: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg));
937285809Sscottl
938285809Sscottl
939285809Sscottl
940285809Sscottl  SM_DBG6(("smsatStartResetDevice: satNewIOContext %p \n", satNewIOContext));
941285809Sscottl
942285809Sscottl  if (oneDeviceData->satDeviceType == SATA_ATAPI_DEVICE)
943285809Sscottl  {
944285809Sscottl      /*if ATAPI device, send DEVICE RESET command to ATAPI device*/
945285809Sscottl      status = smsatDeviceReset(smRoot,
946285809Sscottl                            &satIntIo->satIntSmIORequest, /* New smIORequest */
947285809Sscottl                            smDeviceHandle,
948285809Sscottl                            satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */
949285809Sscottl                            satNewIOContext);
950285809Sscottl  }
951285809Sscottl  else
952285809Sscottl  {
953285809Sscottl      status = smsatResetDevice(smRoot,
954285809Sscottl                            &satIntIo->satIntSmIORequest, /* New smIORequest */
955285809Sscottl                            smDeviceHandle,
956285809Sscottl                            satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */
957285809Sscottl                            satNewIOContext);
958285809Sscottl   }
959285809Sscottl
960285809Sscottl  if (status != SM_RC_SUCCESS)
961285809Sscottl  {
962285809Sscottl    SM_DBG1(("smsatStartResetDevice: failed in sending!!!\n"));
963285809Sscottl
964285809Sscottl    smsatFreeIntIoResource( smRoot,
965285809Sscottl                            oneDeviceData,
966285809Sscottl                            satIntIo);
967285809Sscottl
968285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
969285809Sscottl
970285809Sscottl    return SM_RC_FAILURE;
971285809Sscottl  }
972285809Sscottl
973285809Sscottl
974285809Sscottl  SM_DBG6(("smsatStartResetDevice: end\n"));
975285809Sscottl
976285809Sscottl  return status;
977285809Sscottl}
978285809Sscottl
979285809SscottlosGLOBAL bit32
980285809SscottlsmsatTmAbortTask(
981285809Sscottl                  smRoot_t                  *smRoot,
982285809Sscottl                  smIORequest_t             *currentTaskTag, /* task management */
983285809Sscottl                  smDeviceHandle_t          *smDeviceHandle,
984285809Sscottl                  smScsiInitiatorRequest_t  *smScsiRequest, /* NULL */
985285809Sscottl                  smSatIOContext_t            *satIOContext, /* task management */
986285809Sscottl                  smIORequest_t             *taskTag) /* io to be aborted */
987285809Sscottl{
988285809Sscottl  smDeviceData_t          *oneDeviceData = agNULL;
989285809Sscottl  smSatIOContext_t        *satTempIOContext = agNULL;
990285809Sscottl  smList_t                *elementHdr;
991285809Sscottl  bit32                   found = agFALSE;
992285809Sscottl  smIORequestBody_t       *smIORequestBody = agNULL;
993285809Sscottl  smIORequest_t           *smIOReq = agNULL;
994285809Sscottl  bit32                   status;
995285809Sscottl
996285809Sscottl  SM_DBG1(("smsatTmAbortTask: start\n"));
997285809Sscottl
998285809Sscottl  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
999285809Sscottl
1000285809Sscottl  /*
1001285809Sscottl   * Check that the only pending I/O matches taskTag. If not return tiError.
1002285809Sscottl   */
1003285809Sscottl  tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
1004285809Sscottl
1005285809Sscottl  elementHdr = oneDeviceData->satIoLinkList.flink;
1006285809Sscottl
1007285809Sscottl  while (elementHdr != &oneDeviceData->satIoLinkList)
1008285809Sscottl  {
1009285809Sscottl    satTempIOContext = SMLIST_OBJECT_BASE( smSatIOContext_t,
1010285809Sscottl                                           satIoContextLink,
1011285809Sscottl                                           elementHdr );
1012285809Sscottl
1013285809Sscottl    if ( satTempIOContext != agNULL)
1014285809Sscottl    {
1015285809Sscottl      smIORequestBody = (smIORequestBody_t *) satTempIOContext->smRequestBody;
1016285809Sscottl      smIOReq = smIORequestBody->smIORequest;
1017285809Sscottl    }
1018285809Sscottl
1019285809Sscottl    elementHdr = elementHdr->flink;   /* for the next while loop  */
1020285809Sscottl
1021285809Sscottl    /*
1022285809Sscottl     * Check if the tag matches
1023285809Sscottl     */
1024285809Sscottl    if ( smIOReq == taskTag)
1025285809Sscottl    {
1026285809Sscottl      found = agTRUE;
1027285809Sscottl      satIOContext->satToBeAbortedIOContext = satTempIOContext;
1028285809Sscottl      SM_DBG1(("smsatTmAbortTask: found matching tag.\n"));
1029285809Sscottl
1030285809Sscottl      break;
1031285809Sscottl
1032285809Sscottl    } /* if matching tag */
1033285809Sscottl
1034285809Sscottl  } /* while loop */
1035285809Sscottl
1036285809Sscottl  tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
1037285809Sscottl
1038285809Sscottl  if (found == agFALSE )
1039285809Sscottl  {
1040285809Sscottl    SM_DBG1(("smsatTmAbortTask: *** REJECT *** no match!!!\n"));
1041285809Sscottl
1042285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
1043285809Sscottl    /* clean up TD layer's smIORequestBody */
1044285809Sscottl    if (smIORequestBody)
1045285809Sscottl    {
1046285809Sscottl      if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL)
1047285809Sscottl      {
1048285809Sscottl        tdsmFreeMemory(
1049285809Sscottl                     smRoot,
1050285809Sscottl                     smIORequestBody->IOType.InitiatorTMIO.osMemHandle,
1051285809Sscottl                     sizeof(smIORequestBody_t)
1052285809Sscottl                     );
1053285809Sscottl      }
1054285809Sscottl    }
1055285809Sscottl    else
1056285809Sscottl    {
1057285809Sscottl      SM_DBG1(("smsatTmAbortTask: smIORequestBody is NULL!!!\n"));
1058285809Sscottl    }
1059285809Sscottl
1060285809Sscottl    return SM_RC_FAILURE;
1061285809Sscottl  }
1062285809Sscottl
1063285809Sscottl  if (satTempIOContext == agNULL)
1064285809Sscottl  {
1065285809Sscottl    SM_DBG1(("smsatTmAbortTask: satTempIOContext is NULL!!!\n"));
1066285809Sscottl    return SM_RC_FAILURE;
1067285809Sscottl  }
1068285809Sscottl
1069285809Sscottl  /*
1070285809Sscottl   * Save smIORequest, will be returned at device reset completion to return
1071285809Sscottl   * the TM completion.
1072285809Sscottl   */
1073285809Sscottl  oneDeviceData->satTmTaskTag = currentTaskTag;
1074285809Sscottl
1075285809Sscottl  /*
1076285809Sscottl   * Set flag to indicate device in recovery mode.
1077285809Sscottl   */
1078285809Sscottl  oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
1079285809Sscottl
1080285809Sscottl
1081285809Sscottl  /*
1082285809Sscottl   * Issue SATA device reset or check power mode.. Set flag to to automatically abort
1083285809Sscottl   * at the completion of SATA device reset.
1084285809Sscottl   * SAT r09 p25
1085285809Sscottl   */
1086285809Sscottl  oneDeviceData->satAbortAfterReset = agTRUE;
1087285809Sscottl
1088285809Sscottl  if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
1089285809Sscottl       (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
1090285809Sscottl      )
1091285809Sscottl  {
1092285809Sscottl    SM_DBG1(("smsatTmAbortTask: calling satStartCheckPowerMode!!!\n"));
1093285809Sscottl    /* send check power mode */
1094285809Sscottl    status = smsatStartCheckPowerMode(
1095285809Sscottl                                       smRoot,
1096285809Sscottl                                       currentTaskTag, /* currentTaskTag */
1097285809Sscottl                                       smDeviceHandle,
1098285809Sscottl                                       smScsiRequest, /* NULL */
1099285809Sscottl                                       satIOContext
1100285809Sscottl                                     );
1101285809Sscottl  }
1102285809Sscottl  else
1103285809Sscottl  {
1104285809Sscottl    SM_DBG1(("smsatTmAbortTask: calling satStartResetDevice!!!\n"));
1105285809Sscottl    /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */
1106285809Sscottl    status = smsatStartResetDevice(
1107285809Sscottl                                    smRoot,
1108285809Sscottl                                    currentTaskTag, /* currentTaskTag */
1109285809Sscottl                                    smDeviceHandle,
1110285809Sscottl                                    smScsiRequest, /* NULL */
1111285809Sscottl                                    satIOContext
1112285809Sscottl                                  );
1113285809Sscottl  }
1114285809Sscottl  return status;
1115285809Sscottl}
1116285809Sscottl
1117285809Sscottl/* satTM() */
1118285809SscottlosGLOBAL bit32
1119285809SscottlsmsatTaskManagement(
1120285809Sscottl                    smRoot_t          *smRoot,
1121285809Sscottl                    smDeviceHandle_t  *smDeviceHandle,
1122285809Sscottl                    bit32             task,
1123285809Sscottl                    smLUN_t           *lun,
1124285809Sscottl                    smIORequest_t     *taskTag, /* io to be aborted */
1125285809Sscottl                    smIORequest_t     *currentTaskTag, /* task management */
1126285809Sscottl                    smIORequestBody_t *smIORequestBody
1127285809Sscottl       )
1128285809Sscottl{
1129285809Sscottl  smSatIOContext_t              *satIOContext = agNULL;
1130285809Sscottl  smDeviceData_t              *oneDeviceData = agNULL;
1131285809Sscottl  bit32                       status;
1132285809Sscottl
1133285809Sscottl  SM_DBG1(("smsatTaskManagement: start\n"));
1134285809Sscottl  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
1135285809Sscottl
1136285809Sscottl  satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
1137285809Sscottl
1138285809Sscottl  satIOContext->pSatDevData   = oneDeviceData;
1139285809Sscottl  satIOContext->pFis          =
1140285809Sscottl    &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
1141285809Sscottl
1142285809Sscottl
1143285809Sscottl  satIOContext->smRequestBody = smIORequestBody;
1144285809Sscottl  satIOContext->psmDeviceHandle = smDeviceHandle;
1145285809Sscottl  satIOContext->satIntIoContext  = agNULL;
1146285809Sscottl  satIOContext->satOrgIOContext  = agNULL;
1147285809Sscottl
1148285809Sscottl  /* followings are used only for internal IO */
1149285809Sscottl  satIOContext->currentLBA = 0;
1150285809Sscottl  satIOContext->OrgTL = 0;
1151285809Sscottl
1152285809Sscottl  /* saving task in satIOContext */
1153285809Sscottl  satIOContext->TMF = task;
1154285809Sscottl
1155285809Sscottl  satIOContext->satToBeAbortedIOContext = agNULL;
1156285809Sscottl
1157285809Sscottl  if (task == AG_ABORT_TASK)
1158285809Sscottl  {
1159285809Sscottl    status = smsatTmAbortTask( smRoot,
1160285809Sscottl                               currentTaskTag,
1161285809Sscottl                               smDeviceHandle,
1162285809Sscottl                               agNULL,
1163285809Sscottl                               satIOContext,
1164285809Sscottl                               taskTag);
1165285809Sscottl
1166285809Sscottl    return status;
1167285809Sscottl  }
1168285809Sscottl  else
1169285809Sscottl  {
1170285809Sscottl    SM_DBG1(("smsatTaskManagement: UNSUPPORTED TM task=0x%x!!!\n", task ));
1171285809Sscottl
1172285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
1173285809Sscottl
1174285809Sscottl    return SM_RC_FAILURE;
1175285809Sscottl  }
1176285809Sscottl
1177285809Sscottl  return SM_RC_SUCCESS;
1178285809Sscottl}
1179285809Sscottl
1180285809Sscottl
1181285809SscottlosGLOBAL bit32
1182285809SscottlsmPhyControlSend(
1183285809Sscottl                  smRoot_t             *smRoot,
1184285809Sscottl                  smDeviceData_t       *oneDeviceData, /* sata disk itself */
1185285809Sscottl                  bit8                 phyOp,
1186285809Sscottl                  smIORequest_t        *CurrentTaskTag,
1187285809Sscottl                  bit32                queueNumber
1188285809Sscottl                )
1189285809Sscottl{
1190285809Sscottl  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1191285809Sscottl  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1192285809Sscottl  agsaRoot_t                *agRoot = smAllShared->agRoot;
1193285809Sscottl  agsaDevHandle_t           *agExpDevHandle;
1194285809Sscottl  smpReqPhyControl_t        smpPhyControlReq;
1195285809Sscottl  void                      *osMemHandle;
1196285809Sscottl  bit32                     PhysUpper32;
1197285809Sscottl  bit32                     PhysLower32;
1198285809Sscottl  bit32                     memAllocStatus;
1199285809Sscottl  bit32                     expectedRspLen = 0;
1200285809Sscottl  smSMPRequestBody_t        *smSMPRequestBody;
1201285809Sscottl  agsaSASRequestBody_t      *agSASRequestBody;
1202285809Sscottl  agsaSMPFrame_t            *agSMPFrame;
1203285809Sscottl  agsaIORequest_t           *agIORequest;
1204285809Sscottl//  agsaDevHandle_t           *agDevHandle;
1205285809Sscottl  smSMPFrameHeader_t        smSMPFrameHeader;
1206285809Sscottl  bit32                     status;
1207285809Sscottl  bit8                      *pSmpBody; /* smp payload itself w/o first 4 bytes(header) */
1208285809Sscottl  bit32                     smpBodySize; /* smp payload size w/o first 4 bytes(header) */
1209285809Sscottl  bit32                     agRequestType;
1210285809Sscottl
1211285809Sscottl  SM_DBG2(("smPhyControlSend: start\n"));
1212285809Sscottl
1213285809Sscottl  agExpDevHandle = oneDeviceData->agExpDevHandle;
1214285809Sscottl
1215285809Sscottl  if (agExpDevHandle == agNULL)
1216285809Sscottl  {
1217285809Sscottl    SM_DBG1(("smPhyControlSend: agExpDevHandle is NULL!!!\n"));
1218285809Sscottl    return SM_RC_FAILURE;
1219285809Sscottl  }
1220285809Sscottl
1221285809Sscottl  SM_DBG5(("smPhyControlSend: phyID %d\n", oneDeviceData->phyID));
1222285809Sscottl
1223285809Sscottl  sm_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t));
1224285809Sscottl
1225285809Sscottl  /* fill in SMP payload */
1226285809Sscottl  smpPhyControlReq.phyIdentifier = (bit8)oneDeviceData->phyID;
1227285809Sscottl  smpPhyControlReq.phyOperation = phyOp;
1228285809Sscottl
1229285809Sscottl  /* allocate smp and send it */
1230285809Sscottl  memAllocStatus = tdsmAllocMemory(
1231285809Sscottl                                   smRoot,
1232285809Sscottl                                   &osMemHandle,
1233285809Sscottl                                   (void **)&smSMPRequestBody,
1234285809Sscottl                                   &PhysUpper32,
1235285809Sscottl                                   &PhysLower32,
1236285809Sscottl                                   8,
1237285809Sscottl                                   sizeof(smSMPRequestBody_t),
1238285809Sscottl                                   agTRUE
1239285809Sscottl                                   );
1240285809Sscottl
1241285809Sscottl  if (memAllocStatus != SM_RC_SUCCESS)
1242285809Sscottl  {
1243285809Sscottl    SM_DBG1(("smPhyControlSend: tdsmAllocMemory failed...!!!\n"));
1244285809Sscottl    return SM_RC_FAILURE;
1245285809Sscottl  }
1246285809Sscottl
1247285809Sscottl  if (smSMPRequestBody == agNULL)
1248285809Sscottl  {
1249285809Sscottl    SM_DBG1(("smPhyControlSend: tdsmAllocMemory returned NULL smSMPRequestBody!!!\n"));
1250285809Sscottl    return SM_RC_FAILURE;
1251285809Sscottl  }
1252285809Sscottl
1253285809Sscottl  /* saves mem handle for freeing later */
1254285809Sscottl  smSMPRequestBody->osMemHandle = osMemHandle;
1255285809Sscottl
1256285809Sscottl  /* saves oneDeviceData */
1257285809Sscottl  smSMPRequestBody->smDeviceData = oneDeviceData; /* sata disk */
1258285809Sscottl
1259285809Sscottl  /* saves oneDeviceData */
1260285809Sscottl  smSMPRequestBody->smDevHandle = oneDeviceData->smDevHandle;
1261285809Sscottl
1262285809Sscottl//  agDevHandle = oneDeviceData->agDevHandle;
1263285809Sscottl
1264285809Sscottl  /* save the callback funtion */
1265285809Sscottl  smSMPRequestBody->SMPCompletionFunc = smSMPCompleted; /* in satcb.c */
1266285809Sscottl
1267285809Sscottl  /* for simulate warm target reset */
1268285809Sscottl  smSMPRequestBody->CurrentTaskTag = CurrentTaskTag;
1269285809Sscottl
1270285809Sscottl  if (CurrentTaskTag != agNULL)
1271285809Sscottl  {
1272285809Sscottl    CurrentTaskTag->smData = smSMPRequestBody;
1273285809Sscottl  }
1274285809Sscottl
1275285809Sscottl  /* initializes the number of SMP retries */
1276285809Sscottl  smSMPRequestBody->retries = 0;
1277285809Sscottl
1278285809Sscottl#ifdef TD_INTERNAL_DEBUG  /* debugging */
1279285809Sscottl  SM_DBG4(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody));
1280285809Sscottl  SM_DBG4(("smPhyControlSend: callback fn %p\n", smSMPRequestBody->SMPCompletionFunc));
1281285809Sscottl#endif
1282285809Sscottl
1283285809Sscottl  agIORequest = &(smSMPRequestBody->agIORequest);
1284285809Sscottl  agIORequest->osData = (void *) smSMPRequestBody;
1285285809Sscottl  agIORequest->sdkData = agNULL; /* SALL takes care of this */
1286285809Sscottl
1287285809Sscottl
1288285809Sscottl  agSASRequestBody = &(smSMPRequestBody->agSASRequestBody);
1289285809Sscottl  agSMPFrame = &(agSASRequestBody->smpFrame);
1290285809Sscottl
1291285809Sscottl  SM_DBG3(("smPhyControlSend: agIORequest %p\n", agIORequest));
1292285809Sscottl  SM_DBG3(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody));
1293285809Sscottl
1294285809Sscottl  expectedRspLen = 4;
1295285809Sscottl
1296285809Sscottl  pSmpBody = (bit8 *)&smpPhyControlReq;
1297285809Sscottl  smpBodySize = sizeof(smpReqPhyControl_t);
1298285809Sscottl  agRequestType = AGSA_SMP_INIT_REQ;
1299285809Sscottl
1300285809Sscottl  if (SMIsSPC(agRoot))
1301285809Sscottl  {
1302285809Sscottl    if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */
1303285809Sscottl    {
1304285809Sscottl      SM_DBG3(("smPhyControlSend: DIRECT smp payload\n"));
1305285809Sscottl      sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t));
1306285809Sscottl      sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
1307285809Sscottl
1308285809Sscottl      /* SMP header */
1309285809Sscottl      smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
1310285809Sscottl      smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL;
1311285809Sscottl      smSMPFrameHeader.smpFunctionResult = 0;
1312285809Sscottl      smSMPFrameHeader.smpReserved = 0;
1313285809Sscottl
1314285809Sscottl      sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4);
1315285809Sscottl      sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
1316285809Sscottl
1317285809Sscottl      /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
1318285809Sscottl      agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload;
1319285809Sscottl      agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
1320285809Sscottl      /* to specify DIRECT SMP response */
1321285809Sscottl      agSMPFrame->inFrameLen = 0;
1322285809Sscottl
1323285809Sscottl      /* temporary solution for T2D Combo*/
1324285809Sscottl#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
1325285809Sscottl      /* force smp repsonse to be direct */
1326285809Sscottl      agSMPFrame->expectedRespLen = 0;
1327285809Sscottl#else
1328285809Sscottl      agSMPFrame->expectedRespLen = expectedRspLen;
1329285809Sscottl#endif
1330285809Sscottl  //    smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
1331285809Sscottl  //    smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen);
1332285809Sscottl  //    smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t));
1333285809Sscottl    }
1334285809Sscottl    else
1335285809Sscottl    {
1336285809Sscottl      SM_DBG1(("smPhyControlSend: INDIRECT smp payload, not supported!!!\n"));
1337285809Sscottl      tdsmFreeMemory(
1338285809Sscottl                     smRoot,
1339285809Sscottl                     osMemHandle,
1340285809Sscottl                     sizeof(smSMPRequestBody_t)
1341285809Sscottl                     );
1342285809Sscottl
1343285809Sscottl      return SM_RC_FAILURE;
1344285809Sscottl    }
1345285809Sscottl  }
1346285809Sscottl  else /* SPCv controller */
1347285809Sscottl  {
1348285809Sscottl    /* only direct mode for both request and response */
1349285809Sscottl    SM_DBG3(("smPhyControlSend: DIRECT smp payload\n"));
1350285809Sscottl    agSMPFrame->flag = 0;
1351285809Sscottl    sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t));
1352285809Sscottl    sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
1353285809Sscottl
1354285809Sscottl    /* SMP header */
1355285809Sscottl    smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
1356285809Sscottl    smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL;
1357285809Sscottl    smSMPFrameHeader.smpFunctionResult = 0;
1358285809Sscottl    smSMPFrameHeader.smpReserved = 0;
1359285809Sscottl
1360285809Sscottl    sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4);
1361285809Sscottl    sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
1362285809Sscottl
1363285809Sscottl    /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
1364285809Sscottl    agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload;
1365285809Sscottl    agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
1366285809Sscottl    /* to specify DIRECT SMP response */
1367285809Sscottl    agSMPFrame->inFrameLen = 0;
1368285809Sscottl
1369285809Sscottl    /* temporary solution for T2D Combo*/
1370285809Sscottl#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
1371285809Sscottl    /* force smp repsonse to be direct */
1372285809Sscottl    agSMPFrame->expectedRespLen = 0;
1373285809Sscottl#else
1374285809Sscottl    agSMPFrame->expectedRespLen = expectedRspLen;
1375285809Sscottl#endif
1376285809Sscottl//    smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
1377285809Sscottl//    smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen);
1378285809Sscottl//    smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t));
1379285809Sscottl  }
1380285809Sscottl
1381285809Sscottl  status = saSMPStart(
1382285809Sscottl                      agRoot,
1383285809Sscottl                      agIORequest,
1384285809Sscottl                      queueNumber,
1385285809Sscottl                      agExpDevHandle,
1386285809Sscottl                      agRequestType,
1387285809Sscottl                      agSASRequestBody,
1388285809Sscottl                      &smSMPCompletedCB
1389285809Sscottl                      );
1390285809Sscottl
1391285809Sscottl  if (status == AGSA_RC_SUCCESS)
1392285809Sscottl  {
1393285809Sscottl    return SM_RC_SUCCESS;
1394285809Sscottl  }
1395285809Sscottl  else if (status == AGSA_RC_BUSY)
1396285809Sscottl  {
1397285809Sscottl    SM_DBG1(("smPhyControlSend: saSMPStart is busy!!!\n"));
1398285809Sscottl    tdsmFreeMemory(
1399285809Sscottl                   smRoot,
1400285809Sscottl                   osMemHandle,
1401285809Sscottl                   sizeof(smSMPRequestBody_t)
1402285809Sscottl                   );
1403285809Sscottl
1404285809Sscottl    return SM_RC_BUSY;
1405285809Sscottl  }
1406285809Sscottl  else /* AGSA_RC_FAILURE */
1407285809Sscottl  {
1408285809Sscottl    SM_DBG1(("smPhyControlSend: saSMPStart is failed. status %d!!!\n", status));
1409285809Sscottl    tdsmFreeMemory(
1410285809Sscottl                   smRoot,
1411285809Sscottl                   osMemHandle,
1412285809Sscottl                   sizeof(smSMPRequestBody_t)
1413285809Sscottl                   );
1414285809Sscottl
1415285809Sscottl    return SM_RC_FAILURE;
1416285809Sscottl  }
1417285809Sscottl}
1418285809Sscottl
1419285809Sscottl/* free IO which are internally completed within SM
1420285809Sscottl   counterpart is
1421285809Sscottl   osGLOBAL smIORequestBody_t *
1422285809Sscottl   smDequeueIO(smRoot_t          *smRoot)
1423285809Sscottl*/
1424285809SscottlosGLOBAL void
1425285809SscottlsmEnqueueIO(
1426285809Sscottl             smRoot_t               *smRoot,
1427285809Sscottl             smSatIOContext_t         *satIOContext
1428285809Sscottl      )
1429285809Sscottl{
1430285809Sscottl  smIntRoot_t          *smIntRoot = agNULL;
1431285809Sscottl  smIntContext_t       *smAllShared = agNULL;
1432285809Sscottl  smIORequestBody_t    *smIORequestBody;
1433285809Sscottl
1434285809Sscottl  SM_DBG3(("smEnqueueIO: start\n"));
1435285809Sscottl  smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
1436285809Sscottl  smIntRoot       = (smIntRoot_t *)smRoot->smData;
1437285809Sscottl  smAllShared     = (smIntContext_t *)&smIntRoot->smAllShared;
1438285809Sscottl
1439285809Sscottl  /* enque back to smAllShared->freeIOList */
1440285809Sscottl  if (satIOContext->satIntIoContext == agNULL)
1441285809Sscottl  {
1442285809Sscottl    SM_DBG2(("smEnqueueIO: external command!!!, io ID %d!!!\n", smIORequestBody->id));
1443285809Sscottl    /* debugging only */
1444285809Sscottl    if (smIORequestBody->satIoBodyLink.flink == agNULL)
1445285809Sscottl    {
1446285809Sscottl      SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id));
1447285809Sscottl    }
1448285809Sscottl    if (smIORequestBody->satIoBodyLink.blink == agNULL)
1449285809Sscottl    {
1450285809Sscottl      SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id));
1451285809Sscottl    }
1452285809Sscottl  }
1453285809Sscottl  else
1454285809Sscottl  {
1455285809Sscottl    SM_DBG2(("smEnqueueIO: internal command!!!, io ID %d!!!\n", smIORequestBody->id));
1456285809Sscottl    /* debugging only */
1457285809Sscottl    if (smIORequestBody->satIoBodyLink.flink == agNULL)
1458285809Sscottl    {
1459285809Sscottl      SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id));
1460285809Sscottl    }
1461285809Sscottl    if (smIORequestBody->satIoBodyLink.blink == agNULL)
1462285809Sscottl    {
1463285809Sscottl      SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id));
1464285809Sscottl    }
1465285809Sscottl  }
1466285809Sscottl
1467285809Sscottl  if (smIORequestBody->smIORequest == agNULL)
1468285809Sscottl  {
1469285809Sscottl    SM_DBG1(("smEnqueueIO: smIORequest is NULL, io ID %d!!!\n", smIORequestBody->id));
1470285809Sscottl  }
1471285809Sscottl
1472285809Sscottl  if (smIORequestBody->InUse == agTRUE)
1473285809Sscottl  {
1474285809Sscottl    smIORequestBody->InUse = agFALSE;
1475285809Sscottl    tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
1476285809Sscottl    SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink));
1477285809Sscottl    SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->freeIOList));
1478285809Sscottl    tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
1479285809Sscottl  }
1480285809Sscottl  else
1481285809Sscottl  {
1482285809Sscottl    SM_DBG2(("smEnqueueIO: check!!!, io ID %d!!!\n", smIORequestBody->id));
1483285809Sscottl  }
1484285809Sscottl
1485285809Sscottl
1486285809Sscottl  return;
1487285809Sscottl}
1488285809Sscottl
1489285809SscottlFORCEINLINE void
1490285809SscottlsmsatFreeIntIoResource(
1491285809Sscottl       smRoot_t              *smRoot,
1492285809Sscottl       smDeviceData_t        *satDevData,
1493285809Sscottl       smSatInternalIo_t     *satIntIo
1494285809Sscottl       )
1495285809Sscottl{
1496285809Sscottl  SM_DBG3(("smsatFreeIntIoResource: start\n"));
1497285809Sscottl
1498285809Sscottl  if (satIntIo == agNULL)
1499285809Sscottl  {
1500285809Sscottl    SM_DBG2(("smsatFreeIntIoResource: allowed call\n"));
1501285809Sscottl    return;
1502285809Sscottl  }
1503285809Sscottl
1504285809Sscottl  /* sets the original smIOrequest to agNULL for internally generated ATA cmnd */
1505285809Sscottl  satIntIo->satOrgSmIORequest = agNULL;
1506285809Sscottl
1507285809Sscottl  /*
1508285809Sscottl   * Free DMA memory if previosly alocated
1509285809Sscottl   */
1510285809Sscottl  if (satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength != 0)
1511285809Sscottl  {
1512285809Sscottl    SM_DBG3(("smsatFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
1513285809Sscottl    SM_DBG3(("smsatFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
1514285809Sscottl
1515285809Sscottl    tdsmFreeMemory( smRoot,
1516285809Sscottl                    satIntIo->satIntDmaMem.osHandle,
1517285809Sscottl                    satIntIo->satIntDmaMem.totalLength);
1518285809Sscottl    satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0;
1519285809Sscottl  }
1520285809Sscottl
1521285809Sscottl  if (satIntIo->satIntReqBodyMem.totalLength != 0)
1522285809Sscottl  {
1523285809Sscottl    SM_DBG3(("smsatFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
1524285809Sscottl    /*
1525285809Sscottl     * Free mem allocated for Req body
1526285809Sscottl     */
1527285809Sscottl    tdsmFreeMemory( smRoot,
1528285809Sscottl                    satIntIo->satIntReqBodyMem.osHandle,
1529285809Sscottl                    satIntIo->satIntReqBodyMem.totalLength);
1530285809Sscottl
1531285809Sscottl    satIntIo->satIntReqBodyMem.totalLength = 0;
1532285809Sscottl  }
1533285809Sscottl
1534285809Sscottl  SM_DBG3(("smsatFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1535285809Sscottl  /*
1536285809Sscottl   * Return satIntIo to the free list
1537285809Sscottl   */
1538285809Sscottl  tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1539285809Sscottl  SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
1540285809Sscottl  SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
1541285809Sscottl  tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1542285809Sscottl
1543285809Sscottl  return;
1544285809Sscottl}
1545285809Sscottl//start here
1546285809SscottlosGLOBAL smSatInternalIo_t *
1547285809SscottlsmsatAllocIntIoResource(
1548285809Sscottl                        smRoot_t              *smRoot,
1549285809Sscottl                        smIORequest_t         *smIORequest,
1550285809Sscottl                        smDeviceData_t        *satDevData,
1551285809Sscottl                        bit32                 dmaAllocLength,
1552285809Sscottl                        smSatInternalIo_t     *satIntIo)
1553285809Sscottl{
1554285809Sscottl  smList_t          *smList = agNULL;
1555285809Sscottl  bit32             memAllocStatus;
1556285809Sscottl
1557285809Sscottl  SM_DBG3(("smsatAllocIntIoResource: start\n"));
1558285809Sscottl  SM_DBG3(("smsatAllocIntIoResource: satIntIo %p\n", satIntIo));
1559285809Sscottl  if (satDevData == agNULL)
1560285809Sscottl  {
1561285809Sscottl    SM_DBG1(("smsatAllocIntIoResource: ***** ASSERT satDevData is null!!!\n"));
1562285809Sscottl    return agNULL;
1563285809Sscottl  }
1564285809Sscottl
1565285809Sscottl  tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1566285809Sscottl  if (!SMLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
1567285809Sscottl  {
1568285809Sscottl    SMLIST_DEQUEUE_FROM_HEAD(&smList, &(satDevData->satFreeIntIoLinkList));
1569285809Sscottl  }
1570285809Sscottl  else
1571285809Sscottl  {
1572285809Sscottl    tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1573285809Sscottl    SM_DBG1(("smsatAllocIntIoResource() no more internal free link!!!\n"));
1574285809Sscottl    return agNULL;
1575285809Sscottl  }
1576285809Sscottl
1577285809Sscottl  if (smList == agNULL)
1578285809Sscottl  {
1579285809Sscottl    tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1580285809Sscottl    SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc satIntIo!!!\n"));
1581285809Sscottl    return agNULL;
1582285809Sscottl  }
1583285809Sscottl
1584285809Sscottl  satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList);
1585285809Sscottl  SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1586285809Sscottl
1587285809Sscottl  /* Put in active list */
1588285809Sscottl  SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
1589285809Sscottl  SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
1590285809Sscottl  tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1591285809Sscottl
1592285809Sscottl#ifdef REMOVED
1593285809Sscottl  /* Put in active list */
1594285809Sscottl  tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1595285809Sscottl  SMLIST_DEQUEUE_THIS (smList);
1596285809Sscottl  SMLIST_ENQUEUE_AT_TAIL (smList, &(satDevData->satActiveIntIoLinkList));
1597285809Sscottl  tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1598285809Sscottl
1599285809Sscottl  satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList);
1600285809Sscottl  SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1601285809Sscottl#endif
1602285809Sscottl
1603285809Sscottl  /*
1604285809Sscottl    typedef struct
1605285809Sscottl    {
1606285809Sscottl      tdList_t                    satIntIoLink;
1607285809Sscottl      smIORequest_t               satIntSmIORequest;
1608285809Sscottl      void                        *satIntRequestBody;
1609285809Sscottl      smScsiInitiatorRequest_t    satIntSmScsiXchg;
1610285809Sscottl      smMem_t                     satIntDmaMem;
1611285809Sscottl      smMem_t                     satIntReqBodyMem;
1612285809Sscottl      bit32                       satIntFlag;
1613285809Sscottl    } smSatInternalIo_t;
1614285809Sscottl  */
1615285809Sscottl
1616285809Sscottl  /*
1617285809Sscottl   * Allocate mem for Request Body
1618285809Sscottl   */
1619285809Sscottl  satIntIo->satIntReqBodyMem.totalLength = sizeof(smIORequestBody_t);
1620285809Sscottl
1621285809Sscottl  memAllocStatus = tdsmAllocMemory( smRoot,
1622285809Sscottl                                    &satIntIo->satIntReqBodyMem.osHandle,
1623285809Sscottl                                    (void **)&satIntIo->satIntRequestBody,
1624285809Sscottl                                    &satIntIo->satIntReqBodyMem.physAddrUpper,
1625285809Sscottl                                    &satIntIo->satIntReqBodyMem.physAddrLower,
1626285809Sscottl                                    8,
1627285809Sscottl                                    satIntIo->satIntReqBodyMem.totalLength,
1628285809Sscottl                                    agTRUE );
1629285809Sscottl
1630285809Sscottl  if (memAllocStatus != SM_RC_SUCCESS)
1631285809Sscottl  {
1632285809Sscottl    SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for Req Body!!!\n"));
1633285809Sscottl    /*
1634285809Sscottl     * Return satIntIo to the free list
1635285809Sscottl     */
1636285809Sscottl    tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1637285809Sscottl    SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
1638285809Sscottl    SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
1639285809Sscottl    tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1640285809Sscottl
1641285809Sscottl    return agNULL;
1642285809Sscottl  }
1643285809Sscottl
1644285809Sscottl  /*
1645285809Sscottl   *   Allocate DMA memory if required
1646285809Sscottl   */
1647285809Sscottl  if (dmaAllocLength != 0)
1648285809Sscottl  {
1649285809Sscottl    satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
1650285809Sscottl
1651285809Sscottl    memAllocStatus = tdsmAllocMemory( smRoot,
1652285809Sscottl                                      &satIntIo->satIntDmaMem.osHandle,
1653285809Sscottl                                      (void **)&satIntIo->satIntDmaMem.virtPtr,
1654285809Sscottl                                      &satIntIo->satIntDmaMem.physAddrUpper,
1655285809Sscottl                                      &satIntIo->satIntDmaMem.physAddrLower,
1656285809Sscottl                                      8,
1657285809Sscottl                                      satIntIo->satIntDmaMem.totalLength,
1658285809Sscottl                                      agFALSE);
1659285809Sscottl    SM_DBG3(("smsatAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
1660285809Sscottl    SM_DBG3(("smsatAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
1661285809Sscottl
1662285809Sscottl    if (memAllocStatus != SM_RC_SUCCESS)
1663285809Sscottl    {
1664285809Sscottl      SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for DMA mem!!!\n"));
1665285809Sscottl      /*
1666285809Sscottl       * Return satIntIo to the free list
1667285809Sscottl       */
1668285809Sscottl      tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1669285809Sscottl      SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
1670285809Sscottl      SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
1671285809Sscottl      tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1672285809Sscottl
1673285809Sscottl      /*
1674285809Sscottl       * Free mem allocated for Req body
1675285809Sscottl       */
1676285809Sscottl      tdsmFreeMemory( smRoot,
1677285809Sscottl                      satIntIo->satIntReqBodyMem.osHandle,
1678285809Sscottl                      satIntIo->satIntReqBodyMem.totalLength);
1679285809Sscottl
1680285809Sscottl      return agNULL;
1681285809Sscottl    }
1682285809Sscottl  }
1683285809Sscottl
1684285809Sscottl  /*
1685285809Sscottl    typedef struct
1686285809Sscottl    {
1687285809Sscottl      smList_t                    satIntIoLink;
1688285809Sscottl      smIORequest_t               satIntSmIORequest;
1689285809Sscottl      void                        *satIntRequestBody;
1690285809Sscottl      smScsiInitiatorRequest_t    satIntSmScsiXchg;
1691285809Sscottl      smMem_t                     satIntDmaMem;
1692285809Sscottl      smMem_t                     satIntReqBodyMem;
1693285809Sscottl      bit32                       satIntFlag;
1694285809Sscottl    } smSatInternalIo_t;
1695285809Sscottl  */
1696285809Sscottl
1697285809Sscottl  /*
1698285809Sscottl   * Initialize satIntSmIORequest field
1699285809Sscottl   */
1700285809Sscottl  satIntIo->satIntSmIORequest.tdData = agNULL;  /* Not used for internal SAT I/O */
1701285809Sscottl  satIntIo->satIntSmIORequest.smData = satIntIo->satIntRequestBody;
1702285809Sscottl
1703285809Sscottl  /*
1704285809Sscottl   * saves the original smIOrequest
1705285809Sscottl   */
1706285809Sscottl  satIntIo->satOrgSmIORequest = smIORequest;
1707285809Sscottl  /*
1708285809Sscottl    typedef struct tiIniScsiCmnd
1709285809Sscottl    {
1710285809Sscottl      tiLUN_t     lun;
1711285809Sscottl      bit32       expDataLength;
1712285809Sscottl      bit32       taskAttribute;
1713285809Sscottl      bit32       crn;
1714285809Sscottl      bit8        cdb[16];
1715285809Sscottl    } tiIniScsiCmnd_t;
1716285809Sscottl
1717285809Sscottl    typedef struct tiScsiInitiatorExchange
1718285809Sscottl    {
1719285809Sscottl      void                *sglVirtualAddr;
1720285809Sscottl      tiIniScsiCmnd_t     scsiCmnd;
1721285809Sscottl      tiSgl_t             agSgl1;
1722285809Sscottl      tiSgl_t             agSgl2;
1723285809Sscottl      tiDataDirection_t   dataDirection;
1724285809Sscottl    } tiScsiInitiatorRequest_t;
1725285809Sscottl
1726285809Sscottl  */
1727285809Sscottl
1728285809Sscottl  /*
1729285809Sscottl   * Initialize satIntSmScsiXchg. Since the internal SAT request is NOT
1730285809Sscottl   * originated from SCSI request, only the following fields are initialized:
1731285809Sscottl   *  - sglVirtualAddr if DMA transfer is involved
1732285809Sscottl   *  - agSgl1 if DMA transfer is involved
1733285809Sscottl   *  - expDataLength in scsiCmnd since this field is read by smsataLLIOStart()
1734285809Sscottl   */
1735285809Sscottl  if (dmaAllocLength != 0)
1736285809Sscottl  {
1737285809Sscottl    satIntIo->satIntSmScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
1738285809Sscottl
1739285809Sscottl    OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntSmScsiXchg.smSgl1.len, 0,
1740285809Sscottl                     satIntIo->satIntDmaMem.totalLength);
1741285809Sscottl    satIntIo->satIntSmScsiXchg.smSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
1742285809Sscottl    satIntIo->satIntSmScsiXchg.smSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
1743285809Sscottl    satIntIo->satIntSmScsiXchg.smSgl1.type  = tiSgl;
1744285809Sscottl
1745285809Sscottl    satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
1746285809Sscottl  }
1747285809Sscottl  else
1748285809Sscottl  {
1749285809Sscottl    satIntIo->satIntSmScsiXchg.sglVirtualAddr = agNULL;
1750285809Sscottl
1751285809Sscottl    satIntIo->satIntSmScsiXchg.smSgl1.len   = 0;
1752285809Sscottl    satIntIo->satIntSmScsiXchg.smSgl1.lower = 0;
1753285809Sscottl    satIntIo->satIntSmScsiXchg.smSgl1.upper = 0;
1754285809Sscottl    satIntIo->satIntSmScsiXchg.smSgl1.type  = tiSgl;
1755285809Sscottl
1756285809Sscottl    satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0;
1757285809Sscottl  }
1758285809Sscottl
1759285809Sscottl  SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len));
1760285809Sscottl
1761285809Sscottl  SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper));
1762285809Sscottl
1763285809Sscottl  SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower));
1764285809Sscottl
1765285809Sscottl  SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type));
1766285809Sscottl  SM_DBG5(("smsatAllocIntIoResource: return satIntIo %p\n", satIntIo));
1767285809Sscottl  return  satIntIo;
1768285809Sscottl}
1769285809Sscottl
1770285809SscottlosGLOBAL smDeviceData_t *
1771285809SscottlsmAddToSharedcontext(
1772285809Sscottl                     smRoot_t                   *smRoot,
1773285809Sscottl                     agsaDevHandle_t            *agDevHandle,
1774285809Sscottl                     smDeviceHandle_t           *smDeviceHandle,
1775285809Sscottl                     agsaDevHandle_t            *agExpDevHandle,
1776285809Sscottl                     bit32                      phyID
1777285809Sscottl                    )
1778285809Sscottl{
1779285809Sscottl  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1780285809Sscottl  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1781285809Sscottl  smDeviceData_t            *oneDeviceData = agNULL;
1782285809Sscottl  smList_t                  *DeviceListList;
1783285809Sscottl  bit32                     new_device = agTRUE;
1784285809Sscottl
1785285809Sscottl  SM_DBG2(("smAddToSharedcontext: start\n"));
1786285809Sscottl
1787285809Sscottl  /* find a device's existence */
1788285809Sscottl  DeviceListList = smAllShared->MainDeviceList.flink;
1789285809Sscottl  while (DeviceListList != &(smAllShared->MainDeviceList))
1790285809Sscottl  {
1791285809Sscottl    oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList);
1792285809Sscottl    if (oneDeviceData == agNULL)
1793285809Sscottl    {
1794285809Sscottl      SM_DBG1(("smAddToSharedcontext: oneDeviceData is NULL!!!\n"));
1795285809Sscottl      return agNULL;
1796285809Sscottl    }
1797285809Sscottl    if (oneDeviceData->agDevHandle == agDevHandle)
1798285809Sscottl    {
1799285809Sscottl      SM_DBG2(("smAddToSharedcontext: did %d\n", oneDeviceData->id));
1800285809Sscottl      new_device = agFALSE;
1801285809Sscottl      break;
1802285809Sscottl    }
1803285809Sscottl    DeviceListList = DeviceListList->flink;
1804285809Sscottl  }
1805285809Sscottl
1806285809Sscottl  /* new device */
1807285809Sscottl  if (new_device == agTRUE)
1808285809Sscottl  {
1809285809Sscottl    SM_DBG2(("smAddToSharedcontext: new device\n"));
1810285809Sscottl    tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1811285809Sscottl    if (SMLIST_EMPTY(&(smAllShared->FreeDeviceList)))
1812285809Sscottl    {
1813285809Sscottl      tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1814285809Sscottl      SM_DBG1(("smAddToSharedcontext: empty DeviceData FreeLink!!!\n"));
1815285809Sscottl      smDeviceHandle->smData = agNULL;
1816285809Sscottl      return agNULL;
1817285809Sscottl    }
1818285809Sscottl
1819285809Sscottl    SMLIST_DEQUEUE_FROM_HEAD(&DeviceListList, &(smAllShared->FreeDeviceList));
1820285809Sscottl    tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1821285809Sscottl    oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, FreeLink, DeviceListList);
1822285809Sscottl    oneDeviceData->smRoot = smRoot;
1823285809Sscottl    oneDeviceData->agDevHandle = agDevHandle;
1824285809Sscottl    oneDeviceData->valid = agTRUE;
1825285809Sscottl    smDeviceHandle->smData = oneDeviceData;
1826285809Sscottl    oneDeviceData->smDevHandle = smDeviceHandle;
1827285809Sscottl    if (agExpDevHandle == agNULL)
1828285809Sscottl    {
1829285809Sscottl      oneDeviceData->directlyAttached = agTRUE;
1830285809Sscottl    }
1831285809Sscottl    else
1832285809Sscottl    {
1833285809Sscottl      oneDeviceData->directlyAttached = agFALSE;
1834285809Sscottl    }
1835285809Sscottl    oneDeviceData->agExpDevHandle = agExpDevHandle;
1836285809Sscottl    oneDeviceData->phyID = phyID;
1837285809Sscottl    oneDeviceData->satPendingIO = 0;
1838285809Sscottl    oneDeviceData->satPendingNCQIO = 0;
1839285809Sscottl    oneDeviceData->satPendingNONNCQIO = 0;
1840285809Sscottl    /* add the devicedata to the portcontext */
1841285809Sscottl    tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1842285809Sscottl    SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->MainLink), &(smAllShared->MainDeviceList));
1843285809Sscottl    tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1844285809Sscottl    SM_DBG2(("smAddToSharedcontext: new case did %d\n", oneDeviceData->id));
1845285809Sscottl  }
1846285809Sscottl  else
1847285809Sscottl  {
1848285809Sscottl    SM_DBG2(("smAddToSharedcontext: old device\n"));
1849285809Sscottl    oneDeviceData->smRoot = smRoot;
1850285809Sscottl    oneDeviceData->agDevHandle = agDevHandle;
1851285809Sscottl    oneDeviceData->valid = agTRUE;
1852285809Sscottl    smDeviceHandle->smData = oneDeviceData;
1853285809Sscottl    oneDeviceData->smDevHandle = smDeviceHandle;
1854285809Sscottl    if (agExpDevHandle == agNULL)
1855285809Sscottl    {
1856285809Sscottl      oneDeviceData->directlyAttached = agTRUE;
1857285809Sscottl    }
1858285809Sscottl    else
1859285809Sscottl    {
1860285809Sscottl      oneDeviceData->directlyAttached = agFALSE;
1861285809Sscottl    }
1862285809Sscottl    oneDeviceData->agExpDevHandle = agExpDevHandle;
1863285809Sscottl    oneDeviceData->phyID = phyID;
1864285809Sscottl    oneDeviceData->satPendingIO = 0;
1865285809Sscottl    oneDeviceData->satPendingNCQIO = 0;
1866285809Sscottl    oneDeviceData->satPendingNONNCQIO = 0;
1867285809Sscottl    SM_DBG2(("smAddToSharedcontext: old case did %d\n", oneDeviceData->id));
1868285809Sscottl  }
1869285809Sscottl
1870285809Sscottl  return  oneDeviceData;
1871285809Sscottl}
1872285809Sscottl
1873285809SscottlosGLOBAL bit32
1874285809SscottlsmRemoveFromSharedcontext(
1875285809Sscottl                          smRoot_t                      *smRoot,
1876285809Sscottl                          agsaDevHandle_t               *agDevHandle,
1877285809Sscottl                          smDeviceHandle_t              *smDeviceHandle
1878285809Sscottl                         )
1879285809Sscottl{
1880285809Sscottl  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1881285809Sscottl  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1882285809Sscottl  smDeviceData_t            *oneDeviceData = agNULL;
1883285809Sscottl
1884285809Sscottl  SM_DBG2(("smRemoveFromSharedcontext: start\n"));
1885285809Sscottl
1886285809Sscottl  //due to device all and completion
1887285809Sscottl  //smDeviceHandle->smData = agNULL;
1888285809Sscottl
1889285809Sscottl  /* find oneDeviceData from MainLink */
1890285809Sscottl  oneDeviceData = smFindInSharedcontext(smRoot, agDevHandle);
1891285809Sscottl
1892285809Sscottl  if (oneDeviceData == agNULL)
1893285809Sscottl  {
1894285809Sscottl    return SM_RC_FAILURE;
1895285809Sscottl  }
1896285809Sscottl  else
1897285809Sscottl  {
1898285809Sscottl    if (oneDeviceData->valid == agTRUE)
1899285809Sscottl    {
1900285809Sscottl      smDeviceDataReInit(smRoot, oneDeviceData);
1901285809Sscottl      tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1902285809Sscottl      SMLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
1903285809Sscottl      SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(smAllShared->FreeDeviceList));
1904285809Sscottl      tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1905285809Sscottl      return SM_RC_SUCCESS;
1906285809Sscottl    }
1907285809Sscottl    else
1908285809Sscottl    {
1909285809Sscottl      SM_DBG1(("smRemoveFromSharedcontext: did %d bad case!!!\n", oneDeviceData->id));
1910285809Sscottl      return SM_RC_FAILURE;
1911285809Sscottl    }
1912285809Sscottl  }
1913285809Sscottl
1914285809Sscottl}
1915285809Sscottl
1916285809SscottlosGLOBAL smDeviceData_t *
1917285809SscottlsmFindInSharedcontext(
1918285809Sscottl                      smRoot_t                  *smRoot,
1919285809Sscottl                      agsaDevHandle_t           *agDevHandle
1920285809Sscottl                      )
1921285809Sscottl{
1922285809Sscottl  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1923285809Sscottl  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1924285809Sscottl  smDeviceData_t            *oneDeviceData = agNULL;
1925285809Sscottl  smList_t                  *DeviceListList;
1926285809Sscottl
1927285809Sscottl  SM_DBG2(("smFindInSharedcontext: start\n"));
1928285809Sscottl
1929285809Sscottl  tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1930285809Sscottl  if (SMLIST_EMPTY(&(smAllShared->MainDeviceList)))
1931285809Sscottl  {
1932285809Sscottl    SM_DBG1(("smFindInSharedcontext: empty MainDeviceList!!!\n"));
1933285809Sscottl    tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1934285809Sscottl    return agNULL;
1935285809Sscottl  }
1936285809Sscottl  else
1937285809Sscottl  {
1938285809Sscottl    tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1939285809Sscottl  }
1940285809Sscottl
1941285809Sscottl  DeviceListList = smAllShared->MainDeviceList.flink;
1942285809Sscottl  while (DeviceListList != &(smAllShared->MainDeviceList))
1943285809Sscottl  {
1944285809Sscottl    oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList);
1945285809Sscottl    if (oneDeviceData == agNULL)
1946285809Sscottl    {
1947285809Sscottl      SM_DBG1(("smFindInSharedcontext: oneDeviceData is NULL!!!\n"));
1948285809Sscottl      return agNULL;
1949285809Sscottl    }
1950285809Sscottl    if ((oneDeviceData->agDevHandle == agDevHandle) &&
1951285809Sscottl        (oneDeviceData->valid == agTRUE)
1952285809Sscottl       )
1953285809Sscottl    {
1954285809Sscottl      SM_DBG2(("smFindInSharedcontext: found, did %d\n", oneDeviceData->id));
1955285809Sscottl      return oneDeviceData;
1956285809Sscottl    }
1957285809Sscottl    DeviceListList = DeviceListList->flink;
1958285809Sscottl  }
1959285809Sscottl  SM_DBG2(("smFindInSharedcontext: not found\n"));
1960285809Sscottl  return agNULL;
1961285809Sscottl}
1962285809Sscottl
1963285809SscottlosGLOBAL smSatIOContext_t *
1964285809SscottlsmsatPrepareNewIO(
1965285809Sscottl                  smSatInternalIo_t       *satNewIntIo,
1966285809Sscottl                  smIORequest_t           *smOrgIORequest,
1967285809Sscottl                  smDeviceData_t          *satDevData,
1968285809Sscottl                  smIniScsiCmnd_t         *scsiCmnd,
1969285809Sscottl                  smSatIOContext_t        *satOrgIOContext
1970285809Sscottl                 )
1971285809Sscottl{
1972285809Sscottl  smSatIOContext_t        *satNewIOContext;
1973285809Sscottl  smIORequestBody_t       *smNewIORequestBody;
1974285809Sscottl
1975285809Sscottl  SM_DBG3(("smsatPrepareNewIO: start\n"));
1976285809Sscottl
1977285809Sscottl  /* the one to be used; good 8/2/07 */
1978285809Sscottl  satNewIntIo->satOrgSmIORequest = smOrgIORequest; /* this is already done in
1979285809Sscottl                                                      smsatAllocIntIoResource() */
1980285809Sscottl
1981285809Sscottl  smNewIORequestBody = (smIORequestBody_t *)satNewIntIo->satIntRequestBody;
1982285809Sscottl  satNewIOContext = &(smNewIORequestBody->transport.SATA.satIOContext);
1983285809Sscottl
1984285809Sscottl  satNewIOContext->pSatDevData   = satDevData;
1985285809Sscottl  satNewIOContext->pFis          = &(smNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
1986285809Sscottl  satNewIOContext->pScsiCmnd     = &(satNewIntIo->satIntSmScsiXchg.scsiCmnd);
1987285809Sscottl  if (scsiCmnd != agNULL)
1988285809Sscottl  {
1989285809Sscottl    /* saves only CBD; not scsi command for LBA and number of blocks */
1990285809Sscottl    sm_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
1991285809Sscottl  }
1992285809Sscottl  satNewIOContext->pSense        = &(smNewIORequestBody->transport.SATA.sensePayload);
1993285809Sscottl  satNewIOContext->pSmSenseData  = &(smNewIORequestBody->transport.SATA.smSenseData);
1994285809Sscottl  satNewIOContext->pSmSenseData->senseData = satNewIOContext->pSense;
1995285809Sscottl  satNewIOContext->smRequestBody = satNewIntIo->satIntRequestBody;
1996285809Sscottl  satNewIOContext->interruptContext = satNewIOContext->interruptContext;
1997285809Sscottl  satNewIOContext->satIntIoContext  = satNewIntIo;
1998285809Sscottl  satNewIOContext->psmDeviceHandle = satOrgIOContext->psmDeviceHandle;
1999285809Sscottl  satNewIOContext->satOrgIOContext = satOrgIOContext;
2000285809Sscottl  /* saves tiScsiXchg; only for writesame10() */
2001285809Sscottl  satNewIOContext->smScsiXchg = satOrgIOContext->smScsiXchg;
2002285809Sscottl
2003285809Sscottl  return satNewIOContext;
2004285809Sscottl}
2005285809Sscottl
2006285809Sscottl
2007285809SscottlosGLOBAL void
2008285809SscottlsmsatSetDevInfo(
2009285809Sscottl                 smDeviceData_t            *oneDeviceData,
2010285809Sscottl                 agsaSATAIdentifyData_t    *SATAIdData
2011285809Sscottl               )
2012285809Sscottl{
2013285809Sscottl  SM_DBG3(("smsatSetDevInfo: start\n"));
2014285809Sscottl
2015285809Sscottl  oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
2016285809Sscottl  oneDeviceData->satFormatState = agFALSE;
2017285809Sscottl  oneDeviceData->satDeviceFaultState = agFALSE;
2018285809Sscottl  oneDeviceData->satTmTaskTag  = agNULL;
2019285809Sscottl  oneDeviceData->satAbortAfterReset = agFALSE;
2020285809Sscottl  oneDeviceData->satAbortCalled = agFALSE;
2021285809Sscottl  oneDeviceData->satSectorDone  = 0;
2022285809Sscottl
2023285809Sscottl  /* Qeueu depth, Word 75 */
2024285809Sscottl  oneDeviceData->satNCQMaxIO = SATAIdData->queueDepth + 1;
2025285809Sscottl  SM_DBG3(("smsatSetDevInfo: max queue depth %d\n",oneDeviceData->satNCQMaxIO));
2026285809Sscottl
2027285809Sscottl  /* Support NCQ, if Word 76 bit 8 is set */
2028285809Sscottl  if (SATAIdData->sataCapabilities & 0x100)
2029285809Sscottl  {
2030285809Sscottl    SM_DBG3(("smsatSetDevInfo: device supports NCQ\n"));
2031285809Sscottl    oneDeviceData->satNCQ   = agTRUE;
2032285809Sscottl  }
2033285809Sscottl  else
2034285809Sscottl  {
2035285809Sscottl    SM_DBG3(("smsatSetDevInfo: no NCQ\n"));
2036285809Sscottl    oneDeviceData->satNCQ = agFALSE;
2037285809Sscottl  }
2038285809Sscottl
2039285809Sscottl  /* Support 48 bit addressing, if Word 83 bit 10 and Word 86 bit 10 are set */
2040285809Sscottl  if ((SATAIdData->commandSetSupported1 & 0x400) &&
2041285809Sscottl      (SATAIdData->commandSetFeatureEnabled1 & 0x400) )
2042285809Sscottl  {
2043285809Sscottl    SM_DBG3(("smsatSetDevInfo: support 48 bit addressing\n"));
2044285809Sscottl    oneDeviceData->sat48BitSupport = agTRUE;
2045285809Sscottl  }
2046285809Sscottl  else
2047285809Sscottl  {
2048285809Sscottl    SM_DBG3(("smsatSetDevInfo: NO 48 bit addressing\n"));
2049285809Sscottl    oneDeviceData->sat48BitSupport = agFALSE;
2050285809Sscottl  }
2051285809Sscottl
2052285809Sscottl  /* Support SMART Self Test, word84 bit 1 */
2053285809Sscottl  if (SATAIdData->commandSetFeatureSupportedExt & 0x02)
2054285809Sscottl  {
2055285809Sscottl    SM_DBG3(("smsatSetDevInfo: SMART self-test supported \n"));
2056285809Sscottl    oneDeviceData->satSMARTSelfTest   = agTRUE;
2057285809Sscottl  }
2058285809Sscottl  else
2059285809Sscottl  {
2060285809Sscottl    SM_DBG3(("smsatSetDevInfo: no SMART self-test suppored\n"));
2061285809Sscottl    oneDeviceData->satSMARTSelfTest = agFALSE;
2062285809Sscottl  }
2063285809Sscottl
2064285809Sscottl  /* Support SMART feature set, word82 bit 0 */
2065285809Sscottl  if (SATAIdData->commandSetSupported & 0x01)
2066285809Sscottl  {
2067285809Sscottl    SM_DBG3(("smsatSetDevInfo: SMART feature set supported \n"));
2068285809Sscottl    oneDeviceData->satSMARTFeatureSet   = agTRUE;
2069285809Sscottl  }
2070285809Sscottl  else
2071285809Sscottl  {
2072285809Sscottl    SM_DBG3(("smsatSetDevInfo: no SMART feature set suppored\n"));
2073285809Sscottl    oneDeviceData->satSMARTFeatureSet = agFALSE;
2074285809Sscottl  }
2075285809Sscottl
2076285809Sscottl  /* Support SMART enabled, word85 bit 0 */
2077285809Sscottl  if (SATAIdData->commandSetFeatureEnabled & 0x01)
2078285809Sscottl  {
2079285809Sscottl    SM_DBG3(("smsatSetDevInfo: SMART enabled \n"));
2080285809Sscottl    oneDeviceData->satSMARTEnabled   = agTRUE;
2081285809Sscottl  }
2082285809Sscottl  else
2083285809Sscottl  {
2084285809Sscottl    SM_DBG3(("smsatSetDevInfo: no SMART enabled\n"));
2085285809Sscottl    oneDeviceData->satSMARTEnabled = agFALSE;
2086285809Sscottl  }
2087285809Sscottl
2088285809Sscottl  oneDeviceData->satVerifyState = 0;
2089285809Sscottl
2090285809Sscottl  /* Removable Media feature set support, word82 bit 2 */
2091285809Sscottl  if (SATAIdData->commandSetSupported & 0x4)
2092285809Sscottl  {
2093285809Sscottl    SM_DBG3(("smsatSetDevInfo: Removable Media supported \n"));
2094285809Sscottl    oneDeviceData->satRemovableMedia   = agTRUE;
2095285809Sscottl  }
2096285809Sscottl  else
2097285809Sscottl  {
2098285809Sscottl    SM_DBG3(("smsatSetDevInfo: no Removable Media suppored\n"));
2099285809Sscottl    oneDeviceData->satRemovableMedia = agFALSE;
2100285809Sscottl  }
2101285809Sscottl
2102285809Sscottl  /* Removable Media feature set enabled, word 85, bit 2 */
2103285809Sscottl  if (SATAIdData->commandSetFeatureEnabled & 0x4)
2104285809Sscottl  {
2105285809Sscottl    SM_DBG3(("smsatSetDevInfo: Removable Media enabled\n"));
2106285809Sscottl    oneDeviceData->satRemovableMediaEnabled   = agTRUE;
2107285809Sscottl  }
2108285809Sscottl  else
2109285809Sscottl  {
2110285809Sscottl    SM_DBG3(("smsatSetDevInfo: no Removable Media enabled\n"));
2111285809Sscottl    oneDeviceData->satRemovableMediaEnabled = agFALSE;
2112285809Sscottl  }
2113285809Sscottl
2114285809Sscottl  /* DMA Support, word49 bit8 */
2115285809Sscottl  if (SATAIdData->dma_lba_iod_ios_stimer & 0x100)
2116285809Sscottl  {
2117285809Sscottl    SM_DBG3(("smsatSetDevInfo: DMA supported \n"));
2118285809Sscottl    oneDeviceData->satDMASupport   = agTRUE;
2119285809Sscottl  }
2120285809Sscottl  else
2121285809Sscottl  {
2122285809Sscottl    SM_DBG3(("smsatSetDevInfo: no DMA suppored\n"));
2123285809Sscottl    oneDeviceData->satDMASupport = agFALSE;
2124285809Sscottl  }
2125285809Sscottl
2126285809Sscottl  /* Support DMADIR, if Word 62 bit 8 is set */
2127285809Sscottl  if (SATAIdData->word62_74[0] & 0x8000)
2128285809Sscottl  {
2129285809Sscottl     SM_DBG3(("satSetDevInfo: DMADIR enabled\n"));
2130285809Sscottl     oneDeviceData->satDMADIRSupport   = agTRUE;
2131285809Sscottl  }
2132285809Sscottl  else
2133285809Sscottl  {
2134285809Sscottl     SM_DBG3(("satSetDevInfo: DMADIR disabled\n"));
2135285809Sscottl     oneDeviceData->satDMADIRSupport   = agFALSE;
2136285809Sscottl  }
2137285809Sscottl
2138285809Sscottl  /* DMA Enabled, word88 bit0-6, bit8-14*/
2139285809Sscottl  /* 0x7F7F = 0111 1111 0111 1111*/
2140285809Sscottl  if (SATAIdData->ultraDMAModes & 0x7F7F)
2141285809Sscottl  {
2142285809Sscottl    SM_DBG3(("smsatSetDevInfo: DMA enabled \n"));
2143285809Sscottl    oneDeviceData->satDMAEnabled   = agTRUE;
2144285809Sscottl    if (SATAIdData->ultraDMAModes & 0x40)
2145285809Sscottl    {
2146285809Sscottl       oneDeviceData->satUltraDMAMode = 6;
2147285809Sscottl    }
2148285809Sscottl    else if (SATAIdData->ultraDMAModes & 0x20)
2149285809Sscottl    {
2150285809Sscottl       oneDeviceData->satUltraDMAMode = 5;
2151285809Sscottl    }
2152285809Sscottl    else if (SATAIdData->ultraDMAModes & 0x10)
2153285809Sscottl    {
2154285809Sscottl       oneDeviceData->satUltraDMAMode = 4;
2155285809Sscottl    }
2156285809Sscottl    else if (SATAIdData->ultraDMAModes & 0x08)
2157285809Sscottl    {
2158285809Sscottl       oneDeviceData->satUltraDMAMode = 3;
2159285809Sscottl    }
2160285809Sscottl    else if (SATAIdData->ultraDMAModes & 0x04)
2161285809Sscottl    {
2162285809Sscottl       oneDeviceData->satUltraDMAMode = 2;
2163285809Sscottl    }
2164285809Sscottl    else if (SATAIdData->ultraDMAModes & 0x01)
2165285809Sscottl    {
2166285809Sscottl       oneDeviceData->satUltraDMAMode = 1;
2167285809Sscottl    }
2168285809Sscottl  }
2169285809Sscottl  else
2170285809Sscottl  {
2171285809Sscottl    SM_DBG3(("smsatSetDevInfo: no DMA enabled\n"));
2172285809Sscottl    oneDeviceData->satDMAEnabled = agFALSE;
2173285809Sscottl    oneDeviceData->satUltraDMAMode = 0;
2174285809Sscottl  }
2175285809Sscottl
2176285809Sscottl  /*
2177285809Sscottl    setting MaxUserAddrSectors: max user addressable setctors
2178285809Sscottl    word60 - 61, should be 0x 0F FF FF FF
2179285809Sscottl  */
2180285809Sscottl  oneDeviceData->satMaxUserAddrSectors
2181285809Sscottl    = (SATAIdData->numOfUserAddressableSectorsHi << (8*2) )
2182285809Sscottl    + SATAIdData->numOfUserAddressableSectorsLo;
2183285809Sscottl  SM_DBG3(("smsatSetDevInfo: MaxUserAddrSectors 0x%x decimal %d\n", oneDeviceData->satMaxUserAddrSectors, oneDeviceData->satMaxUserAddrSectors));
2184285809Sscottl
2185285809Sscottl  /* Read Look-ahead is supported */
2186285809Sscottl  if (SATAIdData->commandSetSupported & 0x40)
2187285809Sscottl  {
2188285809Sscottl    SM_DBG3(("smsatSetDevInfo: Read Look-ahead is supported\n"));
2189285809Sscottl    oneDeviceData->satReadLookAheadSupport= agTRUE;
2190285809Sscottl  }
2191285809Sscottl  else
2192285809Sscottl  {
2193285809Sscottl    SM_DBG3(("smsatSetDevInfo: Read Look-ahead is not supported\n"));
2194285809Sscottl    oneDeviceData->satReadLookAheadSupport= agFALSE;
2195285809Sscottl  }
2196285809Sscottl
2197285809Sscottl  /* Volatile Write Cache is supported */
2198285809Sscottl  if (SATAIdData->commandSetSupported & 0x20)
2199285809Sscottl  {
2200285809Sscottl    SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is supported\n"));
2201285809Sscottl    oneDeviceData->satVolatileWriteCacheSupport = agTRUE;
2202285809Sscottl  }
2203285809Sscottl  else
2204285809Sscottl  {
2205285809Sscottl    SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is not supported\n"));
2206285809Sscottl    oneDeviceData->satVolatileWriteCacheSupport = agFALSE;
2207285809Sscottl  }
2208285809Sscottl
2209285809Sscottl  /* write cache enabled for caching mode page SAT Table 67 p69, word85 bit5 */
2210285809Sscottl  if (SATAIdData->commandSetFeatureEnabled & 0x20)
2211285809Sscottl  {
2212285809Sscottl    SM_DBG3(("smsatSetDevInfo: write cache enabled\n"));
2213285809Sscottl    oneDeviceData->satWriteCacheEnabled   = agTRUE;
2214285809Sscottl  }
2215285809Sscottl  else
2216285809Sscottl  {
2217285809Sscottl    SM_DBG3(("smsatSetDevInfo: no write cache enabled\n"));
2218285809Sscottl    oneDeviceData->satWriteCacheEnabled = agFALSE;
2219285809Sscottl  }
2220285809Sscottl
2221285809Sscottl  /* look ahead enabled for caching mode page SAT Table 67 p69, word85 bit6 */
2222285809Sscottl  if (SATAIdData->commandSetFeatureEnabled & 0x40)
2223285809Sscottl  {
2224285809Sscottl    SM_DBG3(("smsatSetDevInfo: look ahead enabled\n"));
2225285809Sscottl    oneDeviceData->satLookAheadEnabled   = agTRUE;
2226285809Sscottl  }
2227285809Sscottl  else
2228285809Sscottl  {
2229285809Sscottl    SM_DBG3(("smsatSetDevInfo: no look ahead enabled\n"));
2230285809Sscottl    oneDeviceData->satLookAheadEnabled = agFALSE;
2231285809Sscottl  }
2232285809Sscottl
2233285809Sscottl  /* Support WWN, if Word 87 bit 8 is set */
2234285809Sscottl  if (SATAIdData->commandSetFeatureDefault & 0x100)
2235285809Sscottl  {
2236285809Sscottl    SM_DBG3(("smsatSetDevInfo: device supports WWN\n"));
2237285809Sscottl    oneDeviceData->satWWNSupport   = agTRUE;
2238285809Sscottl  }
2239285809Sscottl  else
2240285809Sscottl  {
2241285809Sscottl    SM_DBG3(("smsatSetDevInfo: no WWN\n"));
2242285809Sscottl    oneDeviceData->satWWNSupport = agFALSE;
2243285809Sscottl  }
2244285809Sscottl
2245285809Sscottl  /* Support DMA Setup Auto-Activate, if Word 78 bit 2 is set */
2246285809Sscottl  if (SATAIdData->sataFeaturesSupported & 0x4)
2247285809Sscottl  {
2248285809Sscottl    SM_DBG3(("smsatSetDevInfo: device supports DMA Setup Auto-Activate\n"));
2249285809Sscottl    oneDeviceData->satDMASetupAA   = agTRUE;
2250285809Sscottl  }
2251285809Sscottl  else
2252285809Sscottl  {
2253285809Sscottl    SM_DBG3(("smsatSetDevInfo: no DMA Setup Auto-Activate\n"));
2254285809Sscottl    oneDeviceData->satDMASetupAA = agFALSE;
2255285809Sscottl  }
2256285809Sscottl
2257285809Sscottl  /* Support NCQ Queue Management Command, if Word 77 bit 5 is set */
2258285809Sscottl  if (SATAIdData->word77 & 0x10)
2259285809Sscottl  {
2260285809Sscottl    SM_DBG3(("smsatSetDevInfo: device supports NCQ Queue Management Command\n"));
2261285809Sscottl    oneDeviceData->satNCQQMgntCmd   = agTRUE;
2262285809Sscottl  }
2263285809Sscottl  else
2264285809Sscottl  {
2265285809Sscottl    SM_DBG3(("smsatSetDevInfo: no NCQ Queue Management Command\n"));
2266285809Sscottl    oneDeviceData->satNCQQMgntCmd = agFALSE;
2267285809Sscottl  }
2268285809Sscottl  return;
2269285809Sscottl}
2270285809Sscottl
2271285809Sscottl
2272285809SscottlosGLOBAL void
2273285809SscottlsmsatInquiryStandard(
2274285809Sscottl                     bit8                    *pInquiry,
2275285809Sscottl                     agsaSATAIdentifyData_t  *pSATAIdData,
2276285809Sscottl                     smIniScsiCmnd_t         *scsiCmnd
2277285809Sscottl                    )
2278285809Sscottl{
2279285809Sscottl  smLUN_t       *pLun;
2280285809Sscottl  pLun          = &scsiCmnd->lun;
2281285809Sscottl
2282285809Sscottl  /*
2283285809Sscottl    Assumption: Basic Task Mangement is supported
2284285809Sscottl    -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147
2285285809Sscottl  */
2286285809Sscottl /*
2287285809Sscottl    See SPC-4, 6.4.2, p 143
2288285809Sscottl    and SAT revision 8, 8.1.2, p 28
2289285809Sscottl   */
2290285809Sscottl  SM_DBG5(("smsatInquiryStandard: start\n"));
2291285809Sscottl
2292285809Sscottl  if (pInquiry == agNULL)
2293285809Sscottl  {
2294285809Sscottl    SM_DBG1(("smsatInquiryStandard: pInquiry is NULL, wrong\n"));
2295285809Sscottl    return;
2296285809Sscottl  }
2297285809Sscottl  else
2298285809Sscottl  {
2299285809Sscottl    SM_DBG5(("smsatInquiryStandard: pInquiry is NOT NULL\n"));
2300285809Sscottl  }
2301285809Sscottl  /*
2302285809Sscottl   * Reject all other LUN other than LUN 0.
2303285809Sscottl   */
2304285809Sscottl  if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
2305285809Sscottl         pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) )
2306285809Sscottl  {
2307285809Sscottl    /* SAT Spec Table 8, p27, footnote 'a' */
2308285809Sscottl    pInquiry[0] = 0x7F;
2309285809Sscottl
2310285809Sscottl  }
2311285809Sscottl  else
2312285809Sscottl  {
2313285809Sscottl    pInquiry[0] = 0x00;
2314285809Sscottl  }
2315285809Sscottl
2316285809Sscottl  if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
2317285809Sscottl  {
2318285809Sscottl    pInquiry[1] = 0x80;
2319285809Sscottl  }
2320285809Sscottl  else
2321285809Sscottl  {
2322285809Sscottl    pInquiry[1] = 0x00;
2323285809Sscottl  }
2324285809Sscottl  pInquiry[2] = 0x05;   /* SPC-3 */
2325285809Sscottl  pInquiry[3] = 0x12;   /* set HiSup 1; resp data format set to 2 */
2326285809Sscottl  pInquiry[4] = 0x1F;   /* 35 - 4 = 31; Additional length */
2327285809Sscottl  pInquiry[5] = 0x00;
2328285809Sscottl  /* The following two are for task management. SAT Rev8, p20 */
2329285809Sscottl  if (pSATAIdData->sataCapabilities & 0x100)
2330285809Sscottl  {
2331285809Sscottl    /* NCQ supported; multiple outstanding SCSI IO are supported */
2332285809Sscottl    pInquiry[6] = 0x00;   /* BQUE bit is not set */
2333285809Sscottl    pInquiry[7] = 0x02;   /* CMDQUE bit is set */
2334285809Sscottl  }
2335285809Sscottl  else
2336285809Sscottl  {
2337285809Sscottl    pInquiry[6] = 0x80;   /* BQUE bit is set */
2338285809Sscottl    pInquiry[7] = 0x00;   /* CMDQUE bit is not set */
2339285809Sscottl  }
2340285809Sscottl  /*
2341285809Sscottl   * Vendor ID.
2342285809Sscottl   */
2343285809Sscottl  sm_strncpy((char*)&pInquiry[8],  AG_SAT_VENDOR_ID_STRING, 8);   /* 8 bytes   */
2344285809Sscottl
2345285809Sscottl  /*
2346285809Sscottl   * Product ID
2347285809Sscottl   */
2348285809Sscottl  /* when flipped by LL */
2349285809Sscottl  pInquiry[16] = pSATAIdData->modelNumber[1];
2350285809Sscottl  pInquiry[17] = pSATAIdData->modelNumber[0];
2351285809Sscottl  pInquiry[18] = pSATAIdData->modelNumber[3];
2352285809Sscottl  pInquiry[19] = pSATAIdData->modelNumber[2];
2353285809Sscottl  pInquiry[20] = pSATAIdData->modelNumber[5];
2354285809Sscottl  pInquiry[21] = pSATAIdData->modelNumber[4];
2355285809Sscottl  pInquiry[22] = pSATAIdData->modelNumber[7];
2356285809Sscottl  pInquiry[23] = pSATAIdData->modelNumber[6];
2357285809Sscottl  pInquiry[24] = pSATAIdData->modelNumber[9];
2358285809Sscottl  pInquiry[25] = pSATAIdData->modelNumber[8];
2359285809Sscottl  pInquiry[26] = pSATAIdData->modelNumber[11];
2360285809Sscottl  pInquiry[27] = pSATAIdData->modelNumber[10];
2361285809Sscottl  pInquiry[28] = pSATAIdData->modelNumber[13];
2362285809Sscottl  pInquiry[29] = pSATAIdData->modelNumber[12];
2363285809Sscottl  pInquiry[30] = pSATAIdData->modelNumber[15];
2364285809Sscottl  pInquiry[31] = pSATAIdData->modelNumber[14];
2365285809Sscottl
2366285809Sscottl  /* when flipped */
2367285809Sscottl  /*
2368285809Sscottl   * Product Revision level.
2369285809Sscottl   */
2370285809Sscottl
2371285809Sscottl  /*
2372285809Sscottl   * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
2373285809Sscottl   * device are ASCII spaces (20h), do this translation.
2374285809Sscottl   */
2375285809Sscottl  if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
2376285809Sscottl       (pSATAIdData->firmwareVersion[5] == 0x20 ) &&
2377285809Sscottl       (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
2378285809Sscottl       (pSATAIdData->firmwareVersion[7] == 0x20 )
2379285809Sscottl       )
2380285809Sscottl  {
2381285809Sscottl    pInquiry[32] = pSATAIdData->firmwareVersion[1];
2382285809Sscottl    pInquiry[33] = pSATAIdData->firmwareVersion[0];
2383285809Sscottl    pInquiry[34] = pSATAIdData->firmwareVersion[3];
2384285809Sscottl    pInquiry[35] = pSATAIdData->firmwareVersion[2];
2385285809Sscottl  }
2386285809Sscottl  else
2387285809Sscottl  {
2388285809Sscottl    pInquiry[32] = pSATAIdData->firmwareVersion[5];
2389285809Sscottl    pInquiry[33] = pSATAIdData->firmwareVersion[4];
2390285809Sscottl    pInquiry[34] = pSATAIdData->firmwareVersion[7];
2391285809Sscottl    pInquiry[35] = pSATAIdData->firmwareVersion[6];
2392285809Sscottl  }
2393285809Sscottl
2394285809Sscottl
2395285809Sscottl#ifdef REMOVED
2396285809Sscottl  /*
2397285809Sscottl   * Product ID
2398285809Sscottl   */
2399285809Sscottl  /* when flipped by LL */
2400285809Sscottl  pInquiry[16] = pSATAIdData->modelNumber[0];
2401285809Sscottl  pInquiry[17] = pSATAIdData->modelNumber[1];
2402285809Sscottl  pInquiry[18] = pSATAIdData->modelNumber[2];
2403285809Sscottl  pInquiry[19] = pSATAIdData->modelNumber[3];
2404285809Sscottl  pInquiry[20] = pSATAIdData->modelNumber[4];
2405285809Sscottl  pInquiry[21] = pSATAIdData->modelNumber[5];
2406285809Sscottl  pInquiry[22] = pSATAIdData->modelNumber[6];
2407285809Sscottl  pInquiry[23] = pSATAIdData->modelNumber[7];
2408285809Sscottl  pInquiry[24] = pSATAIdData->modelNumber[8];
2409285809Sscottl  pInquiry[25] = pSATAIdData->modelNumber[9];
2410285809Sscottl  pInquiry[26] = pSATAIdData->modelNumber[10];
2411285809Sscottl  pInquiry[27] = pSATAIdData->modelNumber[11];
2412285809Sscottl  pInquiry[28] = pSATAIdData->modelNumber[12];
2413285809Sscottl  pInquiry[29] = pSATAIdData->modelNumber[13];
2414285809Sscottl  pInquiry[30] = pSATAIdData->modelNumber[14];
2415285809Sscottl  pInquiry[31] = pSATAIdData->modelNumber[15];
2416285809Sscottl
2417285809Sscottl  /* when flipped */
2418285809Sscottl  /*
2419285809Sscottl   * Product Revision level.
2420285809Sscottl   */
2421285809Sscottl
2422285809Sscottl  /*
2423285809Sscottl   * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
2424285809Sscottl   * device are ASCII spaces (20h), do this translation.
2425285809Sscottl   */
2426285809Sscottl  if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
2427285809Sscottl       (pSATAIdData->firmwareVersion[5] == 0x20 ) &&
2428285809Sscottl       (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
2429285809Sscottl       (pSATAIdData->firmwareVersion[7] == 0x20 )
2430285809Sscottl       )
2431285809Sscottl  {
2432285809Sscottl    pInquiry[32] = pSATAIdData->firmwareVersion[0];
2433285809Sscottl    pInquiry[33] = pSATAIdData->firmwareVersion[1];
2434285809Sscottl    pInquiry[34] = pSATAIdData->firmwareVersion[2];
2435285809Sscottl    pInquiry[35] = pSATAIdData->firmwareVersion[3];
2436285809Sscottl  }
2437285809Sscottl  else
2438285809Sscottl  {
2439285809Sscottl    pInquiry[32] = pSATAIdData->firmwareVersion[4];
2440285809Sscottl    pInquiry[33] = pSATAIdData->firmwareVersion[5];
2441285809Sscottl    pInquiry[34] = pSATAIdData->firmwareVersion[6];
2442285809Sscottl    pInquiry[35] = pSATAIdData->firmwareVersion[7];
2443285809Sscottl  }
2444285809Sscottl#endif
2445285809Sscottl
2446285809Sscottl  SM_DBG5(("smsatInquiryStandard: end\n"));
2447285809Sscottl
2448285809Sscottl  return;
2449285809Sscottl}
2450285809Sscottl
2451285809SscottlosGLOBAL void
2452285809SscottlsmsatInquiryPage0(
2453285809Sscottl                   bit8                    *pInquiry,
2454285809Sscottl                   agsaSATAIdentifyData_t  *pSATAIdData
2455285809Sscottl     )
2456285809Sscottl{
2457285809Sscottl  SM_DBG5(("smsatInquiryPage0: start\n"));
2458285809Sscottl
2459285809Sscottl  /*
2460285809Sscottl    See SPC-4, 7.6.9, p 345
2461285809Sscottl    and SAT revision 8, 10.3.2, p 77
2462285809Sscottl   */
2463285809Sscottl  pInquiry[0] = 0x00;
2464285809Sscottl  pInquiry[1] = 0x00; /* page code */
2465285809Sscottl  pInquiry[2] = 0x00; /* reserved */
2466285809Sscottl  pInquiry[3] = 8 - 3; /* last index(in this case, 6) - 3; page length */
2467285809Sscottl
2468285809Sscottl  /* supported vpd page list */
2469285809Sscottl  pInquiry[4] = 0x00; /* page 0x00 supported */
2470285809Sscottl  pInquiry[5] = 0x80; /* page 0x80 supported */
2471285809Sscottl  pInquiry[6] = 0x83; /* page 0x83 supported */
2472285809Sscottl  pInquiry[7] = 0x89; /* page 0x89 supported */
2473285809Sscottl  pInquiry[8] = 0xB1; /* page 0xB1 supported */
2474285809Sscottl
2475285809Sscottl  return;
2476285809Sscottl}
2477285809Sscottl
2478285809SscottlosGLOBAL void
2479285809SscottlsmsatInquiryPage83(
2480285809Sscottl                    bit8                    *pInquiry,
2481285809Sscottl                    agsaSATAIdentifyData_t  *pSATAIdData,
2482285809Sscottl                    smDeviceData_t          *oneDeviceData
2483285809Sscottl      )
2484285809Sscottl{
2485285809Sscottl  satSimpleSATAIdentifyData_t   *pSimpleData;
2486285809Sscottl
2487285809Sscottl  /*
2488285809Sscottl   * When translating the fields, in some cases using the simple form of SATA
2489285809Sscottl   * Identify Device Data is easier. So we define it here.
2490285809Sscottl   * Both pSimpleData and pSATAIdData points to the same data.
2491285809Sscottl   */
2492285809Sscottl  pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2493285809Sscottl
2494285809Sscottl  SM_DBG5(("smsatInquiryPage83: start\n"));
2495285809Sscottl
2496285809Sscottl  pInquiry[0] = 0x00;
2497285809Sscottl  pInquiry[1] = 0x83; /* page code */
2498285809Sscottl  pInquiry[2] = 0;    /* Reserved */
2499285809Sscottl  /*
2500285809Sscottl   * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE
2501285809Sscottl   * data indicating that it supports the WORLD WIDE NAME field
2502285809Sscottl   * (i.e., words 108-111), the SATL shall include an identification descriptor
2503285809Sscottl   * containing a logical unit name.
2504285809Sscottl   */
2505285809Sscottl  if ( oneDeviceData->satWWNSupport)
2506285809Sscottl  {
2507285809Sscottl#ifndef PMC_FREEBSD
2508285809Sscottl    /* Fill in SAT Rev8 Table85 */
2509285809Sscottl    /*
2510285809Sscottl     * Logical unit name derived from the world wide name.
2511285809Sscottl     */
2512285809Sscottl    pInquiry[3] = 12;         /* 15-3; page length, no addition ID descriptor assumed*/
2513285809Sscottl
2514285809Sscottl    /*
2515285809Sscottl     * Identifier descriptor
2516285809Sscottl     */
2517285809Sscottl    pInquiry[4]  = 0x01;                        /* Code set: binary codes */
2518285809Sscottl    pInquiry[5]  = 0x03;                        /* Identifier type : NAA  */
2519285809Sscottl    pInquiry[6]  = 0x00;                        /* Reserved               */
2520285809Sscottl    pInquiry[7]  = 0x08;                        /* Identifier length      */
2521285809Sscottl
2522285809Sscottl    /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
2523285809Sscottl    pInquiry[8]  = (bit8)((pSATAIdData->namingAuthority) >> 8);
2524285809Sscottl    pInquiry[9]  = (bit8)((pSATAIdData->namingAuthority) & 0xFF);           /* IEEE Company ID */
2525285809Sscottl    pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8);            /* IEEE Company ID */
2526285809Sscottl    /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
2527285809Sscottl    pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
2528285809Sscottl    pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8);       /* Vendor Specific ID  */
2529285809Sscottl    pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF);     /* Vendor Specific ID  */
2530285809Sscottl    pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8);        /* Vendor Specific ID  */
2531285809Sscottl    pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF);      /* Vendor Specific ID  */
2532285809Sscottl
2533285809Sscottl#else
2534285809Sscottl
2535285809Sscottl    /* For FreeBSD */
2536285809Sscottl
2537285809Sscottl    /* Fill in SAT Rev8 Table85 */
2538285809Sscottl    /*
2539285809Sscottl     * Logical unit name derived from the world wide name.
2540285809Sscottl     */
2541285809Sscottl    pInquiry[3] = 24;         /* 35-3; page length, no addition ID descriptor assumed*/
2542285809Sscottl   /*
2543285809Sscottl     * Identifier descriptor
2544285809Sscottl     */
2545285809Sscottl    pInquiry[4]  = 0x01;                        /* Code set: binary codes; this is proto_codeset in FreeBSD */
2546285809Sscottl    pInquiry[5]  = 0x03;                        /* Identifier type : NAA ; this is  id_type in FreeBSD*/
2547285809Sscottl    pInquiry[6]  = 0x00;                        /* Reserved               */
2548285809Sscottl    pInquiry[7]  = 0x08;                        /* Identifier length      */
2549285809Sscottl
2550285809Sscottl    /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
2551285809Sscottl    pInquiry[8]  = (bit8)((pSATAIdData->namingAuthority) >> 8);
2552285809Sscottl    pInquiry[9]  = (bit8)((pSATAIdData->namingAuthority) & 0xFF);           /* IEEE Company ID */
2553285809Sscottl    pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8);            /* IEEE Company ID */
2554285809Sscottl    /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
2555285809Sscottl    pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
2556285809Sscottl    pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8);       /* Vendor Specific ID  */
2557285809Sscottl    pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF);     /* Vendor Specific ID  */
2558285809Sscottl    pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8);        /* Vendor Specific ID  */
2559285809Sscottl    pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF);      /* Vendor Specific ID  */
2560285809Sscottl
2561285809Sscottl    pInquiry[16]  = 0x61;                        /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */
2562285809Sscottl    pInquiry[17]  = 0x93;                        /* Identifier type : NAA ; this is  id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h)   */
2563285809Sscottl    pInquiry[18]  = 0x00;                        /* Reserved               */
2564285809Sscottl    pInquiry[19]  = 0x08;                        /* Identifier length      */
2565285809Sscottl
2566285809Sscottl    SM_DBG5(("smsatInquiryPage83: sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi));
2567285809Sscottl    SM_DBG5(("smsatInquiryPage83: sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo));
2568285809Sscottl
2569285809Sscottl    /* SAS address of SATA */
2570285809Sscottl    pInquiry[20]  = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24;
2571285809Sscottl    pInquiry[21]  = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16;
2572285809Sscottl    pInquiry[22]  = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8;
2573285809Sscottl    pInquiry[23]  = (oneDeviceData->sasAddressHi) & 0xFF;
2574285809Sscottl    pInquiry[24]  = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24;
2575285809Sscottl    pInquiry[25]  = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16;
2576285809Sscottl    pInquiry[26]  = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8;
2577285809Sscottl    pInquiry[27]  = (oneDeviceData->sasAddressLo) & 0xFF;
2578285809Sscottl#endif
2579285809Sscottl  }
2580285809Sscottl  else
2581285809Sscottl  {
2582285809Sscottl#ifndef PMC_FREEBSD
2583285809Sscottl    /* Fill in SAT Rev8 Table86 */
2584285809Sscottl    /*
2585285809Sscottl     * Logical unit name derived from the model number and serial number.
2586285809Sscottl     */
2587285809Sscottl    pInquiry[3] = 72;    /* 75 - 3; page length */
2588285809Sscottl
2589285809Sscottl    /*
2590285809Sscottl     * Identifier descriptor
2591285809Sscottl     */
2592285809Sscottl    pInquiry[4] = 0x02;             /* Code set: ASCII codes */
2593285809Sscottl    pInquiry[5] = 0x01;             /* Identifier type : T10 vendor ID based */
2594285809Sscottl    pInquiry[6] = 0x00;             /* Reserved */
2595285809Sscottl    pInquiry[7] = 0x44;               /* 0x44, 68 Identifier length */
2596285809Sscottl
2597285809Sscottl    /* Byte 8 to 15 is the vendor id string 'ATA     '. */
2598285809Sscottl    sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
2599285809Sscottl
2600285809Sscottl
2601285809Sscottl        /*
2602285809Sscottl     * Byte 16 to 75 is vendor specific id
2603285809Sscottl     */
2604285809Sscottl    pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
2605285809Sscottl    pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
2606285809Sscottl    pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
2607285809Sscottl    pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
2608285809Sscottl    pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
2609285809Sscottl    pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
2610285809Sscottl    pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
2611285809Sscottl    pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
2612285809Sscottl    pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
2613285809Sscottl    pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
2614285809Sscottl    pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
2615285809Sscottl    pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
2616285809Sscottl    pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
2617285809Sscottl    pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
2618285809Sscottl    pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
2619285809Sscottl    pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
2620285809Sscottl    pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
2621285809Sscottl    pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
2622285809Sscottl    pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
2623285809Sscottl    pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
2624285809Sscottl    pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
2625285809Sscottl    pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
2626285809Sscottl    pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
2627285809Sscottl    pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
2628285809Sscottl    pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
2629285809Sscottl    pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
2630285809Sscottl    pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
2631285809Sscottl    pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
2632285809Sscottl    pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
2633285809Sscottl    pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
2634285809Sscottl    pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
2635285809Sscottl    pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
2636285809Sscottl    pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
2637285809Sscottl    pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
2638285809Sscottl    pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
2639285809Sscottl    pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
2640285809Sscottl    pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
2641285809Sscottl    pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
2642285809Sscottl    pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
2643285809Sscottl    pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
2644285809Sscottl
2645285809Sscottl    pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
2646285809Sscottl    pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
2647285809Sscottl    pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
2648285809Sscottl    pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
2649285809Sscottl    pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
2650285809Sscottl    pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
2651285809Sscottl    pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
2652285809Sscottl    pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
2653285809Sscottl    pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
2654285809Sscottl    pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
2655285809Sscottl    pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
2656285809Sscottl    pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
2657285809Sscottl    pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
2658285809Sscottl    pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
2659285809Sscottl    pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
2660285809Sscottl    pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
2661285809Sscottl    pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
2662285809Sscottl    pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
2663285809Sscottl    pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
2664285809Sscottl    pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
2665285809Sscottl#else
2666285809Sscottl    /* for the FreeBSD */
2667285809Sscottl    /* Fill in SAT Rev8 Table86 */
2668285809Sscottl    /*
2669285809Sscottl     * Logical unit name derived from the model number and serial number.
2670285809Sscottl     */
2671285809Sscottl    pInquiry[3] = 84;    /* 87 - 3; page length */
2672285809Sscottl
2673285809Sscottl    /*
2674285809Sscottl     * Identifier descriptor
2675285809Sscottl     */
2676285809Sscottl    pInquiry[4] = 0x02;             /* Code set: ASCII codes */
2677285809Sscottl    pInquiry[5] = 0x01;             /* Identifier type : T10 vendor ID based */
2678285809Sscottl    pInquiry[6] = 0x00;             /* Reserved */
2679285809Sscottl    pInquiry[7] = 0x44;               /* 0x44, 68 Identifier length */
2680285809Sscottl
2681285809Sscottl    /* Byte 8 to 15 is the vendor id string 'ATA     '. */
2682285809Sscottl    sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
2683285809Sscottl
2684285809Sscottl
2685285809Sscottl        /*
2686285809Sscottl     * Byte 16 to 75 is vendor specific id
2687285809Sscottl     */
2688285809Sscottl    pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
2689285809Sscottl    pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
2690285809Sscottl    pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
2691285809Sscottl    pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
2692285809Sscottl    pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
2693285809Sscottl    pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
2694285809Sscottl    pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
2695285809Sscottl    pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
2696285809Sscottl    pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
2697285809Sscottl    pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
2698285809Sscottl    pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
2699285809Sscottl    pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
2700285809Sscottl    pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
2701285809Sscottl    pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
2702285809Sscottl    pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
2703285809Sscottl    pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
2704285809Sscottl    pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
2705285809Sscottl    pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
2706285809Sscottl    pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
2707285809Sscottl    pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
2708285809Sscottl    pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
2709285809Sscottl    pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
2710285809Sscottl    pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
2711285809Sscottl    pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
2712285809Sscottl    pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
2713285809Sscottl    pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
2714285809Sscottl    pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
2715285809Sscottl    pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
2716285809Sscottl    pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
2717285809Sscottl    pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
2718285809Sscottl    pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
2719285809Sscottl    pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
2720285809Sscottl    pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
2721285809Sscottl    pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
2722285809Sscottl    pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
2723285809Sscottl    pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
2724285809Sscottl    pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
2725285809Sscottl    pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
2726285809Sscottl    pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
2727285809Sscottl    pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
2728285809Sscottl
2729285809Sscottl    pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
2730285809Sscottl    pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
2731285809Sscottl    pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
2732285809Sscottl    pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
2733285809Sscottl    pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
2734285809Sscottl    pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
2735285809Sscottl    pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
2736285809Sscottl    pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
2737285809Sscottl    pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
2738285809Sscottl    pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
2739285809Sscottl    pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
2740285809Sscottl    pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
2741285809Sscottl    pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
2742285809Sscottl    pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
2743285809Sscottl    pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
2744285809Sscottl    pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
2745285809Sscottl    pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
2746285809Sscottl    pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
2747285809Sscottl    pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
2748285809Sscottl    pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
2749285809Sscottl
2750285809Sscottl    pInquiry[76]  = 0x61;                        /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */
2751285809Sscottl    pInquiry[77]  = 0x93;                        /* Identifier type : NAA ; this is  id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h)   */
2752285809Sscottl    pInquiry[78]  = 0x00;                        /* Reserved               */
2753285809Sscottl    pInquiry[79]  = 0x08;                        /* Identifier length      */
2754285809Sscottl
2755285809Sscottl    SM_DBG5(("smsatInquiryPage83: NO WWN sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi));
2756285809Sscottl    SM_DBG5(("smsatInquiryPage83: No WWN sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo));
2757285809Sscottl
2758285809Sscottl    /* SAS address of SATA */
2759285809Sscottl    pInquiry[80]  = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24;
2760285809Sscottl    pInquiry[81]  = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16;
2761285809Sscottl    pInquiry[82]  = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8;
2762285809Sscottl    pInquiry[83]  = (oneDeviceData->sasAddressHi) & 0xFF;
2763285809Sscottl    pInquiry[84]  = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24;
2764285809Sscottl    pInquiry[85]  = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16;
2765285809Sscottl    pInquiry[86]  = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8;
2766285809Sscottl    pInquiry[87]  = (oneDeviceData->sasAddressLo) & 0xFF;
2767285809Sscottl
2768285809Sscottl#endif
2769285809Sscottl  }
2770285809Sscottl
2771285809Sscottl  return;
2772285809Sscottl}
2773285809Sscottl
2774285809SscottlosGLOBAL void
2775285809SscottlsmsatInquiryPage89(
2776285809Sscottl                    bit8                    *pInquiry,
2777285809Sscottl                    agsaSATAIdentifyData_t  *pSATAIdData,
2778285809Sscottl                    smDeviceData_t          *oneDeviceData,
2779285809Sscottl                    bit32                   len
2780285809Sscottl      )
2781285809Sscottl{
2782285809Sscottl  /*
2783285809Sscottl    SAT revision 8, 10.3.5, p 83
2784285809Sscottl   */
2785285809Sscottl  satSimpleSATAIdentifyData_t   *pSimpleData;
2786285809Sscottl
2787285809Sscottl  /*
2788285809Sscottl   * When translating the fields, in some cases using the simple form of SATA
2789285809Sscottl   * Identify Device Data is easier. So we define it here.
2790285809Sscottl   * Both pSimpleData and pSATAIdData points to the same data.
2791285809Sscottl   */
2792285809Sscottl  pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2793285809Sscottl
2794285809Sscottl  SM_DBG5(("smsatInquiryPage89: start\n"));
2795285809Sscottl
2796285809Sscottl  pInquiry[0] = 0x00;   /* Peripheral Qualifier and Peripheral Device Type */
2797285809Sscottl  pInquiry[1] = 0x89;   /* page code */
2798285809Sscottl
2799285809Sscottl  /* Page length 0x238 */
2800285809Sscottl  pInquiry[2] = 0x02;
2801285809Sscottl  pInquiry[3] = 0x38;
2802285809Sscottl
2803285809Sscottl  pInquiry[4] = 0x0;    /* reserved */
2804285809Sscottl  pInquiry[5] = 0x0;    /* reserved */
2805285809Sscottl  pInquiry[6] = 0x0;    /* reserved */
2806285809Sscottl  pInquiry[7] = 0x0;    /* reserved */
2807285809Sscottl
2808285809Sscottl  /* SAT Vendor Identification */
2809285809Sscottl  sm_strncpy((char*)&pInquiry[8],  "PMC-SIERRA", 8);   /* 8 bytes   */
2810285809Sscottl
2811285809Sscottl  /* SAT Product Idetification */
2812285809Sscottl  sm_strncpy((char*)&pInquiry[16],  "Tachyon-SPC    ", 16);   /* 16 bytes   */
2813285809Sscottl
2814285809Sscottl  /* SAT Product Revision Level */
2815285809Sscottl  sm_strncpy((char*)&pInquiry[32],  "01", 4);   /* 4 bytes   */
2816285809Sscottl
2817285809Sscottl  /* Signature, SAT revision8, Table88, p85 */
2818285809Sscottl
2819285809Sscottl
2820285809Sscottl  pInquiry[36] = 0x34;    /* FIS type */
2821285809Sscottl  if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2822285809Sscottl  {
2823285809Sscottl    /* interrupt assume to be 0 */
2824285809Sscottl    pInquiry[37] = (bit8)((oneDeviceData->satPMField) >> (4 * 7)); /* first four bits of PM field */
2825285809Sscottl  }
2826285809Sscottl  else
2827285809Sscottl  {
2828285809Sscottl    /* interrupt assume to be 1 */
2829285809Sscottl    pInquiry[37] = (bit8)(0x40 + (bit8)(((oneDeviceData->satPMField) >> (4 * 7)))); /* first four bits of PM field */
2830285809Sscottl  }
2831285809Sscottl  pInquiry[38] = 0;
2832285809Sscottl  pInquiry[39] = 0;
2833285809Sscottl
2834285809Sscottl  if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2835285809Sscottl  {
2836285809Sscottl    pInquiry[40] = 0x01; /* LBA Low          */
2837285809Sscottl    pInquiry[41] = 0x00; /* LBA Mid          */
2838285809Sscottl    pInquiry[42] = 0x00; /* LBA High         */
2839285809Sscottl    pInquiry[43] = 0x00; /* Device           */
2840285809Sscottl    pInquiry[44] = 0x00; /* LBA Low Exp      */
2841285809Sscottl    pInquiry[45] = 0x00; /* LBA Mid Exp      */
2842285809Sscottl    pInquiry[46] = 0x00; /* LBA High Exp     */
2843285809Sscottl    pInquiry[47] = 0x00; /* Reserved         */
2844285809Sscottl    pInquiry[48] = 0x01; /* Sector Count     */
2845285809Sscottl    pInquiry[49] = 0x00; /* Sector Count Exp */
2846285809Sscottl  }
2847285809Sscottl  else
2848285809Sscottl  {
2849285809Sscottl    pInquiry[40] = 0x01; /* LBA Low          */
2850285809Sscottl    pInquiry[41] = 0x00; /* LBA Mid          */
2851285809Sscottl    pInquiry[42] = 0x00; /* LBA High         */
2852285809Sscottl    pInquiry[43] = 0x00; /* Device           */
2853285809Sscottl    pInquiry[44] = 0x00; /* LBA Low Exp      */
2854285809Sscottl    pInquiry[45] = 0x00; /* LBA Mid Exp      */
2855285809Sscottl    pInquiry[46] = 0x00; /* LBA High Exp     */
2856285809Sscottl    pInquiry[47] = 0x00; /* Reserved         */
2857285809Sscottl    pInquiry[48] = 0x01; /* Sector Count     */
2858285809Sscottl    pInquiry[49] = 0x00; /* Sector Count Exp */
2859285809Sscottl  }
2860285809Sscottl
2861285809Sscottl  /* Reserved */
2862285809Sscottl  pInquiry[50] = 0x00;
2863285809Sscottl  pInquiry[51] = 0x00;
2864285809Sscottl  pInquiry[52] = 0x00;
2865285809Sscottl  pInquiry[53] = 0x00;
2866285809Sscottl  pInquiry[54] = 0x00;
2867285809Sscottl  pInquiry[55] = 0x00;
2868285809Sscottl
2869285809Sscottl  /* Command Code */
2870285809Sscottl  if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2871285809Sscottl  {
2872285809Sscottl    pInquiry[56] = 0xEC;    /* IDENTIFY DEVICE */
2873285809Sscottl  }
2874285809Sscottl  else
2875285809Sscottl  {
2876285809Sscottl    pInquiry[56] = 0xA1;    /* IDENTIFY PACKET DEVICE */
2877285809Sscottl  }
2878285809Sscottl  /* Reserved */
2879285809Sscottl  pInquiry[57] = 0x0;
2880285809Sscottl  pInquiry[58] = 0x0;
2881285809Sscottl  pInquiry[59] = 0x0;
2882285809Sscottl
2883285809Sscottl  /* check the length; len is assumed to be at least 60  */
2884285809Sscottl  if (len < SATA_PAGE89_INQUIRY_SIZE)
2885285809Sscottl  {
2886285809Sscottl    /* Identify Device */
2887285809Sscottl    sm_memcpy(&pInquiry[60], pSimpleData, MIN((len - 60), sizeof(satSimpleSATAIdentifyData_t)));
2888285809Sscottl  }
2889285809Sscottl  else
2890285809Sscottl  {
2891285809Sscottl    /* Identify Device */
2892285809Sscottl    sm_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
2893285809Sscottl  }
2894285809Sscottl
2895285809Sscottl  return;
2896285809Sscottl}
2897285809Sscottl
2898285809SscottlosGLOBAL void
2899285809SscottlsmsatInquiryPage80(
2900285809Sscottl                    bit8                    *pInquiry,
2901285809Sscottl                    agsaSATAIdentifyData_t  *pSATAIdData
2902285809Sscottl       )
2903285809Sscottl{
2904285809Sscottl  SM_DBG5(("smsatInquiryPage89: start\n"));
2905285809Sscottl  /*
2906285809Sscottl    See SPC-4, 7.6.9, p 345
2907285809Sscottl    and SAT revision 8, 10.3.3, p 77
2908285809Sscottl   */
2909285809Sscottl  pInquiry[0] = 0x00;
2910285809Sscottl  pInquiry[1] = 0x80; /* page code */
2911285809Sscottl  pInquiry[2] = 0x00; /* reserved */
2912285809Sscottl  pInquiry[3] = 0x14; /* page length */
2913285809Sscottl
2914285809Sscottl  /* product serial number */
2915285809Sscottl  pInquiry[4] = pSATAIdData->serialNumber[1];
2916285809Sscottl  pInquiry[5] = pSATAIdData->serialNumber[0];
2917285809Sscottl  pInquiry[6] = pSATAIdData->serialNumber[3];
2918285809Sscottl  pInquiry[7] = pSATAIdData->serialNumber[2];
2919285809Sscottl  pInquiry[8] = pSATAIdData->serialNumber[5];
2920285809Sscottl  pInquiry[9] = pSATAIdData->serialNumber[4];
2921285809Sscottl  pInquiry[10] = pSATAIdData->serialNumber[7];
2922285809Sscottl  pInquiry[11] = pSATAIdData->serialNumber[6];
2923285809Sscottl  pInquiry[12] = pSATAIdData->serialNumber[9];
2924285809Sscottl  pInquiry[13] = pSATAIdData->serialNumber[8];
2925285809Sscottl  pInquiry[14] = pSATAIdData->serialNumber[11];
2926285809Sscottl  pInquiry[15] = pSATAIdData->serialNumber[10];
2927285809Sscottl  pInquiry[16] = pSATAIdData->serialNumber[13];
2928285809Sscottl  pInquiry[17] = pSATAIdData->serialNumber[12];
2929285809Sscottl  pInquiry[18] = pSATAIdData->serialNumber[15];
2930285809Sscottl  pInquiry[19] = pSATAIdData->serialNumber[14];
2931285809Sscottl  pInquiry[20] = pSATAIdData->serialNumber[17];
2932285809Sscottl  pInquiry[21] = pSATAIdData->serialNumber[16];
2933285809Sscottl  pInquiry[22] = pSATAIdData->serialNumber[19];
2934285809Sscottl  pInquiry[23] = pSATAIdData->serialNumber[18];
2935285809Sscottl
2936285809Sscottl  return;
2937285809Sscottl}
2938285809Sscottl
2939285809SscottlosGLOBAL void
2940285809SscottlsmsatInquiryPageB1(
2941285809Sscottl                    bit8                    *pInquiry,
2942285809Sscottl                    agsaSATAIdentifyData_t  *pSATAIdData
2943285809Sscottl       )
2944285809Sscottl{
2945285809Sscottl  bit32 i;
2946285809Sscottl  satSimpleSATAIdentifyData_t   *pSimpleData;
2947285809Sscottl
2948285809Sscottl  SM_DBG5(("smsatInquiryPageB1: start\n"));
2949285809Sscottl
2950285809Sscottl  pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2951285809Sscottl  /*
2952285809Sscottl    See SBC-3, revision31, Table193, p273
2953285809Sscottl    and SAT-3 revision 3, 10.3.6, p141
2954285809Sscottl   */
2955285809Sscottl  pInquiry[0] = 0x00;   /* Peripheral Qualifier and Peripheral Device Type */
2956285809Sscottl  pInquiry[1] = 0xB1; /* page code */
2957285809Sscottl
2958285809Sscottl  /* page length */
2959285809Sscottl  pInquiry[2] = 0x0;
2960285809Sscottl  pInquiry[3] = 0x3C;
2961285809Sscottl
2962285809Sscottl  /* medium rotation rate */
2963285809Sscottl  pInquiry[4] = (bit8) ((pSimpleData->word[217]) >> 8);
2964285809Sscottl  pInquiry[5] = (bit8) ((pSimpleData->word[217]) & 0xFF);
2965285809Sscottl
2966285809Sscottl  /* reserved */
2967285809Sscottl  pInquiry[6] = 0x0;
2968285809Sscottl
2969285809Sscottl  /* nominal form factor bits 3:0 */
2970285809Sscottl  pInquiry[7] = (bit8) ((pSimpleData->word[168]) & 0xF);
2971285809Sscottl
2972285809Sscottl
2973285809Sscottl  /* reserved */
2974285809Sscottl  for (i=8;i<64;i++)
2975285809Sscottl  {
2976285809Sscottl    pInquiry[i] = 0x0;
2977285809Sscottl  }
2978285809Sscottl  return;
2979285809Sscottl}
2980285809Sscottl
2981285809SscottlosGLOBAL void
2982285809SscottlsmsatDefaultTranslation(
2983285809Sscottl                        smRoot_t                  *smRoot,
2984285809Sscottl                        smIORequest_t             *smIORequest,
2985285809Sscottl                        smSatIOContext_t            *satIOContext,
2986285809Sscottl                        smScsiRspSense_t          *pSense,
2987285809Sscottl                        bit8                      ataStatus,
2988285809Sscottl                        bit8                      ataError,
2989285809Sscottl                        bit32                     interruptContext
2990285809Sscottl                       )
2991285809Sscottl{
2992285809Sscottl  SM_DBG5(("smsatDefaultTranslation: start\n"));
2993285809Sscottl  /*
2994285809Sscottl   * Check for device fault case
2995285809Sscottl   */
2996285809Sscottl  if ( ataStatus & DF_ATA_STATUS_MASK )
2997285809Sscottl  {
2998285809Sscottl    smsatSetSensePayload( pSense,
2999285809Sscottl                          SCSI_SNSKEY_HARDWARE_ERROR,
3000285809Sscottl                          0,
3001285809Sscottl                          SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3002285809Sscottl                          satIOContext);
3003285809Sscottl
3004285809Sscottl    tdsmIOCompletedCB( smRoot,
3005285809Sscottl                       smIORequest,
3006285809Sscottl                       smIOSuccess,
3007285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
3008285809Sscottl                       satIOContext->pSmSenseData,
3009285809Sscottl                       interruptContext );
3010285809Sscottl    return;
3011285809Sscottl  }
3012285809Sscottl
3013285809Sscottl  /*
3014285809Sscottl   * If status error bit it set, need to check the error register
3015285809Sscottl   */
3016285809Sscottl  if ( ataStatus & ERR_ATA_STATUS_MASK )
3017285809Sscottl  {
3018285809Sscottl    if ( ataError & NM_ATA_ERROR_MASK )
3019285809Sscottl    {
3020285809Sscottl      SM_DBG1(("smsatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3021285809Sscottl                 ataError, smIORequest));
3022285809Sscottl      smsatSetSensePayload( pSense,
3023285809Sscottl                            SCSI_SNSKEY_NOT_READY,
3024285809Sscottl                            0,
3025285809Sscottl                            SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
3026285809Sscottl                            satIOContext);
3027285809Sscottl    }
3028285809Sscottl
3029285809Sscottl    else if (ataError & UNC_ATA_ERROR_MASK)
3030285809Sscottl    {
3031285809Sscottl      SM_DBG1(("smsatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3032285809Sscottl                 ataError, smIORequest));
3033285809Sscottl      smsatSetSensePayload( pSense,
3034285809Sscottl                            SCSI_SNSKEY_MEDIUM_ERROR,
3035285809Sscottl                            0,
3036285809Sscottl                            SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
3037285809Sscottl                            satIOContext);
3038285809Sscottl    }
3039285809Sscottl
3040285809Sscottl    else if (ataError & IDNF_ATA_ERROR_MASK)
3041285809Sscottl    {
3042285809Sscottl      SM_DBG1(("smsatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3043285809Sscottl                 ataError, smIORequest));
3044285809Sscottl      smsatSetSensePayload( pSense,
3045285809Sscottl                            SCSI_SNSKEY_MEDIUM_ERROR,
3046285809Sscottl                            0,
3047285809Sscottl                            SCSI_SNSCODE_RECORD_NOT_FOUND,
3048285809Sscottl                            satIOContext);
3049285809Sscottl    }
3050285809Sscottl
3051285809Sscottl    else if (ataError & MC_ATA_ERROR_MASK)
3052285809Sscottl    {
3053285809Sscottl      SM_DBG1(("smsatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3054285809Sscottl                 ataError, smIORequest));
3055285809Sscottl      smsatSetSensePayload( pSense,
3056285809Sscottl                            SCSI_SNSKEY_UNIT_ATTENTION,
3057285809Sscottl                            0,
3058285809Sscottl                            SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
3059285809Sscottl                            satIOContext);
3060285809Sscottl    }
3061285809Sscottl
3062285809Sscottl    else if (ataError & MCR_ATA_ERROR_MASK)
3063285809Sscottl    {
3064285809Sscottl      SM_DBG1(("smsatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3065285809Sscottl                 ataError, smIORequest));
3066285809Sscottl      smsatSetSensePayload( pSense,
3067285809Sscottl                            SCSI_SNSKEY_UNIT_ATTENTION,
3068285809Sscottl                            0,
3069285809Sscottl                            SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
3070285809Sscottl                            satIOContext);
3071285809Sscottl    }
3072285809Sscottl
3073285809Sscottl    else if (ataError & ICRC_ATA_ERROR_MASK)
3074285809Sscottl    {
3075285809Sscottl      SM_DBG1(("smsatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3076285809Sscottl                 ataError, smIORequest));
3077285809Sscottl      smsatSetSensePayload( pSense,
3078285809Sscottl                            SCSI_SNSKEY_ABORTED_COMMAND,
3079285809Sscottl                            0,
3080285809Sscottl                            SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
3081285809Sscottl                            satIOContext);
3082285809Sscottl    }
3083285809Sscottl
3084285809Sscottl    else if (ataError & ABRT_ATA_ERROR_MASK)
3085285809Sscottl    {
3086285809Sscottl      SM_DBG1(("smsatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3087285809Sscottl                 ataError, smIORequest));
3088285809Sscottl      smsatSetSensePayload( pSense,
3089285809Sscottl                            SCSI_SNSKEY_ABORTED_COMMAND,
3090285809Sscottl                            0,
3091285809Sscottl                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
3092285809Sscottl                            satIOContext);
3093285809Sscottl    }
3094285809Sscottl
3095285809Sscottl    else
3096285809Sscottl    {
3097285809Sscottl      SM_DBG1(("smsatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, smIORequest=%p!!!\n",
3098285809Sscottl                 ataError, smIORequest));
3099285809Sscottl      smsatSetSensePayload( pSense,
3100285809Sscottl                            SCSI_SNSKEY_HARDWARE_ERROR,
3101285809Sscottl                            0,
3102285809Sscottl                            SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3103285809Sscottl                            satIOContext);
3104285809Sscottl    }
3105285809Sscottl
3106285809Sscottl    /* Send the completion response now */
3107285809Sscottl    tdsmIOCompletedCB( smRoot,
3108285809Sscottl                       smIORequest,
3109285809Sscottl                       smIOSuccess,
3110285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
3111285809Sscottl                       satIOContext->pSmSenseData,
3112285809Sscottl                       interruptContext );
3113285809Sscottl    return;
3114285809Sscottl
3115285809Sscottl
3116285809Sscottl  }
3117285809Sscottl
3118285809Sscottl  else /*  (ataStatus & ERR_ATA_STATUS_MASK ) is false */
3119285809Sscottl  {
3120285809Sscottl    /* This case should never happen */
3121285809Sscottl    SM_DBG1(("smsatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** smIORequest=%p!!!\n",
3122285809Sscottl                 ataStatus, smIORequest));
3123285809Sscottl    smsatSetSensePayload( pSense,
3124285809Sscottl                          SCSI_SNSKEY_HARDWARE_ERROR,
3125285809Sscottl                          0,
3126285809Sscottl                          SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3127285809Sscottl                          satIOContext);
3128285809Sscottl
3129285809Sscottl    tdsmIOCompletedCB( smRoot,
3130285809Sscottl                       smIORequest,
3131285809Sscottl                       smIOSuccess,
3132285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
3133285809Sscottl                       satIOContext->pSmSenseData,
3134285809Sscottl                       interruptContext );
3135285809Sscottl    return;
3136285809Sscottl
3137285809Sscottl  }
3138285809Sscottl
3139285809Sscottl  return;
3140285809Sscottl}
3141285809Sscottl
3142285809SscottlosGLOBAL bit32
3143285809SscottlsmIDStart(
3144285809Sscottl          smRoot_t                     *smRoot,
3145285809Sscottl          smIORequest_t                *smIORequest,
3146285809Sscottl          smDeviceHandle_t             *smDeviceHandle
3147285809Sscottl         )
3148285809Sscottl{
3149285809Sscottl  smDeviceData_t            *oneDeviceData = agNULL;
3150285809Sscottl  smIORequestBody_t         *smIORequestBody = agNULL;
3151285809Sscottl  smSatIOContext_t            *satIOContext = agNULL;
3152285809Sscottl  bit32                     status = SM_RC_FAILURE;
3153285809Sscottl
3154285809Sscottl  SM_DBG2(("smIDStart: start, smIORequest %p\n", smIORequest));
3155285809Sscottl
3156285809Sscottl  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
3157285809Sscottl  if (oneDeviceData == agNULL)
3158285809Sscottl  {
3159285809Sscottl    SM_DBG1(("smIDStart: oneDeviceData is NULL!!!\n"));
3160285809Sscottl    return SM_RC_FAILURE;
3161285809Sscottl  }
3162285809Sscottl  if (oneDeviceData->valid == agFALSE)
3163285809Sscottl  {
3164285809Sscottl    SM_DBG1(("smIDStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
3165285809Sscottl    return SM_RC_FAILURE;
3166285809Sscottl  }
3167285809Sscottl
3168285809Sscottl  smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
3169285809Sscottl
3170285809Sscottl  if (smIORequestBody == agNULL)
3171285809Sscottl  {
3172285809Sscottl    SM_DBG1(("smIDStart: smIORequestBody is NULL!!!\n"));
3173285809Sscottl    return SM_RC_FAILURE;
3174285809Sscottl  }
3175285809Sscottl
3176285809Sscottl  smIOReInit(smRoot, smIORequestBody);
3177285809Sscottl
3178285809Sscottl  SM_DBG3(("smIDStart: io ID %d!!!\n", smIORequestBody->id ));
3179285809Sscottl
3180285809Sscottl  smIORequestBody->smIORequest = smIORequest;
3181285809Sscottl  smIORequestBody->smDevHandle = smDeviceHandle;
3182285809Sscottl  satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
3183285809Sscottl
3184285809Sscottl  /* setting up satIOContext */
3185285809Sscottl  satIOContext->pSatDevData   = oneDeviceData;
3186285809Sscottl  satIOContext->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
3187285809Sscottl  satIOContext->smRequestBody = smIORequestBody;
3188285809Sscottl  satIOContext->psmDeviceHandle = smDeviceHandle;
3189285809Sscottl  satIOContext->smScsiXchg = agNULL;
3190285809Sscottl
3191285809Sscottl  /*smIORequest->smData = smIORequestBody;*/
3192285809Sscottl  SM_DBG3(("smIDStart: smIORequestBody %p smIORequestBody->smIORequest %p!!!\n", smIORequestBody, smIORequestBody->smIORequest));
3193285809Sscottl  SM_DBG1(("smIDStart: did %d\n",  oneDeviceData->id));
3194285809Sscottl
3195285809Sscottl  status = smsatIDSubStart( smRoot,
3196285809Sscottl                            smIORequest,
3197285809Sscottl                            smDeviceHandle,
3198285809Sscottl                            agNULL,
3199285809Sscottl                            satIOContext);
3200285809Sscottl
3201285809Sscottl  if (status != SM_RC_SUCCESS)
3202285809Sscottl  {
3203285809Sscottl    SM_DBG1(("smIDStart: smsatIDSubStart failure %d!!!\n", status));
3204285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
3205285809Sscottl  }
3206285809Sscottl  SM_DBG2(("smIDStart: exit\n"));
3207285809Sscottl
3208285809Sscottl  return status;
3209285809Sscottl}
3210285809Sscottl
3211285809Sscottl/*
3212285809Sscottl  SM generated IO, needs to call smsatAllocIntIoResource()
3213285809Sscottl  allocating using smsatAllocIntIoResource
3214285809Sscottl*/
3215285809SscottlosGLOBAL bit32
3216285809SscottlsmsatIDSubStart(
3217285809Sscottl                 smRoot_t                 *smRoot,
3218285809Sscottl                 smIORequest_t            *smIORequest,
3219285809Sscottl                 smDeviceHandle_t         *smDeviceHandle,
3220285809Sscottl                 smScsiInitiatorRequest_t *smSCSIRequest, /* agNULL */
3221285809Sscottl                 smSatIOContext_t         *satIOContext
3222285809Sscottl               )
3223285809Sscottl{
3224285809Sscottl  smSatInternalIo_t           *satIntIo = agNULL;
3225285809Sscottl  smDeviceData_t            *satDevData = agNULL;
3226285809Sscottl  smIORequestBody_t         *smIORequestBody;
3227285809Sscottl  smSatIOContext_t            *satNewIOContext;
3228285809Sscottl  bit32                     status;
3229285809Sscottl  SM_DBG2(("smsatIDSubStart: start\n"));
3230285809Sscottl
3231285809Sscottl  satDevData = satIOContext->pSatDevData;
3232285809Sscottl
3233285809Sscottl  /* allocate identify device command */
3234285809Sscottl  satIntIo = smsatAllocIntIoResource( smRoot,
3235285809Sscottl                                      smIORequest,
3236285809Sscottl                                      satDevData,
3237285809Sscottl                                      sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
3238285809Sscottl                                      satIntIo);
3239285809Sscottl
3240285809Sscottl  if (satIntIo == agNULL)
3241285809Sscottl  {
3242285809Sscottl    SM_DBG1(("smsatIDSubStart: can't alloacate!!!\n"));
3243285809Sscottl    return SM_RC_FAILURE;
3244285809Sscottl  }
3245285809Sscottl
3246285809Sscottl  satIOContext->satIntIoContext = satIntIo;
3247285809Sscottl
3248285809Sscottl  /* fill in fields */
3249285809Sscottl  /* real ttttttthe one worked and the same; 5/21/07/ */
3250285809Sscottl  satIntIo->satOrgSmIORequest = smIORequest; /* changed */
3251285809Sscottl  smIORequestBody = satIntIo->satIntRequestBody;
3252285809Sscottl  satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext);
3253285809Sscottl
3254285809Sscottl  satNewIOContext->pSatDevData   = satDevData;
3255285809Sscottl  satNewIOContext->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
3256285809Sscottl  satNewIOContext->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
3257285809Sscottl  satNewIOContext->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
3258285809Sscottl  satNewIOContext->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
3259285809Sscottl  satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */
3260285809Sscottl  //  satNewIOContext->interruptContext = tiInterruptContext;
3261285809Sscottl  satNewIOContext->satIntIoContext  = satIntIo;
3262285809Sscottl
3263285809Sscottl  satNewIOContext->psmDeviceHandle = smDeviceHandle;
3264285809Sscottl  satNewIOContext->satOrgIOContext = satIOContext; /* changed */
3265285809Sscottl
3266285809Sscottl  /* this is valid only for TD layer generated (not triggered by OS at all) IO */
3267285809Sscottl  satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg);
3268285809Sscottl
3269285809Sscottl
3270285809Sscottl  SM_DBG6(("smsatIDSubStart: SM satIOContext %p \n", satIOContext));
3271285809Sscottl  SM_DBG6(("smsatIDSubStart: SM satNewIOContext %p \n", satNewIOContext));
3272285809Sscottl  SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satIOContext->smScsiXchg));
3273285809Sscottl  SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satNewIOContext->smScsiXchg));
3274285809Sscottl
3275285809Sscottl
3276285809Sscottl
3277285809Sscottl  SM_DBG3(("smsatIDSubStart: satNewIOContext %p smIORequestBody %p\n", satNewIOContext, smIORequestBody));
3278285809Sscottl
3279285809Sscottl  status = smsatIDStart(smRoot,
3280285809Sscottl                        &satIntIo->satIntSmIORequest, /* New smIORequest */
3281285809Sscottl                        smDeviceHandle,
3282285809Sscottl                        satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, */
3283285809Sscottl                        satNewIOContext);
3284285809Sscottl
3285285809Sscottl  if (status != SM_RC_SUCCESS)
3286285809Sscottl  {
3287285809Sscottl    SM_DBG1(("smsatIDSubStart: failed in sending %d!!!\n", status));
3288285809Sscottl
3289285809Sscottl    smsatFreeIntIoResource( smRoot,
3290285809Sscottl                            satDevData,
3291285809Sscottl                            satIntIo);
3292285809Sscottl
3293285809Sscottl    return SM_RC_FAILURE;
3294285809Sscottl  }
3295285809Sscottl
3296285809Sscottl
3297285809Sscottl  SM_DBG2(("smsatIDSubStart: end\n"));
3298285809Sscottl
3299285809Sscottl  return status;
3300285809Sscottl
3301285809Sscottl}
3302285809Sscottl
3303285809Sscottl
3304285809SscottlosGLOBAL bit32
3305285809SscottlsmsatIDStart(
3306285809Sscottl              smRoot_t                  *smRoot,
3307285809Sscottl              smIORequest_t             *smIORequest,
3308285809Sscottl              smDeviceHandle_t          *smDeviceHandle,
3309285809Sscottl              smScsiInitiatorRequest_t  *smSCSIRequest,
3310285809Sscottl              smSatIOContext_t            *satIOContext
3311285809Sscottl             )
3312285809Sscottl{
3313285809Sscottl  bit32                     status;
3314285809Sscottl  bit32                     agRequestType;
3315285809Sscottl  smDeviceData_t            *pSatDevData;
3316285809Sscottl  agsaFisRegHostToDevice_t  *fis;
3317285809Sscottl#ifdef SM_INTERNAL_DEBUG
3318285809Sscottl  smIORequestBody_t         *smIORequestBody;
3319285809Sscottl  smSatInternalIo_t         *satIntIoContext;
3320285809Sscottl#endif
3321285809Sscottl
3322285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
3323285809Sscottl  fis           = satIOContext->pFis;
3324285809Sscottl  SM_DBG2(("smsatIDStart: start\n"));
3325285809Sscottl#ifdef SM_INTERNAL_DEBUG
3326285809Sscottl  satIntIoContext = satIOContext->satIntIoContext;
3327285809Sscottl  smIORequestBody = satIntIoContext->satIntRequestBody;
3328285809Sscottl#endif
3329285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
3330285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3331285809Sscottl  if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
3332285809Sscottl  {
3333285809Sscottl    SM_DBG2(("smsatIDStart: IDENTIFY_PACKET_DEVICE\n"));
3334285809Sscottl    fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
3335285809Sscottl  }
3336285809Sscottl  else
3337285809Sscottl  {
3338285809Sscottl    SM_DBG2(("smsatIDStart: IDENTIFY_DEVICE\n"));
3339285809Sscottl    fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
3340285809Sscottl  }
3341285809Sscottl  fis->h.features       = 0;                      /* FIS reserve */
3342285809Sscottl  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
3343285809Sscottl  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
3344285809Sscottl  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
3345285809Sscottl  fis->d.device         = 0;                      /* FIS LBA mode  */
3346285809Sscottl  fis->d.lbaLowExp      = 0;
3347285809Sscottl  fis->d.lbaMidExp      = 0;
3348285809Sscottl  fis->d.lbaHighExp     = 0;
3349285809Sscottl  fis->d.featuresExp    = 0;
3350285809Sscottl  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
3351285809Sscottl  fis->d.sectorCountExp = 0;
3352285809Sscottl  fis->d.reserved4      = 0;
3353285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
3354285809Sscottl  fis->d.reserved5      = 0;
3355285809Sscottl
3356285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
3357285809Sscottl
3358285809Sscottl  /* Initialize CB for SATA completion.
3359285809Sscottl   */
3360285809Sscottl  satIOContext->satCompleteCB = &smsatIDStartCB;
3361285809Sscottl
3362285809Sscottl  /*
3363285809Sscottl   * Prepare SGL and send FIS to LL layer.
3364285809Sscottl   */
3365285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
3366285809Sscottl
3367285809Sscottl#ifdef SM_INTERNAL_DEBUG
3368285809Sscottl  smhexdump("smsatIDStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
3369285809Sscottl  smhexdump("smsatIDStart LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
3370285809Sscottl#endif
3371285809Sscottl  status = smsataLLIOStart( smRoot,
3372285809Sscottl                            smIORequest,
3373285809Sscottl                            smDeviceHandle,
3374285809Sscottl                            smSCSIRequest,
3375285809Sscottl                            satIOContext);
3376285809Sscottl
3377285809Sscottl  SM_DBG2(("smsatIDStart: end status %d\n", status));
3378285809Sscottl
3379285809Sscottl  return status;
3380285809Sscottl}
3381285809Sscottl
3382285809Sscottl
3383285809SscottlosGLOBAL FORCEINLINE bit32
3384285809SscottlsmsatIOStart(
3385285809Sscottl              smRoot_t                  *smRoot,
3386285809Sscottl              smIORequest_t             *smIORequest,
3387285809Sscottl              smDeviceHandle_t          *smDeviceHandle,
3388285809Sscottl              smScsiInitiatorRequest_t  *smSCSIRequest,
3389285809Sscottl              smSatIOContext_t            *satIOContext
3390285809Sscottl             )
3391285809Sscottl{
3392285809Sscottl  smDeviceData_t            *pSatDevData = satIOContext->pSatDevData;
3393285809Sscottl  smScsiRspSense_t          *pSense      = satIOContext->pSense;
3394285809Sscottl  smIniScsiCmnd_t           *scsiCmnd    = &smSCSIRequest->scsiCmnd;
3395285809Sscottl  smLUN_t                   *pLun        = &scsiCmnd->lun;
3396285809Sscottl  smSatInternalIo_t         *pSatIntIo   = agNULL;
3397285809Sscottl  bit32                     status       = SM_RC_FAILURE;
3398285809Sscottl
3399285809Sscottl  SM_DBG2(("smsatIOStart: start\n"));
3400285809Sscottl
3401285809Sscottl  /*
3402285809Sscottl   * Reject all other LUN other than LUN 0.
3403285809Sscottl   */
3404285809Sscottl  if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
3405285809Sscottl         pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) &&
3406285809Sscottl        (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)
3407285809Sscottl     )
3408285809Sscottl  {
3409285809Sscottl    SM_DBG1(("smsatIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x did %d !!!\n",
3410285809Sscottl                 scsiCmnd->cdb[0], pSatDevData->id));
3411285809Sscottl    smsatSetSensePayload( pSense,
3412285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
3413285809Sscottl                          0,
3414285809Sscottl                          SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
3415285809Sscottl                          satIOContext);
3416285809Sscottl
3417285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
3418285809Sscottl
3419285809Sscottl    tdsmIOCompletedCB( smRoot,
3420285809Sscottl                       smIORequest,
3421285809Sscottl                       smIOSuccess,
3422285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
3423285809Sscottl                       satIOContext->pSmSenseData,
3424285809Sscottl                       satIOContext->interruptContext );
3425285809Sscottl
3426285809Sscottl    return SM_RC_SUCCESS;
3427285809Sscottl  }
3428285809Sscottl
3429285809Sscottl  SM_DBG2(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3430285809Sscottl
3431285809Sscottl  /* this may happen after tiCOMReset until OS sends inquiry */
3432285809Sscottl  if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
3433285809Sscottl  {
3434285809Sscottl    SM_DBG1(("smsatIOStart: invalid identify device data did %d !!!\n", pSatDevData->id));
3435285809Sscottl    SM_DBG1(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n", pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3436285809Sscottl    SM_DBG1(("smsatIOStart: satPendingNCQIO %d satPendingNONNCQIO %d\n", pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3437285809Sscottl
3438285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
3439285809Sscottl
3440285809Sscottl    return SM_RC_NODEVICE;
3441285809Sscottl  }
3442285809Sscottl
3443285809Sscottl  /*
3444285809Sscottl   * Check if we need to return BUSY, i.e. recovery in progress
3445285809Sscottl   */
3446285809Sscottl  if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
3447285809Sscottl  {
3448285809Sscottl    SM_DBG1(("smsatIOStart: IN RECOVERY STATE cdb[0]=0x%x did=%d !!!\n",
3449285809Sscottl                 scsiCmnd->cdb[0], pSatDevData->id));
3450285809Sscottl    SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n", pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3451285809Sscottl    SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3452285809Sscottl
3453285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
3454285809Sscottl
3455285809Sscottl//    return  SM_RC_FAILURE;
3456285809Sscottl    return SM_RC_DEVICE_BUSY;
3457285809Sscottl  }
3458285809Sscottl
3459285809Sscottl  if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
3460285809Sscottl  {
3461285809Sscottl     if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
3462285809Sscottl     {
3463285809Sscottl        return smsatReportLun(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
3464285809Sscottl     }
3465285809Sscottl     else
3466285809Sscottl     {
3467285809Sscottl        return smsatPacket(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
3468285809Sscottl     }
3469285809Sscottl  }
3470285809Sscottl  else
3471285809Sscottl  {
3472285809Sscottl     /* Parse CDB */
3473285809Sscottl     switch(scsiCmnd->cdb[0])
3474285809Sscottl     {
3475285809Sscottl       case SCSIOPC_READ_10:
3476285809Sscottl         status = smsatRead10( smRoot,
3477285809Sscottl                              smIORequest,
3478285809Sscottl                              smDeviceHandle,
3479285809Sscottl                              smSCSIRequest,
3480285809Sscottl                              satIOContext);
3481285809Sscottl         break;
3482285809Sscottl
3483285809Sscottl       case SCSIOPC_WRITE_10:
3484285809Sscottl         status = smsatWrite10( smRoot,
3485285809Sscottl                                smIORequest,
3486285809Sscottl                                smDeviceHandle,
3487285809Sscottl                                smSCSIRequest,
3488285809Sscottl                                satIOContext);
3489285809Sscottl         break;
3490285809Sscottl
3491285809Sscottl       case SCSIOPC_READ_6:
3492285809Sscottl         status = smsatRead6( smRoot,
3493285809Sscottl                              smIORequest,
3494285809Sscottl                              smDeviceHandle,
3495285809Sscottl                              smSCSIRequest,
3496285809Sscottl                              satIOContext);
3497285809Sscottl         break;
3498285809Sscottl
3499285809Sscottl       case SCSIOPC_READ_12:
3500285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_READ_12\n"));
3501285809Sscottl         status = smsatRead12( smRoot,
3502285809Sscottl                               smIORequest,
3503285809Sscottl                               smDeviceHandle,
3504285809Sscottl                               smSCSIRequest,
3505285809Sscottl                               satIOContext);
3506285809Sscottl         break;
3507285809Sscottl
3508285809Sscottl       case SCSIOPC_READ_16:
3509285809Sscottl         status = smsatRead16( smRoot,
3510285809Sscottl                               smIORequest,
3511285809Sscottl                               smDeviceHandle,
3512285809Sscottl                               smSCSIRequest,
3513285809Sscottl                               satIOContext);
3514285809Sscottl         break;
3515285809Sscottl
3516285809Sscottl       case SCSIOPC_WRITE_6:
3517285809Sscottl         status = smsatWrite6( smRoot,
3518285809Sscottl                               smIORequest,
3519285809Sscottl                               smDeviceHandle,
3520285809Sscottl                               smSCSIRequest,
3521285809Sscottl                               satIOContext);
3522285809Sscottl         break;
3523285809Sscottl
3524285809Sscottl       case SCSIOPC_WRITE_12:
3525285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_12 \n"));
3526285809Sscottl         status = smsatWrite12( smRoot,
3527285809Sscottl                                smIORequest,
3528285809Sscottl                                smDeviceHandle,
3529285809Sscottl                                smSCSIRequest,
3530285809Sscottl                                satIOContext);
3531285809Sscottl         break;
3532285809Sscottl
3533285809Sscottl       case SCSIOPC_WRITE_16:
3534285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_16 \n"));
3535285809Sscottl         status = smsatWrite16( smRoot,
3536285809Sscottl                                smIORequest,
3537285809Sscottl                                smDeviceHandle,
3538285809Sscottl                                smSCSIRequest,
3539285809Sscottl                                satIOContext);
3540285809Sscottl         break;
3541285809Sscottl
3542285809Sscottl       case SCSIOPC_VERIFY_10:
3543285809Sscottl         status = smsatVerify10( smRoot,
3544285809Sscottl                                 smIORequest,
3545285809Sscottl                                 smDeviceHandle,
3546285809Sscottl                                 smSCSIRequest,
3547285809Sscottl                                 satIOContext);
3548285809Sscottl         break;
3549285809Sscottl
3550285809Sscottl       case SCSIOPC_VERIFY_12:
3551285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_12\n"));
3552285809Sscottl         status = smsatVerify12( smRoot,
3553285809Sscottl                                 smIORequest,
3554285809Sscottl                                 smDeviceHandle,
3555285809Sscottl                                 smSCSIRequest,
3556285809Sscottl                                 satIOContext);
3557285809Sscottl         break;
3558285809Sscottl
3559285809Sscottl       case SCSIOPC_VERIFY_16:
3560285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_16\n"));
3561285809Sscottl         status = smsatVerify16( smRoot,
3562285809Sscottl                                 smIORequest,
3563285809Sscottl                                 smDeviceHandle,
3564285809Sscottl                                 smSCSIRequest,
3565285809Sscottl                                 satIOContext);
3566285809Sscottl         break;
3567285809Sscottl
3568285809Sscottl       case SCSIOPC_TEST_UNIT_READY:
3569285809Sscottl         status = smsatTestUnitReady( smRoot,
3570285809Sscottl                                      smIORequest,
3571285809Sscottl                                      smDeviceHandle,
3572285809Sscottl                                      smSCSIRequest,
3573285809Sscottl                                      satIOContext);
3574285809Sscottl         break;
3575285809Sscottl
3576285809Sscottl       case SCSIOPC_INQUIRY:
3577285809Sscottl         status = smsatInquiry( smRoot,
3578285809Sscottl                                smIORequest,
3579285809Sscottl                                smDeviceHandle,
3580285809Sscottl                                smSCSIRequest,
3581285809Sscottl                                satIOContext);
3582285809Sscottl         break;
3583285809Sscottl
3584285809Sscottl       case SCSIOPC_REQUEST_SENSE:
3585285809Sscottl         status = smsatRequestSense( smRoot,
3586285809Sscottl                                     smIORequest,
3587285809Sscottl                                     smDeviceHandle,
3588285809Sscottl                                     smSCSIRequest,
3589285809Sscottl                                     satIOContext);
3590285809Sscottl         break;
3591285809Sscottl
3592285809Sscottl       case SCSIOPC_MODE_SENSE_6:
3593285809Sscottl         status = smsatModeSense6( smRoot,
3594285809Sscottl                                   smIORequest,
3595285809Sscottl                                   smDeviceHandle,
3596285809Sscottl                                   smSCSIRequest,
3597285809Sscottl                                   satIOContext);
3598285809Sscottl         break;
3599285809Sscottl
3600285809Sscottl       case SCSIOPC_MODE_SENSE_10:
3601285809Sscottl         status = smsatModeSense10( smRoot,
3602285809Sscottl                                    smIORequest,
3603285809Sscottl                                    smDeviceHandle,
3604285809Sscottl                                    smSCSIRequest,
3605285809Sscottl                                    satIOContext);
3606285809Sscottl         break;
3607285809Sscottl
3608285809Sscottl       case SCSIOPC_READ_CAPACITY_10:
3609285809Sscottl         status = smsatReadCapacity10( smRoot,
3610285809Sscottl                                       smIORequest,
3611285809Sscottl                                       smDeviceHandle,
3612285809Sscottl                                       smSCSIRequest,
3613285809Sscottl                                       satIOContext);
3614285809Sscottl         break;
3615285809Sscottl
3616285809Sscottl       case SCSIOPC_READ_CAPACITY_16:
3617285809Sscottl         status = smsatReadCapacity16( smRoot,
3618285809Sscottl                                       smIORequest,
3619285809Sscottl                                       smDeviceHandle,
3620285809Sscottl                                       smSCSIRequest,
3621285809Sscottl                                       satIOContext);
3622285809Sscottl         break;
3623285809Sscottl
3624285809Sscottl
3625285809Sscottl       case SCSIOPC_REPORT_LUN:
3626285809Sscottl         status = smsatReportLun( smRoot,
3627285809Sscottl                                  smIORequest,
3628285809Sscottl                                  smDeviceHandle,
3629285809Sscottl                                  smSCSIRequest,
3630285809Sscottl                                  satIOContext);
3631285809Sscottl         break;
3632285809Sscottl
3633285809Sscottl       case SCSIOPC_FORMAT_UNIT:
3634285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_FORMAT_UNIT\n"));
3635285809Sscottl         status = smsatFormatUnit( smRoot,
3636285809Sscottl                                   smIORequest,
3637285809Sscottl                                   smDeviceHandle,
3638285809Sscottl                                   smSCSIRequest,
3639285809Sscottl                                   satIOContext);
3640285809Sscottl         break;
3641285809Sscottl
3642285809Sscottl       case SCSIOPC_SEND_DIAGNOSTIC:
3643285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
3644285809Sscottl         status = smsatSendDiagnostic( smRoot,
3645285809Sscottl                                       smIORequest,
3646285809Sscottl                                       smDeviceHandle,
3647285809Sscottl                                       smSCSIRequest,
3648285809Sscottl                                       satIOContext);
3649285809Sscottl         break;
3650285809Sscottl
3651285809Sscottl       case SCSIOPC_START_STOP_UNIT:
3652285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_START_STOP_UNIT\n"));
3653285809Sscottl         status = smsatStartStopUnit( smRoot,
3654285809Sscottl                                      smIORequest,
3655285809Sscottl                                      smDeviceHandle,
3656285809Sscottl                                      smSCSIRequest,
3657285809Sscottl                                      satIOContext);
3658285809Sscottl         break;
3659285809Sscottl
3660285809Sscottl       case SCSIOPC_WRITE_SAME_10:
3661285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_10\n"));
3662285809Sscottl         status = smsatWriteSame10( smRoot,
3663285809Sscottl                                    smIORequest,
3664285809Sscottl                                    smDeviceHandle,
3665285809Sscottl                                    smSCSIRequest,
3666285809Sscottl                                    satIOContext);
3667285809Sscottl         break;
3668285809Sscottl
3669285809Sscottl       case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */
3670285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_16\n"));
3671285809Sscottl         status = smsatWriteSame16( smRoot,
3672285809Sscottl                                    smIORequest,
3673285809Sscottl                                    smDeviceHandle,
3674285809Sscottl                                    smSCSIRequest,
3675285809Sscottl                                    satIOContext);
3676285809Sscottl         break;
3677285809Sscottl
3678285809Sscottl       case SCSIOPC_LOG_SENSE:
3679285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_LOG_SENSE\n"));
3680285809Sscottl         status = smsatLogSense( smRoot,
3681285809Sscottl                                 smIORequest,
3682285809Sscottl                                 smDeviceHandle,
3683285809Sscottl                                 smSCSIRequest,
3684285809Sscottl                                 satIOContext);
3685285809Sscottl         break;
3686285809Sscottl
3687285809Sscottl       case SCSIOPC_MODE_SELECT_6:
3688285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_6\n"));
3689285809Sscottl         status = smsatModeSelect6( smRoot,
3690285809Sscottl                                    smIORequest,
3691285809Sscottl                                    smDeviceHandle,
3692285809Sscottl                                    smSCSIRequest,
3693285809Sscottl                                    satIOContext);
3694285809Sscottl         break;
3695285809Sscottl
3696285809Sscottl       case SCSIOPC_MODE_SELECT_10:
3697285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_10\n"));
3698285809Sscottl         status = smsatModeSelect10( smRoot,
3699285809Sscottl                                     smIORequest,
3700285809Sscottl                                     smDeviceHandle,
3701285809Sscottl                                     smSCSIRequest,
3702285809Sscottl                                     satIOContext);
3703285809Sscottl         break;
3704285809Sscottl
3705285809Sscottl       case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with
3706285809Sscottl                                           satSynchronizeCache16 */
3707285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
3708285809Sscottl         status = smsatSynchronizeCache10( smRoot,
3709285809Sscottl                                           smIORequest,
3710285809Sscottl                                           smDeviceHandle,
3711285809Sscottl                                           smSCSIRequest,
3712285809Sscottl                                           satIOContext);
3713285809Sscottl         break;
3714285809Sscottl
3715285809Sscottl       case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with
3716285809Sscottl                                            satSynchronizeCache16 */
3717285809Sscottl
3718285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
3719285809Sscottl         status = smsatSynchronizeCache16( smRoot,
3720285809Sscottl                                           smIORequest,
3721285809Sscottl                                           smDeviceHandle,
3722285809Sscottl                                           smSCSIRequest,
3723285809Sscottl                                           satIOContext);
3724285809Sscottl         break;
3725285809Sscottl
3726285809Sscottl       case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */
3727285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
3728285809Sscottl         status = smsatWriteAndVerify10( smRoot,
3729285809Sscottl                                         smIORequest,
3730285809Sscottl                                         smDeviceHandle,
3731285809Sscottl                                         smSCSIRequest,
3732285809Sscottl                                         satIOContext);
3733285809Sscottl         break;
3734285809Sscottl
3735285809Sscottl       case SCSIOPC_WRITE_AND_VERIFY_12:
3736285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
3737285809Sscottl         status = smsatWriteAndVerify12( smRoot,
3738285809Sscottl                                         smIORequest,
3739285809Sscottl                                         smDeviceHandle,
3740285809Sscottl                                         smSCSIRequest,
3741285809Sscottl                                         satIOContext);
3742285809Sscottl         break;
3743285809Sscottl
3744285809Sscottl       case SCSIOPC_WRITE_AND_VERIFY_16:
3745285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
3746285809Sscottl         status = smsatWriteAndVerify16( smRoot,
3747285809Sscottl                                         smIORequest,
3748285809Sscottl                                         smDeviceHandle,
3749285809Sscottl                                         smSCSIRequest,
3750285809Sscottl                                         satIOContext);
3751285809Sscottl
3752285809Sscottl         break;
3753285809Sscottl
3754285809Sscottl       case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
3755285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
3756285809Sscottl         status = smsatReadMediaSerialNumber( smRoot,
3757285809Sscottl                                              smIORequest,
3758285809Sscottl                                              smDeviceHandle,
3759285809Sscottl                                              smSCSIRequest,
3760285809Sscottl                                              satIOContext);
3761285809Sscottl
3762285809Sscottl         break;
3763285809Sscottl
3764285809Sscottl       case SCSIOPC_READ_BUFFER:
3765285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_READ_BUFFER\n"));
3766285809Sscottl         status = smsatReadBuffer( smRoot,
3767285809Sscottl                                   smIORequest,
3768285809Sscottl                                   smDeviceHandle,
3769285809Sscottl                                   smSCSIRequest,
3770285809Sscottl                                   satIOContext);
3771285809Sscottl
3772285809Sscottl         break;
3773285809Sscottl
3774285809Sscottl       case SCSIOPC_WRITE_BUFFER:
3775285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_BUFFER\n"));
3776285809Sscottl         status = smsatWriteBuffer( smRoot,
3777285809Sscottl                                    smIORequest,
3778285809Sscottl                                    smDeviceHandle,
3779285809Sscottl                                    smSCSIRequest,
3780285809Sscottl                                    satIOContext);
3781285809Sscottl
3782285809Sscottl         break;
3783285809Sscottl
3784285809Sscottl       case SCSIOPC_REASSIGN_BLOCKS:
3785285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
3786285809Sscottl         status = smsatReassignBlocks( smRoot,
3787285809Sscottl                                       smIORequest,
3788285809Sscottl                                       smDeviceHandle,
3789285809Sscottl                                       smSCSIRequest,
3790285809Sscottl                                       satIOContext);
3791285809Sscottl
3792285809Sscottl         break;
3793285809Sscottl
3794285809Sscottl       case SCSIOPC_ATA_PASS_THROUGH12: /* fall through */
3795285809Sscottl       case SCSIOPC_ATA_PASS_THROUGH16:
3796285809Sscottl         SM_DBG5(("smsatIOStart: SCSIOPC_ATA_PASS_THROUGH\n"));
3797285809Sscottl         status = smsatPassthrough( smRoot,
3798285809Sscottl                                    smIORequest,
3799285809Sscottl                                    smDeviceHandle,
3800285809Sscottl                                    smSCSIRequest,
3801285809Sscottl                                    satIOContext);
3802285809Sscottl         break;
3803285809Sscottl
3804285809Sscottl       default:
3805285809Sscottl         /* Not implemented SCSI cmd, set up error response */
3806285809Sscottl         SM_DBG1(("smsatIOStart: unsupported SCSI cdb[0]=0x%x did=%d !!!\n",
3807285809Sscottl                    scsiCmnd->cdb[0], pSatDevData->id));
3808285809Sscottl
3809285809Sscottl         smsatSetSensePayload( pSense,
3810285809Sscottl                               SCSI_SNSKEY_ILLEGAL_REQUEST,
3811285809Sscottl                               0,
3812285809Sscottl                               SCSI_SNSCODE_INVALID_COMMAND,
3813285809Sscottl                               satIOContext);
3814285809Sscottl
3815285809Sscottl         /*smEnqueueIO(smRoot, satIOContext);*/
3816285809Sscottl
3817285809Sscottl         tdsmIOCompletedCB( smRoot,
3818285809Sscottl                            smIORequest,
3819285809Sscottl                            smIOSuccess,
3820285809Sscottl                            SCSI_STAT_CHECK_CONDITION,
3821285809Sscottl                            satIOContext->pSmSenseData,
3822285809Sscottl                            satIOContext->interruptContext );
3823285809Sscottl         status = SM_RC_SUCCESS;
3824285809Sscottl
3825285809Sscottl         break;
3826285809Sscottl
3827285809Sscottl     }  /* end switch  */
3828285809Sscottl  }
3829285809Sscottl
3830285809Sscottl  if (status == SM_RC_BUSY || status == SM_RC_DEVICE_BUSY)
3831285809Sscottl  {
3832285809Sscottl    SM_DBG1(("smsatIOStart: BUSY did %d!!!\n", pSatDevData->id));
3833285809Sscottl    SM_DBG2(("smsatIOStart: LL is busy or target queue is full\n"));
3834285809Sscottl    SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3835285809Sscottl    SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3836285809Sscottl    pSatIntIo               = satIOContext->satIntIoContext;
3837285809Sscottl
3838285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
3839285809Sscottl
3840285809Sscottl    /* interal structure free */
3841285809Sscottl    smsatFreeIntIoResource( smRoot,
3842285809Sscottl                            pSatDevData,
3843285809Sscottl                            pSatIntIo);
3844285809Sscottl  }
3845285809Sscottl
3846285809Sscottl  return status;
3847285809Sscottl}
3848285809Sscottl
3849285809SscottlosGLOBAL void
3850285809SscottlsmsatSetSensePayload(
3851285809Sscottl                     smScsiRspSense_t   *pSense,
3852285809Sscottl                     bit8               SnsKey,
3853285809Sscottl                     bit32              SnsInfo,
3854285809Sscottl                     bit16              SnsCode,
3855285809Sscottl                     smSatIOContext_t     *satIOContext)
3856285809Sscottl{
3857285809Sscottl  /* for fixed format sense data, SPC-4, p37 */
3858285809Sscottl  bit32      i;
3859285809Sscottl  bit32      senseLength;
3860285809Sscottl  bit8       tmp = 0;
3861285809Sscottl
3862285809Sscottl  SM_DBG2(("smsatSetSensePayload: start\n"));
3863285809Sscottl
3864285809Sscottl  senseLength  = sizeof(smScsiRspSense_t);
3865285809Sscottl
3866285809Sscottl  /* zero out the data area */
3867285809Sscottl  for (i=0;i< senseLength;i++)
3868285809Sscottl  {
3869285809Sscottl    ((bit8*)pSense)[i] = 0;
3870285809Sscottl  }
3871285809Sscottl
3872285809Sscottl  /*
3873285809Sscottl   * SCSI Sense Data part of response data
3874285809Sscottl   */
3875285809Sscottl  pSense->snsRespCode  = 0x70;    /*  0xC0 == vendor specific */
3876285809Sscottl                                      /*  0x70 == standard current error */
3877285809Sscottl  pSense->senseKey     = SnsKey;
3878285809Sscottl  /*
3879285809Sscottl   * Put sense info in scsi order format
3880285809Sscottl   */
3881285809Sscottl  pSense->info[0]      = (bit8)((SnsInfo >> 24) & 0xff);
3882285809Sscottl  pSense->info[1]      = (bit8)((SnsInfo >> 16) & 0xff);
3883285809Sscottl  pSense->info[2]      = (bit8)((SnsInfo >> 8) & 0xff);
3884285809Sscottl  pSense->info[3]      = (bit8)((SnsInfo) & 0xff);
3885285809Sscottl  pSense->addSenseLen  = 11;          /* fixed size of sense data = 18 */
3886285809Sscottl  pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
3887285809Sscottl  pSense->senseQual    = (bit8)(SnsCode & 0xFF);
3888285809Sscottl  /*
3889285809Sscottl   * Set pointer in scsi status
3890285809Sscottl   */
3891285809Sscottl  switch(SnsKey)
3892285809Sscottl  {
3893285809Sscottl    /*
3894285809Sscottl     * set illegal request sense key specific error in cdb, no bit pointer
3895285809Sscottl     */
3896285809Sscottl    case SCSI_SNSKEY_ILLEGAL_REQUEST:
3897285809Sscottl      pSense->skeySpecific[0] = 0xC8;
3898285809Sscottl      break;
3899285809Sscottl
3900285809Sscottl    default:
3901285809Sscottl      break;
3902285809Sscottl  }
3903285809Sscottl  /* setting sense data length */
3904285809Sscottl  if (satIOContext != agNULL)
3905285809Sscottl  {
3906285809Sscottl    satIOContext->pSmSenseData->senseLen = 18;
3907285809Sscottl  }
3908285809Sscottl  else
3909285809Sscottl  {
3910285809Sscottl    SM_DBG1(("smsatSetSensePayload: satIOContext is NULL!!!\n"));
3911285809Sscottl  }
3912285809Sscottl
3913285809Sscottl  /* Only for SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE */
3914285809Sscottl  if (SnsCode == SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE)
3915285809Sscottl  {
3916285809Sscottl    /* filling in COMMAND-SPECIFIC INFORMATION */
3917285809Sscottl    tmp = satIOContext->extend << 7 | satIOContext->Sector_Cnt_Upper_Nonzero << 6 | satIOContext->LBA_Upper_Nonzero << 5;
3918285809Sscottl    SM_DBG3(("smsatSetSensePayload: extend 0x%x Sector_Cnt_Upper_Nonzero 0x%x LBA_Upper_Nonzero 0x%x\n",
3919285809Sscottl    satIOContext->extend, satIOContext->Sector_Cnt_Upper_Nonzero, satIOContext->LBA_Upper_Nonzero));
3920285809Sscottl    SM_DBG3(("smsatSetSensePayload: tmp 0x%x\n", tmp));
3921285809Sscottl    pSense->cmdSpecific[0]      = tmp;
3922285809Sscottl    pSense->cmdSpecific[1]      = satIOContext->LBAHigh07;
3923285809Sscottl    pSense->cmdSpecific[2]      = satIOContext->LBAMid07;
3924285809Sscottl    pSense->cmdSpecific[3]      = satIOContext->LBALow07;
3925285809Sscottl//    smhexdump("smsatSetSensePayload: cmdSpecific",(bit8 *)pSense->cmdSpecific, 4);
3926285809Sscottl//    smhexdump("smsatSetSensePayload: info",(bit8 *)pSense->info, 4);
3927285809Sscottl
3928285809Sscottl  }
3929285809Sscottl  return;
3930285809Sscottl}
3931285809Sscottl
3932285809Sscottl/*****************************************************************************
3933285809Sscottl*! \brief  smsatDecodeSATADeviceType
3934285809Sscottl*
3935285809Sscottl*   This routine decodes ATA signature
3936285809Sscottl*
3937285809Sscottl*  \param   pSignature:       ATA signature
3938285809Sscottl*
3939285809Sscottl*
3940285809Sscottl*  \return:
3941285809Sscottl*          TRUE if ATA signature
3942285809Sscottl*          FALSE otherwise
3943285809Sscottl*
3944285809Sscottl*****************************************************************************/
3945285809Sscottl/*
3946285809Sscottl  ATA p65
3947285809Sscottl  PM p65
3948285809Sscottl  SATAII p79, p80
3949285809Sscottl */
3950285809SscottlGLOBAL bit32
3951285809SscottlsmsatDecodeSATADeviceType(
3952285809Sscottl                         bit8  *pSignature
3953285809Sscottl                         )
3954285809Sscottl{
3955285809Sscottl  bit32 deviceType = UNKNOWN_DEVICE;
3956285809Sscottl
3957285809Sscottl  if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3958285809Sscottl       && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00
3959285809Sscottl       && (pSignature)[4] == 0xA0 )    /* this is the signature of a Hitachi SATA HDD*/
3960285809Sscottl  {
3961285809Sscottl    deviceType = SATA_ATA_DEVICE;
3962285809Sscottl  }
3963285809Sscottl  else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3964285809Sscottl      && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00
3965285809Sscottl      && (pSignature)[4] == 0x00 )
3966285809Sscottl  {
3967285809Sscottl    deviceType = SATA_ATA_DEVICE;
3968285809Sscottl  }
3969285809Sscottl  else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3970285809Sscottl          && (pSignature)[2] == 0x14 && (pSignature)[3] == 0xEB
3971285809Sscottl          && ( (pSignature)[4] == 0x00 || (pSignature)[4] == 0x10) )
3972285809Sscottl  {
3973285809Sscottl    deviceType = SATA_ATAPI_DEVICE;
3974285809Sscottl  }
3975285809Sscottl  else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3976285809Sscottl          && (pSignature)[2] == 0x69 && (pSignature)[3] == 0x96
3977285809Sscottl          && (pSignature)[4] == 0x00 )
3978285809Sscottl  {
3979285809Sscottl    deviceType = SATA_PM_DEVICE;
3980285809Sscottl  }
3981285809Sscottl  else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3982285809Sscottl          && (pSignature)[2] == 0x3C && (pSignature)[3] == 0xC3
3983285809Sscottl          && (pSignature)[4] == 0x00 )
3984285809Sscottl  {
3985285809Sscottl    deviceType = SATA_SEMB_DEVICE;
3986285809Sscottl  }
3987285809Sscottl  else if ( (pSignature)[0] == 0xFF && (pSignature)[1] == 0xFF
3988285809Sscottl          && (pSignature)[2] == 0xFF && (pSignature)[3] == 0xFF
3989285809Sscottl          && (pSignature)[4] == 0xFF )
3990285809Sscottl  {
3991285809Sscottl    deviceType = SATA_SEMB_WO_SEP_DEVICE;
3992285809Sscottl  }
3993285809Sscottl
3994285809Sscottl  return deviceType;
3995285809Sscottl}
3996285809Sscottl
3997285809Sscottl
3998285809Sscottl/*****************************************************************************/
3999285809Sscottl/*! \brief SAT implementation for ATAPI Packet Command.
4000285809Sscottl *
4001285809Sscottl *  SAT implementation for ATAPI Packet and send FIS request to LL layer.
4002285809Sscottl *
4003285809Sscottl *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4004285809Sscottl *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4005285809Sscottl *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4006285809Sscottl *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4007285809Sscottl *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4008285809Sscottl *
4009285809Sscottl *  \return If command is started successfully
4010285809Sscottl *    - \e smIOSuccess:     I/O request successfully initiated.
4011285809Sscottl *    - \e smIOBusy:        No resources available, try again later.
4012285809Sscottl *    - \e smIONoDevice:  Invalid device handle.
4013285809Sscottl *    - \e smIOError:       Other errors.
4014285809Sscottl */
4015285809Sscottl/*****************************************************************************/
4016285809SscottlosGLOBAL bit32
4017285809SscottlsmsatPacket(
4018285809Sscottl          smRoot_t                  *smRoot,
4019285809Sscottl          smIORequest_t             *smIORequest,
4020285809Sscottl          smDeviceHandle_t          *smDeviceHandle,
4021285809Sscottl          smScsiInitiatorRequest_t  *smScsiRequest,
4022285809Sscottl          smSatIOContext_t            *satIOContext
4023285809Sscottl  )
4024285809Sscottl{
4025285809Sscottl  bit32                     status;
4026285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4027285809Sscottl  smDeviceData_t            *pSatDevData;
4028285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
4029285809Sscottl  agsaFisRegHostToDevice_t  *fis;
4030285809Sscottl
4031285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
4032285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
4033285809Sscottl  fis           = satIOContext->pFis;
4034285809Sscottl
4035285809Sscottl  SM_DBG3(("smsatPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
4036285809Sscottl           scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
4037285809Sscottl           scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
4038285809Sscottl           scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
4039285809Sscottl
4040285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
4041285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
4042285809Sscottl  fis->h.command        = SAT_PACKET;             /* 0xA0 */
4043285809Sscottl  if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
4044285809Sscottl  {
4045285809Sscottl     fis->h.features    = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
4046285809Sscottl  }
4047285809Sscottl  else
4048285809Sscottl  {
4049285809Sscottl     fis->h.features    = 0;                      /* FIS reserve */
4050285809Sscottl  }
4051285809Sscottl
4052285809Sscottl  if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4053285809Sscottl  {
4054285809Sscottl     /*DMA transfer mode*/
4055285809Sscottl     fis->h.features |= 0x01;
4056285809Sscottl  }
4057285809Sscottl  else
4058285809Sscottl  {
4059285809Sscottl     /*PIO transfer mode*/
4060285809Sscottl     fis->h.features |= 0x0;
4061285809Sscottl  }
4062285809Sscottl  /* Byte count low and byte count high */
4063285809Sscottl  if ( scsiCmnd->expDataLength > 0xFFFF )
4064285809Sscottl  {
4065285809Sscottl     fis->d.lbaMid = 0xFF;                                 /* FIS LBA (15:8 ) */
4066285809Sscottl     fis->d.lbaHigh = 0xFF;                                /* FIS LBA (23:16) */
4067285809Sscottl  }
4068285809Sscottl  else
4069285809Sscottl  {
4070285809Sscottl     fis->d.lbaMid = (bit8)scsiCmnd->expDataLength;        /* FIS LBA (15:8 ) */
4071285809Sscottl     fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8);  /* FIS LBA (23:16) */
4072285809Sscottl  }
4073285809Sscottl
4074285809Sscottl  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
4075285809Sscottl  fis->d.device         = 0;                      /* FIS LBA (27:24) and FIS LBA mode  */
4076285809Sscottl  fis->d.lbaLowExp      = 0;
4077285809Sscottl  fis->d.lbaMidExp      = 0;
4078285809Sscottl  fis->d.lbaHighExp     = 0;
4079285809Sscottl  fis->d.featuresExp    = 0;
4080285809Sscottl  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
4081285809Sscottl  fis->d.sectorCountExp = 0;
4082285809Sscottl  fis->d.reserved4      = 0;
4083285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
4084285809Sscottl  fis->d.reserved5      = 0;
4085285809Sscottl
4086285809Sscottl  satIOContext->ATACmd = SAT_PACKET;
4087285809Sscottl
4088285809Sscottl  if (smScsiRequest->dataDirection == smDirectionIn)
4089285809Sscottl  {
4090285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4091285809Sscottl  }
4092285809Sscottl  else
4093285809Sscottl  {
4094285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
4095285809Sscottl  }
4096285809Sscottl
4097285809Sscottl  satIOContext->satCompleteCB = &smsatPacketCB;
4098285809Sscottl
4099285809Sscottl  /*
4100285809Sscottl   * Prepare SGL and send FIS to LL layer.
4101285809Sscottl   */
4102285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
4103285809Sscottl
4104285809Sscottl  status = smsataLLIOStart(smRoot,
4105285809Sscottl                          smIORequest,
4106285809Sscottl                          smDeviceHandle,
4107285809Sscottl                          smScsiRequest,
4108285809Sscottl                          satIOContext);
4109285809Sscottl
4110285809Sscottl  SM_DBG3(("smsatPacket: return\n"));
4111285809Sscottl  return (status);
4112285809Sscottl}
4113285809Sscottl
4114285809Sscottl/*****************************************************************************/
4115285809Sscottl/*! \brief SAT implementation for smsatSetFeaturePIO.
4116285809Sscottl *
4117285809Sscottl *  This function creates Set Features fis and sends the request to LL layer
4118285809Sscottl *
4119285809Sscottl *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4120285809Sscottl *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4121285809Sscottl *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4122285809Sscottl *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4123285809Sscottl *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4124285809Sscottl *
4125285809Sscottl *  \return If command is started successfully
4126285809Sscottl *    - \e smIOSuccess:     I/O request successfully initiated.
4127285809Sscottl *    - \e smIOBusy:        No resources available, try again later.
4128285809Sscottl *    - \e smIONoDevice:  Invalid device handle.
4129285809Sscottl *    - \e smIOError:       Other errors.
4130285809Sscottl */
4131285809Sscottl/*****************************************************************************/
4132285809SscottlosGLOBAL bit32
4133285809SscottlsmsatSetFeaturesPIO(
4134285809Sscottl  smRoot_t                  *smRoot,
4135285809Sscottl  smIORequest_t             *smIORequest,
4136285809Sscottl  smDeviceHandle_t          *smDeviceHandle,
4137285809Sscottl  smScsiInitiatorRequest_t  *smScsiRequest,
4138285809Sscottl  smSatIOContext_t          *satIOContext
4139285809Sscottl  )
4140285809Sscottl{
4141285809Sscottl  bit32                     status = SM_RC_FAILURE;
4142285809Sscottl  bit32                     agRequestType;
4143285809Sscottl  agsaFisRegHostToDevice_t *fis;
4144285809Sscottl
4145285809Sscottl  fis           = satIOContext->pFis;
4146285809Sscottl  SM_DBG2(("smsatSetFeaturesPIO: start\n"));
4147285809Sscottl  /*
4148285809Sscottl   * Send the Set Features command.
4149285809Sscottl   */
4150285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
4151285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4152285809Sscottl  fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
4153285809Sscottl  fis->h.features       = 0x03;                   /* set transfer mode */
4154285809Sscottl  fis->d.lbaLow         = 0;
4155285809Sscottl  fis->d.lbaMid         = 0;
4156285809Sscottl  fis->d.lbaHigh        = 0;
4157285809Sscottl  fis->d.device         = 0;
4158285809Sscottl  fis->d.lbaLowExp      = 0;
4159285809Sscottl  fis->d.lbaMidExp      = 0;
4160285809Sscottl  fis->d.lbaHighExp     = 0;
4161285809Sscottl  fis->d.featuresExp    = 0;
4162285809Sscottl  fis->d.sectorCountExp = 0;
4163285809Sscottl  fis->d.reserved4      = 0;
4164285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
4165285809Sscottl  fis->d.reserved5      = 0;
4166285809Sscottl
4167285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
4168285809Sscottl
4169285809Sscottl  /* Initialize CB for SATA completion.
4170285809Sscottl   */
4171285809Sscottl  fis->d.sectorCount = 0x0C;                     /*enable PIO transfer mode */
4172285809Sscottl  satIOContext->satCompleteCB = &smsatSetFeaturesPIOCB;
4173285809Sscottl
4174285809Sscottl  /*
4175285809Sscottl   * Prepare SGL and send FIS to LL layer.
4176285809Sscottl   */
4177285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
4178285809Sscottl
4179285809Sscottl  status = smsataLLIOStart( smRoot,
4180285809Sscottl                          smIORequest,
4181285809Sscottl                          smDeviceHandle,
4182285809Sscottl                          smScsiRequest,
4183285809Sscottl                          satIOContext);
4184285809Sscottl
4185285809Sscottl  SM_DBG2(("smsatSetFeaturesPIO: return\n"));
4186285809Sscottl  /* debugging code */
4187285809Sscottl  if (smIORequest->tdData == smIORequest->smData)
4188285809Sscottl  {
4189285809Sscottl    SM_DBG1(("smsatSetFeaturesPIO: incorrect smIORequest\n"));
4190285809Sscottl  }
4191285809Sscottl
4192285809Sscottl  return status;
4193285809Sscottl}
4194285809Sscottl/*****************************************************************************/
4195285809Sscottl/*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device.
4196285809Sscottl *
4197285809Sscottl *  SAT implementation for SCSI REQUEST SENSE.
4198285809Sscottl *
4199285809Sscottl *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4200285809Sscottl *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4201285809Sscottl *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4202285809Sscottl *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4203285809Sscottl *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4204285809Sscottl *
4205285809Sscottl *  \return If command is started successfully
4206285809Sscottl *    - \e smIOSuccess:     I/O request successfully initiated.
4207285809Sscottl *    - \e smIOBusy:        No resources available, try again later.
4208285809Sscottl *    - \e smIONoDevice:  Invalid device handle.
4209285809Sscottl *    - \e smIOError:       Other errors.
4210285809Sscottl */
4211285809Sscottl/*****************************************************************************/
4212285809SscottlosGLOBAL bit32
4213285809SscottlsmsatRequestSenseForATAPI(
4214285809Sscottl  smRoot_t                  *smRoot,
4215285809Sscottl  smIORequest_t             *smIORequest,
4216285809Sscottl  smDeviceHandle_t          *smDeviceHandle,
4217285809Sscottl  smScsiInitiatorRequest_t  *smScsiRequest,
4218285809Sscottl  smSatIOContext_t            *satIOContext
4219285809Sscottl  )
4220285809Sscottl{
4221285809Sscottl  bit32                     status;
4222285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4223285809Sscottl  smDeviceData_t            *pSatDevData;
4224285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
4225285809Sscottl  agsaFisRegHostToDevice_t  *fis;
4226285809Sscottl
4227285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
4228285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
4229285809Sscottl  fis           = satIOContext->pFis;
4230285809Sscottl
4231285809Sscottl  scsiCmnd->cdb[0]   = SCSIOPC_REQUEST_SENSE;
4232285809Sscottl  scsiCmnd->cdb[1]   = 0;
4233285809Sscottl  scsiCmnd->cdb[2]   = 0;
4234285809Sscottl  scsiCmnd->cdb[3]   = 0;
4235285809Sscottl  scsiCmnd->cdb[4]   = (bit8)scsiCmnd->expDataLength;
4236285809Sscottl  scsiCmnd->cdb[5]   = 0;
4237285809Sscottl  SM_DBG3(("smsatRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
4238285809Sscottl           scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
4239285809Sscottl           scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
4240285809Sscottl           scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
4241285809Sscottl
4242285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
4243285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
4244285809Sscottl  fis->h.command        = SAT_PACKET;             /* 0xA0 */
4245285809Sscottl  if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
4246285809Sscottl  {
4247285809Sscottl     fis->h.features    = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
4248285809Sscottl  }
4249285809Sscottl  else
4250285809Sscottl  {
4251285809Sscottl     fis->h.features    = 0;                      /* FIS reserve */
4252285809Sscottl  }
4253285809Sscottl
4254285809Sscottl  if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4255285809Sscottl  {
4256285809Sscottl     fis->h.features |= 0x01;
4257285809Sscottl  }
4258285809Sscottl  else
4259285809Sscottl  {
4260285809Sscottl     fis->h.features |= 0x0;
4261285809Sscottl  }
4262285809Sscottl
4263285809Sscottl  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
4264285809Sscottl  fis->d.lbaMid         = (bit8)scsiCmnd->expDataLength;        /* FIS LBA (15:8 ) */
4265285809Sscottl  fis->d.lbaHigh        = (bit8)(scsiCmnd->expDataLength>>8);  /* FIS LBA (23:16) */
4266285809Sscottl  fis->d.device         = 0;                      /* FIS LBA (27:24) and FIS LBA mode  */
4267285809Sscottl  fis->d.lbaLowExp      = 0;
4268285809Sscottl  fis->d.lbaMidExp      = 0;
4269285809Sscottl  fis->d.lbaHighExp     = 0;
4270285809Sscottl  fis->d.featuresExp    = 0;
4271285809Sscottl  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
4272285809Sscottl  fis->d.sectorCountExp = 0;
4273285809Sscottl  fis->d.reserved4      = 0;
4274285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
4275285809Sscottl  fis->d.reserved5      = 0;
4276285809Sscottl
4277285809Sscottl  satIOContext->ATACmd = SAT_PACKET;
4278285809Sscottl
4279285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4280285809Sscottl
4281285809Sscottl
4282285809Sscottl  satIOContext->satCompleteCB = &smsatRequestSenseForATAPICB;
4283285809Sscottl
4284285809Sscottl  /*
4285285809Sscottl   * Prepare SGL and send FIS to LL layer.
4286285809Sscottl   */
4287285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
4288285809Sscottl
4289285809Sscottl  status = smsataLLIOStart( smRoot,
4290285809Sscottl                          smIORequest,
4291285809Sscottl                          smDeviceHandle,
4292285809Sscottl                          smScsiRequest,
4293285809Sscottl                          satIOContext);
4294285809Sscottl
4295285809Sscottl  SM_DBG3(("smsatRequestSenseForATAPI: return\n"));
4296285809Sscottl  return (status);
4297285809Sscottl}
4298285809Sscottl/*****************************************************************************/
4299285809Sscottl/*! \brief SAT implementation for smsatDeviceReset.
4300285809Sscottl *
4301285809Sscottl *  This function creates DEVICE RESET fis and sends the request to LL layer
4302285809Sscottl *
4303285809Sscottl *  \param   smRoot:           Pointer to TISA initiator driver/port instance.
4304285809Sscottl *  \param   smIORequest:      Pointer to TISA I/O request context for this I/O.
4305285809Sscottl *  \param   smDeviceHandle:   Pointer to TISA device handle for this I/O.
4306285809Sscottl *  \param   smScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4307285809Sscottl *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4308285809Sscottl *
4309285809Sscottl *  \return If command is started successfully
4310285809Sscottl *    - \e smIOSuccess:     I/O request successfully initiated.
4311285809Sscottl *    - \e smIOBusy:        No resources available, try again later.
4312285809Sscottl *    - \e smIONoDevice:  Invalid device handle.
4313285809Sscottl *    - \e smIOError:       Other errors.
4314285809Sscottl */
4315285809Sscottl/*****************************************************************************/
4316285809SscottlosGLOBAL bit32
4317285809SscottlsmsatDeviceReset(
4318285809Sscottl  smRoot_t                  *smRoot,
4319285809Sscottl  smIORequest_t             *smIORequest,
4320285809Sscottl  smDeviceHandle_t          *smDeviceHandle,
4321285809Sscottl  smScsiInitiatorRequest_t  *smScsiRequest,
4322285809Sscottl  smSatIOContext_t            *satIOContext
4323285809Sscottl  )
4324285809Sscottl{
4325285809Sscottl  bit32                     status;
4326285809Sscottl  bit32                     agRequestType;
4327285809Sscottl  agsaFisRegHostToDevice_t *fis;
4328285809Sscottl
4329285809Sscottl  fis           = satIOContext->pFis;
4330285809Sscottl  SM_DBG3(("smsatDeviceReset: start\n"));
4331285809Sscottl  /*
4332285809Sscottl   * Send the  Execute Device Diagnostic command.
4333285809Sscottl   */
4334285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
4335285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4336285809Sscottl  fis->h.command        = SAT_DEVICE_RESET;       /* 0x08 */
4337285809Sscottl  fis->h.features       = 0;
4338285809Sscottl  fis->d.lbaLow         = 0;
4339285809Sscottl  fis->d.lbaMid         = 0;
4340285809Sscottl  fis->d.lbaHigh        = 0;
4341285809Sscottl  fis->d.device         = 0;
4342285809Sscottl  fis->d.lbaLowExp      = 0;
4343285809Sscottl  fis->d.lbaMidExp      = 0;
4344285809Sscottl  fis->d.lbaHighExp     = 0;
4345285809Sscottl  fis->d.featuresExp    = 0;
4346285809Sscottl  fis->d.sectorCount    = 0;
4347285809Sscottl  fis->d.sectorCountExp = 0;
4348285809Sscottl  fis->d.reserved4      = 0;
4349285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
4350285809Sscottl  fis->d.reserved5      = 0;
4351285809Sscottl
4352285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
4353285809Sscottl
4354285809Sscottl  /* Initialize CB for SATA completion.
4355285809Sscottl   */
4356285809Sscottl  satIOContext->satCompleteCB = &smsatDeviceResetCB;
4357285809Sscottl
4358285809Sscottl  /*
4359285809Sscottl   * Prepare SGL and send FIS to LL layer.
4360285809Sscottl   */
4361285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
4362285809Sscottl
4363285809Sscottl  status = smsataLLIOStart( smRoot,
4364285809Sscottl                          smIORequest,
4365285809Sscottl                          smDeviceHandle,
4366285809Sscottl                          smScsiRequest,
4367285809Sscottl                          satIOContext);
4368285809Sscottl
4369285809Sscottl  SM_DBG3(("smsatDeviceReset: return\n"));
4370285809Sscottl
4371285809Sscottl  return status;
4372285809Sscottl}
4373285809Sscottl
4374285809Sscottl
4375285809Sscottl/*****************************************************************************/
4376285809Sscottl/*! \brief SAT implementation for smsatExecuteDeviceDiagnostic.
4377285809Sscottl *
4378285809Sscottl *  This function creates Execute Device Diagnostic fis and sends the request to LL layer
4379285809Sscottl *
4380285809Sscottl *  \param   smRoot:           Pointer to TISA initiator driver/port instance.
4381285809Sscottl *  \param   smIORequest:      Pointer to TISA I/O request context for this I/O.
4382285809Sscottl *  \param   smDeviceHandle:   Pointer to TISA device handle for this I/O.
4383285809Sscottl *  \param   smScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4384285809Sscottl *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4385285809Sscottl *
4386285809Sscottl *  \return If command is started successfully
4387285809Sscottl *    - \e smIOSuccess:     I/O request successfully initiated.
4388285809Sscottl *    - \e smIOBusy:        No resources available, try again later.
4389285809Sscottl *    - \e smIONoDevice:  Invalid device handle.
4390285809Sscottl *    - \e smIOError:       Other errors.
4391285809Sscottl */
4392285809Sscottl/*****************************************************************************/
4393285809SscottlosGLOBAL bit32
4394285809SscottlsmsatExecuteDeviceDiagnostic(
4395285809Sscottl  smRoot_t                  *smRoot,
4396285809Sscottl  smIORequest_t             *smIORequest,
4397285809Sscottl  smDeviceHandle_t          *smDeviceHandle,
4398285809Sscottl  smScsiInitiatorRequest_t  *smScsiRequest,
4399285809Sscottl  smSatIOContext_t            *satIOContext
4400285809Sscottl  )
4401285809Sscottl{
4402285809Sscottl  bit32                     status;
4403285809Sscottl  bit32                     agRequestType;
4404285809Sscottl  agsaFisRegHostToDevice_t *fis;
4405285809Sscottl
4406285809Sscottl  fis           = satIOContext->pFis;
4407285809Sscottl  SM_DBG3(("smsatExecuteDeviceDiagnostic: start\n"));
4408285809Sscottl  /*
4409285809Sscottl   * Send the  Execute Device Diagnostic command.
4410285809Sscottl   */
4411285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
4412285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4413285809Sscottl  fis->h.command        = SAT_EXECUTE_DEVICE_DIAGNOSTIC;   /* 0x90 */
4414285809Sscottl  fis->h.features       = 0;
4415285809Sscottl  fis->d.lbaLow         = 0;
4416285809Sscottl  fis->d.lbaMid         = 0;
4417285809Sscottl  fis->d.lbaHigh        = 0;
4418285809Sscottl  fis->d.device         = 0;
4419285809Sscottl  fis->d.lbaLowExp      = 0;
4420285809Sscottl  fis->d.lbaMidExp      = 0;
4421285809Sscottl  fis->d.lbaHighExp     = 0;
4422285809Sscottl  fis->d.featuresExp    = 0;
4423285809Sscottl  fis->d.sectorCount    = 0;
4424285809Sscottl  fis->d.sectorCountExp = 0;
4425285809Sscottl  fis->d.reserved4      = 0;
4426285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
4427285809Sscottl  fis->d.reserved5      = 0;
4428285809Sscottl
4429285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
4430285809Sscottl
4431285809Sscottl  /* Initialize CB for SATA completion.
4432285809Sscottl   */
4433285809Sscottl  satIOContext->satCompleteCB = &smsatExecuteDeviceDiagnosticCB;
4434285809Sscottl
4435285809Sscottl  /*
4436285809Sscottl   * Prepare SGL and send FIS to LL layer.
4437285809Sscottl   */
4438285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
4439285809Sscottl
4440285809Sscottl  status = smsataLLIOStart( smRoot,
4441285809Sscottl                          smIORequest,
4442285809Sscottl                          smDeviceHandle,
4443285809Sscottl                          smScsiRequest,
4444285809Sscottl                          satIOContext);
4445285809Sscottl
4446285809Sscottl  SM_DBG3(("smsatExecuteDeviceDiagnostic: return\n"));
4447285809Sscottl
4448285809Sscottl  return status;
4449285809Sscottl}
4450285809Sscottl
4451285809Sscottl
4452285809SscottlosGLOBAL void
4453285809SscottlsmsatSetDeferredSensePayload(
4454285809Sscottl                             smScsiRspSense_t *pSense,
4455285809Sscottl                             bit8             SnsKey,
4456285809Sscottl                             bit32            SnsInfo,
4457285809Sscottl                             bit16            SnsCode,
4458285809Sscottl                             smSatIOContext_t   *satIOContext
4459285809Sscottl                            )
4460285809Sscottl{
4461285809Sscottl  SM_DBG2(("smsatSetDeferredSensePayload: start\n"));
4462285809Sscottl  return;
4463285809Sscottl}
4464285809Sscottl
4465285809Sscottl
4466285809SscottlGLOBAL bit32
4467285809SscottlsmsatRead6(
4468285809Sscottl           smRoot_t                  *smRoot,
4469285809Sscottl           smIORequest_t             *smIORequest,
4470285809Sscottl           smDeviceHandle_t          *smDeviceHandle,
4471285809Sscottl           smScsiInitiatorRequest_t  *smScsiRequest,
4472285809Sscottl           smSatIOContext_t            *satIOContext
4473285809Sscottl    )
4474285809Sscottl{
4475285809Sscottl  bit32                     status;
4476285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4477285809Sscottl  smDeviceData_t            *pSatDevData;
4478285809Sscottl  smScsiRspSense_t          *pSense;
4479285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
4480285809Sscottl  agsaFisRegHostToDevice_t  *fis;
4481285809Sscottl  bit32                     lba = 0;
4482285809Sscottl  bit16                     tl = 0;
4483285809Sscottl
4484285809Sscottl  pSense        = satIOContext->pSense;
4485285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
4486285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
4487285809Sscottl  fis           = satIOContext->pFis;
4488285809Sscottl
4489285809Sscottl  SM_DBG2(("smsatRead6: start\n"));
4490285809Sscottl
4491285809Sscottl  /* no FUA checking since read6 */
4492285809Sscottl
4493285809Sscottl
4494285809Sscottl  /* checking CONTROL */
4495285809Sscottl  /* NACA == 1 or LINK == 1*/
4496285809Sscottl  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
4497285809Sscottl  {
4498285809Sscottl    smsatSetSensePayload( pSense,
4499285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
4500285809Sscottl                          0,
4501285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4502285809Sscottl                          satIOContext);
4503285809Sscottl
4504285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
4505285809Sscottl
4506285809Sscottl    tdsmIOCompletedCB( smRoot,
4507285809Sscottl                       smIORequest,
4508285809Sscottl                       smIOSuccess,
4509285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
4510285809Sscottl                       satIOContext->pSmSenseData,
4511285809Sscottl                       satIOContext->interruptContext );
4512285809Sscottl
4513285809Sscottl    SM_DBG1(("smsatRead6: return control!!!\n"));
4514285809Sscottl    return SM_RC_SUCCESS;
4515285809Sscottl  }
4516285809Sscottl
4517285809Sscottl  /* cbd6; computing LBA and transfer length */
4518285809Sscottl  lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
4519285809Sscottl    + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
4520285809Sscottl  tl = scsiCmnd->cdb[4];
4521285809Sscottl
4522285809Sscottl  /* Table 34, 9.1, p 46 */
4523285809Sscottl  /*
4524285809Sscottl    note: As of 2/10/2006, no support for DMA QUEUED
4525285809Sscottl   */
4526285809Sscottl
4527285809Sscottl  /*
4528285809Sscottl    Table 34, 9.1, p 46, b
4529285809Sscottl    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4530285809Sscottl    return check condition
4531285809Sscottl  */
4532285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
4533285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
4534285809Sscottl      )
4535285809Sscottl  {
4536285809Sscottl    if (lba > SAT_TR_LBA_LIMIT - 1)
4537285809Sscottl    {
4538285809Sscottl      smsatSetSensePayload( pSense,
4539285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
4540285809Sscottl                            0,
4541285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4542285809Sscottl                            satIOContext);
4543285809Sscottl
4544285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
4545285809Sscottl
4546285809Sscottl      tdsmIOCompletedCB( smRoot,
4547285809Sscottl                         smIORequest,
4548285809Sscottl                         smIOSuccess,
4549285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
4550285809Sscottl                         satIOContext->pSmSenseData,
4551285809Sscottl                         satIOContext->interruptContext );
4552285809Sscottl
4553285809Sscottl    SM_DBG1(("smsatRead6: return LBA out of range!!!\n"));
4554285809Sscottl    return SM_RC_SUCCESS;
4555285809Sscottl    }
4556285809Sscottl  }
4557285809Sscottl
4558285809Sscottl  /* case 1 and 2 */
4559285809Sscottl  if (lba + tl <= SAT_TR_LBA_LIMIT)
4560285809Sscottl  {
4561285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4562285809Sscottl    {
4563285809Sscottl      /* case 2 */
4564285809Sscottl      /* READ DMA*/
4565285809Sscottl      SM_DBG5(("smsatRead6: case 2\n"));
4566285809Sscottl
4567285809Sscottl
4568285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
4569285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4570285809Sscottl      fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
4571285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
4572285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4573285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4574285809Sscottl      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4575285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode  */
4576285809Sscottl      fis->d.lbaLowExp      = 0;
4577285809Sscottl      fis->d.lbaMidExp      = 0;
4578285809Sscottl      fis->d.lbaHighExp     = 0;
4579285809Sscottl      fis->d.featuresExp    = 0;
4580285809Sscottl      if (tl == 0)
4581285809Sscottl      {
4582285809Sscottl        /* temporary fix */
4583285809Sscottl        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4584285809Sscottl      }
4585285809Sscottl      else
4586285809Sscottl      {
4587285809Sscottl        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4588285809Sscottl      }
4589285809Sscottl      fis->d.sectorCountExp = 0;
4590285809Sscottl      fis->d.reserved4      = 0;
4591285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
4592285809Sscottl      fis->d.reserved5      = 0;
4593285809Sscottl
4594285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4595285809Sscottl    }
4596285809Sscottl    else
4597285809Sscottl    {
4598285809Sscottl      /* case 1 */
4599285809Sscottl      /* READ SECTORS for easier implemetation */
4600285809Sscottl      SM_DBG5(("smsatRead6: case 1\n"));
4601285809Sscottl
4602285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
4603285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4604285809Sscottl      fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
4605285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
4606285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4607285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4608285809Sscottl      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4609285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode  */
4610285809Sscottl      fis->d.lbaLowExp      = 0;
4611285809Sscottl      fis->d.lbaMidExp      = 0;
4612285809Sscottl      fis->d.lbaHighExp     = 0;
4613285809Sscottl      fis->d.featuresExp    = 0;
4614285809Sscottl      if (tl == 0)
4615285809Sscottl      {
4616285809Sscottl        /* temporary fix */
4617285809Sscottl        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4618285809Sscottl      }
4619285809Sscottl      else
4620285809Sscottl      {
4621285809Sscottl        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4622285809Sscottl      }
4623285809Sscottl      fis->d.sectorCountExp = 0;
4624285809Sscottl      fis->d.reserved4      = 0;
4625285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
4626285809Sscottl      fis->d.reserved5      = 0;
4627285809Sscottl
4628285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
4629285809Sscottl
4630285809Sscottl    }
4631285809Sscottl  }
4632285809Sscottl
4633285809Sscottl  /* case 3 and 4 */
4634285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
4635285809Sscottl  {
4636285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4637285809Sscottl    {
4638285809Sscottl      /* case 3 */
4639285809Sscottl      /* READ DMA EXT only */
4640285809Sscottl      SM_DBG5(("smsatRead6: case 3\n"));
4641285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
4642285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4643285809Sscottl      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
4644285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
4645285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4646285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4647285809Sscottl      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4648285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
4649285809Sscottl      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4650285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4651285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4652285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
4653285809Sscottl      if (tl == 0)
4654285809Sscottl      {
4655285809Sscottl        /* sector count is 256, 0x100*/
4656285809Sscottl        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4657285809Sscottl        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4658285809Sscottl      }
4659285809Sscottl      else
4660285809Sscottl      {
4661285809Sscottl        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4662285809Sscottl        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4663285809Sscottl      }
4664285809Sscottl      fis->d.reserved4      = 0;
4665285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
4666285809Sscottl      fis->d.reserved5      = 0;
4667285809Sscottl
4668285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4669285809Sscottl    }
4670285809Sscottl    else
4671285809Sscottl    {
4672285809Sscottl      /* case 4 */
4673285809Sscottl      /* READ SECTORS EXT for easier implemetation */
4674285809Sscottl      SM_DBG5(("smsatRead6: case 4\n"));
4675285809Sscottl
4676285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
4677285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4678285809Sscottl      fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
4679285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
4680285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4681285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4682285809Sscottl      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4683285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
4684285809Sscottl      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4685285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4686285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4687285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
4688285809Sscottl      if (tl == 0)
4689285809Sscottl      {
4690285809Sscottl        /* sector count is 256, 0x100*/
4691285809Sscottl        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4692285809Sscottl        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4693285809Sscottl      }
4694285809Sscottl      else
4695285809Sscottl      {
4696285809Sscottl        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4697285809Sscottl        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4698285809Sscottl      }
4699285809Sscottl      fis->d.reserved4      = 0;
4700285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
4701285809Sscottl      fis->d.reserved5      = 0;
4702285809Sscottl
4703285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
4704285809Sscottl    }
4705285809Sscottl  }
4706285809Sscottl
4707285809Sscottl  /* case 5 */
4708285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
4709285809Sscottl  {
4710285809Sscottl    /* READ FPDMA QUEUED */
4711285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
4712285809Sscottl    {
4713285809Sscottl      /* sanity check */
4714285809Sscottl      SM_DBG1(("smsatRead6: case 5 !!! error NCQ but 28 bit address support!!!\n"));
4715285809Sscottl      smsatSetSensePayload( pSense,
4716285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
4717285809Sscottl                            0,
4718285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4719285809Sscottl                            satIOContext);
4720285809Sscottl
4721285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
4722285809Sscottl
4723285809Sscottl      tdsmIOCompletedCB( smRoot,
4724285809Sscottl                         smIORequest,
4725285809Sscottl                         smIOSuccess,
4726285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
4727285809Sscottl                         satIOContext->pSmSenseData,
4728285809Sscottl                         satIOContext->interruptContext );
4729285809Sscottl      return SM_RC_SUCCESS;
4730285809Sscottl    }
4731285809Sscottl    SM_DBG5(("smsatRead6: case 5\n"));
4732285809Sscottl
4733285809Sscottl    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
4734285809Sscottl
4735285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
4736285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4737285809Sscottl    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
4738285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4739285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4740285809Sscottl    fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4741285809Sscottl    fis->d.device         = 0x40;                   /* FIS FUA clear */
4742285809Sscottl    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4743285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4744285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4745285809Sscottl    if (tl == 0)
4746285809Sscottl    {
4747285809Sscottl      /* sector count is 256, 0x100*/
4748285809Sscottl      fis->h.features       = 0;                         /* FIS sector count (7:0) */
4749285809Sscottl      fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
4750285809Sscottl    }
4751285809Sscottl    else
4752285809Sscottl    {
4753285809Sscottl      fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4754285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
4755285809Sscottl    }
4756285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4757285809Sscottl    fis->d.sectorCountExp = 0;
4758285809Sscottl    fis->d.reserved4      = 0;
4759285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
4760285809Sscottl    fis->d.reserved5      = 0;
4761285809Sscottl
4762285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
4763285809Sscottl  }
4764285809Sscottl
4765285809Sscottl   /* Initialize CB for SATA completion.
4766285809Sscottl   */
4767285809Sscottl  satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
4768285809Sscottl
4769285809Sscottl  /*
4770285809Sscottl   * Prepare SGL and send FIS to LL layer.
4771285809Sscottl   */
4772285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
4773285809Sscottl
4774285809Sscottl  status = smsataLLIOStart( smRoot,
4775285809Sscottl                            smIORequest,
4776285809Sscottl                            smDeviceHandle,
4777285809Sscottl                            smScsiRequest,
4778285809Sscottl                            satIOContext);
4779285809Sscottl  return (status);
4780285809Sscottl
4781285809Sscottl}
4782285809Sscottl
4783285809SscottlosGLOBAL FORCEINLINE bit32
4784285809SscottlsmsatRead10(
4785285809Sscottl            smRoot_t                  *smRoot,
4786285809Sscottl            smIORequest_t             *smIORequest,
4787285809Sscottl            smDeviceHandle_t          *smDeviceHandle,
4788285809Sscottl            smScsiInitiatorRequest_t  *smScsiRequest,
4789285809Sscottl            smSatIOContext_t            *satIOContext
4790285809Sscottl     )
4791285809Sscottl{
4792285809Sscottl  smDeviceData_t            *pSatDevData = satIOContext->pSatDevData;
4793285809Sscottl  smScsiRspSense_t          *pSense      = satIOContext->pSense;
4794285809Sscottl  smIniScsiCmnd_t           *scsiCmnd    = &smScsiRequest->scsiCmnd;
4795285809Sscottl  agsaFisRegHostToDevice_t  *fis         = satIOContext->pFis;
4796285809Sscottl
4797285809Sscottl  bit32                     status;
4798285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4799285809Sscottl  bit32                     lba = 0;
4800285809Sscottl  bit32                     tl = 0;
4801285809Sscottl  bit32                     LoopNum = 1;
4802285809Sscottl  bit8                      LBA[8];
4803285809Sscottl  bit8                      TL[8];
4804285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
4805285809Sscottl
4806285809Sscottl  SM_DBG2(("smsatRead10: start\n"));
4807285809Sscottl  SM_DBG2(("smsatRead10: pSatDevData did=%d\n", pSatDevData->id));
4808285809Sscottl  //  smhexdump("smsatRead10", (bit8 *)scsiCmnd->cdb, 10);
4809285809Sscottl
4810285809Sscottl  /* checking FUA_NV */
4811285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
4812285809Sscottl  {
4813285809Sscottl    smsatSetSensePayload( pSense,
4814285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
4815285809Sscottl                          0,
4816285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4817285809Sscottl                          satIOContext);
4818285809Sscottl
4819285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
4820285809Sscottl
4821285809Sscottl    tdsmIOCompletedCB( smRoot,
4822285809Sscottl                       smIORequest,
4823285809Sscottl                       smIOSuccess,
4824285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
4825285809Sscottl                       satIOContext->pSmSenseData,
4826285809Sscottl                       satIOContext->interruptContext );
4827285809Sscottl
4828285809Sscottl    SM_DBG1(("smsatRead10: return FUA_NV!!!\n"));
4829285809Sscottl    return SM_RC_SUCCESS;
4830285809Sscottl
4831285809Sscottl  }
4832285809Sscottl
4833285809Sscottl  /* checking CONTROL */
4834285809Sscottl  /* NACA == 1 or LINK == 1*/
4835285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
4836285809Sscottl  {
4837285809Sscottl    smsatSetSensePayload( pSense,
4838285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
4839285809Sscottl                          0,
4840285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4841285809Sscottl                          satIOContext);
4842285809Sscottl
4843285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
4844285809Sscottl
4845285809Sscottl    tdsmIOCompletedCB( smRoot,
4846285809Sscottl                       smIORequest,
4847285809Sscottl                       smIOSuccess,
4848285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
4849285809Sscottl                       satIOContext->pSmSenseData,
4850285809Sscottl                       satIOContext->interruptContext );
4851285809Sscottl
4852285809Sscottl    SM_DBG1(("smsatRead10: return control!!!\n"));
4853285809Sscottl    return SM_RC_SUCCESS;
4854285809Sscottl  }
4855285809Sscottl  /*
4856285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
4857285809Sscottl  sm_memset(TL, 0, sizeof(TL));
4858285809Sscottl  */
4859285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
4860285809Sscottl  LBA[0] = 0;                  /* MSB */
4861285809Sscottl  LBA[1] = 0;
4862285809Sscottl  LBA[2] = 0;
4863285809Sscottl  LBA[3] = 0;
4864285809Sscottl  LBA[4] = scsiCmnd->cdb[2];
4865285809Sscottl  LBA[5] = scsiCmnd->cdb[3];
4866285809Sscottl  LBA[6] = scsiCmnd->cdb[4];
4867285809Sscottl  LBA[7] = scsiCmnd->cdb[5];   /* LSB */
4868285809Sscottl
4869285809Sscottl  TL[0] = 0;
4870285809Sscottl  TL[1] = 0;
4871285809Sscottl  TL[2] = 0;
4872285809Sscottl  TL[3] = 0;
4873285809Sscottl  TL[4] = 0;
4874285809Sscottl  TL[5] = 0;
4875285809Sscottl  TL[6] = scsiCmnd->cdb[7];
4876285809Sscottl  TL[7] = scsiCmnd->cdb[8];    /* LSB */
4877285809Sscottl
4878285809Sscottl
4879285809Sscottl  /* cbd10; computing LBA and transfer length */
4880285809Sscottl  lba = (scsiCmnd->cdb[2] << 24) + (scsiCmnd->cdb[3] << 16)
4881285809Sscottl        + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
4882285809Sscottl  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
4883285809Sscottl
4884285809Sscottl
4885285809Sscottl  SM_DBG5(("smsatRead10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext)));
4886285809Sscottl  SM_DBG5(("smsatRead10: lba 0x%x functioned lba 0x%x\n", lba, smsatComputeCDB10LBA(satIOContext)));
4887285809Sscottl  SM_DBG5(("smsatRead10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext)));
4888285809Sscottl
4889285809Sscottl  /* Table 34, 9.1, p 46 */
4890285809Sscottl  /*
4891285809Sscottl    note: As of 2/10/2006, no support for DMA QUEUED
4892285809Sscottl   */
4893285809Sscottl
4894285809Sscottl  /*
4895285809Sscottl    Table 34, 9.1, p 46, b
4896285809Sscottl    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4897285809Sscottl    return check condition
4898285809Sscottl  */
4899285809Sscottl
4900285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
4901285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
4902285809Sscottl      )
4903285809Sscottl  {
4904285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
4905285809Sscottl    if (AllChk)
4906285809Sscottl    {
4907285809Sscottl      SM_DBG1(("smsatRead10: return LBA out of range, not EXT!!!\n"));
4908285809Sscottl      smsatSetSensePayload( pSense,
4909285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
4910285809Sscottl                            0,
4911285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4912285809Sscottl                            satIOContext);
4913285809Sscottl
4914285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
4915285809Sscottl
4916285809Sscottl      tdsmIOCompletedCB( smRoot,
4917285809Sscottl                         smIORequest,
4918285809Sscottl                         smIOSuccess,
4919285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
4920285809Sscottl                         satIOContext->pSmSenseData,
4921285809Sscottl                         satIOContext->interruptContext );
4922285809Sscottl
4923285809Sscottl      return SM_RC_SUCCESS;
4924285809Sscottl    }
4925285809Sscottl  }
4926285809Sscottl  else
4927285809Sscottl  {
4928285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
4929285809Sscottl    if (AllChk)
4930285809Sscottl    {
4931285809Sscottl      SM_DBG1(("smsatRead10: return LBA out of range, EXT!!!\n"));
4932285809Sscottl      smsatSetSensePayload( pSense,
4933285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
4934285809Sscottl                            0,
4935285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4936285809Sscottl                            satIOContext);
4937285809Sscottl
4938285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
4939285809Sscottl
4940285809Sscottl      tdsmIOCompletedCB( smRoot,
4941285809Sscottl                         smIORequest,
4942285809Sscottl                         smIOSuccess,
4943285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
4944285809Sscottl                         satIOContext->pSmSenseData,
4945285809Sscottl                         satIOContext->interruptContext );
4946285809Sscottl
4947285809Sscottl    return SM_RC_SUCCESS;
4948285809Sscottl    }
4949285809Sscottl  }
4950285809Sscottl    /* case 5 */
4951285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
4952285809Sscottl  {
4953285809Sscottl    /* READ FPDMA QUEUED */
4954285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
4955285809Sscottl    {
4956285809Sscottl      SM_DBG1(("smsatRead10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
4957285809Sscottl      smsatSetSensePayload( pSense,
4958285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
4959285809Sscottl                            0,
4960285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4961285809Sscottl                            satIOContext);
4962285809Sscottl
4963285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
4964285809Sscottl
4965285809Sscottl      tdsmIOCompletedCB( smRoot,
4966285809Sscottl                         smIORequest,
4967285809Sscottl                         smIOSuccess,
4968285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
4969285809Sscottl                         satIOContext->pSmSenseData,
4970285809Sscottl                         satIOContext->interruptContext );
4971285809Sscottl      return SM_RC_SUCCESS;
4972285809Sscottl    }
4973285809Sscottl
4974285809Sscottl    SM_DBG6(("smsatRead10: case 5\n"));
4975285809Sscottl
4976285809Sscottl    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
4977285809Sscottl
4978285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
4979285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4980285809Sscottl    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
4981285809Sscottl    fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4982285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4983285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4984285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4985285809Sscottl
4986285809Sscottl    /* Check FUA bit */
4987285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
4988285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
4989285809Sscottl    else
4990285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
4991285809Sscottl
4992285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4993285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4994285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4995285809Sscottl    fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4996285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4997285809Sscottl    fis->d.sectorCountExp = 0;
4998285809Sscottl    fis->d.reserved4      = 0;
4999285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
5000285809Sscottl    fis->d.reserved5      = 0;
5001285809Sscottl
5002285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
5003285809Sscottl    satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
5004285809Sscottl  }
5005285809Sscottl  else if (pSatDevData->sat48BitSupport == agTRUE) /* case 3 and 4 */
5006285809Sscottl  {
5007285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5008285809Sscottl    {
5009285809Sscottl      /* case 3 */
5010285809Sscottl      /* READ DMA EXT */
5011285809Sscottl      SM_DBG5(("smsatRead10: case 3\n"));
5012285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
5013285809Sscottl
5014285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5015285809Sscottl      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
5016285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
5017285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5018285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5019285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5020285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5021285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5022285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5023285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5024285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
5025285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5026285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
5027285809Sscottl      fis->d.reserved4      = 0;
5028285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
5029285809Sscottl      fis->d.reserved5      = 0;
5030285809Sscottl
5031285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5032285809Sscottl      satIOContext->ATACmd = SAT_READ_DMA_EXT;
5033285809Sscottl
5034285809Sscottl    }
5035285809Sscottl    else
5036285809Sscottl    {
5037285809Sscottl      /* case 4 */
5038285809Sscottl      /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5039285809Sscottl      /* READ SECTORS EXT for easier implemetation */
5040285809Sscottl      SM_DBG5(("smsatRead10: case 4\n"));
5041285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
5042285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5043285809Sscottl
5044285809Sscottl      /* Check FUA bit */
5045285809Sscottl      if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
5046285809Sscottl      {
5047285809Sscottl
5048285809Sscottl        /* for now, no support for FUA */
5049285809Sscottl        smsatSetSensePayload( pSense,
5050285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
5051285809Sscottl                              0,
5052285809Sscottl                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5053285809Sscottl                              satIOContext);
5054285809Sscottl
5055285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
5056285809Sscottl
5057285809Sscottl        tdsmIOCompletedCB( smRoot,
5058285809Sscottl                           smIORequest,
5059285809Sscottl                           smIOSuccess,
5060285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
5061285809Sscottl                           satIOContext->pSmSenseData,
5062285809Sscottl                           satIOContext->interruptContext );
5063285809Sscottl        return SM_RC_SUCCESS;
5064285809Sscottl      }
5065285809Sscottl
5066285809Sscottl      fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
5067285809Sscottl
5068285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
5069285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5070285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5071285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5072285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5073285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5074285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5075285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5076285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
5077285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5078285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
5079285809Sscottl      fis->d.reserved4      = 0;
5080285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
5081285809Sscottl      fis->d.reserved5      = 0;
5082285809Sscottl
5083285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5084285809Sscottl      satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
5085285809Sscottl    }
5086285809Sscottl  }
5087285809Sscottl  else/* case 1 and 2 */
5088285809Sscottl  {
5089285809Sscottl      if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5090285809Sscottl      {
5091285809Sscottl        /* case 2 */
5092285809Sscottl        /* READ DMA*/
5093285809Sscottl        /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */
5094285809Sscottl        SM_DBG5(("smsatRead10: case 2\n"));
5095285809Sscottl
5096285809Sscottl
5097285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
5098285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5099285809Sscottl        fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
5100285809Sscottl        fis->h.features       = 0;                      /* FIS reserve */
5101285809Sscottl        fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5102285809Sscottl        fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5103285809Sscottl        fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5104285809Sscottl        fis->d.device         =
5105285809Sscottl          (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5106285809Sscottl        fis->d.lbaLowExp      = 0;
5107285809Sscottl        fis->d.lbaMidExp      = 0;
5108285809Sscottl        fis->d.lbaHighExp     = 0;
5109285809Sscottl        fis->d.featuresExp    = 0;
5110285809Sscottl        fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5111285809Sscottl        fis->d.sectorCountExp = 0;
5112285809Sscottl        fis->d.reserved4      = 0;
5113285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
5114285809Sscottl        fis->d.reserved5      = 0;
5115285809Sscottl
5116285809Sscottl
5117285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5118285809Sscottl        satIOContext->ATACmd = SAT_READ_DMA;
5119285809Sscottl      }
5120285809Sscottl      else
5121285809Sscottl      {
5122285809Sscottl        /* case 1 */
5123285809Sscottl        /* READ MULTIPLE or READ SECTOR(S) */
5124285809Sscottl        /* READ SECTORS for easier implemetation */
5125285809Sscottl        /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */
5126285809Sscottl        SM_DBG5(("smsatRead10: case 1\n"));
5127285809Sscottl
5128285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
5129285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5130285809Sscottl        fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
5131285809Sscottl        fis->h.features       = 0;                      /* FIS reserve */
5132285809Sscottl        fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5133285809Sscottl        fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5134285809Sscottl        fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5135285809Sscottl        fis->d.device         =
5136285809Sscottl          (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5137285809Sscottl        fis->d.lbaLowExp      = 0;
5138285809Sscottl        fis->d.lbaMidExp      = 0;
5139285809Sscottl        fis->d.lbaHighExp     = 0;
5140285809Sscottl        fis->d.featuresExp    = 0;
5141285809Sscottl        fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5142285809Sscottl        fis->d.sectorCountExp = 0;
5143285809Sscottl        fis->d.reserved4      = 0;
5144285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
5145285809Sscottl        fis->d.reserved5      = 0;
5146285809Sscottl
5147285809Sscottl
5148285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5149285809Sscottl        satIOContext->ATACmd = SAT_READ_SECTORS;
5150285809Sscottl    }
5151285809Sscottl  }
5152285809Sscottl  //  smhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
5153285809Sscottl
5154285809Sscottl  /* saves the current LBA and orginal TL */
5155285809Sscottl  satIOContext->currentLBA = lba;
5156285809Sscottl  satIOContext->OrgTL = tl;
5157285809Sscottl
5158285809Sscottl /*
5159285809Sscottl    computing number of loop and remainder for tl
5160285809Sscottl    0xFF in case not ext
5161285809Sscottl    0xFFFF in case EXT
5162285809Sscottl  */
5163285809Sscottl  if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5164285809Sscottl  {
5165285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0x100);
5166285809Sscottl  }
5167285809Sscottl  else
5168285809Sscottl  {
5169285809Sscottl     /* SAT_READ_FPDMA_QUEUED */
5170285809Sscottl     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5171285809Sscottl     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5172285809Sscottl  }
5173285809Sscottl
5174285809Sscottl  satIOContext->LoopNum = LoopNum;
5175285809Sscottl
5176285809Sscottl  /* Initialize CB for SATA completion.
5177285809Sscottl   */
5178285809Sscottl  if (LoopNum == 1)
5179285809Sscottl  {
5180285809Sscottl    SM_DBG5(("smsatRead10: NON CHAINED data\n"));
5181285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
5182285809Sscottl  }
5183285809Sscottl  else
5184285809Sscottl  {
5185285809Sscottl    SM_DBG2(("smsatRead10: CHAINED data!!!\n"));
5186285809Sscottl
5187285809Sscottl    /* re-setting tl */
5188285809Sscottl    if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5189285809Sscottl    {
5190285809Sscottl      fis->d.sectorCount    = 0x0;
5191285809Sscottl      smsatSplitSGL(smRoot,
5192285809Sscottl                    smIORequest,
5193285809Sscottl                    smDeviceHandle,
5194285809Sscottl                    smScsiRequest,
5195285809Sscottl                    satIOContext,
5196285809Sscottl                    NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */
5197285809Sscottl                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5198285809Sscottl                    agTRUE);
5199285809Sscottl    }
5200285809Sscottl    else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5201285809Sscottl    {
5202285809Sscottl      /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5203285809Sscottl      fis->d.sectorCount    = 0xFF;
5204285809Sscottl      fis->d.sectorCountExp = 0xFF;
5205285809Sscottl      smsatSplitSGL(smRoot,
5206285809Sscottl                    smIORequest,
5207285809Sscottl                    smDeviceHandle,
5208285809Sscottl                    smScsiRequest,
5209285809Sscottl                    satIOContext,
5210285809Sscottl                    BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
5211285809Sscottl                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5212285809Sscottl                    agTRUE);
5213285809Sscottl    }
5214285809Sscottl    else
5215285809Sscottl    {
5216285809Sscottl      /* SAT_READ_FPDMA_QUEUED */
5217285809Sscottl      fis->h.features       = 0xFF;
5218285809Sscottl      fis->d.featuresExp    = 0xFF;
5219285809Sscottl      smsatSplitSGL(smRoot,
5220285809Sscottl                    smIORequest,
5221285809Sscottl                    smDeviceHandle,
5222285809Sscottl                    smScsiRequest,
5223285809Sscottl                    satIOContext,
5224285809Sscottl                    BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
5225285809Sscottl                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5226285809Sscottl                    agTRUE);
5227285809Sscottl    }
5228285809Sscottl
5229285809Sscottl    /* chained data */
5230285809Sscottl    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
5231285809Sscottl
5232285809Sscottl  }
5233285809Sscottl
5234285809Sscottl  /*
5235285809Sscottl   * Prepare SGL and send FIS to LL layer.
5236285809Sscottl   */
5237285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
5238285809Sscottl
5239285809Sscottl  status = smsataLLIOStart( smRoot,
5240285809Sscottl                            smIORequest,
5241285809Sscottl                            smDeviceHandle,
5242285809Sscottl                            smScsiRequest,
5243285809Sscottl                            satIOContext);
5244285809Sscottl
5245285809Sscottl  SM_DBG5(("smsatRead10: return\n"));
5246285809Sscottl  return (status);
5247285809Sscottl
5248285809Sscottl}
5249285809Sscottl
5250285809SscottlosGLOBAL bit32
5251285809SscottlsmsatRead12(
5252285809Sscottl            smRoot_t                  *smRoot,
5253285809Sscottl            smIORequest_t             *smIORequest,
5254285809Sscottl            smDeviceHandle_t          *smDeviceHandle,
5255285809Sscottl            smScsiInitiatorRequest_t  *smScsiRequest,
5256285809Sscottl            smSatIOContext_t            *satIOContext
5257285809Sscottl     )
5258285809Sscottl{
5259285809Sscottl  bit32                     status;
5260285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5261285809Sscottl  smDeviceData_t            *pSatDevData;
5262285809Sscottl  smScsiRspSense_t          *pSense;
5263285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
5264285809Sscottl  agsaFisRegHostToDevice_t  *fis;
5265285809Sscottl  bit32                     lba = 0;
5266285809Sscottl  bit32                     tl = 0;
5267285809Sscottl  bit32                     LoopNum = 1;
5268285809Sscottl  bit8                      LBA[8];
5269285809Sscottl  bit8                      TL[8];
5270285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
5271285809Sscottl
5272285809Sscottl  pSense        = satIOContext->pSense;
5273285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
5274285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
5275285809Sscottl  fis           = satIOContext->pFis;
5276285809Sscottl
5277285809Sscottl  SM_DBG5(("smsatRead12: start\n"));
5278285809Sscottl
5279285809Sscottl  /* checking FUA_NV */
5280285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
5281285809Sscottl  {
5282285809Sscottl    smsatSetSensePayload( pSense,
5283285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
5284285809Sscottl                          0,
5285285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5286285809Sscottl                          satIOContext);
5287285809Sscottl
5288285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
5289285809Sscottl
5290285809Sscottl    tdsmIOCompletedCB( smRoot,
5291285809Sscottl                       smIORequest,
5292285809Sscottl                       smIOSuccess,
5293285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
5294285809Sscottl                       satIOContext->pSmSenseData,
5295285809Sscottl                       satIOContext->interruptContext );
5296285809Sscottl
5297285809Sscottl    SM_DBG1(("smsatRead12: return FUA_NV!!!\n"));
5298285809Sscottl    return SM_RC_SUCCESS;
5299285809Sscottl
5300285809Sscottl  }
5301285809Sscottl
5302285809Sscottl  /* checking CONTROL */
5303285809Sscottl  /* NACA == 1 or LINK == 1*/
5304285809Sscottl  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
5305285809Sscottl  {
5306285809Sscottl    smsatSetSensePayload( pSense,
5307285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
5308285809Sscottl                          0,
5309285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5310285809Sscottl                          satIOContext);
5311285809Sscottl
5312285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
5313285809Sscottl
5314285809Sscottl    tdsmIOCompletedCB( smRoot,
5315285809Sscottl                       smIORequest,
5316285809Sscottl                       smIOSuccess,
5317285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
5318285809Sscottl                       satIOContext->pSmSenseData,
5319285809Sscottl                       satIOContext->interruptContext );
5320285809Sscottl
5321285809Sscottl    SM_DBG1(("smsatRead12: return control!!!\n"));
5322285809Sscottl    return SM_RC_SUCCESS;
5323285809Sscottl  }
5324285809Sscottl
5325285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
5326285809Sscottl  sm_memset(TL, 0, sizeof(TL));
5327285809Sscottl
5328285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
5329285809Sscottl  LBA[0] = 0;                  /* MSB */
5330285809Sscottl  LBA[1] = 0;
5331285809Sscottl  LBA[2] = 0;
5332285809Sscottl  LBA[3] = 0;
5333285809Sscottl  LBA[4] = scsiCmnd->cdb[2];
5334285809Sscottl  LBA[5] = scsiCmnd->cdb[3];
5335285809Sscottl  LBA[6] = scsiCmnd->cdb[4];
5336285809Sscottl  LBA[7] = scsiCmnd->cdb[5];   /* LSB */
5337285809Sscottl
5338285809Sscottl  TL[0] = 0;                   /* MSB */
5339285809Sscottl  TL[1] = 0;
5340285809Sscottl  TL[2] = 0;
5341285809Sscottl  TL[3] = 0;
5342285809Sscottl  TL[4] = scsiCmnd->cdb[6];
5343285809Sscottl  TL[5] = scsiCmnd->cdb[7];
5344285809Sscottl  TL[6] = scsiCmnd->cdb[8];
5345285809Sscottl  TL[7] = scsiCmnd->cdb[9];   	/* LSB */
5346285809Sscottl
5347285809Sscottl
5348285809Sscottl  lba = smsatComputeCDB12LBA(satIOContext);
5349285809Sscottl  tl = smsatComputeCDB12TL(satIOContext);
5350285809Sscottl
5351285809Sscottl  /* Table 34, 9.1, p 46 */
5352285809Sscottl  /*
5353285809Sscottl    note: As of 2/10/2006, no support for DMA QUEUED
5354285809Sscottl   */
5355285809Sscottl
5356285809Sscottl  /*
5357285809Sscottl    Table 34, 9.1, p 46, b
5358285809Sscottl    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
5359285809Sscottl    return check condition
5360285809Sscottl  */
5361285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
5362285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
5363285809Sscottl      )
5364285809Sscottl  {
5365285809Sscottl
5366285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
5367285809Sscottl    if (AllChk)
5368285809Sscottl    {
5369285809Sscottl      SM_DBG1(("smsatRead12: return LBA out of range, not EXT!!!\n"));
5370285809Sscottl      smsatSetSensePayload( pSense,
5371285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
5372285809Sscottl                            0,
5373285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5374285809Sscottl                            satIOContext);
5375285809Sscottl
5376285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
5377285809Sscottl
5378285809Sscottl      tdsmIOCompletedCB( smRoot,
5379285809Sscottl                         smIORequest,
5380285809Sscottl                         smIOSuccess,
5381285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
5382285809Sscottl                         satIOContext->pSmSenseData,
5383285809Sscottl                         satIOContext->interruptContext );
5384285809Sscottl
5385285809Sscottl    return SM_RC_SUCCESS;
5386285809Sscottl    }
5387285809Sscottl  }
5388285809Sscottl  else
5389285809Sscottl  {
5390285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
5391285809Sscottl    if (AllChk)
5392285809Sscottl    {
5393285809Sscottl      SM_DBG1(("smsatRead12: return LBA out of range, EXT!!!\n"));
5394285809Sscottl      smsatSetSensePayload( pSense,
5395285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
5396285809Sscottl                            0,
5397285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5398285809Sscottl                            satIOContext);
5399285809Sscottl
5400285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
5401285809Sscottl
5402285809Sscottl      tdsmIOCompletedCB( smRoot,
5403285809Sscottl                         smIORequest,
5404285809Sscottl                         smIOSuccess,
5405285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
5406285809Sscottl                         satIOContext->pSmSenseData,
5407285809Sscottl                         satIOContext->interruptContext );
5408285809Sscottl
5409285809Sscottl    return SM_RC_SUCCESS;
5410285809Sscottl    }
5411285809Sscottl  }
5412285809Sscottl
5413285809Sscottl  /* case 1 and 2 */
5414285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5415285809Sscottl    {
5416285809Sscottl      /* case 2 */
5417285809Sscottl      /* READ DMA*/
5418285809Sscottl      /* in case that we can't fit the transfer length,
5419285809Sscottl         we need to make it fit by sending multiple ATA cmnds */
5420285809Sscottl      SM_DBG5(("smsatRead12: case 2\n"));
5421285809Sscottl
5422285809Sscottl
5423285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
5424285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5425285809Sscottl      fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
5426285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
5427285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5428285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5429285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5430285809Sscottl      fis->d.device         =
5431285809Sscottl        (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5432285809Sscottl      fis->d.lbaLowExp      = 0;
5433285809Sscottl      fis->d.lbaMidExp      = 0;
5434285809Sscottl      fis->d.lbaHighExp     = 0;
5435285809Sscottl      fis->d.featuresExp    = 0;
5436285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5437285809Sscottl      fis->d.sectorCountExp = 0;
5438285809Sscottl      fis->d.reserved4      = 0;
5439285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
5440285809Sscottl      fis->d.reserved5      = 0;
5441285809Sscottl
5442285809Sscottl
5443285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5444285809Sscottl      satIOContext->ATACmd = SAT_READ_DMA;
5445285809Sscottl    }
5446285809Sscottl    else
5447285809Sscottl    {
5448285809Sscottl      /* case 1 */
5449285809Sscottl      /* READ MULTIPLE or READ SECTOR(S) */
5450285809Sscottl      /* READ SECTORS for easier implemetation */
5451285809Sscottl      /* can't fit the transfer length but need to make it fit by sending multiple*/
5452285809Sscottl      SM_DBG5(("smsatRead12: case 1\n"));
5453285809Sscottl
5454285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
5455285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5456285809Sscottl      fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
5457285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
5458285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5459285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5460285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5461285809Sscottl      fis->d.device         =
5462285809Sscottl        (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5463285809Sscottl      fis->d.lbaLowExp      = 0;
5464285809Sscottl      fis->d.lbaMidExp      = 0;
5465285809Sscottl      fis->d.lbaHighExp     = 0;
5466285809Sscottl      fis->d.featuresExp    = 0;
5467285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5468285809Sscottl      fis->d.sectorCountExp = 0;
5469285809Sscottl      fis->d.reserved4      = 0;
5470285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
5471285809Sscottl      fis->d.reserved5      = 0;
5472285809Sscottl
5473285809Sscottl
5474285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5475285809Sscottl      satIOContext->ATACmd = SAT_READ_SECTORS;
5476285809Sscottl  }
5477285809Sscottl
5478285809Sscottl  /* case 3 and 4 */
5479285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
5480285809Sscottl  {
5481285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5482285809Sscottl    {
5483285809Sscottl      /* case 3 */
5484285809Sscottl      /* READ DMA EXT */
5485285809Sscottl      SM_DBG5(("smsatRead12: case 3\n"));
5486285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
5487285809Sscottl
5488285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5489285809Sscottl      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
5490285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
5491285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5492285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5493285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5494285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5495285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5496285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5497285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5498285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
5499285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5500285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
5501285809Sscottl      fis->d.reserved4      = 0;
5502285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
5503285809Sscottl      fis->d.reserved5      = 0;
5504285809Sscottl
5505285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5506285809Sscottl      satIOContext->ATACmd = SAT_READ_DMA_EXT;
5507285809Sscottl
5508285809Sscottl    }
5509285809Sscottl    else
5510285809Sscottl    {
5511285809Sscottl      /* case 4 */
5512285809Sscottl      /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5513285809Sscottl      /* READ SECTORS EXT for easier implemetation */
5514285809Sscottl      SM_DBG5(("smsatRead12: case 4\n"));
5515285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
5516285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5517285809Sscottl
5518285809Sscottl      /* Check FUA bit */
5519285809Sscottl      if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
5520285809Sscottl      {
5521285809Sscottl
5522285809Sscottl        /* for now, no support for FUA */
5523285809Sscottl        smsatSetSensePayload( pSense,
5524285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
5525285809Sscottl                              0,
5526285809Sscottl                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5527285809Sscottl                              satIOContext);
5528285809Sscottl
5529285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
5530285809Sscottl
5531285809Sscottl        tdsmIOCompletedCB( smRoot,
5532285809Sscottl                           smIORequest,
5533285809Sscottl                           smIOSuccess,
5534285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
5535285809Sscottl                           satIOContext->pSmSenseData,
5536285809Sscottl                           satIOContext->interruptContext );
5537285809Sscottl        return SM_RC_SUCCESS;
5538285809Sscottl      }
5539285809Sscottl
5540285809Sscottl      fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
5541285809Sscottl
5542285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
5543285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5544285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5545285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5546285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5547285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5548285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5549285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5550285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
5551285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5552285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
5553285809Sscottl      fis->d.reserved4      = 0;
5554285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
5555285809Sscottl      fis->d.reserved5      = 0;
5556285809Sscottl
5557285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5558285809Sscottl      satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
5559285809Sscottl    }
5560285809Sscottl  }
5561285809Sscottl
5562285809Sscottl  /* case 5 */
5563285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
5564285809Sscottl  {
5565285809Sscottl    /* READ FPDMA QUEUED */
5566285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
5567285809Sscottl    {
5568285809Sscottl      SM_DBG1(("smsatRead12: case 5 !!! error NCQ but 28 bit address support!!!\n"));
5569285809Sscottl      smsatSetSensePayload( pSense,
5570285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
5571285809Sscottl                            0,
5572285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5573285809Sscottl                            satIOContext);
5574285809Sscottl
5575285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
5576285809Sscottl
5577285809Sscottl        tdsmIOCompletedCB( smRoot,
5578285809Sscottl                           smIORequest,
5579285809Sscottl                           smIOSuccess,
5580285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
5581285809Sscottl                           satIOContext->pSmSenseData,
5582285809Sscottl                           satIOContext->interruptContext );
5583285809Sscottl      return SM_RC_SUCCESS;
5584285809Sscottl    }
5585285809Sscottl
5586285809Sscottl    SM_DBG6(("smsatRead12: case 5\n"));
5587285809Sscottl
5588285809Sscottl    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
5589285809Sscottl
5590285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
5591285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5592285809Sscottl    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
5593285809Sscottl    fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5594285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5595285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5596285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5597285809Sscottl
5598285809Sscottl    /* Check FUA bit */
5599285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
5600285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
5601285809Sscottl    else
5602285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
5603285809Sscottl
5604285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5605285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5606285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5607285809Sscottl    fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
5608285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
5609285809Sscottl    fis->d.sectorCountExp = 0;
5610285809Sscottl    fis->d.reserved4      = 0;
5611285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
5612285809Sscottl    fis->d.reserved5      = 0;
5613285809Sscottl
5614285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
5615285809Sscottl    satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
5616285809Sscottl  }
5617285809Sscottl
5618285809Sscottl  /* saves the current LBA and orginal TL */
5619285809Sscottl  satIOContext->currentLBA = lba;
5620285809Sscottl  satIOContext->OrgTL = tl;
5621285809Sscottl
5622285809Sscottl  /*
5623285809Sscottl    computing number of loop and remainder for tl
5624285809Sscottl    0xFF in case not ext
5625285809Sscottl    0xFFFF in case EXT
5626285809Sscottl  */
5627285809Sscottl  if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5628285809Sscottl  {
5629285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFF);
5630285809Sscottl  }
5631285809Sscottl  else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5632285809Sscottl  {
5633285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5634285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5635285809Sscottl  }
5636285809Sscottl  else
5637285809Sscottl  {
5638285809Sscottl    /* SAT_READ_FPDMA_QUEUEDK */
5639285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5640285809Sscottl  }
5641285809Sscottl
5642285809Sscottl  satIOContext->LoopNum = LoopNum;
5643285809Sscottl
5644285809Sscottl  if (LoopNum == 1)
5645285809Sscottl  {
5646285809Sscottl    SM_DBG5(("smsatRead12: NON CHAINED data\n"));
5647285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
5648285809Sscottl  }
5649285809Sscottl  else
5650285809Sscottl  {
5651285809Sscottl    SM_DBG1(("smsatRead12: CHAINED data\n"));
5652285809Sscottl    /* re-setting tl */
5653285809Sscottl    if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5654285809Sscottl    {
5655285809Sscottl       fis->d.sectorCount    = 0xFF;
5656285809Sscottl    }
5657285809Sscottl    else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5658285809Sscottl    {
5659285809Sscottl      /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5660285809Sscottl      fis->d.sectorCount    = 0xFF;
5661285809Sscottl      fis->d.sectorCountExp = 0xFF;
5662285809Sscottl    }
5663285809Sscottl    else
5664285809Sscottl    {
5665285809Sscottl      /* SAT_READ_FPDMA_QUEUED */
5666285809Sscottl      fis->h.features       = 0xFF;
5667285809Sscottl      fis->d.featuresExp    = 0xFF;
5668285809Sscottl    }
5669285809Sscottl
5670285809Sscottl    /* chained data */
5671285809Sscottl    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
5672285809Sscottl  }
5673285809Sscottl
5674285809Sscottl  /*
5675285809Sscottl   * Prepare SGL and send FIS to LL layer.
5676285809Sscottl   */
5677285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
5678285809Sscottl
5679285809Sscottl  status = smsataLLIOStart( smRoot,
5680285809Sscottl                            smIORequest,
5681285809Sscottl                            smDeviceHandle,
5682285809Sscottl                            smScsiRequest,
5683285809Sscottl                            satIOContext);
5684285809Sscottl
5685285809Sscottl  SM_DBG5(("smsatRead12: return\n"));
5686285809Sscottl  return (status);
5687285809Sscottl}
5688285809Sscottl
5689285809SscottlosGLOBAL bit32
5690285809SscottlsmsatRead16(
5691285809Sscottl            smRoot_t                  *smRoot,
5692285809Sscottl            smIORequest_t             *smIORequest,
5693285809Sscottl            smDeviceHandle_t          *smDeviceHandle,
5694285809Sscottl            smScsiInitiatorRequest_t  *smScsiRequest,
5695285809Sscottl            smSatIOContext_t            *satIOContext
5696285809Sscottl     )
5697285809Sscottl{
5698285809Sscottl  bit32                     status;
5699285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5700285809Sscottl  smDeviceData_t            *pSatDevData;
5701285809Sscottl  smScsiRspSense_t          *pSense;
5702285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
5703285809Sscottl  agsaFisRegHostToDevice_t  *fis;
5704285809Sscottl  bit32                     lba = 0;
5705285809Sscottl  bit32                     tl = 0;
5706285809Sscottl  bit32                     LoopNum = 1;
5707285809Sscottl  bit8                      LBA[8];
5708285809Sscottl  bit8                      TL[8];
5709285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
5710285809Sscottl//  bit32                     limitExtChk = agFALSE; /* lba limit check for bit48 addressing check */
5711285809Sscottl
5712285809Sscottl  pSense        = satIOContext->pSense;
5713285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
5714285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
5715285809Sscottl  fis           = satIOContext->pFis;
5716285809Sscottl
5717285809Sscottl  SM_DBG5(("smsatRead16: start\n"));
5718285809Sscottl
5719285809Sscottl  /* checking FUA_NV */
5720285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
5721285809Sscottl  {
5722285809Sscottl    smsatSetSensePayload( pSense,
5723285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
5724285809Sscottl                          0,
5725285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5726285809Sscottl                          satIOContext);
5727285809Sscottl
5728285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
5729285809Sscottl
5730285809Sscottl    tdsmIOCompletedCB( smRoot,
5731285809Sscottl                       smIORequest,
5732285809Sscottl                       smIOSuccess,
5733285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
5734285809Sscottl                       satIOContext->pSmSenseData,
5735285809Sscottl                       satIOContext->interruptContext );
5736285809Sscottl
5737285809Sscottl    SM_DBG1(("smsatRead16: return FUA_NV!!!\n"));
5738285809Sscottl    return SM_RC_SUCCESS;
5739285809Sscottl
5740285809Sscottl  }
5741285809Sscottl
5742285809Sscottl  /* checking CONTROL */
5743285809Sscottl  /* NACA == 1 or LINK == 1*/
5744285809Sscottl  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
5745285809Sscottl  {
5746285809Sscottl    smsatSetSensePayload( pSense,
5747285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
5748285809Sscottl                          0,
5749285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5750285809Sscottl                          satIOContext);
5751285809Sscottl
5752285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
5753285809Sscottl
5754285809Sscottl    tdsmIOCompletedCB( smRoot,
5755285809Sscottl                       smIORequest,
5756285809Sscottl                       smIOSuccess,
5757285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
5758285809Sscottl                       satIOContext->pSmSenseData,
5759285809Sscottl                       satIOContext->interruptContext );
5760285809Sscottl
5761285809Sscottl    SM_DBG1(("smsatRead16: return control!!!\n"));
5762285809Sscottl    return SM_RC_SUCCESS;
5763285809Sscottl  }
5764285809Sscottl
5765285809Sscottl
5766285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
5767285809Sscottl  sm_memset(TL, 0, sizeof(TL));
5768285809Sscottl
5769285809Sscottl
5770285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
5771285809Sscottl  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
5772285809Sscottl  LBA[1] = scsiCmnd->cdb[3];
5773285809Sscottl  LBA[2] = scsiCmnd->cdb[4];
5774285809Sscottl  LBA[3] = scsiCmnd->cdb[5];
5775285809Sscottl  LBA[4] = scsiCmnd->cdb[6];
5776285809Sscottl  LBA[5] = scsiCmnd->cdb[7];
5777285809Sscottl  LBA[6] = scsiCmnd->cdb[8];
5778285809Sscottl  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
5779285809Sscottl
5780285809Sscottl  TL[0] = 0;
5781285809Sscottl  TL[1] = 0;
5782285809Sscottl  TL[2] = 0;
5783285809Sscottl  TL[3] = 0;
5784285809Sscottl  TL[4] = scsiCmnd->cdb[10];   /* MSB */
5785285809Sscottl  TL[5] = scsiCmnd->cdb[11];
5786285809Sscottl  TL[6] = scsiCmnd->cdb[12];
5787285809Sscottl  TL[7] = scsiCmnd->cdb[13];   /* LSB */
5788285809Sscottl
5789285809Sscottl
5790285809Sscottl
5791285809Sscottl
5792285809Sscottl lba = smsatComputeCDB16LBA(satIOContext);
5793285809Sscottl tl = smsatComputeCDB16TL(satIOContext);
5794285809Sscottl
5795285809Sscottl
5796285809Sscottl  /* Table 34, 9.1, p 46 */
5797285809Sscottl  /*
5798285809Sscottl    note: As of 2/10/2006, no support for DMA QUEUED
5799285809Sscottl   */
5800285809Sscottl
5801285809Sscottl  /*
5802285809Sscottl    Table 34, 9.1, p 46, b
5803285809Sscottl    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
5804285809Sscottl    return check condition
5805285809Sscottl  */
5806285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
5807285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
5808285809Sscottl      )
5809285809Sscottl  {
5810285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
5811285809Sscottl    if (AllChk)
5812285809Sscottl    {
5813285809Sscottl      SM_DBG1(("smsatRead16: return LBA out of range, not EXT!!!\n"));
5814285809Sscottl
5815285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
5816285809Sscottl
5817285809Sscottl
5818285809Sscottl      smsatSetSensePayload( pSense,
5819285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
5820285809Sscottl                            0,
5821285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5822285809Sscottl                            satIOContext);
5823285809Sscottl
5824285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
5825285809Sscottl
5826285809Sscottl      tdsmIOCompletedCB( smRoot,
5827285809Sscottl                         smIORequest,
5828285809Sscottl                         smIOSuccess,
5829285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
5830285809Sscottl                         satIOContext->pSmSenseData,
5831285809Sscottl                         satIOContext->interruptContext );
5832285809Sscottl
5833285809Sscottl      return SM_RC_SUCCESS;
5834285809Sscottl    }
5835285809Sscottl  }
5836285809Sscottl  else
5837285809Sscottl  {
5838285809Sscottl//    rangeChk = smsatAddNComparebit64(LBA, TL);
5839285809Sscottl
5840285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
5841285809Sscottl
5842285809Sscottl
5843285809Sscottl    if (AllChk)
5844285809Sscottl    {
5845285809Sscottl      SM_DBG1(("smsatRead16: return LBA out of range, EXT!!!\n"));
5846285809Sscottl      smsatSetSensePayload( pSense,
5847285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
5848285809Sscottl                            0,
5849285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5850285809Sscottl                            satIOContext);
5851285809Sscottl
5852285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
5853285809Sscottl
5854285809Sscottl      tdsmIOCompletedCB( smRoot,
5855285809Sscottl                         smIORequest,
5856285809Sscottl                         smIOSuccess,
5857285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
5858285809Sscottl                         satIOContext->pSmSenseData,
5859285809Sscottl                         satIOContext->interruptContext );
5860285809Sscottl
5861285809Sscottl      return SM_RC_SUCCESS;
5862285809Sscottl    }
5863285809Sscottl  }
5864285809Sscottl
5865285809Sscottl  /* case 1 and 2 */
5866285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5867285809Sscottl    {
5868285809Sscottl      /* case 2 */
5869285809Sscottl      /* READ DMA*/
5870285809Sscottl      /* in case that we can't fit the transfer length,
5871285809Sscottl         we need to make it fit by sending multiple ATA cmnds */
5872285809Sscottl      SM_DBG5(("smsatRead16: case 2\n"));
5873285809Sscottl
5874285809Sscottl
5875285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
5876285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5877285809Sscottl      fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
5878285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
5879285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5880285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5881285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5882285809Sscottl      fis->d.device         =
5883285809Sscottl        (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5884285809Sscottl      fis->d.lbaLowExp      = 0;
5885285809Sscottl      fis->d.lbaMidExp      = 0;
5886285809Sscottl      fis->d.lbaHighExp     = 0;
5887285809Sscottl      fis->d.featuresExp    = 0;
5888285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
5889285809Sscottl      fis->d.sectorCountExp = 0;
5890285809Sscottl      fis->d.reserved4      = 0;
5891285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
5892285809Sscottl      fis->d.reserved5      = 0;
5893285809Sscottl
5894285809Sscottl
5895285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5896285809Sscottl      satIOContext->ATACmd = SAT_READ_DMA;
5897285809Sscottl    }
5898285809Sscottl    else
5899285809Sscottl    {
5900285809Sscottl      /* case 1 */
5901285809Sscottl      /* READ MULTIPLE or READ SECTOR(S) */
5902285809Sscottl      /* READ SECTORS for easier implemetation */
5903285809Sscottl      /* can't fit the transfer length but need to make it fit by sending multiple*/
5904285809Sscottl      SM_DBG5(("smsatRead16: case 1\n"));
5905285809Sscottl
5906285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
5907285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5908285809Sscottl      fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
5909285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
5910285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5911285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5912285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5913285809Sscottl      fis->d.device         =
5914285809Sscottl        (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5915285809Sscottl      fis->d.lbaLowExp      = 0;
5916285809Sscottl      fis->d.lbaMidExp      = 0;
5917285809Sscottl      fis->d.lbaHighExp     = 0;
5918285809Sscottl      fis->d.featuresExp    = 0;
5919285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
5920285809Sscottl      fis->d.sectorCountExp = 0;
5921285809Sscottl      fis->d.reserved4      = 0;
5922285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
5923285809Sscottl      fis->d.reserved5      = 0;
5924285809Sscottl
5925285809Sscottl
5926285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5927285809Sscottl      satIOContext->ATACmd = SAT_READ_SECTORS;
5928285809Sscottl  }
5929285809Sscottl
5930285809Sscottl  /* case 3 and 4 */
5931285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
5932285809Sscottl  {
5933285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5934285809Sscottl    {
5935285809Sscottl      /* case 3 */
5936285809Sscottl      /* READ DMA EXT */
5937285809Sscottl      SM_DBG5(("smsatRead16: case 3\n"));
5938285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
5939285809Sscottl
5940285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5941285809Sscottl      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
5942285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
5943285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5944285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5945285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5946285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5947285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
5948285809Sscottl      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
5949285809Sscottl      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
5950285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
5951285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
5952285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
5953285809Sscottl      fis->d.reserved4      = 0;
5954285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
5955285809Sscottl      fis->d.reserved5      = 0;
5956285809Sscottl
5957285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5958285809Sscottl      satIOContext->ATACmd = SAT_READ_DMA_EXT;
5959285809Sscottl
5960285809Sscottl    }
5961285809Sscottl    else
5962285809Sscottl    {
5963285809Sscottl      /* case 4 */
5964285809Sscottl      /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5965285809Sscottl      /* READ SECTORS EXT for easier implemetation */
5966285809Sscottl      SM_DBG5(("smsatRead16: case 4\n"));
5967285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
5968285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5969285809Sscottl
5970285809Sscottl      /* Check FUA bit */
5971285809Sscottl      if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
5972285809Sscottl      {
5973285809Sscottl        /* for now, no support for FUA */
5974285809Sscottl        smsatSetSensePayload( pSense,
5975285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
5976285809Sscottl                              0,
5977285809Sscottl                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5978285809Sscottl                              satIOContext);
5979285809Sscottl
5980285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
5981285809Sscottl
5982285809Sscottl        tdsmIOCompletedCB( smRoot,
5983285809Sscottl                           smIORequest,
5984285809Sscottl                           smIOSuccess,
5985285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
5986285809Sscottl                           satIOContext->pSmSenseData,
5987285809Sscottl                           satIOContext->interruptContext );
5988285809Sscottl        return SM_RC_SUCCESS;
5989285809Sscottl      }
5990285809Sscottl
5991285809Sscottl      fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
5992285809Sscottl
5993285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
5994285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5995285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5996285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5997285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5998285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
5999285809Sscottl      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
6000285809Sscottl      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
6001285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
6002285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
6003285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
6004285809Sscottl      fis->d.reserved4      = 0;
6005285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
6006285809Sscottl      fis->d.reserved5      = 0;
6007285809Sscottl
6008285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
6009285809Sscottl      satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
6010285809Sscottl    }
6011285809Sscottl  }
6012285809Sscottl
6013285809Sscottl
6014285809Sscottl  /* case 5 */
6015285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
6016285809Sscottl  {
6017285809Sscottl    /* READ FPDMA QUEUED */
6018285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
6019285809Sscottl    {
6020285809Sscottl      SM_DBG1(("smsatRead16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6021285809Sscottl      smsatSetSensePayload( pSense,
6022285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6023285809Sscottl                            0,
6024285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6025285809Sscottl                            satIOContext);
6026285809Sscottl
6027285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
6028285809Sscottl
6029285809Sscottl      tdsmIOCompletedCB( smRoot,
6030285809Sscottl                         smIORequest,
6031285809Sscottl                         smIOSuccess,
6032285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
6033285809Sscottl                         satIOContext->pSmSenseData,
6034285809Sscottl                         satIOContext->interruptContext );
6035285809Sscottl      return SM_RC_SUCCESS;
6036285809Sscottl    }
6037285809Sscottl
6038285809Sscottl    SM_DBG6(("smsatRead16: case 5\n"));
6039285809Sscottl
6040285809Sscottl    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
6041285809Sscottl
6042285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
6043285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6044285809Sscottl    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
6045285809Sscottl    fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
6046285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
6047285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
6048285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
6049285809Sscottl
6050285809Sscottl    /* Check FUA bit */
6051285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
6052285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
6053285809Sscottl    else
6054285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
6055285809Sscottl
6056285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
6057285809Sscottl    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
6058285809Sscottl    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
6059285809Sscottl    fis->d.featuresExp    = scsiCmnd->cdb[12];      /* FIS sector count (15:8) */
6060285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
6061285809Sscottl    fis->d.sectorCountExp = 0;
6062285809Sscottl    fis->d.reserved4      = 0;
6063285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
6064285809Sscottl    fis->d.reserved5      = 0;
6065285809Sscottl
6066285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
6067285809Sscottl    satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
6068285809Sscottl  }
6069285809Sscottl
6070285809Sscottl  /* saves the current LBA and orginal TL */
6071285809Sscottl  satIOContext->currentLBA = lba;
6072285809Sscottl  satIOContext->OrgTL = tl;
6073285809Sscottl
6074285809Sscottl  /*
6075285809Sscottl    computing number of loop and remainder for tl
6076285809Sscottl    0xFF in case not ext
6077285809Sscottl    0xFFFF in case EXT
6078285809Sscottl  */
6079285809Sscottl  if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
6080285809Sscottl  {
6081285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFF);
6082285809Sscottl  }
6083285809Sscottl  else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
6084285809Sscottl  {
6085285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6086285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6087285809Sscottl  }
6088285809Sscottl  else
6089285809Sscottl  {
6090285809Sscottl    /* SAT_READ_FPDMA_QUEUEDK */
6091285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6092285809Sscottl  }
6093285809Sscottl  satIOContext->LoopNum = LoopNum;
6094285809Sscottl
6095285809Sscottl  if (LoopNum == 1)
6096285809Sscottl  {
6097285809Sscottl    SM_DBG5(("smsatRead16: NON CHAINED data\n"));
6098285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6099285809Sscottl  }
6100285809Sscottl  else
6101285809Sscottl  {
6102285809Sscottl    SM_DBG1(("smsatRead16: CHAINED data!!!\n"));
6103285809Sscottl    /* re-setting tl */
6104285809Sscottl    if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
6105285809Sscottl    {
6106285809Sscottl       fis->d.sectorCount    = 0xFF;
6107285809Sscottl    }
6108285809Sscottl    else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
6109285809Sscottl    {
6110285809Sscottl      /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6111285809Sscottl      fis->d.sectorCount    = 0xFF;
6112285809Sscottl      fis->d.sectorCountExp = 0xFF;
6113285809Sscottl    }
6114285809Sscottl    else
6115285809Sscottl    {
6116285809Sscottl      /* SAT_READ_FPDMA_QUEUED */
6117285809Sscottl      fis->h.features       = 0xFF;
6118285809Sscottl      fis->d.featuresExp    = 0xFF;
6119285809Sscottl    }
6120285809Sscottl
6121285809Sscottl    /* chained data */
6122285809Sscottl    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
6123285809Sscottl  }
6124285809Sscottl
6125285809Sscottl  /*
6126285809Sscottl   * Prepare SGL and send FIS to LL layer.
6127285809Sscottl   */
6128285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
6129285809Sscottl
6130285809Sscottl  status = smsataLLIOStart( smRoot,
6131285809Sscottl                            smIORequest,
6132285809Sscottl                            smDeviceHandle,
6133285809Sscottl                            smScsiRequest,
6134285809Sscottl                            satIOContext);
6135285809Sscottl
6136285809Sscottl  SM_DBG5(("smsatRead16: return\n"));
6137285809Sscottl  return (status);
6138285809Sscottl
6139285809Sscottl}
6140285809Sscottl
6141285809SscottlosGLOBAL bit32
6142285809SscottlsmsatWrite6(
6143285809Sscottl            smRoot_t                  *smRoot,
6144285809Sscottl            smIORequest_t             *smIORequest,
6145285809Sscottl            smDeviceHandle_t          *smDeviceHandle,
6146285809Sscottl            smScsiInitiatorRequest_t  *smScsiRequest,
6147285809Sscottl            smSatIOContext_t            *satIOContext
6148285809Sscottl     )
6149285809Sscottl{
6150285809Sscottl
6151285809Sscottl  bit32                     status;
6152285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6153285809Sscottl  smDeviceData_t            *pSatDevData;
6154285809Sscottl  smScsiRspSense_t          *pSense;
6155285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
6156285809Sscottl  agsaFisRegHostToDevice_t  *fis;
6157285809Sscottl  bit32                     lba = 0;
6158285809Sscottl  bit16                     tl = 0;
6159285809Sscottl
6160285809Sscottl  pSense        = satIOContext->pSense;
6161285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
6162285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
6163285809Sscottl  fis           = satIOContext->pFis;
6164285809Sscottl
6165285809Sscottl  SM_DBG5(("smsatWrite6: start\n"));
6166285809Sscottl
6167285809Sscottl  /* checking CONTROL */
6168285809Sscottl  /* NACA == 1 or LINK == 1*/
6169285809Sscottl  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
6170285809Sscottl  {
6171285809Sscottl    smsatSetSensePayload( pSense,
6172285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
6173285809Sscottl                          0,
6174285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6175285809Sscottl                          satIOContext);
6176285809Sscottl
6177285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
6178285809Sscottl
6179285809Sscottl    tdsmIOCompletedCB( smRoot,
6180285809Sscottl                       smIORequest,
6181285809Sscottl                       smIOSuccess,
6182285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
6183285809Sscottl                       satIOContext->pSmSenseData,
6184285809Sscottl                       satIOContext->interruptContext );
6185285809Sscottl
6186285809Sscottl    SM_DBG1(("smsatWrite6: return control!!!\n"));
6187285809Sscottl    return SM_RC_SUCCESS;
6188285809Sscottl  }
6189285809Sscottl
6190285809Sscottl
6191285809Sscottl  /* cbd6; computing LBA and transfer length */
6192285809Sscottl  lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
6193285809Sscottl    + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
6194285809Sscottl  tl = scsiCmnd->cdb[4];
6195285809Sscottl
6196285809Sscottl
6197285809Sscottl  /* Table 34, 9.1, p 46 */
6198285809Sscottl  /*
6199285809Sscottl    note: As of 2/10/2006, no support for DMA QUEUED
6200285809Sscottl   */
6201285809Sscottl
6202285809Sscottl  /*
6203285809Sscottl    Table 34, 9.1, p 46, b
6204285809Sscottl    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
6205285809Sscottl    return check condition
6206285809Sscottl  */
6207285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
6208285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
6209285809Sscottl      )
6210285809Sscottl  {
6211285809Sscottl    if (lba > SAT_TR_LBA_LIMIT - 1)
6212285809Sscottl    {
6213285809Sscottl      smsatSetSensePayload( pSense,
6214285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6215285809Sscottl                            0,
6216285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6217285809Sscottl                            satIOContext);
6218285809Sscottl
6219285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
6220285809Sscottl
6221285809Sscottl      tdsmIOCompletedCB( smRoot,
6222285809Sscottl                         smIORequest,
6223285809Sscottl                         smIOSuccess,
6224285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
6225285809Sscottl                         satIOContext->pSmSenseData,
6226285809Sscottl                         satIOContext->interruptContext );
6227285809Sscottl
6228285809Sscottl    SM_DBG1(("smsatWrite6: return LBA out of range!!!\n"));
6229285809Sscottl    return SM_RC_SUCCESS;
6230285809Sscottl    }
6231285809Sscottl  }
6232285809Sscottl
6233285809Sscottl  /* case 1 and 2 */
6234285809Sscottl  if (lba + tl <= SAT_TR_LBA_LIMIT)
6235285809Sscottl  {
6236285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6237285809Sscottl    {
6238285809Sscottl      /* case 2 */
6239285809Sscottl      /* WRITE DMA*/
6240285809Sscottl      SM_DBG5(("smsatWrite6: case 2\n"));
6241285809Sscottl
6242285809Sscottl
6243285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
6244285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6245285809Sscottl      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
6246285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
6247285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6248285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6249285809Sscottl      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6250285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode  */
6251285809Sscottl      fis->d.lbaLowExp      = 0;
6252285809Sscottl      fis->d.lbaMidExp      = 0;
6253285809Sscottl      fis->d.lbaHighExp     = 0;
6254285809Sscottl      fis->d.featuresExp    = 0;
6255285809Sscottl      if (tl == 0)
6256285809Sscottl      {
6257285809Sscottl        /* temporary fix */
6258285809Sscottl        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
6259285809Sscottl      }
6260285809Sscottl      else
6261285809Sscottl      {
6262285809Sscottl        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6263285809Sscottl      }
6264285809Sscottl      fis->d.sectorCountExp = 0;
6265285809Sscottl      fis->d.reserved4      = 0;
6266285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
6267285809Sscottl      fis->d.reserved5      = 0;
6268285809Sscottl
6269285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6270285809Sscottl    }
6271285809Sscottl    else
6272285809Sscottl    {
6273285809Sscottl      /* case 1 */
6274285809Sscottl      /* WRITE SECTORS for easier implemetation */
6275285809Sscottl      SM_DBG5(("smsatWrite6: case 1\n"));
6276285809Sscottl
6277285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
6278285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6279285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS;          /* 0xCA */
6280285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
6281285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6282285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6283285809Sscottl      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6284285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode  */
6285285809Sscottl      fis->d.lbaLowExp      = 0;
6286285809Sscottl      fis->d.lbaMidExp      = 0;
6287285809Sscottl      fis->d.lbaHighExp     = 0;
6288285809Sscottl      fis->d.featuresExp    = 0;
6289285809Sscottl      if (tl == 0)
6290285809Sscottl      {
6291285809Sscottl        /* temporary fix */
6292285809Sscottl        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
6293285809Sscottl      }
6294285809Sscottl      else
6295285809Sscottl      {
6296285809Sscottl        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6297285809Sscottl      }
6298285809Sscottl      fis->d.sectorCountExp = 0;
6299285809Sscottl      fis->d.reserved4      = 0;
6300285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
6301285809Sscottl      fis->d.reserved5      = 0;
6302285809Sscottl
6303285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6304285809Sscottl
6305285809Sscottl    }
6306285809Sscottl  }
6307285809Sscottl
6308285809Sscottl  /* case 3 and 4 */
6309285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
6310285809Sscottl  {
6311285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6312285809Sscottl    {
6313285809Sscottl      /* case 3 */
6314285809Sscottl      /* WRITE DMA EXT only */
6315285809Sscottl      SM_DBG5(("smsatWrite6: case 3\n"));
6316285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
6317285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6318285809Sscottl      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
6319285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
6320285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6321285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6322285809Sscottl      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6323285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
6324285809Sscottl      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
6325285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6326285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6327285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
6328285809Sscottl      if (tl == 0)
6329285809Sscottl      {
6330285809Sscottl        /* sector count is 256, 0x100*/
6331285809Sscottl        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
6332285809Sscottl        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
6333285809Sscottl      }
6334285809Sscottl      else
6335285809Sscottl      {
6336285809Sscottl        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6337285809Sscottl        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
6338285809Sscottl      }
6339285809Sscottl      fis->d.reserved4      = 0;
6340285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
6341285809Sscottl      fis->d.reserved5      = 0;
6342285809Sscottl
6343285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6344285809Sscottl    }
6345285809Sscottl    else
6346285809Sscottl    {
6347285809Sscottl      /* case 4 */
6348285809Sscottl      /* WRITE SECTORS EXT for easier implemetation */
6349285809Sscottl      SM_DBG5(("smsatWrite6: case 4\n"));
6350285809Sscottl
6351285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
6352285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6353285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
6354285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
6355285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6356285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6357285809Sscottl      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6358285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
6359285809Sscottl      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
6360285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6361285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6362285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
6363285809Sscottl      if (tl == 0)
6364285809Sscottl      {
6365285809Sscottl        /* sector count is 256, 0x100*/
6366285809Sscottl        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
6367285809Sscottl        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
6368285809Sscottl      }
6369285809Sscottl      else
6370285809Sscottl      {
6371285809Sscottl        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6372285809Sscottl        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
6373285809Sscottl      }
6374285809Sscottl      fis->d.reserved4      = 0;
6375285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
6376285809Sscottl      fis->d.reserved5      = 0;
6377285809Sscottl
6378285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6379285809Sscottl    }
6380285809Sscottl  }
6381285809Sscottl
6382285809Sscottl   /* case 5 */
6383285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
6384285809Sscottl  {
6385285809Sscottl    /* WRITE FPDMA QUEUED */
6386285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
6387285809Sscottl    {
6388285809Sscottl      /* sanity check */
6389285809Sscottl      SM_DBG5(("smsatWrite6: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6390285809Sscottl      smsatSetSensePayload( pSense,
6391285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6392285809Sscottl                            0,
6393285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6394285809Sscottl                            satIOContext);
6395285809Sscottl
6396285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
6397285809Sscottl
6398285809Sscottl      tdsmIOCompletedCB( smRoot,
6399285809Sscottl                         smIORequest,
6400285809Sscottl                         smIOSuccess,
6401285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
6402285809Sscottl                         satIOContext->pSmSenseData,
6403285809Sscottl                         satIOContext->interruptContext );
6404285809Sscottl      return SM_RC_SUCCESS;
6405285809Sscottl    }
6406285809Sscottl    SM_DBG5(("smsatWrite6: case 5\n"));
6407285809Sscottl
6408285809Sscottl    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
6409285809Sscottl
6410285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
6411285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6412285809Sscottl    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
6413285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6414285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6415285809Sscottl    fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6416285809Sscottl    fis->d.device         = 0x40;                   /* FIS FUA clear */
6417285809Sscottl    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
6418285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6419285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6420285809Sscottl    if (tl == 0)
6421285809Sscottl    {
6422285809Sscottl      /* sector count is 256, 0x100*/
6423285809Sscottl      fis->h.features       = 0;                         /* FIS sector count (7:0) */
6424285809Sscottl      fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
6425285809Sscottl    }
6426285809Sscottl    else
6427285809Sscottl    {
6428285809Sscottl      fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6429285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
6430285809Sscottl    }
6431285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
6432285809Sscottl    fis->d.sectorCountExp = 0;
6433285809Sscottl    fis->d.reserved4      = 0;
6434285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
6435285809Sscottl    fis->d.reserved5      = 0;
6436285809Sscottl
6437285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
6438285809Sscottl  }
6439285809Sscottl
6440285809Sscottl  /* Initialize CB for SATA completion.
6441285809Sscottl   */
6442285809Sscottl  satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6443285809Sscottl
6444285809Sscottl  /*
6445285809Sscottl   * Prepare SGL and send FIS to LL layer.
6446285809Sscottl   */
6447285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
6448285809Sscottl
6449285809Sscottl  status = smsataLLIOStart( smRoot,
6450285809Sscottl                            smIORequest,
6451285809Sscottl                            smDeviceHandle,
6452285809Sscottl                            smScsiRequest,
6453285809Sscottl                            satIOContext);
6454285809Sscottl  return (status);
6455285809Sscottl}
6456285809Sscottl
6457285809SscottlosGLOBAL FORCEINLINE bit32
6458285809SscottlsmsatWrite10(
6459285809Sscottl             smRoot_t                  *smRoot,
6460285809Sscottl             smIORequest_t             *smIORequest,
6461285809Sscottl             smDeviceHandle_t          *smDeviceHandle,
6462285809Sscottl             smScsiInitiatorRequest_t  *smScsiRequest,
6463285809Sscottl             smSatIOContext_t            *satIOContext
6464285809Sscottl            )
6465285809Sscottl{
6466285809Sscottl  smDeviceData_t           *pSatDevData = satIOContext->pSatDevData;
6467285809Sscottl  smScsiRspSense_t         *pSense      = satIOContext->pSense;
6468285809Sscottl  smIniScsiCmnd_t          *scsiCmnd    = &smScsiRequest->scsiCmnd;
6469285809Sscottl  agsaFisRegHostToDevice_t *fis         =  satIOContext->pFis;
6470285809Sscottl  bit32                     status      = SM_RC_FAILURE;
6471285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6472285809Sscottl  bit32                     lba = 0;
6473285809Sscottl  bit32                     tl = 0;
6474285809Sscottl  bit32                     LoopNum = 1;
6475285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
6476285809Sscottl  bit8                      LBA[8];
6477285809Sscottl  bit8                      TL[8];
6478285809Sscottl
6479285809Sscottl  SM_DBG2(("smsatWrite10: start\n"));
6480285809Sscottl
6481285809Sscottl  /* checking FUA_NV */
6482285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
6483285809Sscottl  {
6484285809Sscottl    smsatSetSensePayload( pSense,
6485285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
6486285809Sscottl                          0,
6487285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6488285809Sscottl                          satIOContext);
6489285809Sscottl
6490285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
6491285809Sscottl
6492285809Sscottl    tdsmIOCompletedCB( smRoot,
6493285809Sscottl                       smIORequest,
6494285809Sscottl                       smIOSuccess,
6495285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
6496285809Sscottl                       satIOContext->pSmSenseData,
6497285809Sscottl                       satIOContext->interruptContext );
6498285809Sscottl
6499285809Sscottl    SM_DBG1(("smsatWrite10: return FUA_NV!!!\n"));
6500285809Sscottl    return SM_RC_SUCCESS;
6501285809Sscottl
6502285809Sscottl  }
6503285809Sscottl
6504285809Sscottl  /* checking CONTROL */
6505285809Sscottl  /* NACA == 1 or LINK == 1*/
6506285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
6507285809Sscottl  {
6508285809Sscottl    smsatSetSensePayload( pSense,
6509285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
6510285809Sscottl                          0,
6511285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6512285809Sscottl                          satIOContext);
6513285809Sscottl
6514285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
6515285809Sscottl
6516285809Sscottl    tdsmIOCompletedCB( smRoot,
6517285809Sscottl                       smIORequest,
6518285809Sscottl                       smIOSuccess,
6519285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
6520285809Sscottl                       satIOContext->pSmSenseData,
6521285809Sscottl                       satIOContext->interruptContext );
6522285809Sscottl
6523285809Sscottl    SM_DBG1(("smsatWrite10: return control!!!\n"));
6524285809Sscottl    return SM_RC_SUCCESS;
6525285809Sscottl  }
6526285809Sscottl/*
6527285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
6528285809Sscottl  sm_memset(TL, 0, sizeof(TL));
6529285809Sscottl*/
6530285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
6531285809Sscottl  LBA[0] = 0;                  /* MSB */
6532285809Sscottl  LBA[1] = 0;
6533285809Sscottl  LBA[2] = 0;
6534285809Sscottl  LBA[3] = 0;
6535285809Sscottl  LBA[4] = scsiCmnd->cdb[2];
6536285809Sscottl  LBA[5] = scsiCmnd->cdb[3];
6537285809Sscottl  LBA[6] = scsiCmnd->cdb[4];
6538285809Sscottl  LBA[7] = scsiCmnd->cdb[5];   /* LSB */
6539285809Sscottl
6540285809Sscottl  TL[0] = 0;
6541285809Sscottl  TL[1] = 0;
6542285809Sscottl  TL[2] = 0;
6543285809Sscottl  TL[3] = 0;
6544285809Sscottl  TL[4] = 0;
6545285809Sscottl  TL[5] = 0;
6546285809Sscottl  TL[6] = scsiCmnd->cdb[7];
6547285809Sscottl  TL[7] = scsiCmnd->cdb[8];  	/* LSB */
6548285809Sscottl
6549285809Sscottl
6550285809Sscottl
6551285809Sscottl  /* cbd10; computing LBA and transfer length */
6552285809Sscottl  lba = (scsiCmnd->cdb[2] << (24)) + (scsiCmnd->cdb[3] << (16))
6553285809Sscottl    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
6554285809Sscottl  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
6555285809Sscottl
6556285809Sscottl  SM_DBG5(("smsatWrite10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext)));
6557285809Sscottl  SM_DBG5(("smsatWrite10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext)));
6558285809Sscottl
6559285809Sscottl  /* Table 34, 9.1, p 46 */
6560285809Sscottl  /*
6561285809Sscottl    note: As of 2/10/2006, no support for DMA QUEUED
6562285809Sscottl   */
6563285809Sscottl
6564285809Sscottl  /*
6565285809Sscottl    Table 34, 9.1, p 46, b
6566285809Sscottl    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
6567285809Sscottl    return check condition
6568285809Sscottl  */
6569285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
6570285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
6571285809Sscottl      )
6572285809Sscottl  {
6573285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
6574285809Sscottl    if (AllChk)
6575285809Sscottl    {
6576285809Sscottl     SM_DBG1(("smsatWrite10: return LBA out of range, not EXT!!!\n"));
6577285809Sscottl     SM_DBG1(("smsatWrite10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
6578285809Sscottl             scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
6579285809Sscottl     SM_DBG1(("smsatWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
6580285809Sscottl      smsatSetSensePayload( pSense,
6581285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6582285809Sscottl                            0,
6583285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6584285809Sscottl                            satIOContext);
6585285809Sscottl
6586285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
6587285809Sscottl
6588285809Sscottl      tdsmIOCompletedCB( smRoot,
6589285809Sscottl                         smIORequest,
6590285809Sscottl                         smIOSuccess,
6591285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
6592285809Sscottl                         satIOContext->pSmSenseData,
6593285809Sscottl                         satIOContext->interruptContext );
6594285809Sscottl
6595285809Sscottl    return SM_RC_SUCCESS;
6596285809Sscottl    }
6597285809Sscottl  }
6598285809Sscottl  else
6599285809Sscottl  {
6600285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
6601285809Sscottl    if (AllChk)
6602285809Sscottl    {
6603285809Sscottl      SM_DBG1(("smsatWrite10: return LBA out of range, EXT!!!\n"));
6604285809Sscottl      smsatSetSensePayload( pSense,
6605285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6606285809Sscottl                            0,
6607285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6608285809Sscottl                            satIOContext);
6609285809Sscottl
6610285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
6611285809Sscottl
6612285809Sscottl    tdsmIOCompletedCB( smRoot,
6613285809Sscottl                       smIORequest,
6614285809Sscottl                       smIOSuccess,
6615285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
6616285809Sscottl                       satIOContext->pSmSenseData,
6617285809Sscottl                       satIOContext->interruptContext );
6618285809Sscottl
6619285809Sscottl    return SM_RC_SUCCESS;
6620285809Sscottl    }
6621285809Sscottl
6622285809Sscottl  }
6623285809Sscottl
6624285809Sscottl  /* case 5 */
6625285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
6626285809Sscottl  {
6627285809Sscottl    /* WRITE FPDMA QUEUED */
6628285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
6629285809Sscottl    {
6630285809Sscottl      SM_DBG1(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6631285809Sscottl      smsatSetSensePayload( pSense,
6632285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6633285809Sscottl                            0,
6634285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6635285809Sscottl                            satIOContext);
6636285809Sscottl
6637285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
6638285809Sscottl
6639285809Sscottl      tdsmIOCompletedCB( smRoot,
6640285809Sscottl                         smIORequest,
6641285809Sscottl                         smIOSuccess,
6642285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
6643285809Sscottl                         satIOContext->pSmSenseData,
6644285809Sscottl                         satIOContext->interruptContext );
6645285809Sscottl      return SM_RC_SUCCESS;
6646285809Sscottl    }
6647285809Sscottl    SM_DBG6(("smsatWrite10: case 5\n"));
6648285809Sscottl
6649285809Sscottl    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
6650285809Sscottl
6651285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
6652285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6653285809Sscottl    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
6654285809Sscottl    fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6655285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6656285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6657285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6658285809Sscottl
6659285809Sscottl    /* Check FUA bit */
6660285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
6661285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
6662285809Sscottl    else
6663285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
6664285809Sscottl
6665285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
6666285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6667285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6668285809Sscottl    fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
6669285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
6670285809Sscottl    fis->d.sectorCountExp = 0;
6671285809Sscottl    fis->d.reserved4      = 0;
6672285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
6673285809Sscottl    fis->d.reserved5      = 0;
6674285809Sscottl
6675285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
6676285809Sscottl    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
6677285809Sscottl  }
6678285809Sscottl  /* case 3 and 4 */
6679285809Sscottl  else if (pSatDevData->sat48BitSupport == agTRUE)
6680285809Sscottl  {
6681285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6682285809Sscottl    {
6683285809Sscottl      /* case 3 */
6684285809Sscottl      /* WRITE DMA EXT or WRITE DMA FUA EXT */
6685285809Sscottl      SM_DBG5(("smsatWrite10: case 3\n"));
6686285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
6687285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6688285809Sscottl
6689285809Sscottl      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
6690285809Sscottl      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
6691285809Sscottl      satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
6692285809Sscottl
6693285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
6694285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6695285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6696285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6697285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
6698285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
6699285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6700285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6701285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
6702285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6703285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
6704285809Sscottl      fis->d.reserved4      = 0;
6705285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
6706285809Sscottl      fis->d.reserved5      = 0;
6707285809Sscottl
6708285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6709285809Sscottl    }
6710285809Sscottl    else
6711285809Sscottl    {
6712285809Sscottl      /* case 4 */
6713285809Sscottl      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
6714285809Sscottl      /* WRITE SECTORS EXT for easier implemetation */
6715285809Sscottl      SM_DBG5(("smsatWrite10: case 4\n"));
6716285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
6717285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6718285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
6719285809Sscottl
6720285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
6721285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6722285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6723285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6724285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
6725285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
6726285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6727285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6728285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
6729285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6730285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
6731285809Sscottl      fis->d.reserved4      = 0;
6732285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
6733285809Sscottl      fis->d.reserved5      = 0;
6734285809Sscottl
6735285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6736285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
6737285809Sscottl    }
6738285809Sscottl  }
6739285809Sscottl  else /* case 1 and 2 */
6740285809Sscottl  {
6741285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6742285809Sscottl    {
6743285809Sscottl      /* case 2 */
6744285809Sscottl      /* WRITE DMA*/
6745285809Sscottl      /* can't fit the transfer length */
6746285809Sscottl      SM_DBG5(("smsatWrite10: case 2\n"));
6747285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
6748285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
6749285809Sscottl      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
6750285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
6751285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6752285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6753285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6754285809Sscottl
6755285809Sscottl      /* FIS LBA mode set LBA (27:24) */
6756285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
6757285809Sscottl
6758285809Sscottl      fis->d.lbaLowExp      = 0;
6759285809Sscottl      fis->d.lbaMidExp      = 0;
6760285809Sscottl      fis->d.lbaHighExp     = 0;
6761285809Sscottl      fis->d.featuresExp    = 0;
6762285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6763285809Sscottl      fis->d.sectorCountExp = 0;
6764285809Sscottl      fis->d.reserved4      = 0;
6765285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
6766285809Sscottl      fis->d.reserved5      = 0;
6767285809Sscottl
6768285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6769285809Sscottl      satIOContext->ATACmd = SAT_WRITE_DMA;
6770285809Sscottl    }
6771285809Sscottl    else
6772285809Sscottl    {
6773285809Sscottl      /* case 1 */
6774285809Sscottl      /* WRITE MULTIPLE or WRITE SECTOR(S) */
6775285809Sscottl      /* WRITE SECTORS for easier implemetation */
6776285809Sscottl      /* can't fit the transfer length */
6777285809Sscottl      SM_DBG5(("smsatWrite10: case 1\n"));
6778285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
6779285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
6780285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
6781285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
6782285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6783285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6784285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6785285809Sscottl
6786285809Sscottl      /* FIS LBA mode set LBA (27:24) */
6787285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
6788285809Sscottl
6789285809Sscottl      fis->d.lbaLowExp      = 0;
6790285809Sscottl      fis->d.lbaMidExp      = 0;
6791285809Sscottl      fis->d.lbaHighExp     = 0;
6792285809Sscottl      fis->d.featuresExp    = 0;
6793285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6794285809Sscottl      fis->d.sectorCountExp = 0;
6795285809Sscottl      fis->d.reserved4      = 0;
6796285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
6797285809Sscottl      fis->d.reserved5      = 0;
6798285809Sscottl
6799285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6800285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS;
6801285809Sscottl    }
6802285809Sscottl  }
6803285809Sscottl
6804285809Sscottl  //  smhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
6805285809Sscottl
6806285809Sscottl  satIOContext->currentLBA = lba;
6807285809Sscottl  satIOContext->OrgTL = tl;
6808285809Sscottl
6809285809Sscottl  /*
6810285809Sscottl    computing number of loop and remainder for tl
6811285809Sscottl    0xFF in case not ext
6812285809Sscottl    0xFFFF in case EXT
6813285809Sscottl  */
6814285809Sscottl  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
6815285809Sscottl  {
6816285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0x100);
6817285809Sscottl  }
6818285809Sscottl  else
6819285809Sscottl  {
6820285809Sscottl    /* SAT_WRITE_FPDMA_QUEUEDK */
6821285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6822285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6823285809Sscottl  }
6824285809Sscottl
6825285809Sscottl  satIOContext->LoopNum = LoopNum;
6826285809Sscottl
6827285809Sscottl
6828285809Sscottl  if (LoopNum == 1)
6829285809Sscottl  {
6830285809Sscottl    SM_DBG5(("smsatWrite10: NON CHAINED data\n"));
6831285809Sscottl    /* Initialize CB for SATA completion.
6832285809Sscottl     */
6833285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6834285809Sscottl  }
6835285809Sscottl  else
6836285809Sscottl  {
6837285809Sscottl    SM_DBG2(("smsatWrite10: CHAINED data!!!\n"));
6838285809Sscottl    /* re-setting tl */
6839285809Sscottl    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
6840285809Sscottl    {
6841285809Sscottl      fis->d.sectorCount    = 0x0;
6842285809Sscottl      smsatSplitSGL(smRoot,
6843285809Sscottl                    smIORequest,
6844285809Sscottl                    smDeviceHandle,
6845285809Sscottl                    smScsiRequest,
6846285809Sscottl                    satIOContext,
6847285809Sscottl                    NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */
6848285809Sscottl                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6849285809Sscottl                    agTRUE);
6850285809Sscottl    }
6851285809Sscottl    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
6852285809Sscottl             fis->h.command == SAT_WRITE_DMA_EXT ||
6853285809Sscottl             fis->h.command == SAT_WRITE_DMA_FUA_EXT
6854285809Sscottl             )
6855285809Sscottl    {
6856285809Sscottl      fis->d.sectorCount    = 0xFF;
6857285809Sscottl      fis->d.sectorCountExp = 0xFF;
6858285809Sscottl      smsatSplitSGL(smRoot,
6859285809Sscottl                    smIORequest,
6860285809Sscottl                    smDeviceHandle,
6861285809Sscottl                    smScsiRequest,
6862285809Sscottl                    satIOContext,
6863285809Sscottl                    BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
6864285809Sscottl                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6865285809Sscottl                    agTRUE);
6866285809Sscottl    }
6867285809Sscottl    else
6868285809Sscottl    {
6869285809Sscottl      /* SAT_WRITE_FPDMA_QUEUED */
6870285809Sscottl      fis->h.features       = 0xFF;
6871285809Sscottl      fis->d.featuresExp    = 0xFF;
6872285809Sscottl      smsatSplitSGL(smRoot,
6873285809Sscottl                    smIORequest,
6874285809Sscottl                    smDeviceHandle,
6875285809Sscottl                    smScsiRequest,
6876285809Sscottl                    satIOContext,
6877285809Sscottl                    BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
6878285809Sscottl                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6879285809Sscottl                    agTRUE);
6880285809Sscottl    }
6881285809Sscottl
6882285809Sscottl    /* Initialize CB for SATA completion.
6883285809Sscottl     */
6884285809Sscottl    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
6885285809Sscottl  }
6886285809Sscottl
6887285809Sscottl
6888285809Sscottl  /*
6889285809Sscottl   * Prepare SGL and send FIS to LL layer.
6890285809Sscottl   */
6891285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
6892285809Sscottl
6893285809Sscottl  status = smsataLLIOStart( smRoot,
6894285809Sscottl                            smIORequest,
6895285809Sscottl                            smDeviceHandle,
6896285809Sscottl                            smScsiRequest,
6897285809Sscottl                            satIOContext);
6898285809Sscottl  return (status);
6899285809Sscottl}
6900285809Sscottl
6901285809SscottlosGLOBAL bit32
6902285809SscottlsmsatWrite12(
6903285809Sscottl             smRoot_t                  *smRoot,
6904285809Sscottl             smIORequest_t             *smIORequest,
6905285809Sscottl             smDeviceHandle_t          *smDeviceHandle,
6906285809Sscottl             smScsiInitiatorRequest_t  *smScsiRequest,
6907285809Sscottl             smSatIOContext_t            *satIOContext
6908285809Sscottl            )
6909285809Sscottl{
6910285809Sscottl  bit32                     status;
6911285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6912285809Sscottl  smDeviceData_t            *pSatDevData;
6913285809Sscottl  smScsiRspSense_t          *pSense;
6914285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
6915285809Sscottl  agsaFisRegHostToDevice_t  *fis;
6916285809Sscottl  bit32                     lba = 0;
6917285809Sscottl  bit32                     tl = 0;
6918285809Sscottl  bit32                     LoopNum = 1;
6919285809Sscottl  bit8                      LBA[8];
6920285809Sscottl  bit8                      TL[8];
6921285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
6922285809Sscottl
6923285809Sscottl  pSense        = satIOContext->pSense;
6924285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
6925285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
6926285809Sscottl  fis           = satIOContext->pFis;
6927285809Sscottl
6928285809Sscottl  SM_DBG5(("smsatWrite12: start\n"));
6929285809Sscottl
6930285809Sscottl  /* checking FUA_NV */
6931285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
6932285809Sscottl  {
6933285809Sscottl    smsatSetSensePayload( pSense,
6934285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
6935285809Sscottl                          0,
6936285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6937285809Sscottl                          satIOContext);
6938285809Sscottl
6939285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
6940285809Sscottl
6941285809Sscottl    tdsmIOCompletedCB( smRoot,
6942285809Sscottl                       smIORequest,
6943285809Sscottl                       smIOSuccess,
6944285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
6945285809Sscottl                       satIOContext->pSmSenseData,
6946285809Sscottl                       satIOContext->interruptContext );
6947285809Sscottl
6948285809Sscottl    SM_DBG1(("smsatWrite12: return FUA_NV!!!\n"));
6949285809Sscottl    return SM_RC_SUCCESS;
6950285809Sscottl
6951285809Sscottl  }
6952285809Sscottl
6953285809Sscottl
6954285809Sscottl  /* checking CONTROL */
6955285809Sscottl  /* NACA == 1 or LINK == 1*/
6956285809Sscottl  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
6957285809Sscottl  {
6958285809Sscottl    smsatSetSensePayload( pSense,
6959285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
6960285809Sscottl                          0,
6961285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6962285809Sscottl                          satIOContext);
6963285809Sscottl
6964285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
6965285809Sscottl
6966285809Sscottl    tdsmIOCompletedCB( smRoot,
6967285809Sscottl                       smIORequest,
6968285809Sscottl                       smIOSuccess,
6969285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
6970285809Sscottl                       satIOContext->pSmSenseData,
6971285809Sscottl                       satIOContext->interruptContext );
6972285809Sscottl
6973285809Sscottl    SM_DBG1(("smsatWrite10: return control!!!\n"));
6974285809Sscottl    return SM_RC_SUCCESS;
6975285809Sscottl  }
6976285809Sscottl
6977285809Sscottl
6978285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
6979285809Sscottl  sm_memset(TL, 0, sizeof(TL));
6980285809Sscottl
6981285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
6982285809Sscottl  LBA[0] = 0;                  /* MSB */
6983285809Sscottl  LBA[1] = 0;
6984285809Sscottl  LBA[2] = 0;
6985285809Sscottl  LBA[3] = 0;
6986285809Sscottl  LBA[4] = scsiCmnd->cdb[2];
6987285809Sscottl  LBA[5] = scsiCmnd->cdb[3];
6988285809Sscottl  LBA[6] = scsiCmnd->cdb[4];
6989285809Sscottl  LBA[7] = scsiCmnd->cdb[5];  	/* LSB */
6990285809Sscottl
6991285809Sscottl  TL[0] = 0;                    /* MSB */
6992285809Sscottl  TL[1] = 0;
6993285809Sscottl  TL[2] = 0;
6994285809Sscottl  TL[3] = 0;
6995285809Sscottl  TL[4] = scsiCmnd->cdb[6];
6996285809Sscottl  TL[5] = scsiCmnd->cdb[7];
6997285809Sscottl  TL[6] = scsiCmnd->cdb[8];
6998285809Sscottl  TL[7] = scsiCmnd->cdb[9];   	/* LSB */
6999285809Sscottl
7000285809Sscottl
7001285809Sscottl  lba = smsatComputeCDB12LBA(satIOContext);
7002285809Sscottl  tl = smsatComputeCDB12TL(satIOContext);
7003285809Sscottl
7004285809Sscottl
7005285809Sscottl  /* Table 34, 9.1, p 46 */
7006285809Sscottl  /*
7007285809Sscottl    note: As of 2/10/2006, no support for DMA QUEUED
7008285809Sscottl   */
7009285809Sscottl
7010285809Sscottl  /*
7011285809Sscottl    Table 34, 9.1, p 46, b
7012285809Sscottl    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
7013285809Sscottl    return check condition
7014285809Sscottl  */
7015285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
7016285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
7017285809Sscottl      )
7018285809Sscottl  {
7019285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7020285809Sscottl
7021285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
7022285809Sscottl
7023285809Sscottl
7024285809Sscottl
7025285809Sscottl    if (AllChk)
7026285809Sscottl    {
7027285809Sscottl      SM_DBG1(("smsatWrite12: return LBA out of range, not EXT!!!\n"));
7028285809Sscottl      smsatSetSensePayload( pSense,
7029285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7030285809Sscottl                            0,
7031285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7032285809Sscottl                            satIOContext);
7033285809Sscottl
7034285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
7035285809Sscottl
7036285809Sscottl      tdsmIOCompletedCB( smRoot,
7037285809Sscottl                         smIORequest,
7038285809Sscottl                         smIOSuccess,
7039285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
7040285809Sscottl                         satIOContext->pSmSenseData,
7041285809Sscottl                         satIOContext->interruptContext );
7042285809Sscottl
7043285809Sscottl      return SM_RC_SUCCESS;
7044285809Sscottl    }
7045285809Sscottl  }
7046285809Sscottl  else
7047285809Sscottl  {
7048285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7049285809Sscottl    if (AllChk)
7050285809Sscottl    {
7051285809Sscottl      SM_DBG1(("smsatWrite12: return LBA out of range, EXT!!!\n"));
7052285809Sscottl      smsatSetSensePayload( pSense,
7053285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7054285809Sscottl                            0,
7055285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7056285809Sscottl                            satIOContext);
7057285809Sscottl      tdsmIOCompletedCB( smRoot,
7058285809Sscottl                         smIORequest,
7059285809Sscottl                         smIOSuccess,
7060285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
7061285809Sscottl                         satIOContext->pSmSenseData,
7062285809Sscottl                         satIOContext->interruptContext );
7063285809Sscottl      return SM_RC_SUCCESS;
7064285809Sscottl    }
7065285809Sscottl  }
7066285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7067285809Sscottl    {
7068285809Sscottl      /* case 2 */
7069285809Sscottl      /* WRITE DMA*/
7070285809Sscottl      /* In case that we can't fit the transfer length, we loop */
7071285809Sscottl      SM_DBG5(("smsatWrite10: case 2\n"));
7072285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
7073285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7074285809Sscottl      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
7075285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
7076285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7077285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7078285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7079285809Sscottl
7080285809Sscottl      /* FIS LBA mode set LBA (27:24) */
7081285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7082285809Sscottl
7083285809Sscottl      fis->d.lbaLowExp      = 0;
7084285809Sscottl      fis->d.lbaMidExp      = 0;
7085285809Sscottl      fis->d.lbaHighExp     = 0;
7086285809Sscottl      fis->d.featuresExp    = 0;
7087285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7088285809Sscottl      fis->d.sectorCountExp = 0;
7089285809Sscottl      fis->d.reserved4      = 0;
7090285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
7091285809Sscottl      fis->d.reserved5      = 0;
7092285809Sscottl
7093285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7094285809Sscottl      satIOContext->ATACmd = SAT_WRITE_DMA;
7095285809Sscottl    }
7096285809Sscottl    else
7097285809Sscottl    {
7098285809Sscottl      /* case 1 */
7099285809Sscottl      /* WRITE MULTIPLE or WRITE SECTOR(S) */
7100285809Sscottl      /* WRITE SECTORS for easier implemetation */
7101285809Sscottl      /* In case that we can't fit the transfer length, we loop */
7102285809Sscottl      SM_DBG5(("smsatWrite10: case 1\n"));
7103285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
7104285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7105285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
7106285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
7107285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7108285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7109285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7110285809Sscottl
7111285809Sscottl      /* FIS LBA mode set LBA (27:24) */
7112285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7113285809Sscottl
7114285809Sscottl      fis->d.lbaLowExp      = 0;
7115285809Sscottl      fis->d.lbaMidExp      = 0;
7116285809Sscottl      fis->d.lbaHighExp     = 0;
7117285809Sscottl      fis->d.featuresExp    = 0;
7118285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7119285809Sscottl      fis->d.sectorCountExp = 0;
7120285809Sscottl      fis->d.reserved4      = 0;
7121285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
7122285809Sscottl      fis->d.reserved5      = 0;
7123285809Sscottl
7124285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7125285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS;
7126285809Sscottl  }
7127285809Sscottl
7128285809Sscottl  /* case 3 and 4 */
7129285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
7130285809Sscottl  {
7131285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7132285809Sscottl    {
7133285809Sscottl      /* case 3 */
7134285809Sscottl      /* WRITE DMA EXT or WRITE DMA FUA EXT */
7135285809Sscottl      SM_DBG5(("smsatWrite10: case 3\n"));
7136285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
7137285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7138285809Sscottl
7139285809Sscottl      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
7140285809Sscottl      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
7141285809Sscottl
7142285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
7143285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7144285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7145285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7146285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
7147285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7148285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7149285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7150285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
7151285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7152285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
7153285809Sscottl      fis->d.reserved4      = 0;
7154285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
7155285809Sscottl      fis->d.reserved5      = 0;
7156285809Sscottl
7157285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7158285809Sscottl      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
7159285809Sscottl    }
7160285809Sscottl    else
7161285809Sscottl    {
7162285809Sscottl      /* case 4 */
7163285809Sscottl      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
7164285809Sscottl      /* WRITE SECTORS EXT for easier implemetation */
7165285809Sscottl      SM_DBG5(("smsatWrite10: case 4\n"));
7166285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
7167285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7168285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
7169285809Sscottl
7170285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
7171285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7172285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7173285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7174285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
7175285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7176285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7177285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7178285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
7179285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7180285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
7181285809Sscottl      fis->d.reserved4      = 0;
7182285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
7183285809Sscottl      fis->d.reserved5      = 0;
7184285809Sscottl
7185285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7186285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
7187285809Sscottl    }
7188285809Sscottl  }
7189285809Sscottl
7190285809Sscottl  /* case 5 */
7191285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
7192285809Sscottl  {
7193285809Sscottl    /* WRITE FPDMA QUEUED */
7194285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
7195285809Sscottl    {
7196285809Sscottl       SM_DBG5(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
7197285809Sscottl       smsatSetSensePayload( pSense,
7198285809Sscottl                             SCSI_SNSKEY_ILLEGAL_REQUEST,
7199285809Sscottl                             0,
7200285809Sscottl                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7201285809Sscottl                             satIOContext);
7202285809Sscottl
7203285809Sscottl       /*smEnqueueIO(smRoot, satIOContext);*/
7204285809Sscottl
7205285809Sscottl       tdsmIOCompletedCB( smRoot,
7206285809Sscottl                          smIORequest,
7207285809Sscottl                          smIOSuccess,
7208285809Sscottl                          SCSI_STAT_CHECK_CONDITION,
7209285809Sscottl                          satIOContext->pSmSenseData,
7210285809Sscottl                          satIOContext->interruptContext );
7211285809Sscottl      return SM_RC_SUCCESS;
7212285809Sscottl    }
7213285809Sscottl    SM_DBG6(("smsatWrite10: case 5\n"));
7214285809Sscottl
7215285809Sscottl    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
7216285809Sscottl
7217285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
7218285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7219285809Sscottl    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
7220285809Sscottl    fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7221285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7222285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7223285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7224285809Sscottl
7225285809Sscottl    /* Check FUA bit */
7226285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
7227285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
7228285809Sscottl    else
7229285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
7230285809Sscottl
7231285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7232285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7233285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7234285809Sscottl    fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
7235285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
7236285809Sscottl    fis->d.sectorCountExp = 0;
7237285809Sscottl    fis->d.reserved4      = 0;
7238285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
7239285809Sscottl    fis->d.reserved5      = 0;
7240285809Sscottl
7241285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
7242285809Sscottl    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
7243285809Sscottl  }
7244285809Sscottl
7245285809Sscottl  satIOContext->currentLBA = lba;
7246285809Sscottl  satIOContext->OrgTL = tl;
7247285809Sscottl
7248285809Sscottl  /*
7249285809Sscottl    computing number of loop and remainder for tl
7250285809Sscottl    0xFF in case not ext
7251285809Sscottl    0xFFFF in case EXT
7252285809Sscottl  */
7253285809Sscottl  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7254285809Sscottl  {
7255285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFF);
7256285809Sscottl  }
7257285809Sscottl  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7258285809Sscottl           fis->h.command == SAT_WRITE_DMA_EXT     ||
7259285809Sscottl           fis->h.command == SAT_WRITE_DMA_FUA_EXT
7260285809Sscottl           )
7261285809Sscottl  {
7262285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7263285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7264285809Sscottl  }
7265285809Sscottl  else
7266285809Sscottl  {
7267285809Sscottl    /* SAT_WRITE_FPDMA_QUEUEDK */
7268285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7269285809Sscottl  }
7270285809Sscottl
7271285809Sscottl  satIOContext->LoopNum = LoopNum;
7272285809Sscottl
7273285809Sscottl
7274285809Sscottl  if (LoopNum == 1)
7275285809Sscottl  {
7276285809Sscottl    SM_DBG5(("smsatWrite10: NON CHAINED data\n"));
7277285809Sscottl    /* Initialize CB for SATA completion.
7278285809Sscottl     */
7279285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
7280285809Sscottl  }
7281285809Sscottl  else
7282285809Sscottl  {
7283285809Sscottl    SM_DBG1(("smsatWrite10: CHAINED data\n"));
7284285809Sscottl    /* re-setting tl */
7285285809Sscottl    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7286285809Sscottl    {
7287285809Sscottl       fis->d.sectorCount    = 0xFF;
7288285809Sscottl    }
7289285809Sscottl    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7290285809Sscottl             fis->h.command == SAT_WRITE_DMA_EXT ||
7291285809Sscottl             fis->h.command == SAT_WRITE_DMA_FUA_EXT
7292285809Sscottl             )
7293285809Sscottl    {
7294285809Sscottl      fis->d.sectorCount    = 0xFF;
7295285809Sscottl      fis->d.sectorCountExp = 0xFF;
7296285809Sscottl    }
7297285809Sscottl    else
7298285809Sscottl    {
7299285809Sscottl      /* SAT_WRITE_FPDMA_QUEUED */
7300285809Sscottl      fis->h.features       = 0xFF;
7301285809Sscottl      fis->d.featuresExp    = 0xFF;
7302285809Sscottl    }
7303285809Sscottl
7304285809Sscottl    /* Initialize CB for SATA completion.
7305285809Sscottl     */
7306285809Sscottl    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
7307285809Sscottl  }
7308285809Sscottl
7309285809Sscottl
7310285809Sscottl  /*
7311285809Sscottl   * Prepare SGL and send FIS to LL layer.
7312285809Sscottl   */
7313285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
7314285809Sscottl
7315285809Sscottl  status = smsataLLIOStart( smRoot,
7316285809Sscottl                            smIORequest,
7317285809Sscottl                            smDeviceHandle,
7318285809Sscottl                            smScsiRequest,
7319285809Sscottl                            satIOContext);
7320285809Sscottl  return (status);
7321285809Sscottl}
7322285809Sscottl
7323285809SscottlosGLOBAL bit32
7324285809SscottlsmsatWrite16(
7325285809Sscottl             smRoot_t                  *smRoot,
7326285809Sscottl             smIORequest_t             *smIORequest,
7327285809Sscottl             smDeviceHandle_t          *smDeviceHandle,
7328285809Sscottl             smScsiInitiatorRequest_t  *smScsiRequest,
7329285809Sscottl             smSatIOContext_t            *satIOContext
7330285809Sscottl            )
7331285809Sscottl{
7332285809Sscottl  bit32                     status;
7333285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7334285809Sscottl  smDeviceData_t            *pSatDevData;
7335285809Sscottl  smScsiRspSense_t          *pSense;
7336285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
7337285809Sscottl  agsaFisRegHostToDevice_t  *fis;
7338285809Sscottl  bit32                     lba = 0;
7339285809Sscottl  bit32                     tl = 0;
7340285809Sscottl  bit32                     LoopNum = 1;
7341285809Sscottl  bit8                      LBA[8];
7342285809Sscottl  bit8                      TL[8];
7343285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
7344285809Sscottl
7345285809Sscottl  pSense        = satIOContext->pSense;
7346285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
7347285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
7348285809Sscottl  fis           = satIOContext->pFis;
7349285809Sscottl
7350285809Sscottl  SM_DBG5(("smsatWrite16: start\n"));
7351285809Sscottl
7352285809Sscottl  /* checking FUA_NV */
7353285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
7354285809Sscottl  {
7355285809Sscottl    smsatSetSensePayload( pSense,
7356285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
7357285809Sscottl                          0,
7358285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7359285809Sscottl                          satIOContext);
7360285809Sscottl
7361285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
7362285809Sscottl
7363285809Sscottl    tdsmIOCompletedCB( smRoot,
7364285809Sscottl                       smIORequest,
7365285809Sscottl                       smIOSuccess,
7366285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
7367285809Sscottl                       satIOContext->pSmSenseData,
7368285809Sscottl                       satIOContext->interruptContext );
7369285809Sscottl
7370285809Sscottl    SM_DBG1(("smsatWrite16: return FUA_NV!!!\n"));
7371285809Sscottl    return SM_RC_SUCCESS;
7372285809Sscottl
7373285809Sscottl  }
7374285809Sscottl
7375285809Sscottl  /* checking CONTROL */
7376285809Sscottl  /* NACA == 1 or LINK == 1*/
7377285809Sscottl  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
7378285809Sscottl  {
7379285809Sscottl    smsatSetSensePayload( pSense,
7380285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
7381285809Sscottl                          0,
7382285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7383285809Sscottl                          satIOContext);
7384285809Sscottl
7385285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
7386285809Sscottl
7387285809Sscottl    tdsmIOCompletedCB( smRoot,
7388285809Sscottl                       smIORequest,
7389285809Sscottl                       smIOSuccess,
7390285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
7391285809Sscottl                       satIOContext->pSmSenseData,
7392285809Sscottl                       satIOContext->interruptContext );
7393285809Sscottl
7394285809Sscottl    SM_DBG1(("smsatWrite16: return control!!!\n"));
7395285809Sscottl    return SM_RC_SUCCESS;
7396285809Sscottl  }
7397285809Sscottl
7398285809Sscottl
7399285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
7400285809Sscottl  sm_memset(TL, 0, sizeof(TL));
7401285809Sscottl
7402285809Sscottl
7403285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
7404285809Sscottl  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
7405285809Sscottl  LBA[1] = scsiCmnd->cdb[3];
7406285809Sscottl  LBA[2] = scsiCmnd->cdb[4];
7407285809Sscottl  LBA[3] = scsiCmnd->cdb[5];
7408285809Sscottl  LBA[4] = scsiCmnd->cdb[6];
7409285809Sscottl  LBA[5] = scsiCmnd->cdb[7];
7410285809Sscottl  LBA[6] = scsiCmnd->cdb[8];
7411285809Sscottl  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
7412285809Sscottl
7413285809Sscottl  TL[0] = 0;
7414285809Sscottl  TL[1] = 0;
7415285809Sscottl  TL[2] = 0;
7416285809Sscottl  TL[3] = 0;
7417285809Sscottl  TL[4] = scsiCmnd->cdb[10];   /* MSB */
7418285809Sscottl  TL[5] = scsiCmnd->cdb[11];
7419285809Sscottl  TL[6] = scsiCmnd->cdb[12];
7420285809Sscottl  TL[7] = scsiCmnd->cdb[13];   /* LSB */
7421285809Sscottl
7422285809Sscottl
7423285809Sscottl
7424285809Sscottl  lba = smsatComputeCDB16LBA(satIOContext);
7425285809Sscottl  tl = smsatComputeCDB16TL(satIOContext);
7426285809Sscottl
7427285809Sscottl
7428285809Sscottl
7429285809Sscottl  /* Table 34, 9.1, p 46 */
7430285809Sscottl  /*
7431285809Sscottl    note: As of 2/10/2006, no support for DMA QUEUED
7432285809Sscottl  */
7433285809Sscottl
7434285809Sscottl  /*
7435285809Sscottl    Table 34, 9.1, p 46, b
7436285809Sscottl    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
7437285809Sscottl    return check condition
7438285809Sscottl  */
7439285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
7440285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
7441285809Sscottl     )
7442285809Sscottl  {
7443285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7444285809Sscottl    if (AllChk)
7445285809Sscottl    {
7446285809Sscottl      SM_DBG1(("smsatWrite16: return LBA out of range, not EXT!!!\n"));
7447285809Sscottl      smsatSetSensePayload( pSense,
7448285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7449285809Sscottl                            0,
7450285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7451285809Sscottl                            satIOContext);
7452285809Sscottl
7453285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
7454285809Sscottl
7455285809Sscottl      tdsmIOCompletedCB( smRoot,
7456285809Sscottl                         smIORequest,
7457285809Sscottl                         smIOSuccess,
7458285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
7459285809Sscottl                         satIOContext->pSmSenseData,
7460285809Sscottl                         satIOContext->interruptContext );
7461285809Sscottl
7462285809Sscottl    return SM_RC_SUCCESS;
7463285809Sscottl    }
7464285809Sscottl  }
7465285809Sscottl  else
7466285809Sscottl  {
7467285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7468285809Sscottl    if (AllChk)
7469285809Sscottl    {
7470285809Sscottl      SM_DBG1(("smsatWrite16: return LBA out of range, EXT!!!\n"));
7471285809Sscottl      smsatSetSensePayload( pSense,
7472285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7473285809Sscottl                            0,
7474285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7475285809Sscottl                            satIOContext);
7476285809Sscottl
7477285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
7478285809Sscottl
7479285809Sscottl      tdsmIOCompletedCB( smRoot,
7480285809Sscottl                         smIORequest,
7481285809Sscottl                         smIOSuccess,
7482285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
7483285809Sscottl                         satIOContext->pSmSenseData,
7484285809Sscottl                         satIOContext->interruptContext );
7485285809Sscottl
7486285809Sscottl    return SM_RC_SUCCESS;
7487285809Sscottl    }
7488285809Sscottl  }
7489285809Sscottl
7490285809Sscottl  /* case 1 and 2 */
7491285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7492285809Sscottl    {
7493285809Sscottl      /* case 2 */
7494285809Sscottl      /* WRITE DMA*/
7495285809Sscottl      /* In case that we can't fit the transfer length, we loop */
7496285809Sscottl      SM_DBG5(("smsatWrite16: case 2\n"));
7497285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
7498285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7499285809Sscottl      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
7500285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
7501285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7502285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7503285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7504285809Sscottl
7505285809Sscottl      /* FIS LBA mode set LBA (27:24) */
7506285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
7507285809Sscottl
7508285809Sscottl      fis->d.lbaLowExp      = 0;
7509285809Sscottl      fis->d.lbaMidExp      = 0;
7510285809Sscottl      fis->d.lbaHighExp     = 0;
7511285809Sscottl      fis->d.featuresExp    = 0;
7512285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7513285809Sscottl      fis->d.sectorCountExp = 0;
7514285809Sscottl      fis->d.reserved4      = 0;
7515285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
7516285809Sscottl      fis->d.reserved5      = 0;
7517285809Sscottl
7518285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7519285809Sscottl      satIOContext->ATACmd = SAT_WRITE_DMA;
7520285809Sscottl    }
7521285809Sscottl    else
7522285809Sscottl    {
7523285809Sscottl      /* case 1 */
7524285809Sscottl      /* WRITE MULTIPLE or WRITE SECTOR(S) */
7525285809Sscottl      /* WRITE SECTORS for easier implemetation */
7526285809Sscottl      /* In case that we can't fit the transfer length, we loop */
7527285809Sscottl      SM_DBG5(("smsatWrite16: case 1\n"));
7528285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
7529285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7530285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
7531285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
7532285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7533285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7534285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7535285809Sscottl
7536285809Sscottl      /* FIS LBA mode set LBA (27:24) */
7537285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
7538285809Sscottl
7539285809Sscottl      fis->d.lbaLowExp      = 0;
7540285809Sscottl      fis->d.lbaMidExp      = 0;
7541285809Sscottl      fis->d.lbaHighExp     = 0;
7542285809Sscottl      fis->d.featuresExp    = 0;
7543285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7544285809Sscottl      fis->d.sectorCountExp = 0;
7545285809Sscottl      fis->d.reserved4      = 0;
7546285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
7547285809Sscottl      fis->d.reserved5      = 0;
7548285809Sscottl
7549285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7550285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS;
7551285809Sscottl  }
7552285809Sscottl
7553285809Sscottl  /* case 3 and 4 */
7554285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
7555285809Sscottl  {
7556285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7557285809Sscottl    {
7558285809Sscottl      /* case 3 */
7559285809Sscottl      /* WRITE DMA EXT or WRITE DMA FUA EXT */
7560285809Sscottl      SM_DBG5(("smsatWrite16: case 3\n"));
7561285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
7562285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7563285809Sscottl
7564285809Sscottl      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
7565285809Sscottl      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
7566285809Sscottl
7567285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
7568285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7569285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7570285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7571285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
7572285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
7573285809Sscottl      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
7574285809Sscottl      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
7575285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
7576285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7577285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
7578285809Sscottl      fis->d.reserved4      = 0;
7579285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
7580285809Sscottl      fis->d.reserved5      = 0;
7581285809Sscottl
7582285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7583285809Sscottl      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
7584285809Sscottl    }
7585285809Sscottl    else
7586285809Sscottl    {
7587285809Sscottl      /* case 4 */
7588285809Sscottl      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
7589285809Sscottl      /* WRITE SECTORS EXT for easier implemetation */
7590285809Sscottl      SM_DBG5(("smsatWrite16: case 4\n"));
7591285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
7592285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7593285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
7594285809Sscottl
7595285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
7596285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7597285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7598285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7599285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
7600285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
7601285809Sscottl      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
7602285809Sscottl      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
7603285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
7604285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7605285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
7606285809Sscottl      fis->d.reserved4      = 0;
7607285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
7608285809Sscottl      fis->d.reserved5      = 0;
7609285809Sscottl
7610285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7611285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
7612285809Sscottl    }
7613285809Sscottl  }
7614285809Sscottl
7615285809Sscottl  /* case 5 */
7616285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
7617285809Sscottl  {
7618285809Sscottl    /* WRITE FPDMA QUEUED */
7619285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
7620285809Sscottl    {
7621285809Sscottl      SM_DBG5(("smsatWrite16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
7622285809Sscottl      smsatSetSensePayload( pSense,
7623285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7624285809Sscottl                            0,
7625285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7626285809Sscottl                            satIOContext);
7627285809Sscottl
7628285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
7629285809Sscottl
7630285809Sscottl      tdsmIOCompletedCB( smRoot,
7631285809Sscottl                         smIORequest,
7632285809Sscottl                         smIOSuccess,
7633285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
7634285809Sscottl                         satIOContext->pSmSenseData,
7635285809Sscottl                         satIOContext->interruptContext );
7636285809Sscottl      return SM_RC_SUCCESS;
7637285809Sscottl    }
7638285809Sscottl    SM_DBG6(("smsatWrite16: case 5\n"));
7639285809Sscottl
7640285809Sscottl    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
7641285809Sscottl
7642285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
7643285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7644285809Sscottl    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
7645285809Sscottl    fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7646285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7647285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7648285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7649285809Sscottl
7650285809Sscottl    /* Check FUA bit */
7651285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
7652285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
7653285809Sscottl    else
7654285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
7655285809Sscottl
7656285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
7657285809Sscottl    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
7658285809Sscottl    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
7659285809Sscottl    fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
7660285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
7661285809Sscottl    fis->d.sectorCountExp = 0;
7662285809Sscottl    fis->d.reserved4      = 0;
7663285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
7664285809Sscottl    fis->d.reserved5      = 0;
7665285809Sscottl
7666285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
7667285809Sscottl    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
7668285809Sscottl  }
7669285809Sscottl
7670285809Sscottl  satIOContext->currentLBA = lba;
7671285809Sscottl  satIOContext->OrgTL = tl;
7672285809Sscottl
7673285809Sscottl  /*
7674285809Sscottl    computing number of loop and remainder for tl
7675285809Sscottl    0xFF in case not ext
7676285809Sscottl    0xFFFF in case EXT
7677285809Sscottl  */
7678285809Sscottl  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7679285809Sscottl  {
7680285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFF);
7681285809Sscottl  }
7682285809Sscottl  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7683285809Sscottl           fis->h.command == SAT_WRITE_DMA_EXT     ||
7684285809Sscottl           fis->h.command == SAT_WRITE_DMA_FUA_EXT
7685285809Sscottl           )
7686285809Sscottl  {
7687285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7688285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7689285809Sscottl  }
7690285809Sscottl  else
7691285809Sscottl  {
7692285809Sscottl    /* SAT_WRITE_FPDMA_QUEUEDK */
7693285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7694285809Sscottl  }
7695285809Sscottl
7696285809Sscottl  satIOContext->LoopNum = LoopNum;
7697285809Sscottl
7698285809Sscottl
7699285809Sscottl  if (LoopNum == 1)
7700285809Sscottl  {
7701285809Sscottl    SM_DBG5(("smsatWrite16: NON CHAINED data\n"));
7702285809Sscottl    /* Initialize CB for SATA completion.
7703285809Sscottl     */
7704285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
7705285809Sscottl  }
7706285809Sscottl  else
7707285809Sscottl  {
7708285809Sscottl    SM_DBG1(("smsatWrite16: CHAINED data!!!\n"));
7709285809Sscottl    /* re-setting tl */
7710285809Sscottl    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7711285809Sscottl    {
7712285809Sscottl       fis->d.sectorCount    = 0xFF;
7713285809Sscottl    }
7714285809Sscottl    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7715285809Sscottl             fis->h.command == SAT_WRITE_DMA_EXT ||
7716285809Sscottl             fis->h.command == SAT_WRITE_DMA_FUA_EXT
7717285809Sscottl             )
7718285809Sscottl    {
7719285809Sscottl      fis->d.sectorCount    = 0xFF;
7720285809Sscottl      fis->d.sectorCountExp = 0xFF;
7721285809Sscottl    }
7722285809Sscottl    else
7723285809Sscottl    {
7724285809Sscottl      /* SAT_WRITE_FPDMA_QUEUED */
7725285809Sscottl      fis->h.features       = 0xFF;
7726285809Sscottl      fis->d.featuresExp    = 0xFF;
7727285809Sscottl    }
7728285809Sscottl
7729285809Sscottl    /* Initialize CB for SATA completion.
7730285809Sscottl     */
7731285809Sscottl    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
7732285809Sscottl  }
7733285809Sscottl
7734285809Sscottl
7735285809Sscottl  /*
7736285809Sscottl   * Prepare SGL and send FIS to LL layer.
7737285809Sscottl   */
7738285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
7739285809Sscottl
7740285809Sscottl  status = smsataLLIOStart( smRoot,
7741285809Sscottl                            smIORequest,
7742285809Sscottl                            smDeviceHandle,
7743285809Sscottl                            smScsiRequest,
7744285809Sscottl                            satIOContext);
7745285809Sscottl  return (status);
7746285809Sscottl}
7747285809Sscottl
7748285809Sscottl
7749285809SscottlosGLOBAL bit32
7750285809SscottlsmsatVerify10(
7751285809Sscottl              smRoot_t                  *smRoot,
7752285809Sscottl              smIORequest_t             *smIORequest,
7753285809Sscottl              smDeviceHandle_t          *smDeviceHandle,
7754285809Sscottl              smScsiInitiatorRequest_t  *smScsiRequest,
7755285809Sscottl              smSatIOContext_t            *satIOContext
7756285809Sscottl             )
7757285809Sscottl{
7758285809Sscottl  /*
7759285809Sscottl    For simple implementation,
7760285809Sscottl    no byte comparison supported as of 4/5/06
7761285809Sscottl  */
7762285809Sscottl  smScsiRspSense_t          *pSense;
7763285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
7764285809Sscottl  smDeviceData_t            *pSatDevData;
7765285809Sscottl  agsaFisRegHostToDevice_t  *fis;
7766285809Sscottl  bit32                     status;
7767285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7768285809Sscottl  bit32                     lba = 0;
7769285809Sscottl  bit32                     tl = 0;
7770285809Sscottl  bit32                     LoopNum = 1;
7771285809Sscottl  bit8                      LBA[8];
7772285809Sscottl  bit8                      TL[8];
7773285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
7774285809Sscottl
7775285809Sscottl  pSense            = satIOContext->pSense;
7776285809Sscottl  scsiCmnd          = &smScsiRequest->scsiCmnd;
7777285809Sscottl  pSatDevData       = satIOContext->pSatDevData;
7778285809Sscottl  fis               = satIOContext->pFis;
7779285809Sscottl  SM_DBG5(("smsatVerify10: start\n"));
7780285809Sscottl  /* checking BYTCHK */
7781285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
7782285809Sscottl  {
7783285809Sscottl    /*
7784285809Sscottl      should do the byte check
7785285809Sscottl      but not supported in this version
7786285809Sscottl     */
7787285809Sscottl    smsatSetSensePayload( pSense,
7788285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
7789285809Sscottl                          0,
7790285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7791285809Sscottl                          satIOContext);
7792285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
7793285809Sscottl    tdsmIOCompletedCB( smRoot,
7794285809Sscottl                       smIORequest,
7795285809Sscottl                       smIOSuccess,
7796285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
7797285809Sscottl                       satIOContext->pSmSenseData,
7798285809Sscottl                       satIOContext->interruptContext );
7799285809Sscottl
7800285809Sscottl    SM_DBG1(("smsatVerify10: no byte checking!!!\n"));
7801285809Sscottl    return SM_RC_SUCCESS;
7802285809Sscottl  }
7803285809Sscottl
7804285809Sscottl  /* checking CONTROL */
7805285809Sscottl  /* NACA == 1 or LINK == 1*/
7806285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
7807285809Sscottl  {
7808285809Sscottl    smsatSetSensePayload( pSense,
7809285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
7810285809Sscottl                          0,
7811285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7812285809Sscottl                          satIOContext);
7813285809Sscottl
7814285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
7815285809Sscottl
7816285809Sscottl    tdsmIOCompletedCB( smRoot,
7817285809Sscottl                       smIORequest,
7818285809Sscottl                       smIOSuccess,
7819285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
7820285809Sscottl                       satIOContext->pSmSenseData,
7821285809Sscottl                       satIOContext->interruptContext );
7822285809Sscottl
7823285809Sscottl    SM_DBG1(("smsatVerify10: return control!!!\n"));
7824285809Sscottl    return SM_RC_SUCCESS;
7825285809Sscottl  }
7826285809Sscottl
7827285809Sscottl
7828285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
7829285809Sscottl  sm_memset(TL, 0, sizeof(TL));
7830285809Sscottl
7831285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
7832285809Sscottl  LBA[0] = 0;                  /* MSB */
7833285809Sscottl  LBA[1] = 0;
7834285809Sscottl  LBA[2] = 0;
7835285809Sscottl  LBA[3] = 0;
7836285809Sscottl  LBA[4] = scsiCmnd->cdb[2];
7837285809Sscottl  LBA[5] = scsiCmnd->cdb[3];
7838285809Sscottl  LBA[6] = scsiCmnd->cdb[4];
7839285809Sscottl  LBA[7] = scsiCmnd->cdb[5];  	/* LSB */
7840285809Sscottl
7841285809Sscottl  TL[0] = 0;
7842285809Sscottl  TL[1] = 0;
7843285809Sscottl  TL[2] = 0;
7844285809Sscottl  TL[3] = 0;
7845285809Sscottl  TL[4] = 0;
7846285809Sscottl  TL[5] = 0;
7847285809Sscottl  TL[6] = scsiCmnd->cdb[7];
7848285809Sscottl  TL[7] = scsiCmnd->cdb[8];  	/* LSB */
7849285809Sscottl
7850285809Sscottl
7851285809Sscottl  /* cbd10; computing LBA and transfer length */
7852285809Sscottl  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
7853285809Sscottl    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
7854285809Sscottl  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7855285809Sscottl
7856285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
7857285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
7858285809Sscottl      )
7859285809Sscottl  {
7860285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7861285809Sscottl    if (AllChk)
7862285809Sscottl    {
7863285809Sscottl      SM_DBG1(("smsatVerify10: return LBA out of range, not EXT!!!\n"));
7864285809Sscottl      SM_DBG1(("smsatVerify10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
7865285809Sscottl             scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
7866285809Sscottl      SM_DBG1(("smsatVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
7867285809Sscottl      smsatSetSensePayload( pSense,
7868285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7869285809Sscottl                            0,
7870285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7871285809Sscottl                            satIOContext);
7872285809Sscottl
7873285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
7874285809Sscottl
7875285809Sscottl      tdsmIOCompletedCB( smRoot,
7876285809Sscottl                         smIORequest,
7877285809Sscottl                         smIOSuccess,
7878285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
7879285809Sscottl                         satIOContext->pSmSenseData,
7880285809Sscottl                         satIOContext->interruptContext );
7881285809Sscottl
7882285809Sscottl    return SM_RC_SUCCESS;
7883285809Sscottl    }
7884285809Sscottl  }
7885285809Sscottl  else
7886285809Sscottl  {
7887285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7888285809Sscottl    if (AllChk)
7889285809Sscottl    {
7890285809Sscottl      SM_DBG1(("smsatVerify10: return LBA out of range, EXT!!!\n"));
7891285809Sscottl      smsatSetSensePayload( pSense,
7892285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7893285809Sscottl                            0,
7894285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7895285809Sscottl                            satIOContext);
7896285809Sscottl
7897285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
7898285809Sscottl
7899285809Sscottl      tdsmIOCompletedCB( smRoot,
7900285809Sscottl                         smIORequest,
7901285809Sscottl                         smIOSuccess,
7902285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
7903285809Sscottl                         satIOContext->pSmSenseData,
7904285809Sscottl                         satIOContext->interruptContext );
7905285809Sscottl
7906285809Sscottl    return SM_RC_SUCCESS;
7907285809Sscottl    }
7908285809Sscottl  }
7909285809Sscottl
7910285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
7911285809Sscottl  {
7912285809Sscottl    SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS_EXT\n"));
7913285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
7914285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7915285809Sscottl
7916285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
7917285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
7918285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7919285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7920285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7921285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
7922285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7923285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7924285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7925285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
7926285809Sscottl    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7927285809Sscottl    fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
7928285809Sscottl
7929285809Sscottl    fis->d.reserved4      = 0;
7930285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
7931285809Sscottl    fis->d.reserved5      = 0;
7932285809Sscottl
7933285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7934285809Sscottl    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
7935285809Sscottl  }
7936285809Sscottl  else
7937285809Sscottl  {
7938285809Sscottl    SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS\n"));
7939285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
7940285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7941285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
7942285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
7943285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7944285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7945285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7946285809Sscottl      /* FIS LBA mode set LBA (27:24) */
7947285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7948285809Sscottl    fis->d.lbaLowExp      = 0;
7949285809Sscottl    fis->d.lbaMidExp      = 0;
7950285809Sscottl    fis->d.lbaHighExp     = 0;
7951285809Sscottl    fis->d.featuresExp    = 0;
7952285809Sscottl    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7953285809Sscottl    fis->d.sectorCountExp = 0;
7954285809Sscottl    fis->d.reserved4      = 0;
7955285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
7956285809Sscottl    fis->d.reserved5      = 0;
7957285809Sscottl
7958285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7959285809Sscottl    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
7960285809Sscottl
7961285809Sscottl }
7962285809Sscottl
7963285809Sscottl  satIOContext->currentLBA = lba;
7964285809Sscottl  satIOContext->OrgTL = tl;
7965285809Sscottl
7966285809Sscottl  /*
7967285809Sscottl    computing number of loop and remainder for tl
7968285809Sscottl    0xFF in case not ext
7969285809Sscottl    0xFFFF in case EXT
7970285809Sscottl  */
7971285809Sscottl  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7972285809Sscottl  {
7973285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFF);
7974285809Sscottl  }
7975285809Sscottl  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
7976285809Sscottl  {
7977285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7978285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7979285809Sscottl  }
7980285809Sscottl  else
7981285809Sscottl  {
7982285809Sscottl    SM_DBG1(("smsatVerify10: error case 1!!!\n"));
7983285809Sscottl    LoopNum = 1;
7984285809Sscottl  }
7985285809Sscottl
7986285809Sscottl  satIOContext->LoopNum = LoopNum;
7987285809Sscottl
7988285809Sscottl  if (LoopNum == 1)
7989285809Sscottl  {
7990285809Sscottl    SM_DBG5(("smsatVerify10: NON CHAINED data\n"));
7991285809Sscottl    /* Initialize CB for SATA completion.
7992285809Sscottl     */
7993285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
7994285809Sscottl  }
7995285809Sscottl  else
7996285809Sscottl  {
7997285809Sscottl    SM_DBG1(("smsatVerify10: CHAINED data!!!\n"));
7998285809Sscottl    /* re-setting tl */
7999285809Sscottl    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8000285809Sscottl    {
8001285809Sscottl       fis->d.sectorCount    = 0xFF;
8002285809Sscottl    }
8003285809Sscottl    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8004285809Sscottl    {
8005285809Sscottl      fis->d.sectorCount    = 0xFF;
8006285809Sscottl      fis->d.sectorCountExp = 0xFF;
8007285809Sscottl    }
8008285809Sscottl    else
8009285809Sscottl    {
8010285809Sscottl      SM_DBG1(("smsatVerify10: error case 2!!!\n"));
8011285809Sscottl    }
8012285809Sscottl
8013285809Sscottl    /* Initialize CB for SATA completion.
8014285809Sscottl     */
8015285809Sscottl    satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8016285809Sscottl  }
8017285809Sscottl
8018285809Sscottl
8019285809Sscottl  /*
8020285809Sscottl   * Prepare SGL and send FIS to LL layer.
8021285809Sscottl   */
8022285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
8023285809Sscottl
8024285809Sscottl  status = smsataLLIOStart( smRoot,
8025285809Sscottl                            smIORequest,
8026285809Sscottl                            smDeviceHandle,
8027285809Sscottl                            smScsiRequest,
8028285809Sscottl                            satIOContext);
8029285809Sscottl  return (status);
8030285809Sscottl}
8031285809Sscottl
8032285809SscottlosGLOBAL bit32
8033285809SscottlsmsatVerify12(
8034285809Sscottl              smRoot_t                  *smRoot,
8035285809Sscottl              smIORequest_t             *smIORequest,
8036285809Sscottl              smDeviceHandle_t          *smDeviceHandle,
8037285809Sscottl              smScsiInitiatorRequest_t  *smScsiRequest,
8038285809Sscottl              smSatIOContext_t            *satIOContext
8039285809Sscottl             )
8040285809Sscottl{
8041285809Sscottl  /*
8042285809Sscottl    For simple implementation,
8043285809Sscottl    no byte comparison supported as of 4/5/06
8044285809Sscottl  */
8045285809Sscottl  smScsiRspSense_t          *pSense;
8046285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
8047285809Sscottl  smDeviceData_t            *pSatDevData;
8048285809Sscottl  agsaFisRegHostToDevice_t  *fis;
8049285809Sscottl  bit32                     status;
8050285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8051285809Sscottl  bit32                     lba = 0;
8052285809Sscottl  bit32                     tl = 0;
8053285809Sscottl  bit32                     LoopNum = 1;
8054285809Sscottl  bit8                      LBA[8];
8055285809Sscottl  bit8                      TL[8];
8056285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
8057285809Sscottl
8058285809Sscottl  pSense            = satIOContext->pSense;
8059285809Sscottl  scsiCmnd          = &smScsiRequest->scsiCmnd;
8060285809Sscottl  pSatDevData       = satIOContext->pSatDevData;
8061285809Sscottl  fis               = satIOContext->pFis;
8062285809Sscottl  SM_DBG5(("smsatVerify12: start\n"));
8063285809Sscottl  /* checking BYTCHK */
8064285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8065285809Sscottl  {
8066285809Sscottl    /*
8067285809Sscottl      should do the byte check
8068285809Sscottl      but not supported in this version
8069285809Sscottl     */
8070285809Sscottl    smsatSetSensePayload( pSense,
8071285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8072285809Sscottl                          0,
8073285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8074285809Sscottl                          satIOContext);
8075285809Sscottl
8076285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8077285809Sscottl
8078285809Sscottl    tdsmIOCompletedCB( smRoot,
8079285809Sscottl                       smIORequest,
8080285809Sscottl                       smIOSuccess,
8081285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
8082285809Sscottl                       satIOContext->pSmSenseData,
8083285809Sscottl                       satIOContext->interruptContext );
8084285809Sscottl
8085285809Sscottl    SM_DBG1(("smsatVerify12: no byte checking!!!\n"));
8086285809Sscottl    return SM_RC_SUCCESS;
8087285809Sscottl  }
8088285809Sscottl
8089285809Sscottl  /* checking CONTROL */
8090285809Sscottl  /* NACA == 1 or LINK == 1*/
8091285809Sscottl  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
8092285809Sscottl  {
8093285809Sscottl    smsatSetSensePayload( pSense,
8094285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8095285809Sscottl                          0,
8096285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8097285809Sscottl                          satIOContext);
8098285809Sscottl
8099285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8100285809Sscottl
8101285809Sscottl    tdsmIOCompletedCB( smRoot,
8102285809Sscottl                       smIORequest,
8103285809Sscottl                       smIOSuccess,
8104285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
8105285809Sscottl                       satIOContext->pSmSenseData,
8106285809Sscottl                       satIOContext->interruptContext );
8107285809Sscottl
8108285809Sscottl    SM_DBG1(("smsatVerify12: return control!!!\n"));
8109285809Sscottl    return SM_RC_SUCCESS;
8110285809Sscottl  }
8111285809Sscottl
8112285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
8113285809Sscottl  sm_memset(TL, 0, sizeof(TL));
8114285809Sscottl
8115285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
8116285809Sscottl  LBA[0] = 0;                  /* MSB */
8117285809Sscottl  LBA[1] = 0;
8118285809Sscottl  LBA[2] = 0;
8119285809Sscottl  LBA[3] = 0;
8120285809Sscottl  LBA[4] = scsiCmnd->cdb[2];
8121285809Sscottl  LBA[5] = scsiCmnd->cdb[3];
8122285809Sscottl  LBA[6] = scsiCmnd->cdb[4];
8123285809Sscottl  LBA[7] = scsiCmnd->cdb[5];  	/* LSB */
8124285809Sscottl
8125285809Sscottl  TL[0] = 0;                    /* MSB */
8126285809Sscottl  TL[1] = 0;
8127285809Sscottl  TL[2] = 0;
8128285809Sscottl  TL[3] = 0;
8129285809Sscottl  TL[4] = scsiCmnd->cdb[6];
8130285809Sscottl  TL[5] = scsiCmnd->cdb[7];
8131285809Sscottl  TL[6] = scsiCmnd->cdb[8];
8132285809Sscottl  TL[7] = scsiCmnd->cdb[9];   	/* LSB */
8133285809Sscottl
8134285809Sscottl
8135285809Sscottl  lba = smsatComputeCDB12LBA(satIOContext);
8136285809Sscottl  tl = smsatComputeCDB12TL(satIOContext);
8137285809Sscottl
8138285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
8139285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
8140285809Sscottl      )
8141285809Sscottl  {
8142285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
8143285809Sscottl    if (AllChk)
8144285809Sscottl    {
8145285809Sscottl      SM_DBG1(("smsatVerify12: return LBA out of range, not EXT!!!\n"));
8146285809Sscottl      SM_DBG1(("smsatVerify12: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
8147285809Sscottl             scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
8148285809Sscottl      SM_DBG1(("smsatVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
8149285809Sscottl      smsatSetSensePayload( pSense,
8150285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
8151285809Sscottl                            0,
8152285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8153285809Sscottl                            satIOContext);
8154285809Sscottl
8155285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
8156285809Sscottl
8157285809Sscottl      tdsmIOCompletedCB( smRoot,
8158285809Sscottl                         smIORequest,
8159285809Sscottl                         smIOSuccess,
8160285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
8161285809Sscottl                         satIOContext->pSmSenseData,
8162285809Sscottl                         satIOContext->interruptContext );
8163285809Sscottl
8164285809Sscottl    return SM_RC_SUCCESS;
8165285809Sscottl    }
8166285809Sscottl  }
8167285809Sscottl  else
8168285809Sscottl  {
8169285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
8170285809Sscottl    if (AllChk)
8171285809Sscottl    {
8172285809Sscottl      SM_DBG1(("smsatVerify12: return LBA out of range, EXT!!!\n"));
8173285809Sscottl      smsatSetSensePayload( pSense,
8174285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
8175285809Sscottl                            0,
8176285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8177285809Sscottl                            satIOContext);
8178285809Sscottl
8179285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
8180285809Sscottl
8181285809Sscottl      tdsmIOCompletedCB( smRoot,
8182285809Sscottl                         smIORequest,
8183285809Sscottl                         smIOSuccess,
8184285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
8185285809Sscottl                         satIOContext->pSmSenseData,
8186285809Sscottl                         satIOContext->interruptContext );
8187285809Sscottl
8188285809Sscottl    return SM_RC_SUCCESS;
8189285809Sscottl    }
8190285809Sscottl  }
8191285809Sscottl
8192285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
8193285809Sscottl  {
8194285809Sscottl    SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS_EXT\n"));
8195285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
8196285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8197285809Sscottl
8198285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8199285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
8200285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8201285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8202285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8203285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8204285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
8205285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
8206285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
8207285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
8208285809Sscottl    fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8209285809Sscottl    fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
8210285809Sscottl
8211285809Sscottl    fis->d.reserved4      = 0;
8212285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
8213285809Sscottl    fis->d.reserved5      = 0;
8214285809Sscottl
8215285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8216285809Sscottl    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8217285809Sscottl  }
8218285809Sscottl  else
8219285809Sscottl  {
8220285809Sscottl    SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS\n"));
8221285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
8222285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8223285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8224285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
8225285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8226285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8227285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8228285809Sscottl      /* FIS LBA mode set LBA (27:24) */
8229285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
8230285809Sscottl    fis->d.lbaLowExp      = 0;
8231285809Sscottl    fis->d.lbaMidExp      = 0;
8232285809Sscottl    fis->d.lbaHighExp     = 0;
8233285809Sscottl    fis->d.featuresExp    = 0;
8234285809Sscottl    fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8235285809Sscottl    fis->d.sectorCountExp = 0;
8236285809Sscottl    fis->d.reserved4      = 0;
8237285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
8238285809Sscottl    fis->d.reserved5      = 0;
8239285809Sscottl
8240285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8241285809Sscottl    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8242285809Sscottl
8243285809Sscottl }
8244285809Sscottl
8245285809Sscottl  satIOContext->currentLBA = lba;
8246285809Sscottl  satIOContext->OrgTL = tl;
8247285809Sscottl
8248285809Sscottl  /*
8249285809Sscottl    computing number of loop and remainder for tl
8250285809Sscottl    0xFF in case not ext
8251285809Sscottl    0xFFFF in case EXT
8252285809Sscottl  */
8253285809Sscottl  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8254285809Sscottl  {
8255285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFF);
8256285809Sscottl  }
8257285809Sscottl  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8258285809Sscottl  {
8259285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8260285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
8261285809Sscottl  }
8262285809Sscottl  else
8263285809Sscottl  {
8264285809Sscottl    SM_DBG1(("smsatVerify12: error case 1!!!\n"));
8265285809Sscottl    LoopNum = 1;
8266285809Sscottl  }
8267285809Sscottl
8268285809Sscottl  satIOContext->LoopNum = LoopNum;
8269285809Sscottl
8270285809Sscottl  if (LoopNum == 1)
8271285809Sscottl  {
8272285809Sscottl    SM_DBG5(("smsatVerify12: NON CHAINED data\n"));
8273285809Sscottl    /* Initialize CB for SATA completion.
8274285809Sscottl     */
8275285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
8276285809Sscottl  }
8277285809Sscottl  else
8278285809Sscottl  {
8279285809Sscottl    SM_DBG1(("smsatVerify12: CHAINED data!!!\n"));
8280285809Sscottl    /* re-setting tl */
8281285809Sscottl    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8282285809Sscottl    {
8283285809Sscottl       fis->d.sectorCount    = 0xFF;
8284285809Sscottl    }
8285285809Sscottl    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8286285809Sscottl    {
8287285809Sscottl      fis->d.sectorCount    = 0xFF;
8288285809Sscottl      fis->d.sectorCountExp = 0xFF;
8289285809Sscottl    }
8290285809Sscottl    else
8291285809Sscottl    {
8292285809Sscottl      SM_DBG1(("smsatVerify12: error case 2!!!\n"));
8293285809Sscottl    }
8294285809Sscottl
8295285809Sscottl    /* Initialize CB for SATA completion.
8296285809Sscottl     */
8297285809Sscottl    satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8298285809Sscottl  }
8299285809Sscottl
8300285809Sscottl
8301285809Sscottl  /*
8302285809Sscottl   * Prepare SGL and send FIS to LL layer.
8303285809Sscottl   */
8304285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
8305285809Sscottl
8306285809Sscottl  status = smsataLLIOStart( smRoot,
8307285809Sscottl                            smIORequest,
8308285809Sscottl                            smDeviceHandle,
8309285809Sscottl                            smScsiRequest,
8310285809Sscottl                            satIOContext);
8311285809Sscottl  return (status);
8312285809Sscottl}
8313285809Sscottl
8314285809SscottlosGLOBAL bit32
8315285809SscottlsmsatVerify16(
8316285809Sscottl              smRoot_t                  *smRoot,
8317285809Sscottl              smIORequest_t             *smIORequest,
8318285809Sscottl              smDeviceHandle_t          *smDeviceHandle,
8319285809Sscottl              smScsiInitiatorRequest_t  *smScsiRequest,
8320285809Sscottl              smSatIOContext_t            *satIOContext
8321285809Sscottl             )
8322285809Sscottl{
8323285809Sscottl  /*
8324285809Sscottl    For simple implementation,
8325285809Sscottl    no byte comparison supported as of 4/5/06
8326285809Sscottl  */
8327285809Sscottl  smScsiRspSense_t          *pSense;
8328285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
8329285809Sscottl  smDeviceData_t            *pSatDevData;
8330285809Sscottl  agsaFisRegHostToDevice_t  *fis;
8331285809Sscottl  bit32                     status;
8332285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8333285809Sscottl  bit32                     lba = 0;
8334285809Sscottl  bit32                     tl = 0;
8335285809Sscottl  bit32                     LoopNum = 1;
8336285809Sscottl  bit8                      LBA[8];
8337285809Sscottl  bit8                      TL[8];
8338285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
8339285809Sscottl
8340285809Sscottl  pSense            = satIOContext->pSense;
8341285809Sscottl  scsiCmnd          = &smScsiRequest->scsiCmnd;
8342285809Sscottl  pSatDevData       = satIOContext->pSatDevData;
8343285809Sscottl  fis               = satIOContext->pFis;
8344285809Sscottl  SM_DBG5(("smsatVerify16: start\n"));
8345285809Sscottl  /* checking BYTCHK */
8346285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8347285809Sscottl  {
8348285809Sscottl    /*
8349285809Sscottl      should do the byte check
8350285809Sscottl      but not supported in this version
8351285809Sscottl     */
8352285809Sscottl    smsatSetSensePayload( pSense,
8353285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8354285809Sscottl                          0,
8355285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8356285809Sscottl                          satIOContext);
8357285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8358285809Sscottl    tdsmIOCompletedCB( smRoot,
8359285809Sscottl                       smIORequest,
8360285809Sscottl                       smIOSuccess,
8361285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
8362285809Sscottl                       satIOContext->pSmSenseData,
8363285809Sscottl                       satIOContext->interruptContext );
8364285809Sscottl    SM_DBG1(("smsatVerify16: no byte checking!!!\n"));
8365285809Sscottl    return SM_RC_SUCCESS;
8366285809Sscottl  }
8367285809Sscottl  /* checking CONTROL */
8368285809Sscottl  /* NACA == 1 or LINK == 1*/
8369285809Sscottl  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
8370285809Sscottl  {
8371285809Sscottl    smsatSetSensePayload( pSense,
8372285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8373285809Sscottl                          0,
8374285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8375285809Sscottl                          satIOContext);
8376285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8377285809Sscottl    tdsmIOCompletedCB( smRoot,
8378285809Sscottl                       smIORequest,
8379285809Sscottl                       smIOSuccess,
8380285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
8381285809Sscottl                       satIOContext->pSmSenseData,
8382285809Sscottl                       satIOContext->interruptContext );
8383285809Sscottl    SM_DBG1(("smsatVerify16: return control!!!\n"));
8384285809Sscottl    return SM_RC_SUCCESS;
8385285809Sscottl  }
8386285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
8387285809Sscottl  sm_memset(TL, 0, sizeof(TL));
8388285809Sscottl
8389285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
8390285809Sscottl  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
8391285809Sscottl  LBA[1] = scsiCmnd->cdb[3];
8392285809Sscottl  LBA[2] = scsiCmnd->cdb[4];
8393285809Sscottl  LBA[3] = scsiCmnd->cdb[5];
8394285809Sscottl  LBA[4] = scsiCmnd->cdb[6];
8395285809Sscottl  LBA[5] = scsiCmnd->cdb[7];
8396285809Sscottl  LBA[6] = scsiCmnd->cdb[8];
8397285809Sscottl  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
8398285809Sscottl
8399285809Sscottl  TL[0] = 0;
8400285809Sscottl  TL[1] = 0;
8401285809Sscottl  TL[2] = 0;
8402285809Sscottl  TL[3] = 0;
8403285809Sscottl  TL[4] = scsiCmnd->cdb[10];   /* MSB */
8404285809Sscottl  TL[5] = scsiCmnd->cdb[11];
8405285809Sscottl  TL[6] = scsiCmnd->cdb[12];
8406285809Sscottl  TL[7] = scsiCmnd->cdb[13];   /* LSB */
8407285809Sscottl  lba = smsatComputeCDB16LBA(satIOContext);
8408285809Sscottl  tl = smsatComputeCDB16TL(satIOContext);
8409285809Sscottl
8410285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
8411285809Sscottl     pSatDevData->sat48BitSupport != agTRUE
8412285809Sscottl     )
8413285809Sscottl  {
8414285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
8415285809Sscottl    if (AllChk)
8416285809Sscottl    {
8417285809Sscottl      SM_DBG1(("smsatVerify16: return LBA out of range, not EXT!!!\n"));
8418285809Sscottl      smsatSetSensePayload( pSense,
8419285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
8420285809Sscottl                            0,
8421285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8422285809Sscottl                            satIOContext);
8423285809Sscottl     /*smEnqueueIO(smRoot, satIOContext);*/
8424285809Sscottl     tdsmIOCompletedCB( smRoot,
8425285809Sscottl                         smIORequest,
8426285809Sscottl                         smIOSuccess,
8427285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
8428285809Sscottl                         satIOContext->pSmSenseData,
8429285809Sscottl                         satIOContext->interruptContext );
8430285809Sscottl    return SM_RC_SUCCESS;
8431285809Sscottl    }
8432285809Sscottl  }
8433285809Sscottl  else
8434285809Sscottl  {
8435285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
8436285809Sscottl    if (AllChk)
8437285809Sscottl    {
8438285809Sscottl      SM_DBG1(("smsatVerify16: return LBA out of range, EXT!!!\n"));
8439285809Sscottl      smsatSetSensePayload( pSense,
8440285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
8441285809Sscottl                            0,
8442285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8443285809Sscottl                            satIOContext);
8444285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
8445285809Sscottl      tdsmIOCompletedCB( smRoot,
8446285809Sscottl                         smIORequest,
8447285809Sscottl                         smIOSuccess,
8448285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
8449285809Sscottl                         satIOContext->pSmSenseData,
8450285809Sscottl                         satIOContext->interruptContext );
8451285809Sscottl    return SM_RC_SUCCESS;
8452285809Sscottl    }
8453285809Sscottl  }
8454285809Sscottl
8455285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
8456285809Sscottl  {
8457285809Sscottl    SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS_EXT\n"));
8458285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
8459285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8460285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8461285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
8462285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8463285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8464285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8465285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8466285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
8467285809Sscottl    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
8468285809Sscottl    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
8469285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
8470285809Sscottl    fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8471285809Sscottl    fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
8472285809Sscottl
8473285809Sscottl    fis->d.reserved4      = 0;
8474285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
8475285809Sscottl    fis->d.reserved5      = 0;
8476285809Sscottl
8477285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8478285809Sscottl    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8479285809Sscottl  }
8480285809Sscottl  else
8481285809Sscottl  {
8482285809Sscottl    SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS\n"));
8483285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
8484285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8485285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8486285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
8487285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8488285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8489285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8490285809Sscottl      /* FIS LBA mode set LBA (27:24) */
8491285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
8492285809Sscottl    fis->d.lbaLowExp      = 0;
8493285809Sscottl    fis->d.lbaMidExp      = 0;
8494285809Sscottl    fis->d.lbaHighExp     = 0;
8495285809Sscottl    fis->d.featuresExp    = 0;
8496285809Sscottl    fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8497285809Sscottl    fis->d.sectorCountExp = 0;
8498285809Sscottl    fis->d.reserved4      = 0;
8499285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
8500285809Sscottl    fis->d.reserved5      = 0;
8501285809Sscottl
8502285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8503285809Sscottl    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8504285809Sscottl
8505285809Sscottl }
8506285809Sscottl
8507285809Sscottl  satIOContext->currentLBA = lba;
8508285809Sscottl  satIOContext->OrgTL = tl;
8509285809Sscottl
8510285809Sscottl  /*
8511285809Sscottl    computing number of loop and remainder for tl
8512285809Sscottl    0xFF in case not ext
8513285809Sscottl    0xFFFF in case EXT
8514285809Sscottl  */
8515285809Sscottl  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8516285809Sscottl  {
8517285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFF);
8518285809Sscottl  }
8519285809Sscottl  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8520285809Sscottl  {
8521285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8522285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
8523285809Sscottl  }
8524285809Sscottl  else
8525285809Sscottl  {
8526285809Sscottl    SM_DBG1(("smsatVerify16: error case 1!!!\n"));
8527285809Sscottl    LoopNum = 1;
8528285809Sscottl  }
8529285809Sscottl
8530285809Sscottl  satIOContext->LoopNum = LoopNum;
8531285809Sscottl
8532285809Sscottl  if (LoopNum == 1)
8533285809Sscottl  {
8534285809Sscottl    SM_DBG5(("smsatVerify16: NON CHAINED data\n"));
8535285809Sscottl    /* Initialize CB for SATA completion.
8536285809Sscottl     */
8537285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
8538285809Sscottl  }
8539285809Sscottl  else
8540285809Sscottl  {
8541285809Sscottl    SM_DBG1(("smsatVerify16: CHAINED data!!!\n"));
8542285809Sscottl    /* re-setting tl */
8543285809Sscottl    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8544285809Sscottl    {
8545285809Sscottl       fis->d.sectorCount    = 0xFF;
8546285809Sscottl    }
8547285809Sscottl    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8548285809Sscottl    {
8549285809Sscottl      fis->d.sectorCount    = 0xFF;
8550285809Sscottl      fis->d.sectorCountExp = 0xFF;
8551285809Sscottl    }
8552285809Sscottl    else
8553285809Sscottl    {
8554285809Sscottl      SM_DBG1(("smsatVerify16: error case 2!!!\n"));
8555285809Sscottl    }
8556285809Sscottl
8557285809Sscottl    /* Initialize CB for SATA completion.
8558285809Sscottl     */
8559285809Sscottl    satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8560285809Sscottl  }
8561285809Sscottl
8562285809Sscottl
8563285809Sscottl  /*
8564285809Sscottl   * Prepare SGL and send FIS to LL layer.
8565285809Sscottl   */
8566285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
8567285809Sscottl
8568285809Sscottl  status = smsataLLIOStart( smRoot,
8569285809Sscottl                            smIORequest,
8570285809Sscottl                            smDeviceHandle,
8571285809Sscottl                            smScsiRequest,
8572285809Sscottl                            satIOContext);
8573285809Sscottl  return (status);
8574285809Sscottl}
8575285809Sscottl
8576285809SscottlosGLOBAL bit32
8577285809SscottlsmsatTestUnitReady(
8578285809Sscottl                   smRoot_t                  *smRoot,
8579285809Sscottl                   smIORequest_t             *smIORequest,
8580285809Sscottl                   smDeviceHandle_t          *smDeviceHandle,
8581285809Sscottl                   smScsiInitiatorRequest_t  *smScsiRequest,
8582285809Sscottl                   smSatIOContext_t            *satIOContext
8583285809Sscottl                  )
8584285809Sscottl{
8585285809Sscottl  bit32                     status;
8586285809Sscottl  bit32                     agRequestType;
8587285809Sscottl  smDeviceData_t            *pSatDevData;
8588285809Sscottl  smScsiRspSense_t          *pSense;
8589285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
8590285809Sscottl  agsaFisRegHostToDevice_t  *fis;
8591285809Sscottl
8592285809Sscottl  pSense        = satIOContext->pSense;
8593285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
8594285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
8595285809Sscottl  fis           = satIOContext->pFis;
8596285809Sscottl
8597285809Sscottl  SM_DBG5(("smsatTestUnitReady: start\n"));
8598285809Sscottl
8599285809Sscottl  /* checking CONTROL */
8600285809Sscottl  /* NACA == 1 or LINK == 1*/
8601285809Sscottl  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8602285809Sscottl  {
8603285809Sscottl    smsatSetSensePayload( pSense,
8604285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8605285809Sscottl                          0,
8606285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8607285809Sscottl                          satIOContext);
8608285809Sscottl
8609285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8610285809Sscottl
8611285809Sscottl    tdsmIOCompletedCB( smRoot,
8612285809Sscottl                       smIORequest,
8613285809Sscottl                       smIOSuccess,
8614285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
8615285809Sscottl                       satIOContext->pSmSenseData,
8616285809Sscottl                       satIOContext->interruptContext );
8617285809Sscottl
8618285809Sscottl    SM_DBG1(("smsatTestUnitReady: return control!!!\n"));
8619285809Sscottl    return SM_RC_SUCCESS;
8620285809Sscottl  }
8621285809Sscottl
8622285809Sscottl  /* SAT revision 8, 8.11.2, p42*/
8623285809Sscottl  if (pSatDevData->satStopState == agTRUE)
8624285809Sscottl  {
8625285809Sscottl    smsatSetSensePayload( pSense,
8626285809Sscottl                          SCSI_SNSKEY_NOT_READY,
8627285809Sscottl                          0,
8628285809Sscottl                          SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
8629285809Sscottl                          satIOContext);
8630285809Sscottl
8631285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8632285809Sscottl
8633285809Sscottl    tdsmIOCompletedCB( smRoot,
8634285809Sscottl                       smIORequest,
8635285809Sscottl                       smIOSuccess,
8636285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
8637285809Sscottl                       satIOContext->pSmSenseData,
8638285809Sscottl                       satIOContext->interruptContext );
8639285809Sscottl    SM_DBG1(("smsatTestUnitReady: stop state!!!\n"));
8640285809Sscottl    return SM_RC_SUCCESS;
8641285809Sscottl  }
8642285809Sscottl
8643285809Sscottl  /*
8644285809Sscottl   * Check if format is in progress
8645285809Sscottl   */
8646285809Sscottl  if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
8647285809Sscottl  {
8648285809Sscottl    SM_DBG1(("smsatTestUnitReady: FORMAT_IN_PROGRESS!!!\n"));
8649285809Sscottl
8650285809Sscottl    smsatSetSensePayload( pSense,
8651285809Sscottl                          SCSI_SNSKEY_NOT_READY,
8652285809Sscottl                          0,
8653285809Sscottl                          SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
8654285809Sscottl                          satIOContext);
8655285809Sscottl
8656285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8657285809Sscottl
8658285809Sscottl    tdsmIOCompletedCB( smRoot,
8659285809Sscottl                       smIORequest,
8660285809Sscottl                       smIOSuccess,
8661285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
8662285809Sscottl                       satIOContext->pSmSenseData,
8663285809Sscottl                       satIOContext->interruptContext );
8664285809Sscottl    SM_DBG1(("smsatTestUnitReady: format in progress!!!\n"));
8665285809Sscottl    return SM_RC_SUCCESS;
8666285809Sscottl  }
8667285809Sscottl
8668285809Sscottl  /*
8669285809Sscottl    check previously issued ATA command
8670285809Sscottl  */
8671285809Sscottl  if (pSatDevData->satPendingIO != 0)
8672285809Sscottl  {
8673285809Sscottl    if (pSatDevData->satDeviceFaultState == agTRUE)
8674285809Sscottl    {
8675285809Sscottl      smsatSetSensePayload( pSense,
8676285809Sscottl                            SCSI_SNSKEY_HARDWARE_ERROR,
8677285809Sscottl                            0,
8678285809Sscottl                            SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
8679285809Sscottl                            satIOContext);
8680285809Sscottl
8681285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
8682285809Sscottl
8683285809Sscottl      tdsmIOCompletedCB( smRoot,
8684285809Sscottl                         smIORequest,
8685285809Sscottl                         smIOSuccess,
8686285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
8687285809Sscottl                         satIOContext->pSmSenseData,
8688285809Sscottl                         satIOContext->interruptContext );
8689285809Sscottl      SM_DBG1(("smsatTestUnitReady: previous command ended in error!!!\n"));
8690285809Sscottl      return SM_RC_SUCCESS;
8691285809Sscottl    }
8692285809Sscottl  }
8693285809Sscottl
8694285809Sscottl  /*
8695285809Sscottl    check removalbe media feature set
8696285809Sscottl   */
8697285809Sscottl  if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
8698285809Sscottl  {
8699285809Sscottl    SM_DBG5(("smsatTestUnitReady: sending get media status cmnd\n"));
8700285809Sscottl    /* send GET MEDIA STATUS command */
8701285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
8702285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8703285809Sscottl    fis->h.command        = SAT_GET_MEDIA_STATUS;   /* 0xDA */
8704285809Sscottl    fis->h.features       = 0;                      /* FIS features NA       */
8705285809Sscottl    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
8706285809Sscottl    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
8707285809Sscottl    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
8708285809Sscottl    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
8709285809Sscottl    fis->d.lbaLowExp      = 0;
8710285809Sscottl    fis->d.lbaMidExp      = 0;
8711285809Sscottl    fis->d.lbaHighExp     = 0;
8712285809Sscottl    fis->d.featuresExp    = 0;
8713285809Sscottl    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
8714285809Sscottl    fis->d.sectorCountExp = 0;
8715285809Sscottl    fis->d.reserved4      = 0;
8716285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
8717285809Sscottl    fis->d.reserved5      = 0;
8718285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8719285809Sscottl
8720285809Sscottl    /* Initialize CB for SATA completion.
8721285809Sscottl     */
8722285809Sscottl    satIOContext->satCompleteCB = &smsatTestUnitReadyCB;
8723285809Sscottl
8724285809Sscottl    /*
8725285809Sscottl     * Prepare SGL and send FIS to LL layer.
8726285809Sscottl     */
8727285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
8728285809Sscottl
8729285809Sscottl    status = smsataLLIOStart( smRoot,
8730285809Sscottl                              smIORequest,
8731285809Sscottl                              smDeviceHandle,
8732285809Sscottl                              smScsiRequest,
8733285809Sscottl                              satIOContext);
8734285809Sscottl
8735285809Sscottl    return (status);
8736285809Sscottl  }
8737285809Sscottl  /*
8738285809Sscottl    number 6) in SAT p42
8739285809Sscottl    send ATA CHECK POWER MODE
8740285809Sscottl  */
8741285809Sscottl   SM_DBG5(("smsatTestUnitReady: sending check power mode cmnd\n"));
8742285809Sscottl   status = smsatTestUnitReady_1( smRoot,
8743285809Sscottl                                  smIORequest,
8744285809Sscottl                                  smDeviceHandle,
8745285809Sscottl                                  smScsiRequest,
8746285809Sscottl                                  satIOContext);
8747285809Sscottl   return (status);
8748285809Sscottl}
8749285809Sscottl
8750285809SscottlosGLOBAL bit32
8751285809SscottlsmsatTestUnitReady_1(
8752285809Sscottl                     smRoot_t                  *smRoot,
8753285809Sscottl                     smIORequest_t             *smIORequest,
8754285809Sscottl                     smDeviceHandle_t          *smDeviceHandle,
8755285809Sscottl                     smScsiInitiatorRequest_t  *smScsiRequest,
8756285809Sscottl                     smSatIOContext_t            *satIOContext
8757285809Sscottl                    )
8758285809Sscottl{
8759285809Sscottl  /*
8760285809Sscottl    sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY
8761285809Sscottl    internally generated - no directly corresponding scsi
8762285809Sscottl    called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42
8763285809Sscottl  */
8764285809Sscottl  bit32                     status;
8765285809Sscottl  bit32                     agRequestType;
8766285809Sscottl  agsaFisRegHostToDevice_t  *fis;
8767285809Sscottl
8768285809Sscottl  fis           = satIOContext->pFis;
8769285809Sscottl  SM_DBG5(("smsatTestUnitReady_1: start\n"));
8770285809Sscottl  /*
8771285809Sscottl   * Send the ATA CHECK POWER MODE command.
8772285809Sscottl   */
8773285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
8774285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8775285809Sscottl  fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
8776285809Sscottl  fis->h.features       = 0;
8777285809Sscottl  fis->d.lbaLow         = 0;
8778285809Sscottl  fis->d.lbaMid         = 0;
8779285809Sscottl  fis->d.lbaHigh        = 0;
8780285809Sscottl  fis->d.device         = 0;
8781285809Sscottl  fis->d.lbaLowExp      = 0;
8782285809Sscottl  fis->d.lbaMidExp      = 0;
8783285809Sscottl  fis->d.lbaHighExp     = 0;
8784285809Sscottl  fis->d.featuresExp    = 0;
8785285809Sscottl  fis->d.sectorCount    = 0;
8786285809Sscottl  fis->d.sectorCountExp = 0;
8787285809Sscottl  fis->d.reserved4      = 0;
8788285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
8789285809Sscottl  fis->d.reserved5      = 0;
8790285809Sscottl
8791285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8792285809Sscottl
8793285809Sscottl  /* Initialize CB for SATA completion.
8794285809Sscottl   */
8795285809Sscottl  satIOContext->satCompleteCB = &smsatTestUnitReadyCB;
8796285809Sscottl
8797285809Sscottl  /*
8798285809Sscottl   * Prepare SGL and send FIS to LL layer.
8799285809Sscottl   */
8800285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
8801285809Sscottl
8802285809Sscottl  status = smsataLLIOStart( smRoot,
8803285809Sscottl                            smIORequest,
8804285809Sscottl                            smDeviceHandle,
8805285809Sscottl                            smScsiRequest,
8806285809Sscottl                            satIOContext);
8807285809Sscottl
8808285809Sscottl  SM_DBG5(("smsatTestUnitReady_1: return\n"));
8809285809Sscottl
8810285809Sscottl  return status;
8811285809Sscottl}
8812285809Sscottl
8813285809SscottlosGLOBAL bit32
8814285809SscottlsmsatInquiry(
8815285809Sscottl             smRoot_t                  *smRoot,
8816285809Sscottl             smIORequest_t             *smIORequest,
8817285809Sscottl             smDeviceHandle_t          *smDeviceHandle,
8818285809Sscottl             smScsiInitiatorRequest_t  *smScsiRequest,
8819285809Sscottl             smSatIOContext_t            *satIOContext
8820285809Sscottl            )
8821285809Sscottl{
8822285809Sscottl  /*
8823285809Sscottl    CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8
8824285809Sscottl  */
8825285809Sscottl  smScsiRspSense_t          *pSense;
8826285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
8827285809Sscottl  smDeviceData_t            *pSatDevData;
8828285809Sscottl  bit32                      status;
8829285809Sscottl
8830285809Sscottl  pSense      = satIOContext->pSense;
8831285809Sscottl  scsiCmnd    = &smScsiRequest->scsiCmnd;
8832285809Sscottl  pSatDevData = satIOContext->pSatDevData;
8833285809Sscottl  SM_DBG5(("smsatInquiry: start\n"));
8834285809Sscottl  SM_DBG5(("smsatInquiry: pSatDevData did %d\n", pSatDevData->id));
8835285809Sscottl  //smhexdump("smsatInquiry", (bit8 *)scsiCmnd->cdb, 6);
8836285809Sscottl  /* checking CONTROL */
8837285809Sscottl  /* NACA == 1 or LINK == 1*/
8838285809Sscottl  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8839285809Sscottl  {
8840285809Sscottl    smsatSetSensePayload( pSense,
8841285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8842285809Sscottl                          0,
8843285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8844285809Sscottl                          satIOContext);
8845285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8846285809Sscottl    tdsmIOCompletedCB( smRoot,
8847285809Sscottl                       smIORequest,
8848285809Sscottl                       smIOSuccess,
8849285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
8850285809Sscottl                       satIOContext->pSmSenseData,
8851285809Sscottl                       satIOContext->interruptContext );
8852285809Sscottl    SM_DBG1(("smsatInquiry: return control!!!\n"));
8853285809Sscottl    return SM_RC_SUCCESS;
8854285809Sscottl  }
8855285809Sscottl
8856285809Sscottl  /* checking EVPD and Allocation Length */
8857285809Sscottl  /* SPC-4 spec 6.4 p141 */
8858285809Sscottl  /* EVPD bit == 0 && PAGE CODE != 0 */
8859285809Sscottl  if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
8860285809Sscottl       (scsiCmnd->cdb[2] != 0)
8861285809Sscottl       )
8862285809Sscottl  {
8863285809Sscottl    smsatSetSensePayload( pSense,
8864285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8865285809Sscottl                          0,
8866285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8867285809Sscottl                          satIOContext);
8868285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8869285809Sscottl    tdsmIOCompletedCB( smRoot,
8870285809Sscottl                       smIORequest,
8871285809Sscottl                       smIOSuccess,
8872285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
8873285809Sscottl                       satIOContext->pSmSenseData,
8874285809Sscottl                       satIOContext->interruptContext );
8875285809Sscottl    SM_DBG1(("smsatInquiry: return EVPD and PAGE CODE!!!\n"));
8876285809Sscottl    return SM_RC_SUCCESS;
8877285809Sscottl  }
8878285809Sscottl  SM_DBG6(("smsatInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4]));
8879285809Sscottl  /* convert OS IO to TD internal IO */
8880285809Sscottl  if ( pSatDevData->IDDeviceValid == agFALSE)
8881285809Sscottl  {
8882285809Sscottl    status = smsatStartIDDev(
8883285809Sscottl                             smRoot,
8884285809Sscottl                             smIORequest,
8885285809Sscottl                             smDeviceHandle,
8886285809Sscottl                             smScsiRequest,
8887285809Sscottl                             satIOContext
8888285809Sscottl                            );
8889285809Sscottl    SM_DBG6(("smsatInquiry: end status %d\n", status));
8890285809Sscottl    return status;
8891285809Sscottl  }
8892285809Sscottl  else
8893285809Sscottl  {
8894285809Sscottl    SM_DBG6(("smsatInquiry: calling satInquiryIntCB\n"));
8895285809Sscottl    smsatInquiryIntCB(
8896285809Sscottl                      smRoot,
8897285809Sscottl                      smIORequest,
8898285809Sscottl                      smDeviceHandle,
8899285809Sscottl                      smScsiRequest,
8900285809Sscottl                      satIOContext
8901285809Sscottl                     );
8902285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8903285809Sscottl    return SM_RC_SUCCESS;
8904285809Sscottl  }
8905285809Sscottl}
8906285809Sscottl
8907285809Sscottl
8908285809SscottlosGLOBAL bit32
8909285809SscottlsmsatStartIDDev(
8910285809Sscottl                smRoot_t                  *smRoot,
8911285809Sscottl                smIORequest_t             *smIORequest,
8912285809Sscottl                smDeviceHandle_t          *smDeviceHandle,
8913285809Sscottl                smScsiInitiatorRequest_t  *smScsiRequest,
8914285809Sscottl                smSatIOContext_t            *satIOContext
8915285809Sscottl               )
8916285809Sscottl{
8917285809Sscottl  smSatInternalIo_t        *satIntIo = agNULL;
8918285809Sscottl  smDeviceData_t           *satDevData = agNULL;
8919285809Sscottl  smIORequestBody_t        *smIORequestBody;
8920285809Sscottl  smSatIOContext_t         *satNewIOContext;
8921285809Sscottl  bit32                     status;
8922285809Sscottl
8923285809Sscottl  SM_DBG5(("smsatStartIDDev: start\n"));
8924285809Sscottl
8925285809Sscottl  satDevData = satIOContext->pSatDevData;
8926285809Sscottl
8927285809Sscottl  SM_DBG6(("smsatStartIDDev: before alloc\n"));
8928285809Sscottl
8929285809Sscottl  /* allocate identify device command */
8930285809Sscottl  satIntIo = smsatAllocIntIoResource( smRoot,
8931285809Sscottl                                      smIORequest,
8932285809Sscottl                                      satDevData,
8933285809Sscottl                                      sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
8934285809Sscottl                                      satIntIo);
8935285809Sscottl
8936285809Sscottl  SM_DBG6(("smsatStartIDDev: before after\n"));
8937285809Sscottl
8938285809Sscottl  if (satIntIo == agNULL)
8939285809Sscottl  {
8940285809Sscottl    SM_DBG1(("smsatStartIDDev: can't alloacate!!!\n"));
8941285809Sscottl
8942285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8943285809Sscottl
8944285809Sscottl    return SM_RC_FAILURE;
8945285809Sscottl  }
8946285809Sscottl
8947285809Sscottl  satIntIo->satOrgSmIORequest = smIORequest; /* changed */
8948285809Sscottl  smIORequestBody = satIntIo->satIntRequestBody;
8949285809Sscottl  satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext);
8950285809Sscottl
8951285809Sscottl  satNewIOContext->pSatDevData   = satDevData;
8952285809Sscottl  satNewIOContext->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
8953285809Sscottl  satNewIOContext->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
8954285809Sscottl  satNewIOContext->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
8955285809Sscottl  satNewIOContext->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
8956285809Sscottl  satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */
8957285809Sscottl  satNewIOContext->interruptContext = tiInterruptContext;
8958285809Sscottl  satNewIOContext->satIntIoContext  = satIntIo;
8959285809Sscottl
8960285809Sscottl  satNewIOContext->psmDeviceHandle = agNULL;
8961285809Sscottl  satNewIOContext->satOrgIOContext = satIOContext; /* changed */
8962285809Sscottl
8963285809Sscottl  /* this is valid only for TD layer generated (not triggered by OS at all) IO */
8964285809Sscottl  satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg);
8965285809Sscottl
8966285809Sscottl
8967285809Sscottl  SM_DBG6(("smsatStartIDDev: OS satIOContext %p \n", satIOContext));
8968285809Sscottl  SM_DBG6(("smsatStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
8969285809Sscottl  SM_DBG6(("smsatStartIDDev: OS tiScsiXchg %p \n", satIOContext->smScsiXchg));
8970285809Sscottl  SM_DBG6(("smsatStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->smScsiXchg));
8971285809Sscottl
8972285809Sscottl
8973285809Sscottl
8974285809Sscottl  SM_DBG1(("smsatStartIDDev: satNewIOContext %p smIORequestBody %p!!!\n", satNewIOContext, smIORequestBody));
8975285809Sscottl
8976285809Sscottl  status = smsatSendIDDev( smRoot,
8977285809Sscottl                           &satIntIo->satIntSmIORequest, /* New smIORequest */
8978285809Sscottl                           smDeviceHandle,
8979285809Sscottl                           satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
8980285809Sscottl                           satNewIOContext);
8981285809Sscottl
8982285809Sscottl  if (status != SM_RC_SUCCESS)
8983285809Sscottl  {
8984285809Sscottl    SM_DBG1(("smsatStartIDDev: failed in sending!!!\n"));
8985285809Sscottl
8986285809Sscottl    smsatFreeIntIoResource( smRoot,
8987285809Sscottl                            satDevData,
8988285809Sscottl                            satIntIo);
8989285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
8990285809Sscottl
8991285809Sscottl    return SM_RC_FAILURE;
8992285809Sscottl  }
8993285809Sscottl
8994285809Sscottl
8995285809Sscottl  SM_DBG6(("smsatStartIDDev: end\n"));
8996285809Sscottl
8997285809Sscottl  return status;
8998285809Sscottl}
8999285809Sscottl
9000285809SscottlosGLOBAL bit32
9001285809SscottlsmsatSendIDDev(
9002285809Sscottl                smRoot_t                  *smRoot,
9003285809Sscottl                smIORequest_t             *smIORequest,
9004285809Sscottl                smDeviceHandle_t          *smDeviceHandle,
9005285809Sscottl                smScsiInitiatorRequest_t  *smScsiRequest,
9006285809Sscottl                smSatIOContext_t            *satIOContext
9007285809Sscottl               )
9008285809Sscottl{
9009285809Sscottl  bit32                     status;
9010285809Sscottl  bit32                     agRequestType;
9011285809Sscottl  smDeviceData_t           *pSatDevData;
9012285809Sscottl  agsaFisRegHostToDevice_t *fis;
9013285809Sscottl#ifdef SM_INTERNAL_DEBUG
9014285809Sscottl  smIORequestBody_t        *smIORequestBody;
9015285809Sscottl  smSatInternalIo_t        *satIntIoContext;
9016285809Sscottl#endif
9017285809Sscottl
9018285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
9019285809Sscottl  fis           = satIOContext->pFis;
9020285809Sscottl  SM_DBG6(("smsatSendIDDev: start\n"));
9021285809Sscottl  SM_DBG6(("smsatSendIDDev: did %d\n", pSatDevData->id));
9022285809Sscottl#ifdef SM_INTERNAL_DEBUG
9023285809Sscottl  satIntIoContext = satIOContext->satIntIoContext;
9024285809Sscottl  smIORequestBody = satIntIoContext->satIntRequestBody;
9025285809Sscottl#endif
9026285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
9027285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9028285809Sscottl  if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
9029285809Sscottl      fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
9030285809Sscottl  else
9031285809Sscottl      fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
9032285809Sscottl  fis->h.features       = 0;                      /* FIS reserve */
9033285809Sscottl  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9034285809Sscottl  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9035285809Sscottl  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9036285809Sscottl  fis->d.device         = 0;                      /* FIS LBA mode  */
9037285809Sscottl  fis->d.lbaLowExp      = 0;
9038285809Sscottl  fis->d.lbaMidExp      = 0;
9039285809Sscottl  fis->d.lbaHighExp     = 0;
9040285809Sscottl  fis->d.featuresExp    = 0;
9041285809Sscottl  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9042285809Sscottl  fis->d.sectorCountExp = 0;
9043285809Sscottl  fis->d.reserved4      = 0;
9044285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
9045285809Sscottl  fis->d.reserved5      = 0;
9046285809Sscottl
9047285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
9048285809Sscottl
9049285809Sscottl  /* Initialize CB for SATA completion.
9050285809Sscottl   */
9051285809Sscottl  satIOContext->satCompleteCB = &smsatInquiryCB;
9052285809Sscottl
9053285809Sscottl  /*
9054285809Sscottl   * Prepare SGL and send FIS to LL layer.
9055285809Sscottl   */
9056285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
9057285809Sscottl
9058285809Sscottl#ifdef SM_INTERNAL_DEBUG
9059285809Sscottl  smhexdump("smsatSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
9060285809Sscottl  smhexdump("smsatSendIDDev LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
9061285809Sscottl#endif
9062285809Sscottl  status = smsataLLIOStart( smRoot,
9063285809Sscottl                            smIORequest,
9064285809Sscottl                            smDeviceHandle,
9065285809Sscottl                            smScsiRequest,
9066285809Sscottl                            satIOContext);
9067285809Sscottl
9068285809Sscottl  SM_DBG6(("smsatSendIDDev: end status %d\n", status));
9069285809Sscottl  return status;
9070285809Sscottl}
9071285809Sscottl
9072285809SscottlosGLOBAL bit32
9073285809SscottlsmsatRequestSense(
9074285809Sscottl                  smRoot_t                  *smRoot,
9075285809Sscottl                  smIORequest_t             *smIORequest,
9076285809Sscottl                  smDeviceHandle_t          *smDeviceHandle,
9077285809Sscottl                  smScsiInitiatorRequest_t  *smScsiRequest,
9078285809Sscottl                  smSatIOContext_t            *satIOContext
9079285809Sscottl                 )
9080285809Sscottl{
9081285809Sscottl  /*
9082285809Sscottl    SAT Rev 8 p38, Table25
9083285809Sscottl    sending SMART RETURN STATUS
9084285809Sscottl    Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB()
9085285809Sscottl    Only fixed format sense data is support. In other words, we don't support DESC bit is set
9086285809Sscottl    in Request Sense
9087285809Sscottl   */
9088285809Sscottl  bit32                     status;
9089285809Sscottl  bit32                     agRequestType;
9090285809Sscottl  smScsiRspSense_t          *pSense;
9091285809Sscottl  smDeviceData_t            *pSatDevData;
9092285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
9093285809Sscottl  agsaFisRegHostToDevice_t  *fis;
9094285809Sscottl  smIORequestBody_t         *smIORequestBody;
9095285809Sscottl  smSatInternalIo_t           *satIntIo = agNULL;
9096285809Sscottl  smSatIOContext_t            *satIOContext2;
9097285809Sscottl  bit8                      *pDataBuffer = agNULL;
9098285809Sscottl  bit32                     allocationLen = 0;
9099285809Sscottl
9100285809Sscottl  pSense            = satIOContext->pSense;
9101285809Sscottl  pSatDevData       = satIOContext->pSatDevData;
9102285809Sscottl  scsiCmnd          = &smScsiRequest->scsiCmnd;
9103285809Sscottl  fis               = satIOContext->pFis;
9104285809Sscottl  pDataBuffer       = (bit8 *) smScsiRequest->sglVirtualAddr;
9105285809Sscottl  allocationLen     = scsiCmnd->cdb[4];
9106285809Sscottl  allocationLen     = MIN(allocationLen, scsiCmnd->expDataLength);
9107285809Sscottl  SM_DBG5(("smsatRequestSense: start\n"));
9108285809Sscottl
9109285809Sscottl  /* checking CONTROL */
9110285809Sscottl  /* NACA == 1 or LINK == 1*/
9111285809Sscottl  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9112285809Sscottl  {
9113285809Sscottl    smsatSetSensePayload( pSense,
9114285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9115285809Sscottl                          0,
9116285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9117285809Sscottl                          satIOContext);
9118285809Sscottl    sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9119285809Sscottl
9120285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
9121285809Sscottl
9122285809Sscottl    tdsmIOCompletedCB( smRoot,
9123285809Sscottl                       smIORequest,
9124285809Sscottl                       smIOSuccess,
9125285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
9126285809Sscottl                       satIOContext->pSmSenseData,
9127285809Sscottl                       satIOContext->interruptContext );
9128285809Sscottl
9129285809Sscottl    SM_DBG1(("smsatRequestSense: return control!!!\n"));
9130285809Sscottl    return SM_RC_SUCCESS;
9131285809Sscottl  }
9132285809Sscottl
9133285809Sscottl  /*
9134285809Sscottl    Only fixed format sense data is support. In other words, we don't support DESC bit is set
9135285809Sscottl    in Request Sense
9136285809Sscottl   */
9137285809Sscottl  if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
9138285809Sscottl  {
9139285809Sscottl    smsatSetSensePayload( pSense,
9140285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9141285809Sscottl                          0,
9142285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9143285809Sscottl                          satIOContext);
9144285809Sscottl    sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9145285809Sscottl
9146285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
9147285809Sscottl
9148285809Sscottl    tdsmIOCompletedCB( smRoot,
9149285809Sscottl                       smIORequest,
9150285809Sscottl                       smIOSuccess,
9151285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
9152285809Sscottl                       satIOContext->pSmSenseData,
9153285809Sscottl                       satIOContext->interruptContext );
9154285809Sscottl
9155285809Sscottl    SM_DBG1(("smsatRequestSense: DESC bit is set, which we don't support!!!\n"));
9156285809Sscottl    return SM_RC_SUCCESS;
9157285809Sscottl  }
9158285809Sscottl
9159285809Sscottl
9160285809Sscottl  if (pSatDevData->satSMARTEnabled == agTRUE)
9161285809Sscottl  {
9162285809Sscottl    /* sends SMART RETURN STATUS */
9163285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
9164285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9165285809Sscottl
9166285809Sscottl    fis->h.command        = SAT_SMART;               /* 0xB0 */
9167285809Sscottl    fis->h.features       = SAT_SMART_RETURN_STATUS; /* FIS features */
9168285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
9169285809Sscottl    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9170285809Sscottl    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9171285809Sscottl    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9172285809Sscottl    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9173285809Sscottl    fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
9174285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9175285809Sscottl    fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
9176285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9177285809Sscottl    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
9178285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
9179285809Sscottl    fis->d.reserved4      = 0;
9180285809Sscottl    fis->d.reserved5      = 0;
9181285809Sscottl
9182285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9183285809Sscottl    /* Initialize CB for SATA completion.
9184285809Sscottl     */
9185285809Sscottl    satIOContext->satCompleteCB = &smsatRequestSenseCB;
9186285809Sscottl
9187285809Sscottl    /*
9188285809Sscottl     * Prepare SGL and send FIS to LL layer.
9189285809Sscottl     */
9190285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
9191285809Sscottl
9192285809Sscottl    status = smsataLLIOStart( smRoot,
9193285809Sscottl                              smIORequest,
9194285809Sscottl                              smDeviceHandle,
9195285809Sscottl                              smScsiRequest,
9196285809Sscottl                              satIOContext);
9197285809Sscottl
9198285809Sscottl    SM_DBG4(("smsatRequestSense: if return, status %d\n", status));
9199285809Sscottl    return (status);
9200285809Sscottl  }
9201285809Sscottl  else
9202285809Sscottl  {
9203285809Sscottl    /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE
9204285809Sscottl      then call satRequestSense2 */
9205285809Sscottl
9206285809Sscottl    SM_DBG4(("smsatRequestSense: before satIntIo %p\n", satIntIo));
9207285809Sscottl    /* allocate iocontext */
9208285809Sscottl    satIntIo = smsatAllocIntIoResource( smRoot,
9209285809Sscottl                                        smIORequest, /* original request */
9210285809Sscottl                                        pSatDevData,
9211285809Sscottl                                        smScsiRequest->scsiCmnd.expDataLength,
9212285809Sscottl                                        satIntIo);
9213285809Sscottl
9214285809Sscottl    SM_DBG4(("smsatRequestSense: after satIntIo %p\n", satIntIo));
9215285809Sscottl
9216285809Sscottl    if (satIntIo == agNULL)
9217285809Sscottl    {
9218285809Sscottl      /* failed during sending SMART RETURN STATUS */
9219285809Sscottl      smsatSetSensePayload( pSense,
9220285809Sscottl                            SCSI_SNSKEY_NO_SENSE,
9221285809Sscottl                            0,
9222285809Sscottl                            SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
9223285809Sscottl                            satIOContext);
9224285809Sscottl      sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9225285809Sscottl
9226285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
9227285809Sscottl
9228285809Sscottl      tdsmIOCompletedCB( smRoot,
9229285809Sscottl                         smIORequest,
9230285809Sscottl                         smIOSuccess,
9231285809Sscottl                         SCSI_STAT_GOOD,
9232285809Sscottl                         agNULL,
9233285809Sscottl                         satIOContext->interruptContext );
9234285809Sscottl
9235285809Sscottl      SM_DBG1(("smsatRequestSense: else fail 1!!!\n"));
9236285809Sscottl      return SM_RC_SUCCESS;
9237285809Sscottl    } /* end of memory allocation failure */
9238285809Sscottl
9239285809Sscottl
9240285809Sscottl    /*
9241285809Sscottl     * Need to initialize all the fields within satIOContext except
9242285809Sscottl     * reqType and satCompleteCB which will be set depending on cmd.
9243285809Sscottl     */
9244285809Sscottl
9245285809Sscottl    if (satIntIo == agNULL)
9246285809Sscottl    {
9247285809Sscottl      SM_DBG4(("smsatRequestSense: satIntIo is NULL\n"));
9248285809Sscottl    }
9249285809Sscottl    else
9250285809Sscottl    {
9251285809Sscottl      SM_DBG4(("smsatRequestSense: satIntIo is NOT NULL\n"));
9252285809Sscottl    }
9253285809Sscottl    /* use this --- tttttthe one the same */
9254285809Sscottl
9255285809Sscottl
9256285809Sscottl    satIntIo->satOrgSmIORequest = smIORequest;
9257285809Sscottl    smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
9258285809Sscottl    satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);
9259285809Sscottl
9260285809Sscottl    satIOContext2->pSatDevData   = pSatDevData;
9261285809Sscottl    satIOContext2->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
9262285809Sscottl    satIOContext2->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
9263285809Sscottl    satIOContext2->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
9264285809Sscottl    satIOContext2->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
9265285809Sscottl    satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;
9266285809Sscottl    satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
9267285809Sscottl    satIOContext2->interruptContext = satIOContext->interruptContext;
9268285809Sscottl    satIOContext2->satIntIoContext  = satIntIo;
9269285809Sscottl    satIOContext2->psmDeviceHandle = smDeviceHandle;
9270285809Sscottl    satIOContext2->satOrgIOContext = satIOContext;
9271285809Sscottl
9272285809Sscottl    SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len));
9273285809Sscottl
9274285809Sscottl    SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper));
9275285809Sscottl
9276285809Sscottl    SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower));
9277285809Sscottl
9278285809Sscottl    SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type));
9279285809Sscottl
9280285809Sscottl    status = smsatRequestSense_1( smRoot,
9281285809Sscottl                                  &(satIntIo->satIntSmIORequest),
9282285809Sscottl                                  smDeviceHandle,
9283285809Sscottl                                  &(satIntIo->satIntSmScsiXchg),
9284285809Sscottl                                  satIOContext2);
9285285809Sscottl
9286285809Sscottl    if (status != SM_RC_SUCCESS)
9287285809Sscottl    {
9288285809Sscottl      smsatFreeIntIoResource( smRoot,
9289285809Sscottl                              pSatDevData,
9290285809Sscottl                              satIntIo);
9291285809Sscottl
9292285809Sscottl      /* failed during sending SMART RETURN STATUS */
9293285809Sscottl      smsatSetSensePayload( pSense,
9294285809Sscottl                            SCSI_SNSKEY_NO_SENSE,
9295285809Sscottl                            0,
9296285809Sscottl                            SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
9297285809Sscottl                            satIOContext);
9298285809Sscottl      sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9299285809Sscottl
9300285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
9301285809Sscottl
9302285809Sscottl      tdsmIOCompletedCB( smRoot,
9303285809Sscottl                         smIORequest,
9304285809Sscottl                         smIOSuccess,
9305285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
9306285809Sscottl                         agNULL,
9307285809Sscottl                         satIOContext->interruptContext );
9308285809Sscottl
9309285809Sscottl      SM_DBG1(("smsatRequestSense: else fail 2!!!\n"));
9310285809Sscottl      return SM_RC_SUCCESS;
9311285809Sscottl    }
9312285809Sscottl    SM_DBG4(("smsatRequestSense: else return success\n"));
9313285809Sscottl    return SM_RC_SUCCESS;
9314285809Sscottl  }
9315285809Sscottl}
9316285809Sscottl
9317285809SscottlosGLOBAL bit32
9318285809SscottlsmsatRequestSense_1(
9319285809Sscottl                    smRoot_t                  *smRoot,
9320285809Sscottl                    smIORequest_t             *smIORequest,
9321285809Sscottl                    smDeviceHandle_t          *smDeviceHandle,
9322285809Sscottl                    smScsiInitiatorRequest_t  *smScsiRequest,
9323285809Sscottl                    smSatIOContext_t            *satIOContext
9324285809Sscottl                   )
9325285809Sscottl{
9326285809Sscottl  /*
9327285809Sscottl    sends SAT_CHECK_POWER_MODE
9328285809Sscottl  */
9329285809Sscottl  bit32                     status;
9330285809Sscottl  bit32                     agRequestType;
9331285809Sscottl  agsaFisRegHostToDevice_t  *fis;
9332285809Sscottl
9333285809Sscottl  fis               = satIOContext->pFis;
9334285809Sscottl  SM_DBG5(("smsatRequestSense_1: start\n"));
9335285809Sscottl  /*
9336285809Sscottl   * Send the ATA CHECK POWER MODE command.
9337285809Sscottl   */
9338285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
9339285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9340285809Sscottl  fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
9341285809Sscottl  fis->h.features       = 0;
9342285809Sscottl  fis->d.lbaLow         = 0;
9343285809Sscottl  fis->d.lbaMid         = 0;
9344285809Sscottl  fis->d.lbaHigh        = 0;
9345285809Sscottl  fis->d.device         = 0;
9346285809Sscottl  fis->d.lbaLowExp      = 0;
9347285809Sscottl  fis->d.lbaMidExp      = 0;
9348285809Sscottl  fis->d.lbaHighExp     = 0;
9349285809Sscottl  fis->d.featuresExp    = 0;
9350285809Sscottl  fis->d.sectorCount    = 0;
9351285809Sscottl  fis->d.sectorCountExp = 0;
9352285809Sscottl  fis->d.reserved4      = 0;
9353285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
9354285809Sscottl  fis->d.reserved5      = 0;
9355285809Sscottl
9356285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9357285809Sscottl
9358285809Sscottl  /* Initialize CB for SATA completion.
9359285809Sscottl   */
9360285809Sscottl  satIOContext->satCompleteCB = &smsatRequestSenseCB;
9361285809Sscottl
9362285809Sscottl  /*
9363285809Sscottl   * Prepare SGL and send FIS to LL layer.
9364285809Sscottl   */
9365285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
9366285809Sscottl
9367285809Sscottl
9368285809Sscottl  SM_DBG4(("smsatRequestSense_1: smSgl1.len %d\n", smScsiRequest->smSgl1.len));
9369285809Sscottl
9370285809Sscottl  SM_DBG4(("smsatRequestSense_1: smSgl1.upper %d\n", smScsiRequest->smSgl1.upper));
9371285809Sscottl
9372285809Sscottl  SM_DBG4(("smsatRequestSense_1: smSgl1.lower %d\n", smScsiRequest->smSgl1.lower));
9373285809Sscottl
9374285809Sscottl  SM_DBG4(("smsatRequestSense_1: smSgl1.type %d\n", smScsiRequest->smSgl1.type));
9375285809Sscottl
9376285809Sscottl  //  smhexdump("smsatRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
9377285809Sscottl
9378285809Sscottl  status = smsataLLIOStart( smRoot,
9379285809Sscottl                            smIORequest,
9380285809Sscottl                            smDeviceHandle,
9381285809Sscottl                            smScsiRequest,
9382285809Sscottl                            satIOContext);
9383285809Sscottl
9384285809Sscottl
9385285809Sscottl
9386285809Sscottl  return status;
9387285809Sscottl}
9388285809Sscottl
9389285809SscottlosGLOBAL bit32
9390285809SscottlsmsatModeSense6(
9391285809Sscottl                smRoot_t                  *smRoot,
9392285809Sscottl                smIORequest_t             *smIORequest,
9393285809Sscottl                smDeviceHandle_t          *smDeviceHandle,
9394285809Sscottl                smScsiInitiatorRequest_t  *smScsiRequest,
9395285809Sscottl                smSatIOContext_t            *satIOContext
9396285809Sscottl               )
9397285809Sscottl{
9398285809Sscottl  smScsiRspSense_t        *pSense;
9399285809Sscottl  bit32                   allocationLen;
9400285809Sscottl  smIniScsiCmnd_t         *scsiCmnd;
9401285809Sscottl  bit32                   pageSupported;
9402285809Sscottl  bit8                    page;
9403285809Sscottl  bit8                    *pModeSense;    /* Mode Sense data buffer */
9404285809Sscottl  smDeviceData_t          *pSatDevData;
9405285809Sscottl  bit8                    PC;
9406285809Sscottl  bit8                    AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN];
9407285809Sscottl  bit8                    Control[MODE_SENSE6_CONTROL_PAGE_LEN];
9408285809Sscottl  bit8                    RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN];
9409285809Sscottl  bit8                    Caching[MODE_SENSE6_CACHING_LEN];
9410285809Sscottl  bit8                    InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN];
9411285809Sscottl  bit8                    lenRead = 0;
9412285809Sscottl
9413285809Sscottl
9414285809Sscottl  pSense      = satIOContext->pSense;
9415285809Sscottl  scsiCmnd    = &smScsiRequest->scsiCmnd;
9416285809Sscottl  pModeSense  = (bit8 *) smScsiRequest->sglVirtualAddr;
9417285809Sscottl  pSatDevData = satIOContext->pSatDevData;
9418285809Sscottl
9419285809Sscottl  //smhexdump("smsatModeSense6", (bit8 *)scsiCmnd->cdb, 6);
9420285809Sscottl  SM_DBG5(("smsatModeSense6: start\n"));
9421285809Sscottl  /* checking CONTROL */
9422285809Sscottl  /* NACA == 1 or LINK == 1*/
9423285809Sscottl  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9424285809Sscottl  {
9425285809Sscottl    smsatSetSensePayload( pSense,
9426285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9427285809Sscottl                          0,
9428285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9429285809Sscottl                          satIOContext);
9430285809Sscottl   /*smEnqueueIO(smRoot, satIOContext);*/
9431285809Sscottl   tdsmIOCompletedCB( smRoot,
9432285809Sscottl                       smIORequest,
9433285809Sscottl                       smIOSuccess,
9434285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
9435285809Sscottl                       satIOContext->pSmSenseData,
9436285809Sscottl                       satIOContext->interruptContext );
9437285809Sscottl    SM_DBG1(("smsatModeSense6: return control!!!\n"));
9438285809Sscottl    return SM_RC_SUCCESS;
9439285809Sscottl  }
9440285809Sscottl  /* checking PC(Page Control)
9441285809Sscottl     SAT revion 8, 8.5.3 p33 and 10.1.2, p66
9442285809Sscottl  */
9443285809Sscottl  PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
9444285809Sscottl  if (PC != 0)
9445285809Sscottl  {
9446285809Sscottl    smsatSetSensePayload( pSense,
9447285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9448285809Sscottl                          0,
9449285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9450285809Sscottl                          satIOContext);
9451285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
9452285809Sscottl    tdsmIOCompletedCB( smRoot,
9453285809Sscottl                       smIORequest,
9454285809Sscottl                       smIOSuccess,
9455285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
9456285809Sscottl                       satIOContext->pSmSenseData,
9457285809Sscottl                       satIOContext->interruptContext );
9458285809Sscottl    SM_DBG1(("smsatModeSense6: return due to PC value pc 0x%x!!!\n", PC >> 6));
9459285809Sscottl    return SM_RC_SUCCESS;
9460285809Sscottl  }
9461285809Sscottl  /* reading PAGE CODE */
9462285809Sscottl  page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
9463285809Sscottl
9464285809Sscottl
9465285809Sscottl  SM_DBG5(("smsatModeSense6: page=0x%x\n", page));
9466285809Sscottl
9467285809Sscottl  allocationLen = scsiCmnd->cdb[4];
9468285809Sscottl  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
9469285809Sscottl    /*
9470285809Sscottl    Based on page code value, returns a corresponding mode page
9471285809Sscottl    note: no support for subpage
9472285809Sscottl  */
9473285809Sscottl  switch(page)
9474285809Sscottl  {
9475285809Sscottl    case MODESENSE_RETURN_ALL_PAGES:
9476285809Sscottl    case MODESENSE_CONTROL_PAGE: /* control */
9477285809Sscottl    case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
9478285809Sscottl    case MODESENSE_CACHING: /* caching */
9479285809Sscottl    case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
9480285809Sscottl      pageSupported = agTRUE;
9481285809Sscottl      break;
9482285809Sscottl    case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
9483285809Sscottl    default:
9484285809Sscottl      pageSupported = agFALSE;
9485285809Sscottl      break;
9486285809Sscottl  }
9487285809Sscottl
9488285809Sscottl  if (pageSupported == agFALSE)
9489285809Sscottl  {
9490285809Sscottl
9491285809Sscottl    SM_DBG1(("smsatModeSense6 *** ERROR *** not supported page 0x%x did %d!!!\n",
9492285809Sscottl        page, pSatDevData->id));
9493285809Sscottl
9494285809Sscottl    smsatSetSensePayload( pSense,
9495285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9496285809Sscottl                          0,
9497285809Sscottl                          SCSI_SNSCODE_INVALID_COMMAND,
9498285809Sscottl                          satIOContext);
9499285809Sscottl
9500285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
9501285809Sscottl
9502285809Sscottl    tdsmIOCompletedCB( smRoot,
9503285809Sscottl                       smIORequest,
9504285809Sscottl                       smIOSuccess,
9505285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
9506285809Sscottl                       satIOContext->pSmSenseData,
9507285809Sscottl                       satIOContext->interruptContext );
9508285809Sscottl    return SM_RC_SUCCESS;
9509285809Sscottl  }
9510285809Sscottl
9511285809Sscottl  switch(page)
9512285809Sscottl  {
9513285809Sscottl  case MODESENSE_RETURN_ALL_PAGES:
9514285809Sscottl    lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
9515285809Sscottl    break;
9516285809Sscottl  case MODESENSE_CONTROL_PAGE: /* control */
9517285809Sscottl    lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CONTROL_PAGE_LEN);
9518285809Sscottl    break;
9519285809Sscottl  case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
9520285809Sscottl    lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
9521285809Sscottl    break;
9522285809Sscottl  case MODESENSE_CACHING: /* caching */
9523285809Sscottl    lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CACHING_LEN);
9524285809Sscottl    break;
9525285809Sscottl  case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
9526285809Sscottl    lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
9527285809Sscottl    break;
9528285809Sscottl  default:
9529285809Sscottl    SM_DBG1(("smsatModeSense6: default error page %d!!!\n", page));
9530285809Sscottl    break;
9531285809Sscottl  }
9532285809Sscottl
9533285809Sscottl  if (page == MODESENSE_RETURN_ALL_PAGES)
9534285809Sscottl  {
9535285809Sscottl    SM_DBG5(("smsatModeSense6: MODESENSE_RETURN_ALL_PAGES\n"));
9536285809Sscottl    AllPages[0] = (bit8)(lenRead - 1);
9537285809Sscottl    AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */
9538285809Sscottl    AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9539285809Sscottl    AllPages[3] = 0x08; /* block descriptor length */
9540285809Sscottl
9541285809Sscottl    /*
9542285809Sscottl     * Fill-up direct-access device block-descriptor, SAT, Table 19
9543285809Sscottl     */
9544285809Sscottl
9545285809Sscottl    /* density code */
9546285809Sscottl    AllPages[4]  = 0x04; /* density-code : reserved for direct-access */
9547285809Sscottl    /* number of blocks */
9548285809Sscottl    AllPages[5]  = 0x00; /* unspecified */
9549285809Sscottl    AllPages[6]  = 0x00; /* unspecified */
9550285809Sscottl    AllPages[7]  = 0x00; /* unspecified */
9551285809Sscottl    /* reserved */
9552285809Sscottl    AllPages[8]  = 0x00; /* reserved */
9553285809Sscottl    /* Block size */
9554285809Sscottl    AllPages[9]  = 0x00;
9555285809Sscottl    AllPages[10] = 0x02;   /* Block size is always 512 bytes */
9556285809Sscottl    AllPages[11] = 0x00;
9557285809Sscottl
9558285809Sscottl    /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
9559285809Sscottl    AllPages[12] = 0x01; /* page code */
9560285809Sscottl    AllPages[13] = 0x0A; /* page length */
9561285809Sscottl    AllPages[14] = 0x40; /* ARRE is set */
9562285809Sscottl    AllPages[15] = 0x00;
9563285809Sscottl    AllPages[16] = 0x00;
9564285809Sscottl    AllPages[17] = 0x00;
9565285809Sscottl    AllPages[18] = 0x00;
9566285809Sscottl    AllPages[19] = 0x00;
9567285809Sscottl    AllPages[20] = 0x00;
9568285809Sscottl    AllPages[21] = 0x00;
9569285809Sscottl    AllPages[22] = 0x00;
9570285809Sscottl    AllPages[23] = 0x00;
9571285809Sscottl    /* MODESENSE_CACHING */
9572285809Sscottl    AllPages[24] = 0x08; /* page code */
9573285809Sscottl    AllPages[25] = 0x12; /* page length */
9574285809Sscottl    if (pSatDevData->satWriteCacheEnabled == agTRUE)
9575285809Sscottl    {
9576285809Sscottl      AllPages[26] = 0x04;/* WCE bit is set */
9577285809Sscottl    }
9578285809Sscottl    else
9579285809Sscottl    {
9580285809Sscottl      AllPages[26] = 0x00;/* WCE bit is NOT set */
9581285809Sscottl    }
9582285809Sscottl
9583285809Sscottl    AllPages[27] = 0x00;
9584285809Sscottl    AllPages[28] = 0x00;
9585285809Sscottl    AllPages[29] = 0x00;
9586285809Sscottl    AllPages[30] = 0x00;
9587285809Sscottl    AllPages[31] = 0x00;
9588285809Sscottl    AllPages[32] = 0x00;
9589285809Sscottl    AllPages[33] = 0x00;
9590285809Sscottl    AllPages[34] = 0x00;
9591285809Sscottl    AllPages[35] = 0x00;
9592285809Sscottl    if (pSatDevData->satLookAheadEnabled == agTRUE)
9593285809Sscottl    {
9594285809Sscottl      AllPages[36] = 0x00;/* DRA bit is NOT set */
9595285809Sscottl    }
9596285809Sscottl    else
9597285809Sscottl    {
9598285809Sscottl      AllPages[36] = 0x20;/* DRA bit is set */
9599285809Sscottl    }
9600285809Sscottl    AllPages[37] = 0x00;
9601285809Sscottl    AllPages[38] = 0x00;
9602285809Sscottl    AllPages[39] = 0x00;
9603285809Sscottl    AllPages[40] = 0x00;
9604285809Sscottl    AllPages[41] = 0x00;
9605285809Sscottl    AllPages[42] = 0x00;
9606285809Sscottl    AllPages[43] = 0x00;
9607285809Sscottl    /* MODESENSE_CONTROL_PAGE */
9608285809Sscottl    AllPages[44] = 0x0A; /* page code */
9609285809Sscottl    AllPages[45] = 0x0A; /* page length */
9610285809Sscottl    AllPages[46] = 0x02; /* only GLTSD bit is set */
9611285809Sscottl    if (pSatDevData->satNCQ == agTRUE)
9612285809Sscottl    {
9613285809Sscottl      AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
9614285809Sscottl    }
9615285809Sscottl    else
9616285809Sscottl    {
9617285809Sscottl      AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
9618285809Sscottl    }
9619285809Sscottl    AllPages[48] = 0x00;
9620285809Sscottl    AllPages[49] = 0x00;
9621285809Sscottl    AllPages[50] = 0x00; /* obsolete */
9622285809Sscottl    AllPages[51] = 0x00; /* obsolete */
9623285809Sscottl    AllPages[52] = 0xFF; /* Busy Timeout Period */
9624285809Sscottl    AllPages[53] = 0xFF; /* Busy Timeout Period */
9625285809Sscottl    AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */
9626285809Sscottl    AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */
9627285809Sscottl    /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
9628285809Sscottl    AllPages[56] = 0x1C; /* page code */
9629285809Sscottl    AllPages[57] = 0x0A; /* page length */
9630285809Sscottl    if (pSatDevData->satSMARTEnabled == agTRUE)
9631285809Sscottl    {
9632285809Sscottl      AllPages[58] = 0x00;/* DEXCPT bit is NOT set */
9633285809Sscottl    }
9634285809Sscottl    else
9635285809Sscottl    {
9636285809Sscottl      AllPages[58] = 0x08;/* DEXCPT bit is set */
9637285809Sscottl    }
9638285809Sscottl    AllPages[59] = 0x00; /* We don't support MRIE */
9639285809Sscottl    AllPages[60] = 0x00; /* Interval timer vendor-specific */
9640285809Sscottl    AllPages[61] = 0x00;
9641285809Sscottl    AllPages[62] = 0x00;
9642285809Sscottl    AllPages[63] = 0x00;
9643285809Sscottl    AllPages[64] = 0x00; /* REPORT-COUNT */
9644285809Sscottl    AllPages[65] = 0x00;
9645285809Sscottl    AllPages[66] = 0x00;
9646285809Sscottl    AllPages[67] = 0x00;
9647285809Sscottl
9648285809Sscottl    sm_memcpy(pModeSense, &AllPages, lenRead);
9649285809Sscottl  }
9650285809Sscottl  else if (page == MODESENSE_CONTROL_PAGE)
9651285809Sscottl  {
9652285809Sscottl    SM_DBG5(("smsatModeSense6: MODESENSE_CONTROL_PAGE\n"));
9653285809Sscottl    Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1;
9654285809Sscottl    Control[1] = 0x00; /* default medium type (currently mounted medium type) */
9655285809Sscottl    Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9656285809Sscottl    Control[3] = 0x08; /* block descriptor length */
9657285809Sscottl    /*
9658285809Sscottl     * Fill-up direct-access device block-descriptor, SAT, Table 19
9659285809Sscottl     */
9660285809Sscottl
9661285809Sscottl    /* density code */
9662285809Sscottl    Control[4]  = 0x04; /* density-code : reserved for direct-access */
9663285809Sscottl    /* number of blocks */
9664285809Sscottl    Control[5]  = 0x00; /* unspecified */
9665285809Sscottl    Control[6]  = 0x00; /* unspecified */
9666285809Sscottl    Control[7]  = 0x00; /* unspecified */
9667285809Sscottl    /* reserved */
9668285809Sscottl    Control[8]  = 0x00; /* reserved */
9669285809Sscottl    /* Block size */
9670285809Sscottl    Control[9]  = 0x00;
9671285809Sscottl    Control[10] = 0x02;   /* Block size is always 512 bytes */
9672285809Sscottl    Control[11] = 0x00;
9673285809Sscottl    /*
9674285809Sscottl     * Fill-up control mode page, SAT, Table 65
9675285809Sscottl     */
9676285809Sscottl    Control[12] = 0x0A; /* page code */
9677285809Sscottl    Control[13] = 0x0A; /* page length */
9678285809Sscottl    Control[14] = 0x02; /* only GLTSD bit is set */
9679285809Sscottl    if (pSatDevData->satNCQ == agTRUE)
9680285809Sscottl    {
9681285809Sscottl      Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
9682285809Sscottl    }
9683285809Sscottl    else
9684285809Sscottl    {
9685285809Sscottl      Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
9686285809Sscottl    }
9687285809Sscottl    Control[16] = 0x00;
9688285809Sscottl    Control[17] = 0x00;
9689285809Sscottl    Control[18] = 0x00; /* obsolete */
9690285809Sscottl    Control[19] = 0x00; /* obsolete */
9691285809Sscottl    Control[20] = 0xFF; /* Busy Timeout Period */
9692285809Sscottl    Control[21] = 0xFF; /* Busy Timeout Period */
9693285809Sscottl    Control[22] = 0x00; /* we don't support non-000b value for the self-test code */
9694285809Sscottl    Control[23] = 0x00; /* we don't support non-000b value for the self-test code */
9695285809Sscottl
9696285809Sscottl    sm_memcpy(pModeSense, &Control, lenRead);
9697285809Sscottl
9698285809Sscottl  }
9699285809Sscottl  else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
9700285809Sscottl  {
9701285809Sscottl    SM_DBG5(("smsatModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
9702285809Sscottl    RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1;
9703285809Sscottl    RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */
9704285809Sscottl    RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9705285809Sscottl    RWErrorRecovery[3] = 0x08; /* block descriptor length */
9706285809Sscottl    /*
9707285809Sscottl     * Fill-up direct-access device block-descriptor, SAT, Table 19
9708285809Sscottl     */
9709285809Sscottl
9710285809Sscottl    /* density code */
9711285809Sscottl    RWErrorRecovery[4]  = 0x04; /* density-code : reserved for direct-access */
9712285809Sscottl    /* number of blocks */
9713285809Sscottl    RWErrorRecovery[5]  = 0x00; /* unspecified */
9714285809Sscottl    RWErrorRecovery[6]  = 0x00; /* unspecified */
9715285809Sscottl    RWErrorRecovery[7]  = 0x00; /* unspecified */
9716285809Sscottl    /* reserved */
9717285809Sscottl    RWErrorRecovery[8]  = 0x00; /* reserved */
9718285809Sscottl    /* Block size */
9719285809Sscottl    RWErrorRecovery[9]  = 0x00;
9720285809Sscottl    RWErrorRecovery[10] = 0x02;   /* Block size is always 512 bytes */
9721285809Sscottl    RWErrorRecovery[11] = 0x00;
9722285809Sscottl    /*
9723285809Sscottl     * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
9724285809Sscottl     */
9725285809Sscottl    RWErrorRecovery[12] = 0x01; /* page code */
9726285809Sscottl    RWErrorRecovery[13] = 0x0A; /* page length */
9727285809Sscottl    RWErrorRecovery[14] = 0x40; /* ARRE is set */
9728285809Sscottl    RWErrorRecovery[15] = 0x00;
9729285809Sscottl    RWErrorRecovery[16] = 0x00;
9730285809Sscottl    RWErrorRecovery[17] = 0x00;
9731285809Sscottl    RWErrorRecovery[18] = 0x00;
9732285809Sscottl    RWErrorRecovery[19] = 0x00;
9733285809Sscottl    RWErrorRecovery[20] = 0x00;
9734285809Sscottl    RWErrorRecovery[21] = 0x00;
9735285809Sscottl    RWErrorRecovery[22] = 0x00;
9736285809Sscottl    RWErrorRecovery[23] = 0x00;
9737285809Sscottl
9738285809Sscottl    sm_memcpy(pModeSense, &RWErrorRecovery, lenRead);
9739285809Sscottl
9740285809Sscottl  }
9741285809Sscottl  else if (page == MODESENSE_CACHING)
9742285809Sscottl  {
9743285809Sscottl    SM_DBG5(("smsatModeSense6: MODESENSE_CACHING\n"));
9744285809Sscottl    /* special case */
9745285809Sscottl    if (allocationLen == 4 && page == MODESENSE_CACHING)
9746285809Sscottl    {
9747285809Sscottl      SM_DBG5(("smsatModeSense6: linux 2.6.8.24 support\n"));
9748285809Sscottl
9749285809Sscottl      Caching[0] = 0x20 - 1; /* 32 - 1 */
9750285809Sscottl      Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
9751285809Sscottl      Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9752285809Sscottl      Caching[3] = 0x08; /* block descriptor length */
9753285809Sscottl
9754285809Sscottl      sm_memcpy(pModeSense, &Caching, 4);
9755285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
9756285809Sscottl
9757285809Sscottl      tdsmIOCompletedCB( smRoot,
9758285809Sscottl                         smIORequest,
9759285809Sscottl                         smIOSuccess,
9760285809Sscottl                         SCSI_STAT_GOOD,
9761285809Sscottl                         agNULL,
9762285809Sscottl                         satIOContext->interruptContext);
9763285809Sscottl      return SM_RC_SUCCESS;
9764285809Sscottl    }
9765285809Sscottl    Caching[0] = MODE_SENSE6_CACHING_LEN - 1;
9766285809Sscottl    Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
9767285809Sscottl    Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9768285809Sscottl    Caching[3] = 0x08; /* block descriptor length */
9769285809Sscottl    /*
9770285809Sscottl     * Fill-up direct-access device block-descriptor, SAT, Table 19
9771285809Sscottl     */
9772285809Sscottl
9773285809Sscottl    /* density code */
9774285809Sscottl    Caching[4]  = 0x04; /* density-code : reserved for direct-access */
9775285809Sscottl    /* number of blocks */
9776285809Sscottl    Caching[5]  = 0x00; /* unspecified */
9777285809Sscottl    Caching[6]  = 0x00; /* unspecified */
9778285809Sscottl    Caching[7]  = 0x00; /* unspecified */
9779285809Sscottl    /* reserved */
9780285809Sscottl    Caching[8]  = 0x00; /* reserved */
9781285809Sscottl    /* Block size */
9782285809Sscottl    Caching[9]  = 0x00;
9783285809Sscottl    Caching[10] = 0x02;   /* Block size is always 512 bytes */
9784285809Sscottl    Caching[11] = 0x00;
9785285809Sscottl    /*
9786285809Sscottl     * Fill-up Caching mode page, SAT, Table 67
9787285809Sscottl     */
9788285809Sscottl    /* length 20 */
9789285809Sscottl    Caching[12] = 0x08; /* page code */
9790285809Sscottl    Caching[13] = 0x12; /* page length */
9791285809Sscottl    if (pSatDevData->satWriteCacheEnabled == agTRUE)
9792285809Sscottl    {
9793285809Sscottl      Caching[14] = 0x04;/* WCE bit is set */
9794285809Sscottl    }
9795285809Sscottl    else
9796285809Sscottl    {
9797285809Sscottl      Caching[14] = 0x00;/* WCE bit is NOT set */
9798285809Sscottl    }
9799285809Sscottl
9800285809Sscottl    Caching[15] = 0x00;
9801285809Sscottl    Caching[16] = 0x00;
9802285809Sscottl    Caching[17] = 0x00;
9803285809Sscottl    Caching[18] = 0x00;
9804285809Sscottl    Caching[19] = 0x00;
9805285809Sscottl    Caching[20] = 0x00;
9806285809Sscottl    Caching[21] = 0x00;
9807285809Sscottl    Caching[22] = 0x00;
9808285809Sscottl    Caching[23] = 0x00;
9809285809Sscottl    if (pSatDevData->satLookAheadEnabled == agTRUE)
9810285809Sscottl    {
9811285809Sscottl      Caching[24] = 0x00;/* DRA bit is NOT set */
9812285809Sscottl    }
9813285809Sscottl    else
9814285809Sscottl    {
9815285809Sscottl      Caching[24] = 0x20;/* DRA bit is set */
9816285809Sscottl    }
9817285809Sscottl    Caching[25] = 0x00;
9818285809Sscottl    Caching[26] = 0x00;
9819285809Sscottl    Caching[27] = 0x00;
9820285809Sscottl    Caching[28] = 0x00;
9821285809Sscottl    Caching[29] = 0x00;
9822285809Sscottl    Caching[30] = 0x00;
9823285809Sscottl    Caching[31] = 0x00;
9824285809Sscottl
9825285809Sscottl    sm_memcpy(pModeSense, &Caching, lenRead);
9826285809Sscottl
9827285809Sscottl  }
9828285809Sscottl  else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
9829285809Sscottl  {
9830285809Sscottl    SM_DBG5(("smsatModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
9831285809Sscottl    InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1;
9832285809Sscottl    InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */
9833285809Sscottl    InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9834285809Sscottl    InfoExceptionCtrl[3] = 0x08; /* block descriptor length */
9835285809Sscottl    /*
9836285809Sscottl     * Fill-up direct-access device block-descriptor, SAT, Table 19
9837285809Sscottl     */
9838285809Sscottl
9839285809Sscottl    /* density code */
9840285809Sscottl    InfoExceptionCtrl[4]  = 0x04; /* density-code : reserved for direct-access */
9841285809Sscottl    /* number of blocks */
9842285809Sscottl    InfoExceptionCtrl[5]  = 0x00; /* unspecified */
9843285809Sscottl    InfoExceptionCtrl[6]  = 0x00; /* unspecified */
9844285809Sscottl    InfoExceptionCtrl[7]  = 0x00; /* unspecified */
9845285809Sscottl    /* reserved */
9846285809Sscottl    InfoExceptionCtrl[8]  = 0x00; /* reserved */
9847285809Sscottl    /* Block size */
9848285809Sscottl    InfoExceptionCtrl[9]  = 0x00;
9849285809Sscottl    InfoExceptionCtrl[10] = 0x02;   /* Block size is always 512 bytes */
9850285809Sscottl    InfoExceptionCtrl[11] = 0x00;
9851285809Sscottl    /*
9852285809Sscottl     * Fill-up informational-exceptions control mode page, SAT, Table 68
9853285809Sscottl     */
9854285809Sscottl    InfoExceptionCtrl[12] = 0x1C; /* page code */
9855285809Sscottl    InfoExceptionCtrl[13] = 0x0A; /* page length */
9856285809Sscottl     if (pSatDevData->satSMARTEnabled == agTRUE)
9857285809Sscottl    {
9858285809Sscottl      InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */
9859285809Sscottl    }
9860285809Sscottl    else
9861285809Sscottl    {
9862285809Sscottl      InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */
9863285809Sscottl    }
9864285809Sscottl    InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */
9865285809Sscottl    InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */
9866285809Sscottl    InfoExceptionCtrl[17] = 0x00;
9867285809Sscottl    InfoExceptionCtrl[18] = 0x00;
9868285809Sscottl    InfoExceptionCtrl[19] = 0x00;
9869285809Sscottl    InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */
9870285809Sscottl    InfoExceptionCtrl[21] = 0x00;
9871285809Sscottl    InfoExceptionCtrl[22] = 0x00;
9872285809Sscottl    InfoExceptionCtrl[23] = 0x00;
9873285809Sscottl    sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
9874285809Sscottl
9875285809Sscottl  }
9876285809Sscottl  else
9877285809Sscottl  {
9878285809Sscottl    /* Error */
9879285809Sscottl    SM_DBG1(("smsatModeSense6: Error page %d!!!\n", page));
9880285809Sscottl    smsatSetSensePayload( pSense,
9881285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9882285809Sscottl                          0,
9883285809Sscottl                          SCSI_SNSCODE_INVALID_COMMAND,
9884285809Sscottl                          satIOContext);
9885285809Sscottl
9886285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
9887285809Sscottl
9888285809Sscottl    tdsmIOCompletedCB( smRoot,
9889285809Sscottl                       smIORequest,
9890285809Sscottl                       smIOSuccess,
9891285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
9892285809Sscottl                       satIOContext->pSmSenseData,
9893285809Sscottl                       satIOContext->interruptContext );
9894285809Sscottl    return SM_RC_SUCCESS;
9895285809Sscottl  }
9896285809Sscottl
9897285809Sscottl  /* there can be only underrun not overrun in error case */
9898285809Sscottl  if (allocationLen > lenRead)
9899285809Sscottl  {
9900285809Sscottl    SM_DBG6(("smsatModeSense6 reporting underrun lenRead=0x%x allocationLen=0x%x\n", lenRead, allocationLen));
9901285809Sscottl
9902285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
9903285809Sscottl
9904285809Sscottl    tdsmIOCompletedCB( smRoot,
9905285809Sscottl                       smIORequest,
9906285809Sscottl                       smIOUnderRun,
9907285809Sscottl                       allocationLen - lenRead,
9908285809Sscottl                       agNULL,
9909285809Sscottl                       satIOContext->interruptContext );
9910285809Sscottl
9911285809Sscottl
9912285809Sscottl  }
9913285809Sscottl  else
9914285809Sscottl  {
9915285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
9916285809Sscottl
9917285809Sscottl    tdsmIOCompletedCB( smRoot,
9918285809Sscottl                       smIORequest,
9919285809Sscottl                       smIOSuccess,
9920285809Sscottl                       SCSI_STAT_GOOD,
9921285809Sscottl                       agNULL,
9922285809Sscottl                       satIOContext->interruptContext);
9923285809Sscottl  }
9924285809Sscottl
9925285809Sscottl  return SM_RC_SUCCESS;
9926285809Sscottl
9927285809Sscottl}
9928285809Sscottl
9929285809SscottlosGLOBAL bit32
9930285809SscottlsmsatModeSense10(
9931285809Sscottl                  smRoot_t                  *smRoot,
9932285809Sscottl                  smIORequest_t             *smIORequest,
9933285809Sscottl                  smDeviceHandle_t          *smDeviceHandle,
9934285809Sscottl                  smScsiInitiatorRequest_t  *smScsiRequest,
9935285809Sscottl                  smSatIOContext_t            *satIOContext
9936285809Sscottl                 )
9937285809Sscottl{
9938285809Sscottl  smScsiRspSense_t        *pSense;
9939285809Sscottl  bit32                   allocationLen;
9940285809Sscottl  smIniScsiCmnd_t         *scsiCmnd;
9941285809Sscottl  bit32                   pageSupported;
9942285809Sscottl  bit8                    page;
9943285809Sscottl  bit8                    *pModeSense;    /* Mode Sense data buffer */
9944285809Sscottl  smDeviceData_t          *pSatDevData;
9945285809Sscottl  bit8                    PC; /* page control */
9946285809Sscottl  bit8                    LLBAA; /* Long LBA Accepted */
9947285809Sscottl  bit32                   index;
9948285809Sscottl  bit8                    AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN];
9949285809Sscottl  bit8                    Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN];
9950285809Sscottl  bit8                    RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN];
9951285809Sscottl  bit8                    Caching[MODE_SENSE10_CACHING_LLBAA_LEN];
9952285809Sscottl  bit8                    InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN];
9953285809Sscottl  bit8                    lenRead = 0;
9954285809Sscottl
9955285809Sscottl  pSense      = satIOContext->pSense;
9956285809Sscottl  scsiCmnd    = &smScsiRequest->scsiCmnd;
9957285809Sscottl  pModeSense  = (bit8 *) smScsiRequest->sglVirtualAddr;
9958285809Sscottl  pSatDevData = satIOContext->pSatDevData;
9959285809Sscottl  SM_DBG5(("smsatModeSense10: start\n"));
9960285809Sscottl  /* checking CONTROL */
9961285809Sscottl  /* NACA == 1 or LINK == 1*/
9962285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
9963285809Sscottl  {
9964285809Sscottl    smsatSetSensePayload( pSense,
9965285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9966285809Sscottl                          0,
9967285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9968285809Sscottl                          satIOContext);
9969285809Sscottl
9970285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
9971285809Sscottl
9972285809Sscottl    tdsmIOCompletedCB( smRoot,
9973285809Sscottl                       smIORequest,
9974285809Sscottl                       smIOSuccess,
9975285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
9976285809Sscottl                       satIOContext->pSmSenseData,
9977285809Sscottl                       satIOContext->interruptContext );
9978285809Sscottl
9979285809Sscottl    SM_DBG1(("smsatModeSense10: return control!!!\n"));
9980285809Sscottl    return SM_RC_SUCCESS;
9981285809Sscottl  }
9982285809Sscottl
9983285809Sscottl  /* checking PC(Page Control)
9984285809Sscottl     SAT revion 8, 8.5.3 p33 and 10.1.2, p66
9985285809Sscottl  */
9986285809Sscottl  PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
9987285809Sscottl  if (PC != 0)
9988285809Sscottl  {
9989285809Sscottl    smsatSetSensePayload( pSense,
9990285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9991285809Sscottl                          0,
9992285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9993285809Sscottl                          satIOContext);
9994285809Sscottl
9995285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
9996285809Sscottl
9997285809Sscottl    tdsmIOCompletedCB( smRoot,
9998285809Sscottl                       smIORequest,
9999285809Sscottl                       smIOSuccess,
10000285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
10001285809Sscottl                       satIOContext->pSmSenseData,
10002285809Sscottl                       satIOContext->interruptContext );
10003285809Sscottl
10004285809Sscottl    SM_DBG1(("smsatModeSense10: return due to PC value pc 0x%x!!!\n", PC));
10005285809Sscottl    return SM_RC_SUCCESS;
10006285809Sscottl  }
10007285809Sscottl
10008285809Sscottl  /* finding LLBAA bit */
10009285809Sscottl  LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
10010285809Sscottl
10011285809Sscottl  /* reading PAGE CODE */
10012285809Sscottl  page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
10013285809Sscottl  SM_DBG5(("smsatModeSense10: page=0x%x, did %d\n", page, pSatDevData->id));
10014285809Sscottl  allocationLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
10015285809Sscottl  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
10016285809Sscottl
10017285809Sscottl  /*
10018285809Sscottl    Based on page code value, returns a corresponding mode page
10019285809Sscottl    note: no support for subpage
10020285809Sscottl  */
10021285809Sscottl  switch(page)
10022285809Sscottl  {
10023285809Sscottl    case MODESENSE_RETURN_ALL_PAGES: /* return all pages */
10024285809Sscottl    case MODESENSE_CONTROL_PAGE: /* control */
10025285809Sscottl    case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
10026285809Sscottl    case MODESENSE_CACHING: /* caching */
10027285809Sscottl    case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
10028285809Sscottl      pageSupported = agTRUE;
10029285809Sscottl      break;
10030285809Sscottl    case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
10031285809Sscottl    default:
10032285809Sscottl      pageSupported = agFALSE;
10033285809Sscottl      break;
10034285809Sscottl  }
10035285809Sscottl  if (pageSupported == agFALSE)
10036285809Sscottl  {
10037285809Sscottl    SM_DBG1(("smsatModeSense10 *** ERROR *** not supported page 0x%x did %d!!!\n", page, pSatDevData->id));
10038285809Sscottl
10039285809Sscottl    smsatSetSensePayload( pSense,
10040285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10041285809Sscottl                          0,
10042285809Sscottl                          SCSI_SNSCODE_INVALID_COMMAND,
10043285809Sscottl                          satIOContext);
10044285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
10045285809Sscottl    tdsmIOCompletedCB( smRoot,
10046285809Sscottl                       smIORequest,
10047285809Sscottl                       smIOSuccess,
10048285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
10049285809Sscottl                       satIOContext->pSmSenseData,
10050285809Sscottl                       satIOContext->interruptContext );
10051285809Sscottl    return SM_RC_SUCCESS;
10052285809Sscottl  }
10053285809Sscottl  switch(page)
10054285809Sscottl  {
10055285809Sscottl  case MODESENSE_RETURN_ALL_PAGES:
10056285809Sscottl    if (LLBAA)
10057285809Sscottl    {
10058285809Sscottl      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
10059285809Sscottl    }
10060285809Sscottl    else
10061285809Sscottl    {
10062285809Sscottl      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
10063285809Sscottl    }
10064285809Sscottl    break;
10065285809Sscottl  case MODESENSE_CONTROL_PAGE: /* control */
10066285809Sscottl    if (LLBAA)
10067285809Sscottl    {
10068285809Sscottl      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
10069285809Sscottl    }
10070285809Sscottl    else
10071285809Sscottl    {
10072285809Sscottl      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LEN);
10073285809Sscottl    }
10074285809Sscottl    break;
10075285809Sscottl  case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
10076285809Sscottl    if (LLBAA)
10077285809Sscottl    {
10078285809Sscottl      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
10079285809Sscottl    }
10080285809Sscottl    else
10081285809Sscottl    {
10082285809Sscottl      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
10083285809Sscottl    }
10084285809Sscottl    break;
10085285809Sscottl  case MODESENSE_CACHING: /* caching */
10086285809Sscottl    if (LLBAA)
10087285809Sscottl    {
10088285809Sscottl      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LLBAA_LEN);
10089285809Sscottl    }
10090285809Sscottl    else
10091285809Sscottl    {
10092285809Sscottl      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LEN);
10093285809Sscottl    }
10094285809Sscottl    break;
10095285809Sscottl  case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
10096285809Sscottl    if (LLBAA)
10097285809Sscottl    {
10098285809Sscottl      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
10099285809Sscottl    }
10100285809Sscottl    else
10101285809Sscottl    {
10102285809Sscottl      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
10103285809Sscottl    }
10104285809Sscottl    break;
10105285809Sscottl  default:
10106285809Sscottl    SM_DBG1(("smsatModeSense10: default error page %d!!!\n", page));
10107285809Sscottl    break;
10108285809Sscottl  }
10109285809Sscottl
10110285809Sscottl  if (page == MODESENSE_RETURN_ALL_PAGES)
10111285809Sscottl  {
10112285809Sscottl    SM_DBG5(("smsatModeSense10: MODESENSE_RETURN_ALL_PAGES\n"));
10113285809Sscottl    AllPages[0] = 0;
10114285809Sscottl    AllPages[1] = (bit8)(lenRead - 2);
10115285809Sscottl    AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10116285809Sscottl    AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10117285809Sscottl    if (LLBAA)
10118285809Sscottl    {
10119285809Sscottl      AllPages[4] = 0x00; /* reserved and LONGLBA */
10120285809Sscottl      AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */
10121285809Sscottl    }
10122285809Sscottl    else
10123285809Sscottl    {
10124285809Sscottl      AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10125285809Sscottl    }
10126285809Sscottl    AllPages[5] = 0x00; /* reserved */
10127285809Sscottl    AllPages[6] = 0x00; /* block descriptot length */
10128285809Sscottl    if (LLBAA)
10129285809Sscottl    {
10130285809Sscottl      AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10131285809Sscottl    }
10132285809Sscottl    else
10133285809Sscottl    {
10134285809Sscottl      AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10135285809Sscottl    }
10136285809Sscottl
10137285809Sscottl    /*
10138285809Sscottl     * Fill-up direct-access device block-descriptor, SAT, Table 19
10139285809Sscottl     */
10140285809Sscottl
10141285809Sscottl    if (LLBAA)
10142285809Sscottl    {
10143285809Sscottl      /* density code */
10144285809Sscottl      AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
10145285809Sscottl      /* number of blocks */
10146285809Sscottl      AllPages[9]   = 0x00; /* unspecified */
10147285809Sscottl      AllPages[10]  = 0x00; /* unspecified */
10148285809Sscottl      AllPages[11]  = 0x00; /* unspecified */
10149285809Sscottl      AllPages[12]  = 0x00; /* unspecified */
10150285809Sscottl      AllPages[13]  = 0x00; /* unspecified */
10151285809Sscottl      AllPages[14]  = 0x00; /* unspecified */
10152285809Sscottl      AllPages[15]  = 0x00; /* unspecified */
10153285809Sscottl      /* reserved */
10154285809Sscottl      AllPages[16]  = 0x00; /* reserved */
10155285809Sscottl      AllPages[17]  = 0x00; /* reserved */
10156285809Sscottl      AllPages[18]  = 0x00; /* reserved */
10157285809Sscottl      AllPages[19]  = 0x00; /* reserved */
10158285809Sscottl      /* Block size */
10159285809Sscottl      AllPages[20]  = 0x00;
10160285809Sscottl      AllPages[21]  = 0x00;
10161285809Sscottl      AllPages[22]  = 0x02;   /* Block size is always 512 bytes */
10162285809Sscottl      AllPages[23]  = 0x00;
10163285809Sscottl    }
10164285809Sscottl    else
10165285809Sscottl    {
10166285809Sscottl      /* density code */
10167285809Sscottl      AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
10168285809Sscottl      /* number of blocks */
10169285809Sscottl      AllPages[9]   = 0x00; /* unspecified */
10170285809Sscottl      AllPages[10]  = 0x00; /* unspecified */
10171285809Sscottl      AllPages[11]  = 0x00; /* unspecified */
10172285809Sscottl      /* reserved */
10173285809Sscottl      AllPages[12]  = 0x00; /* reserved */
10174285809Sscottl      /* Block size */
10175285809Sscottl      AllPages[13]  = 0x00;
10176285809Sscottl      AllPages[14]  = 0x02;   /* Block size is always 512 bytes */
10177285809Sscottl      AllPages[15]  = 0x00;
10178285809Sscottl    }
10179285809Sscottl
10180285809Sscottl    if (LLBAA)
10181285809Sscottl    {
10182285809Sscottl      index = 24;
10183285809Sscottl    }
10184285809Sscottl    else
10185285809Sscottl    {
10186285809Sscottl      index = 16;
10187285809Sscottl    }
10188285809Sscottl    /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
10189285809Sscottl    AllPages[index+0] = 0x01; /* page code */
10190285809Sscottl    AllPages[index+1] = 0x0A; /* page length */
10191285809Sscottl    AllPages[index+2] = 0x40; /* ARRE is set */
10192285809Sscottl    AllPages[index+3] = 0x00;
10193285809Sscottl    AllPages[index+4] = 0x00;
10194285809Sscottl    AllPages[index+5] = 0x00;
10195285809Sscottl    AllPages[index+6] = 0x00;
10196285809Sscottl    AllPages[index+7] = 0x00;
10197285809Sscottl    AllPages[index+8] = 0x00;
10198285809Sscottl    AllPages[index+9] = 0x00;
10199285809Sscottl    AllPages[index+10] = 0x00;
10200285809Sscottl    AllPages[index+11] = 0x00;
10201285809Sscottl
10202285809Sscottl    /* MODESENSE_CACHING */
10203285809Sscottl    /*
10204285809Sscottl     * Fill-up Caching mode page, SAT, Table 67
10205285809Sscottl     */
10206285809Sscottl    /* length 20 */
10207285809Sscottl    AllPages[index+12] = 0x08; /* page code */
10208285809Sscottl    AllPages[index+13] = 0x12; /* page length */
10209285809Sscottl    if (pSatDevData->satWriteCacheEnabled == agTRUE)
10210285809Sscottl    {
10211285809Sscottl      AllPages[index+14] = 0x04;/* WCE bit is set */
10212285809Sscottl    }
10213285809Sscottl    else
10214285809Sscottl    {
10215285809Sscottl      AllPages[index+14] = 0x00;/* WCE bit is NOT set */
10216285809Sscottl    }
10217285809Sscottl
10218285809Sscottl    AllPages[index+15] = 0x00;
10219285809Sscottl    AllPages[index+16] = 0x00;
10220285809Sscottl    AllPages[index+17] = 0x00;
10221285809Sscottl    AllPages[index+18] = 0x00;
10222285809Sscottl    AllPages[index+19] = 0x00;
10223285809Sscottl    AllPages[index+20] = 0x00;
10224285809Sscottl    AllPages[index+21] = 0x00;
10225285809Sscottl    AllPages[index+22] = 0x00;
10226285809Sscottl    AllPages[index+23] = 0x00;
10227285809Sscottl    if (pSatDevData->satLookAheadEnabled == agTRUE)
10228285809Sscottl    {
10229285809Sscottl      AllPages[index+24] = 0x00;/* DRA bit is NOT set */
10230285809Sscottl    }
10231285809Sscottl    else
10232285809Sscottl    {
10233285809Sscottl      AllPages[index+24] = 0x20;/* DRA bit is set */
10234285809Sscottl    }
10235285809Sscottl    AllPages[index+25] = 0x00;
10236285809Sscottl    AllPages[index+26] = 0x00;
10237285809Sscottl    AllPages[index+27] = 0x00;
10238285809Sscottl    AllPages[index+28] = 0x00;
10239285809Sscottl    AllPages[index+29] = 0x00;
10240285809Sscottl    AllPages[index+30] = 0x00;
10241285809Sscottl    AllPages[index+31] = 0x00;
10242285809Sscottl
10243285809Sscottl    /* MODESENSE_CONTROL_PAGE */
10244285809Sscottl    /*
10245285809Sscottl     * Fill-up control mode page, SAT, Table 65
10246285809Sscottl     */
10247285809Sscottl    AllPages[index+32] = 0x0A; /* page code */
10248285809Sscottl    AllPages[index+33] = 0x0A; /* page length */
10249285809Sscottl    AllPages[index+34] = 0x02; /* only GLTSD bit is set */
10250285809Sscottl    if (pSatDevData->satNCQ == agTRUE)
10251285809Sscottl    {
10252285809Sscottl      AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
10253285809Sscottl    }
10254285809Sscottl    else
10255285809Sscottl    {
10256285809Sscottl      AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
10257285809Sscottl    }
10258285809Sscottl    AllPages[index+36] = 0x00;
10259285809Sscottl    AllPages[index+37] = 0x00;
10260285809Sscottl    AllPages[index+38] = 0x00; /* obsolete */
10261285809Sscottl    AllPages[index+39] = 0x00; /* obsolete */
10262285809Sscottl    AllPages[index+40] = 0xFF; /* Busy Timeout Period */
10263285809Sscottl    AllPages[index+41] = 0xFF; /* Busy Timeout Period */
10264285809Sscottl    AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */
10265285809Sscottl    AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */
10266285809Sscottl
10267285809Sscottl    /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
10268285809Sscottl    /*
10269285809Sscottl     * Fill-up informational-exceptions control mode page, SAT, Table 68
10270285809Sscottl     */
10271285809Sscottl    AllPages[index+44] = 0x1C; /* page code */
10272285809Sscottl    AllPages[index+45] = 0x0A; /* page length */
10273285809Sscottl     if (pSatDevData->satSMARTEnabled == agTRUE)
10274285809Sscottl    {
10275285809Sscottl      AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */
10276285809Sscottl    }
10277285809Sscottl    else
10278285809Sscottl    {
10279285809Sscottl      AllPages[index+46] = 0x08;/* DEXCPT bit is set */
10280285809Sscottl    }
10281285809Sscottl    AllPages[index+47] = 0x00; /* We don't support MRIE */
10282285809Sscottl    AllPages[index+48] = 0x00; /* Interval timer vendor-specific */
10283285809Sscottl    AllPages[index+49] = 0x00;
10284285809Sscottl    AllPages[index+50] = 0x00;
10285285809Sscottl    AllPages[index+51] = 0x00;
10286285809Sscottl    AllPages[index+52] = 0x00; /* REPORT-COUNT */
10287285809Sscottl    AllPages[index+53] = 0x00;
10288285809Sscottl    AllPages[index+54] = 0x00;
10289285809Sscottl    AllPages[index+55] = 0x00;
10290285809Sscottl
10291285809Sscottl    sm_memcpy(pModeSense, &AllPages, lenRead);
10292285809Sscottl  }
10293285809Sscottl  else if (page == MODESENSE_CONTROL_PAGE)
10294285809Sscottl  {
10295285809Sscottl    SM_DBG5(("smsatModeSense10: MODESENSE_CONTROL_PAGE\n"));
10296285809Sscottl    Control[0] = 0;
10297285809Sscottl    Control[1] = (bit8)(lenRead - 2);
10298285809Sscottl    Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10299285809Sscottl    Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10300285809Sscottl    if (LLBAA)
10301285809Sscottl    {
10302285809Sscottl      Control[4] = 0x00; /* reserved and LONGLBA */
10303285809Sscottl      Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */
10304285809Sscottl    }
10305285809Sscottl    else
10306285809Sscottl    {
10307285809Sscottl      Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10308285809Sscottl    }
10309285809Sscottl    Control[5] = 0x00; /* reserved */
10310285809Sscottl    Control[6] = 0x00; /* block descriptot length */
10311285809Sscottl    if (LLBAA)
10312285809Sscottl    {
10313285809Sscottl      Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10314285809Sscottl    }
10315285809Sscottl    else
10316285809Sscottl    {
10317285809Sscottl      Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10318285809Sscottl    }
10319285809Sscottl
10320285809Sscottl    /*
10321285809Sscottl     * Fill-up direct-access device block-descriptor, SAT, Table 19
10322285809Sscottl     */
10323285809Sscottl
10324285809Sscottl    if (LLBAA)
10325285809Sscottl    {
10326285809Sscottl      /* density code */
10327285809Sscottl      Control[8]   = 0x04; /* density-code : reserved for direct-access */
10328285809Sscottl      /* number of blocks */
10329285809Sscottl      Control[9]   = 0x00; /* unspecified */
10330285809Sscottl      Control[10]  = 0x00; /* unspecified */
10331285809Sscottl      Control[11]  = 0x00; /* unspecified */
10332285809Sscottl      Control[12]  = 0x00; /* unspecified */
10333285809Sscottl      Control[13]  = 0x00; /* unspecified */
10334285809Sscottl      Control[14]  = 0x00; /* unspecified */
10335285809Sscottl      Control[15]  = 0x00; /* unspecified */
10336285809Sscottl      /* reserved */
10337285809Sscottl      Control[16]  = 0x00; /* reserved */
10338285809Sscottl      Control[17]  = 0x00; /* reserved */
10339285809Sscottl      Control[18]  = 0x00; /* reserved */
10340285809Sscottl      Control[19]  = 0x00; /* reserved */
10341285809Sscottl      /* Block size */
10342285809Sscottl      Control[20]  = 0x00;
10343285809Sscottl      Control[21]  = 0x00;
10344285809Sscottl      Control[22]  = 0x02;   /* Block size is always 512 bytes */
10345285809Sscottl      Control[23]  = 0x00;
10346285809Sscottl    }
10347285809Sscottl    else
10348285809Sscottl    {
10349285809Sscottl      /* density code */
10350285809Sscottl      Control[8]   = 0x04; /* density-code : reserved for direct-access */
10351285809Sscottl      /* number of blocks */
10352285809Sscottl      Control[9]   = 0x00; /* unspecified */
10353285809Sscottl      Control[10]  = 0x00; /* unspecified */
10354285809Sscottl      Control[11]  = 0x00; /* unspecified */
10355285809Sscottl      /* reserved */
10356285809Sscottl      Control[12]  = 0x00; /* reserved */
10357285809Sscottl      /* Block size */
10358285809Sscottl      Control[13]  = 0x00;
10359285809Sscottl      Control[14]  = 0x02;   /* Block size is always 512 bytes */
10360285809Sscottl      Control[15]  = 0x00;
10361285809Sscottl    }
10362285809Sscottl
10363285809Sscottl    if (LLBAA)
10364285809Sscottl    {
10365285809Sscottl      index = 24;
10366285809Sscottl    }
10367285809Sscottl    else
10368285809Sscottl    {
10369285809Sscottl      index = 16;
10370285809Sscottl    }
10371285809Sscottl    /*
10372285809Sscottl     * Fill-up control mode page, SAT, Table 65
10373285809Sscottl     */
10374285809Sscottl    Control[index+0] = 0x0A; /* page code */
10375285809Sscottl    Control[index+1] = 0x0A; /* page length */
10376285809Sscottl    Control[index+2] = 0x02; /* only GLTSD bit is set */
10377285809Sscottl    if (pSatDevData->satNCQ == agTRUE)
10378285809Sscottl    {
10379285809Sscottl      Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
10380285809Sscottl    }
10381285809Sscottl    else
10382285809Sscottl    {
10383285809Sscottl      Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
10384285809Sscottl    }
10385285809Sscottl    Control[index+4] = 0x00;
10386285809Sscottl    Control[index+5] = 0x00;
10387285809Sscottl    Control[index+6] = 0x00; /* obsolete */
10388285809Sscottl    Control[index+7] = 0x00; /* obsolete */
10389285809Sscottl    Control[index+8] = 0xFF; /* Busy Timeout Period */
10390285809Sscottl    Control[index+9] = 0xFF; /* Busy Timeout Period */
10391285809Sscottl    Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */
10392285809Sscottl    Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */
10393285809Sscottl
10394285809Sscottl    sm_memcpy(pModeSense, &Control, lenRead);
10395285809Sscottl  }
10396285809Sscottl  else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
10397285809Sscottl  {
10398285809Sscottl    SM_DBG5(("smsatModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
10399285809Sscottl    RWErrorRecovery[0] = 0;
10400285809Sscottl    RWErrorRecovery[1] = (bit8)(lenRead - 2);
10401285809Sscottl    RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10402285809Sscottl    RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10403285809Sscottl    if (LLBAA)
10404285809Sscottl    {
10405285809Sscottl      RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */
10406285809Sscottl      RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */
10407285809Sscottl    }
10408285809Sscottl    else
10409285809Sscottl    {
10410285809Sscottl      RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10411285809Sscottl    }
10412285809Sscottl    RWErrorRecovery[5] = 0x00; /* reserved */
10413285809Sscottl    RWErrorRecovery[6] = 0x00; /* block descriptot length */
10414285809Sscottl    if (LLBAA)
10415285809Sscottl    {
10416285809Sscottl      RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10417285809Sscottl    }
10418285809Sscottl    else
10419285809Sscottl    {
10420285809Sscottl      RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10421285809Sscottl    }
10422285809Sscottl
10423285809Sscottl    /*
10424285809Sscottl     * Fill-up direct-access device block-descriptor, SAT, Table 19
10425285809Sscottl     */
10426285809Sscottl
10427285809Sscottl    if (LLBAA)
10428285809Sscottl    {
10429285809Sscottl      /* density code */
10430285809Sscottl      RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
10431285809Sscottl      /* number of blocks */
10432285809Sscottl      RWErrorRecovery[9]   = 0x00; /* unspecified */
10433285809Sscottl      RWErrorRecovery[10]  = 0x00; /* unspecified */
10434285809Sscottl      RWErrorRecovery[11]  = 0x00; /* unspecified */
10435285809Sscottl      RWErrorRecovery[12]  = 0x00; /* unspecified */
10436285809Sscottl      RWErrorRecovery[13]  = 0x00; /* unspecified */
10437285809Sscottl      RWErrorRecovery[14]  = 0x00; /* unspecified */
10438285809Sscottl      RWErrorRecovery[15]  = 0x00; /* unspecified */
10439285809Sscottl      /* reserved */
10440285809Sscottl      RWErrorRecovery[16]  = 0x00; /* reserved */
10441285809Sscottl      RWErrorRecovery[17]  = 0x00; /* reserved */
10442285809Sscottl      RWErrorRecovery[18]  = 0x00; /* reserved */
10443285809Sscottl      RWErrorRecovery[19]  = 0x00; /* reserved */
10444285809Sscottl      /* Block size */
10445285809Sscottl      RWErrorRecovery[20]  = 0x00;
10446285809Sscottl      RWErrorRecovery[21]  = 0x00;
10447285809Sscottl      RWErrorRecovery[22]  = 0x02;   /* Block size is always 512 bytes */
10448285809Sscottl      RWErrorRecovery[23]  = 0x00;
10449285809Sscottl    }
10450285809Sscottl    else
10451285809Sscottl    {
10452285809Sscottl      /* density code */
10453285809Sscottl      RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
10454285809Sscottl      /* number of blocks */
10455285809Sscottl      RWErrorRecovery[9]   = 0x00; /* unspecified */
10456285809Sscottl      RWErrorRecovery[10]  = 0x00; /* unspecified */
10457285809Sscottl      RWErrorRecovery[11]  = 0x00; /* unspecified */
10458285809Sscottl      /* reserved */
10459285809Sscottl      RWErrorRecovery[12]  = 0x00; /* reserved */
10460285809Sscottl      /* Block size */
10461285809Sscottl      RWErrorRecovery[13]  = 0x00;
10462285809Sscottl      RWErrorRecovery[14]  = 0x02;   /* Block size is always 512 bytes */
10463285809Sscottl      RWErrorRecovery[15]  = 0x00;
10464285809Sscottl    }
10465285809Sscottl
10466285809Sscottl    if (LLBAA)
10467285809Sscottl    {
10468285809Sscottl      index = 24;
10469285809Sscottl    }
10470285809Sscottl    else
10471285809Sscottl    {
10472285809Sscottl      index = 16;
10473285809Sscottl    }
10474285809Sscottl    /*
10475285809Sscottl     * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
10476285809Sscottl     */
10477285809Sscottl    RWErrorRecovery[index+0] = 0x01; /* page code */
10478285809Sscottl    RWErrorRecovery[index+1] = 0x0A; /* page length */
10479285809Sscottl    RWErrorRecovery[index+2] = 0x40; /* ARRE is set */
10480285809Sscottl    RWErrorRecovery[index+3] = 0x00;
10481285809Sscottl    RWErrorRecovery[index+4] = 0x00;
10482285809Sscottl    RWErrorRecovery[index+5] = 0x00;
10483285809Sscottl    RWErrorRecovery[index+6] = 0x00;
10484285809Sscottl    RWErrorRecovery[index+7] = 0x00;
10485285809Sscottl    RWErrorRecovery[index+8] = 0x00;
10486285809Sscottl    RWErrorRecovery[index+9] = 0x00;
10487285809Sscottl    RWErrorRecovery[index+10] = 0x00;
10488285809Sscottl    RWErrorRecovery[index+11] = 0x00;
10489285809Sscottl
10490285809Sscottl    sm_memcpy(pModeSense, &RWErrorRecovery, lenRead);
10491285809Sscottl  }
10492285809Sscottl  else if (page == MODESENSE_CACHING)
10493285809Sscottl  {
10494285809Sscottl    SM_DBG5(("smsatModeSense10: MODESENSE_CACHING\n"));
10495285809Sscottl    Caching[0] = 0;
10496285809Sscottl    Caching[1] = (bit8)(lenRead - 2);
10497285809Sscottl    Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10498285809Sscottl    Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10499285809Sscottl    if (LLBAA)
10500285809Sscottl    {
10501285809Sscottl      Caching[4] = 0x00; /* reserved and LONGLBA */
10502285809Sscottl      Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */
10503285809Sscottl    }
10504285809Sscottl    else
10505285809Sscottl    {
10506285809Sscottl      Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10507285809Sscottl    }
10508285809Sscottl    Caching[5] = 0x00; /* reserved */
10509285809Sscottl    Caching[6] = 0x00; /* block descriptot length */
10510285809Sscottl    if (LLBAA)
10511285809Sscottl    {
10512285809Sscottl      Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10513285809Sscottl    }
10514285809Sscottl    else
10515285809Sscottl    {
10516285809Sscottl      Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10517285809Sscottl    }
10518285809Sscottl
10519285809Sscottl    /*
10520285809Sscottl     * Fill-up direct-access device block-descriptor, SAT, Table 19
10521285809Sscottl     */
10522285809Sscottl
10523285809Sscottl    if (LLBAA)
10524285809Sscottl    {
10525285809Sscottl      /* density code */
10526285809Sscottl      Caching[8]   = 0x04; /* density-code : reserved for direct-access */
10527285809Sscottl      /* number of blocks */
10528285809Sscottl      Caching[9]   = 0x00; /* unspecified */
10529285809Sscottl      Caching[10]  = 0x00; /* unspecified */
10530285809Sscottl      Caching[11]  = 0x00; /* unspecified */
10531285809Sscottl      Caching[12]  = 0x00; /* unspecified */
10532285809Sscottl      Caching[13]  = 0x00; /* unspecified */
10533285809Sscottl      Caching[14]  = 0x00; /* unspecified */
10534285809Sscottl      Caching[15]  = 0x00; /* unspecified */
10535285809Sscottl      /* reserved */
10536285809Sscottl      Caching[16]  = 0x00; /* reserved */
10537285809Sscottl      Caching[17]  = 0x00; /* reserved */
10538285809Sscottl      Caching[18]  = 0x00; /* reserved */
10539285809Sscottl      Caching[19]  = 0x00; /* reserved */
10540285809Sscottl      /* Block size */
10541285809Sscottl      Caching[20]  = 0x00;
10542285809Sscottl      Caching[21]  = 0x00;
10543285809Sscottl      Caching[22]  = 0x02;   /* Block size is always 512 bytes */
10544285809Sscottl      Caching[23]  = 0x00;
10545285809Sscottl    }
10546285809Sscottl    else
10547285809Sscottl    {
10548285809Sscottl      /* density code */
10549285809Sscottl      Caching[8]   = 0x04; /* density-code : reserved for direct-access */
10550285809Sscottl      /* number of blocks */
10551285809Sscottl      Caching[9]   = 0x00; /* unspecified */
10552285809Sscottl      Caching[10]  = 0x00; /* unspecified */
10553285809Sscottl      Caching[11]  = 0x00; /* unspecified */
10554285809Sscottl      /* reserved */
10555285809Sscottl      Caching[12]  = 0x00; /* reserved */
10556285809Sscottl      /* Block size */
10557285809Sscottl      Caching[13]  = 0x00;
10558285809Sscottl      Caching[14]  = 0x02;   /* Block size is always 512 bytes */
10559285809Sscottl      Caching[15]  = 0x00;
10560285809Sscottl    }
10561285809Sscottl
10562285809Sscottl    if (LLBAA)
10563285809Sscottl    {
10564285809Sscottl      index = 24;
10565285809Sscottl    }
10566285809Sscottl    else
10567285809Sscottl    {
10568285809Sscottl      index = 16;
10569285809Sscottl    }
10570285809Sscottl    /*
10571285809Sscottl     * Fill-up Caching mode page, SAT, Table 67
10572285809Sscottl     */
10573285809Sscottl    /* length 20 */
10574285809Sscottl    Caching[index+0] = 0x08; /* page code */
10575285809Sscottl    Caching[index+1] = 0x12; /* page length */
10576285809Sscottl    if (pSatDevData->satWriteCacheEnabled == agTRUE)
10577285809Sscottl    {
10578285809Sscottl      Caching[index+2] = 0x04;/* WCE bit is set */
10579285809Sscottl    }
10580285809Sscottl    else
10581285809Sscottl    {
10582285809Sscottl      Caching[index+2] = 0x00;/* WCE bit is NOT set */
10583285809Sscottl    }
10584285809Sscottl
10585285809Sscottl    Caching[index+3] = 0x00;
10586285809Sscottl    Caching[index+4] = 0x00;
10587285809Sscottl    Caching[index+5] = 0x00;
10588285809Sscottl    Caching[index+6] = 0x00;
10589285809Sscottl    Caching[index+7] = 0x00;
10590285809Sscottl    Caching[index+8] = 0x00;
10591285809Sscottl    Caching[index+9] = 0x00;
10592285809Sscottl    Caching[index+10] = 0x00;
10593285809Sscottl    Caching[index+11] = 0x00;
10594285809Sscottl    if (pSatDevData->satLookAheadEnabled == agTRUE)
10595285809Sscottl    {
10596285809Sscottl      Caching[index+12] = 0x00;/* DRA bit is NOT set */
10597285809Sscottl    }
10598285809Sscottl    else
10599285809Sscottl    {
10600285809Sscottl      Caching[index+12] = 0x20;/* DRA bit is set */
10601285809Sscottl    }
10602285809Sscottl    Caching[index+13] = 0x00;
10603285809Sscottl    Caching[index+14] = 0x00;
10604285809Sscottl    Caching[index+15] = 0x00;
10605285809Sscottl    Caching[index+16] = 0x00;
10606285809Sscottl    Caching[index+17] = 0x00;
10607285809Sscottl    Caching[index+18] = 0x00;
10608285809Sscottl    Caching[index+19] = 0x00;
10609285809Sscottl    sm_memcpy(pModeSense, &Caching, lenRead);
10610285809Sscottl
10611285809Sscottl  }
10612285809Sscottl  else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
10613285809Sscottl  {
10614285809Sscottl    SM_DBG5(("smsatModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
10615285809Sscottl    InfoExceptionCtrl[0] = 0;
10616285809Sscottl    InfoExceptionCtrl[1] = (bit8)(lenRead - 2);
10617285809Sscottl    InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10618285809Sscottl    InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10619285809Sscottl    if (LLBAA)
10620285809Sscottl    {
10621285809Sscottl      InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */
10622285809Sscottl      InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */
10623285809Sscottl    }
10624285809Sscottl    else
10625285809Sscottl    {
10626285809Sscottl      InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10627285809Sscottl    }
10628285809Sscottl    InfoExceptionCtrl[5] = 0x00; /* reserved */
10629285809Sscottl    InfoExceptionCtrl[6] = 0x00; /* block descriptot length */
10630285809Sscottl    if (LLBAA)
10631285809Sscottl    {
10632285809Sscottl      InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10633285809Sscottl    }
10634285809Sscottl    else
10635285809Sscottl    {
10636285809Sscottl      InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10637285809Sscottl    }
10638285809Sscottl
10639285809Sscottl    /*
10640285809Sscottl     * Fill-up direct-access device block-descriptor, SAT, Table 19
10641285809Sscottl     */
10642285809Sscottl
10643285809Sscottl    if (LLBAA)
10644285809Sscottl    {
10645285809Sscottl      /* density code */
10646285809Sscottl      InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
10647285809Sscottl      /* number of blocks */
10648285809Sscottl      InfoExceptionCtrl[9]   = 0x00; /* unspecified */
10649285809Sscottl      InfoExceptionCtrl[10]  = 0x00; /* unspecified */
10650285809Sscottl      InfoExceptionCtrl[11]  = 0x00; /* unspecified */
10651285809Sscottl      InfoExceptionCtrl[12]  = 0x00; /* unspecified */
10652285809Sscottl      InfoExceptionCtrl[13]  = 0x00; /* unspecified */
10653285809Sscottl      InfoExceptionCtrl[14]  = 0x00; /* unspecified */
10654285809Sscottl      InfoExceptionCtrl[15]  = 0x00; /* unspecified */
10655285809Sscottl      /* reserved */
10656285809Sscottl      InfoExceptionCtrl[16]  = 0x00; /* reserved */
10657285809Sscottl      InfoExceptionCtrl[17]  = 0x00; /* reserved */
10658285809Sscottl      InfoExceptionCtrl[18]  = 0x00; /* reserved */
10659285809Sscottl      InfoExceptionCtrl[19]  = 0x00; /* reserved */
10660285809Sscottl      /* Block size */
10661285809Sscottl      InfoExceptionCtrl[20]  = 0x00;
10662285809Sscottl      InfoExceptionCtrl[21]  = 0x00;
10663285809Sscottl      InfoExceptionCtrl[22]  = 0x02;   /* Block size is always 512 bytes */
10664285809Sscottl      InfoExceptionCtrl[23]  = 0x00;
10665285809Sscottl    }
10666285809Sscottl    else
10667285809Sscottl    {
10668285809Sscottl      /* density code */
10669285809Sscottl      InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
10670285809Sscottl      /* number of blocks */
10671285809Sscottl      InfoExceptionCtrl[9]   = 0x00; /* unspecified */
10672285809Sscottl      InfoExceptionCtrl[10]  = 0x00; /* unspecified */
10673285809Sscottl      InfoExceptionCtrl[11]  = 0x00; /* unspecified */
10674285809Sscottl      /* reserved */
10675285809Sscottl      InfoExceptionCtrl[12]  = 0x00; /* reserved */
10676285809Sscottl      /* Block size */
10677285809Sscottl      InfoExceptionCtrl[13]  = 0x00;
10678285809Sscottl      InfoExceptionCtrl[14]  = 0x02;   /* Block size is always 512 bytes */
10679285809Sscottl      InfoExceptionCtrl[15]  = 0x00;
10680285809Sscottl    }
10681285809Sscottl
10682285809Sscottl    if (LLBAA)
10683285809Sscottl    {
10684285809Sscottl      index = 24;
10685285809Sscottl    }
10686285809Sscottl    else
10687285809Sscottl    {
10688285809Sscottl      index = 16;
10689285809Sscottl    }
10690285809Sscottl    /*
10691285809Sscottl     * Fill-up informational-exceptions control mode page, SAT, Table 68
10692285809Sscottl     */
10693285809Sscottl    InfoExceptionCtrl[index+0] = 0x1C; /* page code */
10694285809Sscottl    InfoExceptionCtrl[index+1] = 0x0A; /* page length */
10695285809Sscottl     if (pSatDevData->satSMARTEnabled == agTRUE)
10696285809Sscottl    {
10697285809Sscottl      InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */
10698285809Sscottl    }
10699285809Sscottl    else
10700285809Sscottl    {
10701285809Sscottl      InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */
10702285809Sscottl    }
10703285809Sscottl    InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */
10704285809Sscottl    InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */
10705285809Sscottl    InfoExceptionCtrl[index+5] = 0x00;
10706285809Sscottl    InfoExceptionCtrl[index+6] = 0x00;
10707285809Sscottl    InfoExceptionCtrl[index+7] = 0x00;
10708285809Sscottl    InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */
10709285809Sscottl    InfoExceptionCtrl[index+9] = 0x00;
10710285809Sscottl    InfoExceptionCtrl[index+10] = 0x00;
10711285809Sscottl    InfoExceptionCtrl[index+11] = 0x00;
10712285809Sscottl    sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
10713285809Sscottl
10714285809Sscottl  }
10715285809Sscottl  else
10716285809Sscottl  {
10717285809Sscottl    /* Error */
10718285809Sscottl    SM_DBG1(("smsatModeSense10: Error page %d!!!\n", page));
10719285809Sscottl    smsatSetSensePayload( pSense,
10720285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10721285809Sscottl                          0,
10722285809Sscottl                          SCSI_SNSCODE_INVALID_COMMAND,
10723285809Sscottl                          satIOContext);
10724285809Sscottl
10725285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
10726285809Sscottl
10727285809Sscottl    tdsmIOCompletedCB( smRoot,
10728285809Sscottl                       smIORequest,
10729285809Sscottl                       smIOSuccess,
10730285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
10731285809Sscottl                       satIOContext->pSmSenseData,
10732285809Sscottl                       satIOContext->interruptContext );
10733285809Sscottl    return SM_RC_SUCCESS;
10734285809Sscottl  }
10735285809Sscottl
10736285809Sscottl  if (allocationLen > lenRead)
10737285809Sscottl  {
10738285809Sscottl    SM_DBG1(("smsatModeSense10: reporting underrun lenRead=0x%x allocationLen=0x%x smIORequest=%p\n", lenRead, allocationLen, smIORequest));
10739285809Sscottl
10740285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
10741285809Sscottl
10742285809Sscottl    tdsmIOCompletedCB( smRoot,
10743285809Sscottl                       smIORequest,
10744285809Sscottl                       smIOUnderRun,
10745285809Sscottl                       allocationLen - lenRead,
10746285809Sscottl                       agNULL,
10747285809Sscottl                       satIOContext->interruptContext );
10748285809Sscottl
10749285809Sscottl
10750285809Sscottl  }
10751285809Sscottl  else
10752285809Sscottl  {
10753285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
10754285809Sscottl
10755285809Sscottl    tdsmIOCompletedCB( smRoot,
10756285809Sscottl                       smIORequest,
10757285809Sscottl                       smIOSuccess,
10758285809Sscottl                       SCSI_STAT_GOOD,
10759285809Sscottl                       agNULL,
10760285809Sscottl                       satIOContext->interruptContext);
10761285809Sscottl  }
10762285809Sscottl
10763285809Sscottl  return SM_RC_SUCCESS;
10764285809Sscottl}
10765285809Sscottl
10766285809SscottlosGLOBAL bit32
10767285809SscottlsmsatReadCapacity10(
10768285809Sscottl                    smRoot_t                  *smRoot,
10769285809Sscottl                    smIORequest_t             *smIORequest,
10770285809Sscottl                    smDeviceHandle_t          *smDeviceHandle,
10771285809Sscottl                    smScsiInitiatorRequest_t  *smScsiRequest,
10772285809Sscottl                    smSatIOContext_t            *satIOContext
10773285809Sscottl                   )
10774285809Sscottl{
10775285809Sscottl  smScsiRspSense_t        *pSense;
10776285809Sscottl  smIniScsiCmnd_t         *scsiCmnd;
10777285809Sscottl  bit8                    dataBuffer[8] = {0};
10778285809Sscottl  bit32                   allocationLen;
10779285809Sscottl  bit8  	              *pVirtAddr = agNULL;
10780285809Sscottl  smDeviceData_t          *pSatDevData;
10781285809Sscottl  agsaSATAIdentifyData_t  *pSATAIdData;
10782285809Sscottl  bit32                   lastLba;
10783285809Sscottl  bit32                   word117_118;
10784285809Sscottl  bit32                   word117;
10785285809Sscottl  bit32                   word118;
10786285809Sscottl
10787285809Sscottl  pSense      = satIOContext->pSense;
10788285809Sscottl  pVirtAddr   = (bit8 *) smScsiRequest->sglVirtualAddr;
10789285809Sscottl  scsiCmnd    = &smScsiRequest->scsiCmnd;
10790285809Sscottl  pSatDevData = satIOContext->pSatDevData;
10791285809Sscottl  pSATAIdData = &pSatDevData->satIdentifyData;
10792285809Sscottl  allocationLen = scsiCmnd->expDataLength;
10793285809Sscottl
10794285809Sscottl  SM_DBG5(("smsatReadCapacity10: start\n"));
10795285809Sscottl
10796285809Sscottl  /* checking CONTROL */
10797285809Sscottl  /* NACA == 1 or LINK == 1*/
10798285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
10799285809Sscottl  {
10800285809Sscottl    smsatSetSensePayload( pSense,
10801285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10802285809Sscottl                          0,
10803285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10804285809Sscottl                          satIOContext);
10805285809Sscottl
10806285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
10807285809Sscottl
10808285809Sscottl    tdsmIOCompletedCB( smRoot,
10809285809Sscottl                       smIORequest,
10810285809Sscottl                       smIOSuccess,
10811285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
10812285809Sscottl                       satIOContext->pSmSenseData,
10813285809Sscottl                       satIOContext->interruptContext );
10814285809Sscottl
10815285809Sscottl    SM_DBG1(("smsatReadCapacity10: return control!!!\n"));
10816285809Sscottl    return SM_RC_SUCCESS;
10817285809Sscottl  }
10818285809Sscottl
10819285809Sscottl
10820285809Sscottl  /*
10821285809Sscottl   * If Logical block address is not set to zero, return error
10822285809Sscottl   */
10823285809Sscottl  if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
10824285809Sscottl  {
10825285809Sscottl    SM_DBG1(("smsatReadCapacity10: *** ERROR *** logical address non zero, did %d!!!\n",
10826285809Sscottl        pSatDevData->id));
10827285809Sscottl
10828285809Sscottl    smsatSetSensePayload( pSense,
10829285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10830285809Sscottl                          0,
10831285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10832285809Sscottl                          satIOContext);
10833285809Sscottl
10834285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
10835285809Sscottl
10836285809Sscottl    tdsmIOCompletedCB( smRoot,
10837285809Sscottl                       smIORequest,
10838285809Sscottl                       smIOSuccess,
10839285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
10840285809Sscottl                       satIOContext->pSmSenseData,
10841285809Sscottl                       satIOContext->interruptContext );
10842285809Sscottl    return SM_RC_SUCCESS;
10843285809Sscottl
10844285809Sscottl  }
10845285809Sscottl
10846285809Sscottl  /*
10847285809Sscottl   * If PMI bit is not zero, return error
10848285809Sscottl   */
10849285809Sscottl  if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
10850285809Sscottl  {
10851285809Sscottl    SM_DBG1(("smsatReadCapacity10: *** ERROR *** PMI is not zero, did %d\n",
10852285809Sscottl        pSatDevData->id));
10853285809Sscottl
10854285809Sscottl    smsatSetSensePayload( pSense,
10855285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10856285809Sscottl                          0,
10857285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10858285809Sscottl                          satIOContext);
10859285809Sscottl
10860285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
10861285809Sscottl
10862285809Sscottl    tdsmIOCompletedCB( smRoot,
10863285809Sscottl                       smIORequest,
10864285809Sscottl                       smIOSuccess,
10865285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
10866285809Sscottl                       satIOContext->pSmSenseData,
10867285809Sscottl                       satIOContext->interruptContext );
10868285809Sscottl    return SM_RC_SUCCESS;
10869285809Sscottl
10870285809Sscottl  }
10871285809Sscottl
10872285809Sscottl  /*
10873285809Sscottl    filling in Read Capacity parameter data
10874285809Sscottl    saved identify device has been already flipped
10875285809Sscottl    See ATA spec p125 and p136 and SBC spec p54
10876285809Sscottl  */
10877285809Sscottl  /*
10878285809Sscottl   * If 48-bit addressing is supported, set capacity information from Identify
10879285809Sscottl   * Device Word 100-103.
10880285809Sscottl   */
10881285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
10882285809Sscottl  {
10883285809Sscottl    /*
10884285809Sscottl     * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data:
10885285809Sscottl     * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL
10886285809Sscottl     * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the the RETURNED LOGICAL
10887285809Sscottl     * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would
10888285809Sscottl     * then issue a READ CAPACITY(16) command.
10889285809Sscottl     */
10890285809Sscottl    /* ATA Identify Device information word 100 - 103 */
10891285809Sscottl    if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
10892285809Sscottl    {
10893285809Sscottl      dataBuffer[0] = 0xFF;        /* MSB number of block */
10894285809Sscottl      dataBuffer[1] = 0xFF;
10895285809Sscottl      dataBuffer[2] = 0xFF;
10896285809Sscottl      dataBuffer[3] = 0xFF;        /* LSB number of block */
10897285809Sscottl      SM_DBG1(("smsatReadCapacity10: returns 0xFFFFFFFF!!!\n"));
10898285809Sscottl    }
10899285809Sscottl    else  /* Fit the Readcapacity10 4-bytes response length */
10900285809Sscottl    {
10901285809Sscottl      lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
10902285809Sscottl                  (pSATAIdData->maxLBA0_15);
10903285809Sscottl      lastLba = lastLba - 1;      /* LBA starts from zero */
10904285809Sscottl
10905285809Sscottl      /*
10906285809Sscottl        for testing
10907285809Sscottl      lastLba = lastLba - (512*10) - 1;
10908285809Sscottl      */
10909285809Sscottl
10910285809Sscottl
10911285809Sscottl      dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
10912285809Sscottl      dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF);
10913285809Sscottl      dataBuffer[2] = (bit8)((lastLba >> 8)  & 0xFF);
10914285809Sscottl      dataBuffer[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
10915285809Sscottl
10916285809Sscottl      SM_DBG3(("smsatReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
10917285809Sscottl      SM_DBG3(("smsatReadCapacity10: LBA 0 is 0x%x %d\n", dataBuffer[0], dataBuffer[0]));
10918285809Sscottl      SM_DBG3(("smsatReadCapacity10: LBA 1 is 0x%x %d\n", dataBuffer[1], dataBuffer[1]));
10919285809Sscottl      SM_DBG3(("smsatReadCapacity10: LBA 2 is 0x%x %d\n", dataBuffer[2], dataBuffer[2]));
10920285809Sscottl      SM_DBG3(("smsatReadCapacity10: LBA 3 is 0x%x %d\n", dataBuffer[3], dataBuffer[3]));
10921285809Sscottl
10922285809Sscottl    }
10923285809Sscottl  }
10924285809Sscottl
10925285809Sscottl  /*
10926285809Sscottl   * For 28-bit addressing, set capacity information from Identify
10927285809Sscottl   * Device Word 60-61.
10928285809Sscottl   */
10929285809Sscottl  else
10930285809Sscottl  {
10931285809Sscottl    /* ATA Identify Device information word 60 - 61 */
10932285809Sscottl    lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
10933285809Sscottl                (pSATAIdData->numOfUserAddressableSectorsLo);
10934285809Sscottl    lastLba = lastLba - 1;      /* LBA starts from zero */
10935285809Sscottl
10936285809Sscottl    dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
10937285809Sscottl    dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF);
10938285809Sscottl    dataBuffer[2] = (bit8)((lastLba >> 8)  & 0xFF);
10939285809Sscottl    dataBuffer[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
10940285809Sscottl  }
10941285809Sscottl  /* SAT Rev 8d */
10942285809Sscottl  if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
10943285809Sscottl  {
10944285809Sscottl    SM_DBG5(("smsatReadCapacity10: Default Block Length is 512\n"));
10945285809Sscottl    /*
10946285809Sscottl     * Set the block size, fixed at 512 bytes.
10947285809Sscottl     */
10948285809Sscottl    dataBuffer[4] = 0x00;        /* MSB block size in bytes */
10949285809Sscottl    dataBuffer[5] = 0x00;
10950285809Sscottl    dataBuffer[6] = 0x02;
10951285809Sscottl    dataBuffer[7] = 0x00;        /* LSB block size in bytes */
10952285809Sscottl  }
10953285809Sscottl  else
10954285809Sscottl  {
10955285809Sscottl    word118 = pSATAIdData->word112_126[6];
10956285809Sscottl    word117 = pSATAIdData->word112_126[5];
10957285809Sscottl
10958285809Sscottl    word117_118 = (word118 << 16) + word117;
10959285809Sscottl    word117_118 = word117_118 * 2;
10960285809Sscottl    dataBuffer[4] = (bit8)((word117_118 >> 24) & 0xFF);        /* MSB block size in bytes */
10961285809Sscottl    dataBuffer[5] = (bit8)((word117_118 >> 16) & 0xFF);
10962285809Sscottl    dataBuffer[6] = (bit8)((word117_118 >> 8) & 0xFF);
10963285809Sscottl    dataBuffer[7] = (bit8)(word117_118 & 0xFF);                /* LSB block size in bytes */
10964285809Sscottl
10965285809Sscottl    SM_DBG1(("smsatReadCapacity10: Nondefault word118 %d 0x%x !!!\n", word118, word118));
10966285809Sscottl    SM_DBG1(("smsatReadCapacity10: Nondefault word117 %d 0x%x !!!\n", word117, word117));
10967285809Sscottl    SM_DBG1(("smsatReadCapacity10: Nondefault Block Length is %d 0x%x !!!\n",word117_118, word117_118));
10968285809Sscottl
10969285809Sscottl  }
10970285809Sscottl
10971285809Sscottl  /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
10972285809Sscottl  pSatDevData->satMaxLBA[0] = 0;            /* MSB */
10973285809Sscottl  pSatDevData->satMaxLBA[1] = 0;
10974285809Sscottl  pSatDevData->satMaxLBA[2] = 0;
10975285809Sscottl  pSatDevData->satMaxLBA[3] = 0;
10976285809Sscottl  pSatDevData->satMaxLBA[4] = dataBuffer[0];
10977285809Sscottl  pSatDevData->satMaxLBA[5] = dataBuffer[1];
10978285809Sscottl  pSatDevData->satMaxLBA[6] = dataBuffer[2];
10979285809Sscottl  pSatDevData->satMaxLBA[7] = dataBuffer[3]; /* LSB */
10980285809Sscottl
10981285809Sscottl
10982285809Sscottl  SM_DBG4(("smsatReadCapacity10: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , did %d\n",
10983285809Sscottl        dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3],
10984285809Sscottl        dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7],
10985285809Sscottl        pSatDevData->id));
10986285809Sscottl
10987285809Sscottl  sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, 8));
10988285809Sscottl
10989285809Sscottl  /*
10990285809Sscottl   * Send the completion response now.
10991285809Sscottl   */
10992285809Sscottl  /*smEnqueueIO(smRoot, satIOContext);*/
10993285809Sscottl
10994285809Sscottl  tdsmIOCompletedCB( smRoot,
10995285809Sscottl                     smIORequest,
10996285809Sscottl                     smIOSuccess,
10997285809Sscottl                     SCSI_STAT_GOOD,
10998285809Sscottl                     agNULL,
10999285809Sscottl                     satIOContext->interruptContext);
11000285809Sscottl  return SM_RC_SUCCESS;
11001285809Sscottl}
11002285809Sscottl
11003285809SscottlosGLOBAL bit32
11004285809SscottlsmsatReadCapacity16(
11005285809Sscottl                    smRoot_t                  *smRoot,
11006285809Sscottl                    smIORequest_t             *smIORequest,
11007285809Sscottl                    smDeviceHandle_t          *smDeviceHandle,
11008285809Sscottl                    smScsiInitiatorRequest_t  *smScsiRequest,
11009285809Sscottl                    smSatIOContext_t            *satIOContext
11010285809Sscottl                   )
11011285809Sscottl{
11012285809Sscottl  smScsiRspSense_t        *pSense;
11013285809Sscottl  smIniScsiCmnd_t         *scsiCmnd;
11014285809Sscottl  bit8                    dataBuffer[32] = {0};
11015285809Sscottl  bit8  	              *pVirtAddr = agNULL;
11016285809Sscottl  smDeviceData_t          *pSatDevData;
11017285809Sscottl  agsaSATAIdentifyData_t  *pSATAIdData;
11018285809Sscottl  bit32                   lastLbaLo;
11019285809Sscottl  bit32                   allocationLen;
11020285809Sscottl  bit32                   readCapacityLen  = 32;
11021285809Sscottl  bit32                   i = 0;
11022285809Sscottl
11023285809Sscottl  pSense      = satIOContext->pSense;
11024285809Sscottl  pVirtAddr   = (bit8 *) smScsiRequest->sglVirtualAddr;
11025285809Sscottl  scsiCmnd    = &smScsiRequest->scsiCmnd;
11026285809Sscottl  pSatDevData = satIOContext->pSatDevData;
11027285809Sscottl  pSATAIdData = &pSatDevData->satIdentifyData;
11028285809Sscottl
11029285809Sscottl  SM_DBG5(("smsatReadCapacity16: start\n"));
11030285809Sscottl
11031285809Sscottl  /* Find the buffer size allocated by Initiator */
11032285809Sscottl  allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
11033285809Sscottl                  (((bit32)scsiCmnd->cdb[11]) << 16) |
11034285809Sscottl                  (((bit32)scsiCmnd->cdb[12]) << 8 ) |
11035285809Sscottl                  (((bit32)scsiCmnd->cdb[13])      );
11036285809Sscottl  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
11037285809Sscottl
11038285809Sscottl#ifdef REMOVED
11039285809Sscottl  if (allocationLen < readCapacityLen)
11040285809Sscottl  {
11041285809Sscottl    SM_DBG1(("smsatReadCapacity16: *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x!!!\n", allocationLen, readCapacityLen));
11042285809Sscottl
11043285809Sscottl    smsatSetSensePayload( pSense,
11044285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11045285809Sscottl                          0,
11046285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11047285809Sscottl                          satIOContext);
11048285809Sscottl
11049285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11050285809Sscottl
11051285809Sscottl    tdsmIOCompletedCB( smRoot,
11052285809Sscottl                       smIORequest,
11053285809Sscottl                       smIOSuccess,
11054285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
11055285809Sscottl                       satIOContext->pSmSenseData,
11056285809Sscottl                       satIOContext->interruptContext );
11057285809Sscottl    return SM_RC_SUCCESS;
11058285809Sscottl
11059285809Sscottl  }
11060285809Sscottl#endif
11061285809Sscottl
11062285809Sscottl  /* checking CONTROL */
11063285809Sscottl  /* NACA == 1 or LINK == 1*/
11064285809Sscottl  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
11065285809Sscottl  {
11066285809Sscottl    smsatSetSensePayload( pSense,
11067285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11068285809Sscottl                          0,
11069285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11070285809Sscottl                          satIOContext);
11071285809Sscottl
11072285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11073285809Sscottl
11074285809Sscottl    tdsmIOCompletedCB( smRoot,
11075285809Sscottl                       smIORequest,
11076285809Sscottl                       smIOSuccess,
11077285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
11078285809Sscottl                       satIOContext->pSmSenseData,
11079285809Sscottl                       satIOContext->interruptContext );
11080285809Sscottl
11081285809Sscottl    SM_DBG1(("smsatReadCapacity16: return control!!!\n"));
11082285809Sscottl    return SM_RC_SUCCESS;
11083285809Sscottl  }
11084285809Sscottl
11085285809Sscottl  /*
11086285809Sscottl   * If Logical blcok address is not set to zero, return error
11087285809Sscottl   */
11088285809Sscottl  if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) ||
11089285809Sscottl      (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9])  )
11090285809Sscottl  {
11091285809Sscottl    SM_DBG1(("smsatReadCapacity16: *** ERROR *** logical address non zero, did %d\n",
11092285809Sscottl        pSatDevData->id));
11093285809Sscottl
11094285809Sscottl    smsatSetSensePayload( pSense,
11095285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11096285809Sscottl                          0,
11097285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11098285809Sscottl                          satIOContext);
11099285809Sscottl
11100285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11101285809Sscottl
11102285809Sscottl    tdsmIOCompletedCB( smRoot,
11103285809Sscottl                       smIORequest,
11104285809Sscottl                       smIOSuccess,
11105285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
11106285809Sscottl                       satIOContext->pSmSenseData,
11107285809Sscottl                       satIOContext->interruptContext );
11108285809Sscottl    return SM_RC_SUCCESS;
11109285809Sscottl
11110285809Sscottl  }
11111285809Sscottl
11112285809Sscottl  /*
11113285809Sscottl   * If PMI bit is not zero, return error
11114285809Sscottl   */
11115285809Sscottl  if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
11116285809Sscottl  {
11117285809Sscottl    SM_DBG1(("smsatReadCapacity16: *** ERROR *** PMI is not zero, did %d\n",
11118285809Sscottl        pSatDevData->id));
11119285809Sscottl
11120285809Sscottl    smsatSetSensePayload( pSense,
11121285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11122285809Sscottl                          0,
11123285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11124285809Sscottl                          satIOContext);
11125285809Sscottl
11126285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11127285809Sscottl
11128285809Sscottl    tdsmIOCompletedCB( smRoot,
11129285809Sscottl                       smIORequest,
11130285809Sscottl                       smIOSuccess,
11131285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
11132285809Sscottl                       satIOContext->pSmSenseData,
11133285809Sscottl                       satIOContext->interruptContext );
11134285809Sscottl    return SM_RC_SUCCESS;
11135285809Sscottl
11136285809Sscottl  }
11137285809Sscottl
11138285809Sscottl  /*
11139285809Sscottl    filling in Read Capacity parameter data
11140285809Sscottl  */
11141285809Sscottl
11142285809Sscottl  /*
11143285809Sscottl   * If 48-bit addressing is supported, set capacity information from Identify
11144285809Sscottl   * Device Word 100-103.
11145285809Sscottl   */
11146285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
11147285809Sscottl  {
11148285809Sscottl    dataBuffer[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff);  /* MSB */
11149285809Sscottl    dataBuffer[1] = (bit8)((pSATAIdData->maxLBA48_63)        & 0xff);
11150285809Sscottl    dataBuffer[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
11151285809Sscottl    dataBuffer[3] = (bit8)((pSATAIdData->maxLBA32_47)        & 0xff);
11152285809Sscottl
11153285809Sscottl    lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
11154285809Sscottl    lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
11155285809Sscottl
11156285809Sscottl    dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
11157285809Sscottl    dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
11158285809Sscottl    dataBuffer[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
11159285809Sscottl    dataBuffer[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
11160285809Sscottl
11161285809Sscottl  }
11162285809Sscottl
11163285809Sscottl  /*
11164285809Sscottl   * For 28-bit addressing, set capacity information from Identify
11165285809Sscottl   * Device Word 60-61.
11166285809Sscottl   */
11167285809Sscottl  else
11168285809Sscottl  {
11169285809Sscottl    dataBuffer[0] = 0;       /* MSB */
11170285809Sscottl    dataBuffer[1] = 0;
11171285809Sscottl    dataBuffer[2] = 0;
11172285809Sscottl    dataBuffer[3] = 0;
11173285809Sscottl
11174285809Sscottl    lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
11175285809Sscottl                  (pSATAIdData->numOfUserAddressableSectorsLo);
11176285809Sscottl    lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
11177285809Sscottl
11178285809Sscottl    dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
11179285809Sscottl    dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
11180285809Sscottl    dataBuffer[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
11181285809Sscottl    dataBuffer[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
11182285809Sscottl
11183285809Sscottl  }
11184285809Sscottl
11185285809Sscottl  /*
11186285809Sscottl   * Set the block size, fixed at 512 bytes.
11187285809Sscottl   */
11188285809Sscottl  dataBuffer[8]  = 0x00;        /* MSB block size in bytes */
11189285809Sscottl  dataBuffer[9]  = 0x00;
11190285809Sscottl  dataBuffer[10] = 0x02;
11191285809Sscottl  dataBuffer[11] = 0x00;        /* LSB block size in bytes */
11192285809Sscottl
11193285809Sscottl
11194285809Sscottl  /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
11195285809Sscottl  pSatDevData->satMaxLBA[0] = dataBuffer[0];            /* MSB */
11196285809Sscottl  pSatDevData->satMaxLBA[1] = dataBuffer[1];
11197285809Sscottl  pSatDevData->satMaxLBA[2] = dataBuffer[2];
11198285809Sscottl  pSatDevData->satMaxLBA[3] = dataBuffer[3];
11199285809Sscottl  pSatDevData->satMaxLBA[4] = dataBuffer[4];
11200285809Sscottl  pSatDevData->satMaxLBA[5] = dataBuffer[5];
11201285809Sscottl  pSatDevData->satMaxLBA[6] = dataBuffer[6];
11202285809Sscottl  pSatDevData->satMaxLBA[7] = dataBuffer[7];             /* LSB */
11203285809Sscottl
11204285809Sscottl  SM_DBG5(("smsatReadCapacity16: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , did %d\n",
11205285809Sscottl        dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3],
11206285809Sscottl        dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7],
11207285809Sscottl        dataBuffer[8], dataBuffer[9], dataBuffer[10], dataBuffer[11],
11208285809Sscottl        pSatDevData->id));
11209285809Sscottl
11210285809Sscottl  if (allocationLen > 0xC) /* 0xc = 12 */
11211285809Sscottl  {
11212285809Sscottl    for(i=12;i<=31;i++)
11213285809Sscottl    {
11214285809Sscottl      dataBuffer[i] = 0x00;
11215285809Sscottl    }
11216285809Sscottl  }
11217285809Sscottl
11218285809Sscottl  sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, readCapacityLen));
11219285809Sscottl  /*
11220285809Sscottl   * Send the completion response now.
11221285809Sscottl   */
11222285809Sscottl  if (allocationLen > readCapacityLen)
11223285809Sscottl  {
11224285809Sscottl    /* underrun */
11225285809Sscottl    SM_DBG1(("smsatReadCapacity16: reporting underrun readCapacityLen=0x%x allocationLen=0x%x !!!\n", readCapacityLen, allocationLen));
11226285809Sscottl
11227285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11228285809Sscottl
11229285809Sscottl    tdsmIOCompletedCB( smRoot,
11230285809Sscottl                       smIORequest,
11231285809Sscottl                       smIOUnderRun,
11232285809Sscottl                       allocationLen - readCapacityLen,
11233285809Sscottl                       agNULL,
11234285809Sscottl                       satIOContext->interruptContext );
11235285809Sscottl
11236285809Sscottl
11237285809Sscottl  }
11238285809Sscottl  else
11239285809Sscottl  {
11240285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11241285809Sscottl
11242285809Sscottl    tdsmIOCompletedCB( smRoot,
11243285809Sscottl                       smIORequest,
11244285809Sscottl                       smIOSuccess,
11245285809Sscottl                       SCSI_STAT_GOOD,
11246285809Sscottl                       agNULL,
11247285809Sscottl                       satIOContext->interruptContext);
11248285809Sscottl  }
11249285809Sscottl  return SM_RC_SUCCESS;
11250285809Sscottl}
11251285809Sscottl
11252285809SscottlosGLOBAL bit32
11253285809SscottlsmsatReportLun(
11254285809Sscottl               smRoot_t                  *smRoot,
11255285809Sscottl               smIORequest_t             *smIORequest,
11256285809Sscottl               smDeviceHandle_t          *smDeviceHandle,
11257285809Sscottl               smScsiInitiatorRequest_t  *smScsiRequest,
11258285809Sscottl               smSatIOContext_t            *satIOContext
11259285809Sscottl              )
11260285809Sscottl{
11261285809Sscottl  smScsiRspSense_t      *pSense;
11262285809Sscottl  bit8                  dataBuffer[16] = {0};
11263285809Sscottl  bit32                 allocationLen;
11264285809Sscottl  bit32                 reportLunLen;
11265285809Sscottl  smScsiReportLun_t     *pReportLun;
11266285809Sscottl  smIniScsiCmnd_t       *scsiCmnd;
11267285809Sscottl#ifdef  TD_DEBUG_ENABLE
11268285809Sscottl  smDeviceData_t        *pSatDevData;
11269285809Sscottl#endif
11270285809Sscottl
11271285809Sscottl  pSense     = satIOContext->pSense;
11272285809Sscottl  pReportLun = (smScsiReportLun_t *) dataBuffer;
11273285809Sscottl  scsiCmnd   = &smScsiRequest->scsiCmnd;
11274285809Sscottl#ifdef  TD_DEBUG_ENABLE
11275285809Sscottl  pSatDevData = satIOContext->pSatDevData;
11276285809Sscottl#endif
11277285809Sscottl  SM_DBG5(("smsatReportLun: start\n"));
11278285809Sscottl//  smhexdump("smsatReportLun: cdb", (bit8 *)scsiCmnd, 16);
11279285809Sscottl  /* Find the buffer size allocated by Initiator */
11280285809Sscottl  allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
11281285809Sscottl                  (((bit32)scsiCmnd->cdb[7]) << 16) |
11282285809Sscottl                  (((bit32)scsiCmnd->cdb[8]) << 8 ) |
11283285809Sscottl                  (((bit32)scsiCmnd->cdb[9])      );
11284285809Sscottl  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
11285285809Sscottl  reportLunLen  = 16;     /* 8 byte header and 8 bytes of LUN0 */
11286285809Sscottl  if (allocationLen < reportLunLen)
11287285809Sscottl  {
11288285809Sscottl    SM_DBG1(("smsatReportLun: *** ERROR *** insufficient len=0x%x did %d\n",
11289285809Sscottl        reportLunLen, pSatDevData->id));
11290285809Sscottl    smsatSetSensePayload( pSense,
11291285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11292285809Sscottl                          0,
11293285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11294285809Sscottl                          satIOContext);
11295285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11296285809Sscottl    tdsmIOCompletedCB( smRoot,
11297285809Sscottl                       smIORequest,
11298285809Sscottl                       smIOSuccess,
11299285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
11300285809Sscottl                       satIOContext->pSmSenseData,
11301285809Sscottl                       satIOContext->interruptContext );
11302285809Sscottl    return SM_RC_SUCCESS;
11303285809Sscottl  }
11304285809Sscottl  /* Set length to one entry */
11305285809Sscottl  pReportLun->len[0] = 0;
11306285809Sscottl  pReportLun->len[1] = 0;
11307285809Sscottl  pReportLun->len[2] = 0;
11308285809Sscottl  pReportLun->len[3] = sizeof (tiLUN_t);
11309285809Sscottl  pReportLun->reserved = 0;
11310285809Sscottl  /* Set to LUN 0:
11311285809Sscottl   * - address method to 0x00: Peripheral device addressing method,
11312285809Sscottl   * - bus identifier to 0
11313285809Sscottl   */
11314285809Sscottl  pReportLun->lunList[0].lun[0] = 0;
11315285809Sscottl  pReportLun->lunList[0].lun[1] = 0;
11316285809Sscottl  pReportLun->lunList[0].lun[2] = 0;
11317285809Sscottl  pReportLun->lunList[0].lun[3] = 0;
11318285809Sscottl  pReportLun->lunList[0].lun[4] = 0;
11319285809Sscottl  pReportLun->lunList[0].lun[5] = 0;
11320285809Sscottl  pReportLun->lunList[0].lun[6] = 0;
11321285809Sscottl  pReportLun->lunList[0].lun[7] = 0;
11322285809Sscottl
11323285809Sscottl  sm_memcpy(smScsiRequest->sglVirtualAddr, dataBuffer, MIN(allocationLen, reportLunLen));
11324285809Sscottl  if (allocationLen > reportLunLen)
11325285809Sscottl  {
11326285809Sscottl    /* underrun */
11327285809Sscottl    SM_DBG1(("smsatReportLun: reporting underrun reportLunLen=0x%x allocationLen=0x%x !!!\n", reportLunLen, allocationLen));
11328285809Sscottl
11329285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11330285809Sscottl
11331285809Sscottl    tdsmIOCompletedCB( smRoot,
11332285809Sscottl                       smIORequest,
11333285809Sscottl                       smIOUnderRun,
11334285809Sscottl                       allocationLen - reportLunLen,
11335285809Sscottl                       agNULL,
11336285809Sscottl                       satIOContext->interruptContext );
11337285809Sscottl
11338285809Sscottl
11339285809Sscottl  }
11340285809Sscottl  else
11341285809Sscottl  {
11342285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11343285809Sscottl
11344285809Sscottl    tdsmIOCompletedCB( smRoot,
11345285809Sscottl                       smIORequest,
11346285809Sscottl                       smIOSuccess,
11347285809Sscottl                       SCSI_STAT_GOOD,
11348285809Sscottl                       agNULL,
11349285809Sscottl                       satIOContext->interruptContext);
11350285809Sscottl  }
11351285809Sscottl  return SM_RC_SUCCESS;
11352285809Sscottl}
11353285809Sscottl
11354285809SscottlosGLOBAL bit32
11355285809SscottlsmsatFormatUnit(
11356285809Sscottl                smRoot_t                  *smRoot,
11357285809Sscottl                smIORequest_t             *smIORequest,
11358285809Sscottl                smDeviceHandle_t          *smDeviceHandle,
11359285809Sscottl                smScsiInitiatorRequest_t  *smScsiRequest,
11360285809Sscottl                smSatIOContext_t            *satIOContext
11361285809Sscottl               )
11362285809Sscottl{
11363285809Sscottl  /*
11364285809Sscottl    note: we don't support media certification in this version and IP bit
11365285809Sscottl    satDevData->satFormatState will be agFalse since SAT does not actually sends
11366285809Sscottl    any ATA command
11367285809Sscottl   */
11368285809Sscottl
11369285809Sscottl  smScsiRspSense_t        *pSense;
11370285809Sscottl  smIniScsiCmnd_t         *scsiCmnd;
11371285809Sscottl  bit32                    index = 0;
11372285809Sscottl
11373285809Sscottl  pSense        = satIOContext->pSense;
11374285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
11375285809Sscottl  SM_DBG5(("smsatFormatUnit: start\n"));
11376285809Sscottl  /*
11377285809Sscottl    checking opcode
11378285809Sscottl    1. FMTDATA bit == 0(no defect list header)
11379285809Sscottl    2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided
11380285809Sscottl    with DCRT bit set)
11381285809Sscottl  */
11382285809Sscottl  if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) ||
11383285809Sscottl       ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
11384285809Sscottl        (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK))
11385285809Sscottl       )
11386285809Sscottl  {
11387285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11388285809Sscottl
11389285809Sscottl    tdsmIOCompletedCB( smRoot,
11390285809Sscottl                       smIORequest,
11391285809Sscottl                       smIOSuccess,
11392285809Sscottl                       SCSI_STAT_GOOD,
11393285809Sscottl                       agNULL,
11394285809Sscottl                       satIOContext->interruptContext);
11395285809Sscottl
11396285809Sscottl    SM_DBG1(("smsatFormatUnit: return opcode!!!\n"));
11397285809Sscottl    return SM_RC_SUCCESS;
11398285809Sscottl  }
11399285809Sscottl
11400285809Sscottl  /*
11401285809Sscottl    checking DEFECT LIST FORMAT and defect list length
11402285809Sscottl  */
11403285809Sscottl  if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) ||
11404285809Sscottl        ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) )
11405285809Sscottl  {
11406285809Sscottl    /* short parameter header */
11407285809Sscottl    if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00)
11408285809Sscottl    {
11409285809Sscottl      index = 8;
11410285809Sscottl    }
11411285809Sscottl    /* long parameter header */
11412285809Sscottl    if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01)
11413285809Sscottl    {
11414285809Sscottl      index = 10;
11415285809Sscottl    }
11416285809Sscottl    /* defect list length */
11417285809Sscottl    if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0))
11418285809Sscottl    {
11419285809Sscottl      smsatSetSensePayload( pSense,
11420285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
11421285809Sscottl                            0,
11422285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11423285809Sscottl                            satIOContext);
11424285809Sscottl
11425285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
11426285809Sscottl
11427285809Sscottl      tdsmIOCompletedCB( smRoot,
11428285809Sscottl                         smIORequest,
11429285809Sscottl                         smIOSuccess,
11430285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
11431285809Sscottl                         satIOContext->pSmSenseData,
11432285809Sscottl                         satIOContext->interruptContext );
11433285809Sscottl
11434285809Sscottl      SM_DBG1(("smsatFormatUnit: return defect list format!!!\n"));
11435285809Sscottl      return SM_RC_SUCCESS;
11436285809Sscottl    }
11437285809Sscottl  }
11438285809Sscottl
11439285809Sscottl  if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
11440285809Sscottl       (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
11441285809Sscottl  {
11442285809Sscottl    smsatSetSensePayload( pSense,
11443285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11444285809Sscottl                          0,
11445285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11446285809Sscottl                          satIOContext);
11447285809Sscottl
11448285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11449285809Sscottl
11450285809Sscottl    tdsmIOCompletedCB( smRoot,
11451285809Sscottl                       smIORequest,
11452285809Sscottl                       smIOSuccess,
11453285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
11454285809Sscottl                       satIOContext->pSmSenseData,
11455285809Sscottl                       satIOContext->interruptContext );
11456285809Sscottl
11457285809Sscottl    SM_DBG1(("smsatFormatUnit: return cmplist!!!\n"));
11458285809Sscottl    return SM_RC_SUCCESS;
11459285809Sscottl
11460285809Sscottl  }
11461285809Sscottl
11462285809Sscottl  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
11463285809Sscottl  {
11464285809Sscottl    smsatSetSensePayload( pSense,
11465285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11466285809Sscottl                          0,
11467285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11468285809Sscottl                          satIOContext);
11469285809Sscottl
11470285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11471285809Sscottl
11472285809Sscottl    tdsmIOCompletedCB( smRoot,
11473285809Sscottl                       smIORequest,
11474285809Sscottl                       smIOSuccess,
11475285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
11476285809Sscottl                       satIOContext->pSmSenseData,
11477285809Sscottl                       satIOContext->interruptContext );
11478285809Sscottl
11479285809Sscottl    SM_DBG1(("smsatFormatUnit: return control!!!\n"));
11480285809Sscottl    return SM_RC_SUCCESS;
11481285809Sscottl  }
11482285809Sscottl
11483285809Sscottl  /* defect list header filed, if exists, SAT rev8, Table 37, p48 */
11484285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK)
11485285809Sscottl  {
11486285809Sscottl    /* case 1,2,3 */
11487285809Sscottl    /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */
11488285809Sscottl    if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) ||
11489285809Sscottl         ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) ||
11490285809Sscottl         ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11491285809Sscottl           (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11492285809Sscottl           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK))
11493285809Sscottl         )
11494285809Sscottl    {
11495285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
11496285809Sscottl
11497285809Sscottl      tdsmIOCompletedCB( smRoot,
11498285809Sscottl                         smIORequest,
11499285809Sscottl                         smIOSuccess,
11500285809Sscottl                         SCSI_STAT_GOOD,
11501285809Sscottl                         agNULL,
11502285809Sscottl                         satIOContext->interruptContext);
11503285809Sscottl
11504285809Sscottl      SM_DBG5(("smsatFormatUnit: return defect list case 1\n"));
11505285809Sscottl      return SM_RC_SUCCESS;
11506285809Sscottl    }
11507285809Sscottl    /* case 4,5,6 */
11508285809Sscottl    /*
11509285809Sscottl        1. IMMED 0, FOV 1, DCRT 0, IP 0
11510285809Sscottl        2. IMMED 0, FOV 1, DCRT 0, IP 1
11511285809Sscottl        3. IMMED 0, FOV 1, DCRT 1, IP 1
11512285809Sscottl      */
11513285809Sscottl
11514285809Sscottl    if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11515285809Sscottl            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11516285809Sscottl           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11517285809Sscottl           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11518285809Sscottl         ||
11519285809Sscottl         ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11520285809Sscottl            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11521285809Sscottl           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11522285809Sscottl            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11523285809Sscottl         ||
11524285809Sscottl         ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11525285809Sscottl            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11526285809Sscottl            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11527285809Sscottl            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11528285809Sscottl         )
11529285809Sscottl    {
11530285809Sscottl
11531285809Sscottl      smsatSetSensePayload( pSense,
11532285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
11533285809Sscottl                            0,
11534285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
11535285809Sscottl                            satIOContext);
11536285809Sscottl
11537285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
11538285809Sscottl
11539285809Sscottl      tdsmIOCompletedCB( smRoot,
11540285809Sscottl                         smIORequest,
11541285809Sscottl                         smIOSuccess,
11542285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
11543285809Sscottl                         satIOContext->pSmSenseData,
11544285809Sscottl                         satIOContext->interruptContext );
11545285809Sscottl
11546285809Sscottl      SM_DBG5(("smsatFormatUnit: return defect list case 2\n"));
11547285809Sscottl      return SM_RC_SUCCESS;
11548285809Sscottl
11549285809Sscottl    }
11550285809Sscottl  }
11551285809Sscottl
11552285809Sscottl
11553285809Sscottl  /*
11554285809Sscottl   * Send the completion response now.
11555285809Sscottl   */
11556285809Sscottl  /*smEnqueueIO(smRoot, satIOContext);*/
11557285809Sscottl
11558285809Sscottl  tdsmIOCompletedCB( smRoot,
11559285809Sscottl                     smIORequest,
11560285809Sscottl                     smIOSuccess,
11561285809Sscottl                     SCSI_STAT_GOOD,
11562285809Sscottl                     agNULL,
11563285809Sscottl                     satIOContext->interruptContext);
11564285809Sscottl
11565285809Sscottl  SM_DBG5(("smsatFormatUnit: return last\n"));
11566285809Sscottl  return SM_RC_SUCCESS;
11567285809Sscottl}
11568285809Sscottl
11569285809SscottlosGLOBAL bit32
11570285809SscottlsmsatSendDiagnostic(
11571285809Sscottl                    smRoot_t                  *smRoot,
11572285809Sscottl                    smIORequest_t             *smIORequest,
11573285809Sscottl                    smDeviceHandle_t          *smDeviceHandle,
11574285809Sscottl                    smScsiInitiatorRequest_t  *smScsiRequest,
11575285809Sscottl                    smSatIOContext_t            *satIOContext
11576285809Sscottl                   )
11577285809Sscottl{
11578285809Sscottl  bit32                     status;
11579285809Sscottl  bit32                     agRequestType;
11580285809Sscottl  smDeviceData_t            *pSatDevData;
11581285809Sscottl  smScsiRspSense_t          *pSense;
11582285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
11583285809Sscottl  agsaFisRegHostToDevice_t  *fis;
11584285809Sscottl  bit32                     parmLen;
11585285809Sscottl
11586285809Sscottl  pSense        = satIOContext->pSense;
11587285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
11588285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
11589285809Sscottl  fis           = satIOContext->pFis;
11590285809Sscottl
11591285809Sscottl  SM_DBG5(("smsatSendDiagnostic: start\n"));
11592285809Sscottl
11593285809Sscottl  /* reset satVerifyState */
11594285809Sscottl  pSatDevData->satVerifyState = 0;
11595285809Sscottl  /* no pending diagnostic in background */
11596285809Sscottl  pSatDevData->satBGPendingDiag = agFALSE;
11597285809Sscottl
11598285809Sscottl  /* table 27, 8.10 p39 SAT Rev8 */
11599285809Sscottl  /*
11600285809Sscottl    1. checking PF == 1
11601285809Sscottl    2. checking DEVOFFL == 1
11602285809Sscottl    3. checking UNITOFFL == 1
11603285809Sscottl    4. checking PARAMETER LIST LENGTH != 0
11604285809Sscottl
11605285809Sscottl  */
11606285809Sscottl  if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) ||
11607285809Sscottl       (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) ||
11608285809Sscottl       (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) ||
11609285809Sscottl       ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) )
11610285809Sscottl       )
11611285809Sscottl  {
11612285809Sscottl    smsatSetSensePayload( pSense,
11613285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11614285809Sscottl                          0,
11615285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11616285809Sscottl                          satIOContext);
11617285809Sscottl
11618285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11619285809Sscottl
11620285809Sscottl    tdsmIOCompletedCB( smRoot,
11621285809Sscottl                       smIORequest,
11622285809Sscottl                       smIOSuccess,
11623285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
11624285809Sscottl                       satIOContext->pSmSenseData,
11625285809Sscottl                       satIOContext->interruptContext );
11626285809Sscottl
11627285809Sscottl    SM_DBG1(("smsatSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST!!!\n"));
11628285809Sscottl    return SM_RC_SUCCESS;
11629285809Sscottl  }
11630285809Sscottl
11631285809Sscottl  /* checking CONTROL */
11632285809Sscottl  /* NACA == 1 or LINK == 1*/
11633285809Sscottl  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
11634285809Sscottl  {
11635285809Sscottl    smsatSetSensePayload( pSense,
11636285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11637285809Sscottl                          0,
11638285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11639285809Sscottl                          satIOContext);
11640285809Sscottl
11641285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11642285809Sscottl
11643285809Sscottl    tdsmIOCompletedCB( smRoot,
11644285809Sscottl                       smIORequest,
11645285809Sscottl                       smIOSuccess,
11646285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
11647285809Sscottl                       satIOContext->pSmSenseData,
11648285809Sscottl                       satIOContext->interruptContext );
11649285809Sscottl
11650285809Sscottl    SM_DBG1(("smsatSendDiagnostic: return control!!!\n"));
11651285809Sscottl    return SM_RC_SUCCESS;
11652285809Sscottl  }
11653285809Sscottl
11654285809Sscottl  parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
11655285809Sscottl
11656285809Sscottl  /* checking SELFTEST bit*/
11657285809Sscottl  /* table 29, 8.10.3, p41 SAT Rev8 */
11658285809Sscottl  /* case 1 */
11659285809Sscottl  if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11660285809Sscottl       (pSatDevData->satSMARTSelfTest == agFALSE)
11661285809Sscottl       )
11662285809Sscottl  {
11663285809Sscottl    smsatSetSensePayload( pSense,
11664285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11665285809Sscottl                          0,
11666285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11667285809Sscottl                          satIOContext);
11668285809Sscottl
11669285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11670285809Sscottl
11671285809Sscottl    tdsmIOCompletedCB( smRoot,
11672285809Sscottl                       smIORequest,
11673285809Sscottl                       smIOSuccess,
11674285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
11675285809Sscottl                       satIOContext->pSmSenseData,
11676285809Sscottl                       satIOContext->interruptContext );
11677285809Sscottl
11678285809Sscottl    SM_DBG1(("smsatSendDiagnostic: return Table 29 case 1!!!\n"));
11679285809Sscottl    return SM_RC_SUCCESS;
11680285809Sscottl  }
11681285809Sscottl
11682285809Sscottl  /* case 2 */
11683285809Sscottl  if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11684285809Sscottl       (pSatDevData->satSMARTSelfTest == agTRUE) &&
11685285809Sscottl       (pSatDevData->satSMARTEnabled == agFALSE)
11686285809Sscottl       )
11687285809Sscottl  {
11688285809Sscottl    smsatSetSensePayload( pSense,
11689285809Sscottl                          SCSI_SNSKEY_ABORTED_COMMAND,
11690285809Sscottl                          0,
11691285809Sscottl                          SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
11692285809Sscottl                          satIOContext);
11693285809Sscottl
11694285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
11695285809Sscottl
11696285809Sscottl    tdsmIOCompletedCB( smRoot,
11697285809Sscottl                       smIORequest,
11698285809Sscottl                       smIOSuccess,
11699285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
11700285809Sscottl                       satIOContext->pSmSenseData,
11701285809Sscottl                       satIOContext->interruptContext );
11702285809Sscottl
11703285809Sscottl    SM_DBG5(("smsatSendDiagnostic: return Table 29 case 2\n"));
11704285809Sscottl    return SM_RC_SUCCESS;
11705285809Sscottl  }
11706285809Sscottl  /*
11707285809Sscottl    case 3
11708285809Sscottl     see SELF TEST CODE later
11709285809Sscottl  */
11710285809Sscottl
11711285809Sscottl
11712285809Sscottl
11713285809Sscottl  /* case 4 */
11714285809Sscottl
11715285809Sscottl  /*
11716285809Sscottl    sends three ATA verify commands
11717285809Sscottl
11718285809Sscottl  */
11719285809Sscottl  if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11720285809Sscottl        (pSatDevData->satSMARTSelfTest == agFALSE))
11721285809Sscottl       ||
11722285809Sscottl       ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11723285809Sscottl        (pSatDevData->satSMARTSelfTest == agTRUE) &&
11724285809Sscottl        (pSatDevData->satSMARTEnabled == agFALSE))
11725285809Sscottl       )
11726285809Sscottl  {
11727285809Sscottl    /*
11728285809Sscottl      sector count 1, LBA 0
11729285809Sscottl      sector count 1, LBA MAX
11730285809Sscottl      sector count 1, LBA random
11731285809Sscottl    */
11732285809Sscottl    if (pSatDevData->sat48BitSupport == agTRUE)
11733285809Sscottl    {
11734285809Sscottl      /* sends READ VERIFY SECTOR(S) EXT*/
11735285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
11736285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11737285809Sscottl      fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
11738285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
11739285809Sscottl      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
11740285809Sscottl      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
11741285809Sscottl      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
11742285809Sscottl      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
11743285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
11744285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
11745285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
11746285809Sscottl      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
11747285809Sscottl      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
11748285809Sscottl      fis->d.reserved4      = 0;
11749285809Sscottl      fis->d.device         = 0x40;                   /* 01000000 */
11750285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
11751285809Sscottl      fis->d.reserved5      = 0;
11752285809Sscottl
11753285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11754285809Sscottl    }
11755285809Sscottl    else
11756285809Sscottl    {
11757285809Sscottl      /* READ VERIFY SECTOR(S)*/
11758285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
11759285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11760285809Sscottl      fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
11761285809Sscottl      fis->h.features       = 0;                      /* FIS features NA       */
11762285809Sscottl      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
11763285809Sscottl      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
11764285809Sscottl      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
11765285809Sscottl      fis->d.lbaLowExp      = 0;
11766285809Sscottl      fis->d.lbaMidExp      = 0;
11767285809Sscottl      fis->d.lbaHighExp     = 0;
11768285809Sscottl      fis->d.featuresExp    = 0;
11769285809Sscottl      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
11770285809Sscottl      fis->d.sectorCountExp = 0;
11771285809Sscottl      fis->d.reserved4      = 0;
11772285809Sscottl      fis->d.device         = 0x40;                   /* 01000000 */
11773285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
11774285809Sscottl      fis->d.reserved5      = 0;
11775285809Sscottl
11776285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11777285809Sscottl    }
11778285809Sscottl
11779285809Sscottl    /* Initialize CB for SATA completion.
11780285809Sscottl     */
11781285809Sscottl    satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11782285809Sscottl
11783285809Sscottl    /*
11784285809Sscottl     * Prepare SGL and send FIS to LL layer.
11785285809Sscottl     */
11786285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
11787285809Sscottl
11788285809Sscottl    status = smsataLLIOStart( smRoot,
11789285809Sscottl                              smIORequest,
11790285809Sscottl                              smDeviceHandle,
11791285809Sscottl                              smScsiRequest,
11792285809Sscottl                              satIOContext);
11793285809Sscottl
11794285809Sscottl
11795285809Sscottl    SM_DBG5(("smsatSendDiagnostic: return Table 29 case 4\n"));
11796285809Sscottl    return (status);
11797285809Sscottl  }
11798285809Sscottl  /* case 5 */
11799285809Sscottl  if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11800285809Sscottl       (pSatDevData->satSMARTSelfTest == agTRUE) &&
11801285809Sscottl       (pSatDevData->satSMARTEnabled == agTRUE)
11802285809Sscottl       )
11803285809Sscottl  {
11804285809Sscottl    /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
11805285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
11806285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11807285809Sscottl    fis->h.command        = SAT_SMART;               /* 0xB0 */
11808285809Sscottl    fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
11809285809Sscottl    fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
11810285809Sscottl    fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11811285809Sscottl    fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11812285809Sscottl    fis->d.lbaLowExp      = 0;
11813285809Sscottl    fis->d.lbaMidExp      = 0;
11814285809Sscottl    fis->d.lbaHighExp     = 0;
11815285809Sscottl    fis->d.featuresExp    = 0;
11816285809Sscottl    fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11817285809Sscottl    fis->d.sectorCountExp = 0;
11818285809Sscottl    fis->d.reserved4      = 0;
11819285809Sscottl    fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
11820285809Sscottl    fis->d.control        = 0;                         /* FIS HOB bit clear */
11821285809Sscottl    fis->d.reserved5      = 0;
11822285809Sscottl
11823285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11824285809Sscottl
11825285809Sscottl    /* Initialize CB for SATA completion.
11826285809Sscottl     */
11827285809Sscottl    satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11828285809Sscottl
11829285809Sscottl    /*
11830285809Sscottl     * Prepare SGL and send FIS to LL layer.
11831285809Sscottl     */
11832285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
11833285809Sscottl
11834285809Sscottl    status = smsataLLIOStart( smRoot,
11835285809Sscottl                              smIORequest,
11836285809Sscottl                              smDeviceHandle,
11837285809Sscottl                              smScsiRequest,
11838285809Sscottl                              satIOContext);
11839285809Sscottl
11840285809Sscottl
11841285809Sscottl    SM_DBG5(("smsatSendDiagnostic: return Table 29 case 5\n"));
11842285809Sscottl    return (status);
11843285809Sscottl  }
11844285809Sscottl
11845285809Sscottl
11846285809Sscottl
11847285809Sscottl
11848285809Sscottl  /* SAT rev8 Table29 p41 case 3*/
11849285809Sscottl  /* checking SELF TEST CODE*/
11850285809Sscottl  if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11851285809Sscottl       (pSatDevData->satSMARTSelfTest == agTRUE) &&
11852285809Sscottl       (pSatDevData->satSMARTEnabled == agTRUE)
11853285809Sscottl       )
11854285809Sscottl  {
11855285809Sscottl    /* SAT rev8 Table28 p40 */
11856285809Sscottl    /* finding self-test code */
11857285809Sscottl    switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5)
11858285809Sscottl    {
11859285809Sscottl    case 1:
11860285809Sscottl      pSatDevData->satBGPendingDiag = agTRUE;
11861285809Sscottl
11862285809Sscottl      tdsmIOCompletedCB( smRoot,
11863285809Sscottl                         smIORequest,
11864285809Sscottl                         smIOSuccess,
11865285809Sscottl                         SCSI_STAT_GOOD,
11866285809Sscottl                         agNULL,
11867285809Sscottl                         satIOContext->interruptContext );
11868285809Sscottl      /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
11869285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
11870285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11871285809Sscottl      fis->h.command        = SAT_SMART;              /* 0x40 */
11872285809Sscottl      fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;  /* FIS features NA       */
11873285809Sscottl      fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
11874285809Sscottl      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11875285809Sscottl      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11876285809Sscottl
11877285809Sscottl      fis->d.lbaLowExp      = 0;
11878285809Sscottl      fis->d.lbaMidExp      = 0;
11879285809Sscottl      fis->d.lbaHighExp     = 0;
11880285809Sscottl      fis->d.featuresExp    = 0;
11881285809Sscottl      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11882285809Sscottl      fis->d.sectorCountExp = 0;
11883285809Sscottl      fis->d.reserved4      = 0;
11884285809Sscottl      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
11885285809Sscottl      fis->d.control        = 0;                         /* FIS HOB bit clear */
11886285809Sscottl      fis->d.reserved5      = 0;
11887285809Sscottl
11888285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11889285809Sscottl
11890285809Sscottl      /* Initialize CB for SATA completion.
11891285809Sscottl       */
11892285809Sscottl      satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11893285809Sscottl
11894285809Sscottl      /*
11895285809Sscottl       * Prepare SGL and send FIS to LL layer.
11896285809Sscottl       */
11897285809Sscottl      satIOContext->reqType = agRequestType;       /* Save it */
11898285809Sscottl
11899285809Sscottl      status = smsataLLIOStart( smRoot,
11900285809Sscottl                                smIORequest,
11901285809Sscottl                                smDeviceHandle,
11902285809Sscottl                                smScsiRequest,
11903285809Sscottl                                satIOContext);
11904285809Sscottl
11905285809Sscottl
11906285809Sscottl      SM_DBG5(("smsatSendDiagnostic: return Table 28 case 1\n"));
11907285809Sscottl      return (status);
11908285809Sscottl    case 2:
11909285809Sscottl      pSatDevData->satBGPendingDiag = agTRUE;
11910285809Sscottl
11911285809Sscottl      tdsmIOCompletedCB( smRoot,
11912285809Sscottl                         smIORequest,
11913285809Sscottl                         smIOSuccess,
11914285809Sscottl                         SCSI_STAT_GOOD,
11915285809Sscottl                         agNULL,
11916285809Sscottl                         satIOContext->interruptContext );
11917285809Sscottl
11918285809Sscottl
11919285809Sscottl      /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
11920285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
11921285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11922285809Sscottl      fis->h.command        = SAT_SMART;              /* 0x40 */
11923285809Sscottl      fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
11924285809Sscottl      fis->d.lbaLow         = 0x02;                      /* FIS LBA (7 :0 ) */
11925285809Sscottl      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11926285809Sscottl      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11927285809Sscottl      fis->d.lbaLowExp      = 0;
11928285809Sscottl      fis->d.lbaMidExp      = 0;
11929285809Sscottl      fis->d.lbaHighExp     = 0;
11930285809Sscottl      fis->d.featuresExp    = 0;
11931285809Sscottl      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11932285809Sscottl      fis->d.sectorCountExp = 0;
11933285809Sscottl      fis->d.reserved4      = 0;
11934285809Sscottl      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
11935285809Sscottl      fis->d.control        = 0;                         /* FIS HOB bit clear */
11936285809Sscottl      fis->d.reserved5      = 0;
11937285809Sscottl
11938285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11939285809Sscottl
11940285809Sscottl      /* Initialize CB for SATA completion.
11941285809Sscottl       */
11942285809Sscottl      satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11943285809Sscottl
11944285809Sscottl      /*
11945285809Sscottl       * Prepare SGL and send FIS to LL layer.
11946285809Sscottl       */
11947285809Sscottl      satIOContext->reqType = agRequestType;       /* Save it */
11948285809Sscottl
11949285809Sscottl      status = smsataLLIOStart( smRoot,
11950285809Sscottl                                smIORequest,
11951285809Sscottl                                smDeviceHandle,
11952285809Sscottl                                smScsiRequest,
11953285809Sscottl                                satIOContext);
11954285809Sscottl
11955285809Sscottl
11956285809Sscottl      SM_DBG5(("smsatSendDiagnostic: return Table 28 case 2\n"));
11957285809Sscottl      return (status);
11958285809Sscottl    case 4:
11959285809Sscottl
11960285809Sscottl      if (parmLen != 0)
11961285809Sscottl      {
11962285809Sscottl        /* check condition */
11963285809Sscottl        smsatSetSensePayload( pSense,
11964285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
11965285809Sscottl                              0,
11966285809Sscottl                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11967285809Sscottl                              satIOContext);
11968285809Sscottl
11969285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
11970285809Sscottl
11971285809Sscottl        tdsmIOCompletedCB( smRoot,
11972285809Sscottl                           smIORequest,
11973285809Sscottl                           smIOSuccess,
11974285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
11975285809Sscottl                           satIOContext->pSmSenseData,
11976285809Sscottl                           satIOContext->interruptContext );
11977285809Sscottl
11978285809Sscottl        SM_DBG1(("smsatSendDiagnostic: case 4, non zero ParmLen %d!!!\n", parmLen));
11979285809Sscottl        return SM_RC_SUCCESS;
11980285809Sscottl      }
11981285809Sscottl      if (pSatDevData->satBGPendingDiag == agTRUE)
11982285809Sscottl      {
11983285809Sscottl        /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */
11984285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
11985285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11986285809Sscottl        fis->h.command        = SAT_SMART;              /* 0x40 */
11987285809Sscottl        fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
11988285809Sscottl        fis->d.lbaLow         = 0x7F;                      /* FIS LBA (7 :0 ) */
11989285809Sscottl        fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11990285809Sscottl        fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11991285809Sscottl
11992285809Sscottl        fis->d.lbaLowExp      = 0;
11993285809Sscottl        fis->d.lbaMidExp      = 0;
11994285809Sscottl        fis->d.lbaHighExp     = 0;
11995285809Sscottl        fis->d.featuresExp    = 0;
11996285809Sscottl        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11997285809Sscottl        fis->d.sectorCountExp = 0;
11998285809Sscottl        fis->d.reserved4      = 0;
11999285809Sscottl        fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
12000285809Sscottl        fis->d.control        = 0;                         /* FIS HOB bit clear */
12001285809Sscottl        fis->d.reserved5      = 0;
12002285809Sscottl
12003285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12004285809Sscottl
12005285809Sscottl        /* Initialize CB for SATA completion.
12006285809Sscottl         */
12007285809Sscottl        satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12008285809Sscottl
12009285809Sscottl        /*
12010285809Sscottl         * Prepare SGL and send FIS to LL layer.
12011285809Sscottl         */
12012285809Sscottl        satIOContext->reqType = agRequestType;       /* Save it */
12013285809Sscottl
12014285809Sscottl        status = smsataLLIOStart( smRoot,
12015285809Sscottl                                  smIORequest,
12016285809Sscottl                                  smDeviceHandle,
12017285809Sscottl                                  smScsiRequest,
12018285809Sscottl                                  satIOContext);
12019285809Sscottl
12020285809Sscottl
12021285809Sscottl        SM_DBG5(("smsatSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
12022285809Sscottl        SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n"));
12023285809Sscottl        return (status);
12024285809Sscottl      }
12025285809Sscottl      else
12026285809Sscottl      {
12027285809Sscottl        /* check condition */
12028285809Sscottl        smsatSetSensePayload( pSense,
12029285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
12030285809Sscottl                              0,
12031285809Sscottl                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12032285809Sscottl                              satIOContext);
12033285809Sscottl
12034285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
12035285809Sscottl
12036285809Sscottl        tdsmIOCompletedCB( smRoot,
12037285809Sscottl                           smIORequest,
12038285809Sscottl                           smIOSuccess,
12039285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
12040285809Sscottl                           satIOContext->pSmSenseData,
12041285809Sscottl                           satIOContext->interruptContext );
12042285809Sscottl
12043285809Sscottl        SM_DBG1(("smsatSendDiagnostic: case 4, no pending diagnostic in background!!!\n"));
12044285809Sscottl        SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n"));
12045285809Sscottl        return SM_RC_SUCCESS;
12046285809Sscottl      }
12047285809Sscottl      break;
12048285809Sscottl    case 5:
12049285809Sscottl      /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
12050285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
12051285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12052285809Sscottl      fis->h.command        = SAT_SMART;              /* 0x40 */
12053285809Sscottl      fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
12054285809Sscottl      fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
12055285809Sscottl      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
12056285809Sscottl      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
12057285809Sscottl      fis->d.lbaLowExp      = 0;
12058285809Sscottl      fis->d.lbaMidExp      = 0;
12059285809Sscottl      fis->d.lbaHighExp     = 0;
12060285809Sscottl      fis->d.featuresExp    = 0;
12061285809Sscottl      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
12062285809Sscottl      fis->d.sectorCountExp = 0;
12063285809Sscottl      fis->d.reserved4      = 0;
12064285809Sscottl      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
12065285809Sscottl      fis->d.control        = 0;                         /* FIS HOB bit clear */
12066285809Sscottl      fis->d.reserved5      = 0;
12067285809Sscottl
12068285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12069285809Sscottl
12070285809Sscottl      /* Initialize CB for SATA completion.
12071285809Sscottl       */
12072285809Sscottl      satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12073285809Sscottl
12074285809Sscottl      /*
12075285809Sscottl       * Prepare SGL and send FIS to LL layer.
12076285809Sscottl       */
12077285809Sscottl      satIOContext->reqType = agRequestType;       /* Save it */
12078285809Sscottl
12079285809Sscottl      status = smsataLLIOStart( smRoot,
12080285809Sscottl                                smIORequest,
12081285809Sscottl                                smDeviceHandle,
12082285809Sscottl                                smScsiRequest,
12083285809Sscottl                                satIOContext);
12084285809Sscottl
12085285809Sscottl
12086285809Sscottl      SM_DBG5(("smsatSendDiagnostic: return Table 28 case 5\n"));
12087285809Sscottl      return (status);
12088285809Sscottl    case 6:
12089285809Sscottl      /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
12090285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
12091285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12092285809Sscottl      fis->h.command        = SAT_SMART;              /* 0x40 */
12093285809Sscottl      fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
12094285809Sscottl      fis->d.lbaLow         = 0x82;                      /* FIS LBA (7 :0 ) */
12095285809Sscottl      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
12096285809Sscottl      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
12097285809Sscottl      fis->d.lbaLowExp      = 0;
12098285809Sscottl      fis->d.lbaMidExp      = 0;
12099285809Sscottl      fis->d.lbaHighExp     = 0;
12100285809Sscottl      fis->d.featuresExp    = 0;
12101285809Sscottl      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
12102285809Sscottl      fis->d.sectorCountExp = 0;
12103285809Sscottl      fis->d.reserved4      = 0;
12104285809Sscottl      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
12105285809Sscottl      fis->d.control        = 0;                         /* FIS HOB bit clear */
12106285809Sscottl      fis->d.reserved5      = 0;
12107285809Sscottl
12108285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12109285809Sscottl
12110285809Sscottl      /* Initialize CB for SATA completion.
12111285809Sscottl       */
12112285809Sscottl      satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12113285809Sscottl
12114285809Sscottl      /*
12115285809Sscottl       * Prepare SGL and send FIS to LL layer.
12116285809Sscottl       */
12117285809Sscottl      satIOContext->reqType = agRequestType;       /* Save it */
12118285809Sscottl
12119285809Sscottl      status = smsataLLIOStart( smRoot,
12120285809Sscottl                                smIORequest,
12121285809Sscottl                                smDeviceHandle,
12122285809Sscottl                                smScsiRequest,
12123285809Sscottl                                satIOContext);
12124285809Sscottl
12125285809Sscottl
12126285809Sscottl      SM_DBG5(("smsatSendDiagnostic: return Table 28 case 6\n"));
12127285809Sscottl      return (status);
12128285809Sscottl    case 0:
12129285809Sscottl    case 3: /* fall through */
12130285809Sscottl    case 7: /* fall through */
12131285809Sscottl    default:
12132285809Sscottl      break;
12133285809Sscottl    }/* switch */
12134285809Sscottl
12135285809Sscottl    /* returns the results of default self-testing, which is good */
12136285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
12137285809Sscottl
12138285809Sscottl    tdsmIOCompletedCB( smRoot,
12139285809Sscottl                       smIORequest,
12140285809Sscottl                       smIOSuccess,
12141285809Sscottl                       SCSI_STAT_GOOD,
12142285809Sscottl                       agNULL,
12143285809Sscottl                       satIOContext->interruptContext );
12144285809Sscottl
12145285809Sscottl    SM_DBG5(("smsatSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
12146285809Sscottl    return SM_RC_SUCCESS;
12147285809Sscottl  }
12148285809Sscottl
12149285809Sscottl
12150285809Sscottl  /*smEnqueueIO(smRoot, satIOContext);*/
12151285809Sscottl
12152285809Sscottl  tdsmIOCompletedCB( smRoot,
12153285809Sscottl                     smIORequest,
12154285809Sscottl                     smIOSuccess,
12155285809Sscottl                     SCSI_STAT_GOOD,
12156285809Sscottl                     agNULL,
12157285809Sscottl                     satIOContext->interruptContext );
12158285809Sscottl
12159285809Sscottl
12160285809Sscottl  SM_DBG5(("smsatSendDiagnostic: return last\n"));
12161285809Sscottl  return SM_RC_SUCCESS;
12162285809Sscottl
12163285809Sscottl}
12164285809Sscottl
12165285809SscottlosGLOBAL bit32
12166285809SscottlsmsatStartStopUnit(
12167285809Sscottl                   smRoot_t                  *smRoot,
12168285809Sscottl                   smIORequest_t             *smIORequest,
12169285809Sscottl                   smDeviceHandle_t          *smDeviceHandle,
12170285809Sscottl                   smScsiInitiatorRequest_t  *smScsiRequest,
12171285809Sscottl                   smSatIOContext_t            *satIOContext
12172285809Sscottl                  )
12173285809Sscottl{
12174285809Sscottl  bit32                     status;
12175285809Sscottl  bit32                     agRequestType;
12176285809Sscottl  smDeviceData_t            *pSatDevData;
12177285809Sscottl  smScsiRspSense_t          *pSense;
12178285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
12179285809Sscottl  agsaFisRegHostToDevice_t  *fis;
12180285809Sscottl
12181285809Sscottl  pSense        = satIOContext->pSense;
12182285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
12183285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
12184285809Sscottl  fis           = satIOContext->pFis;
12185285809Sscottl
12186285809Sscottl  SM_DBG5(("smsatStartStopUnit: start\n"));
12187285809Sscottl
12188285809Sscottl  /* checking CONTROL */
12189285809Sscottl  /* NACA == 1 or LINK == 1*/
12190285809Sscottl  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
12191285809Sscottl  {
12192285809Sscottl    smsatSetSensePayload( pSense,
12193285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12194285809Sscottl                          0,
12195285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12196285809Sscottl                          satIOContext);
12197285809Sscottl
12198285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
12199285809Sscottl
12200285809Sscottl    tdsmIOCompletedCB( smRoot,
12201285809Sscottl                       smIORequest,
12202285809Sscottl                       smIOSuccess,
12203285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
12204285809Sscottl                       satIOContext->pSmSenseData,
12205285809Sscottl                       satIOContext->interruptContext );
12206285809Sscottl
12207285809Sscottl    SM_DBG1(("smsatStartStopUnit: return control!!!\n"));
12208285809Sscottl    return SM_RC_SUCCESS;
12209285809Sscottl  }
12210285809Sscottl
12211285809Sscottl  /* Spec p55, Table 48 checking START and LOEJ bit */
12212285809Sscottl  /* case 1 */
12213285809Sscottl  if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12214285809Sscottl  {
12215285809Sscottl    if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12216285809Sscottl    {
12217285809Sscottl      /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12218285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
12219285809Sscottl
12220285809Sscottl      tdsmIOCompletedCB( smRoot,
12221285809Sscottl                         smIORequest,
12222285809Sscottl                         smIOSuccess,
12223285809Sscottl                         SCSI_STAT_GOOD,
12224285809Sscottl                         agNULL,
12225285809Sscottl                         satIOContext->interruptContext );
12226285809Sscottl      SM_DBG5(("smsatStartStopUnit: return table48 case 1-1\n"));
12227285809Sscottl      return SM_RC_SUCCESS;
12228285809Sscottl    }
12229285809Sscottl    /* sends FLUSH CACHE or FLUSH CACHE EXT */
12230285809Sscottl    if (pSatDevData->sat48BitSupport == agTRUE)
12231285809Sscottl    {
12232285809Sscottl      /* FLUSH CACHE EXT */
12233285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
12234285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12235285809Sscottl
12236285809Sscottl      fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
12237285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
12238285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
12239285809Sscottl      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
12240285809Sscottl      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12241285809Sscottl      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
12242285809Sscottl      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
12243285809Sscottl      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
12244285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12245285809Sscottl      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
12246285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12247285809Sscottl      fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
12248285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
12249285809Sscottl      fis->d.reserved4      = 0;
12250285809Sscottl      fis->d.reserved5      = 0;
12251285809Sscottl
12252285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12253285809Sscottl    }
12254285809Sscottl    else
12255285809Sscottl    {
12256285809Sscottl      /* FLUSH CACHE */
12257285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
12258285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12259285809Sscottl
12260285809Sscottl      fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
12261285809Sscottl      fis->h.features       = 0;                      /* FIS features NA       */
12262285809Sscottl      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
12263285809Sscottl      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
12264285809Sscottl      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
12265285809Sscottl      fis->d.lbaLowExp      = 0;
12266285809Sscottl      fis->d.lbaMidExp      = 0;
12267285809Sscottl      fis->d.lbaHighExp     = 0;
12268285809Sscottl      fis->d.featuresExp    = 0;
12269285809Sscottl      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
12270285809Sscottl      fis->d.sectorCountExp = 0;
12271285809Sscottl      fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
12272285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
12273285809Sscottl      fis->d.reserved4      = 0;
12274285809Sscottl      fis->d.reserved5      = 0;
12275285809Sscottl
12276285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12277285809Sscottl    }
12278285809Sscottl
12279285809Sscottl    /* Initialize CB for SATA completion.
12280285809Sscottl     */
12281285809Sscottl    satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12282285809Sscottl
12283285809Sscottl    /*
12284285809Sscottl     * Prepare SGL and send FIS to LL layer.
12285285809Sscottl     */
12286285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
12287285809Sscottl
12288285809Sscottl    status = smsataLLIOStart( smRoot,
12289285809Sscottl                              smIORequest,
12290285809Sscottl                              smDeviceHandle,
12291285809Sscottl                              smScsiRequest,
12292285809Sscottl                              satIOContext);
12293285809Sscottl
12294285809Sscottl
12295285809Sscottl    SM_DBG5(("smsatStartStopUnit: return table48 case 1\n"));
12296285809Sscottl    return (status);
12297285809Sscottl  }
12298285809Sscottl  /* case 2 */
12299285809Sscottl  else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12300285809Sscottl  {
12301285809Sscottl    /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12302285809Sscottl    if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12303285809Sscottl    {
12304285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
12305285809Sscottl
12306285809Sscottl      tdsmIOCompletedCB( smRoot,
12307285809Sscottl                         smIORequest,
12308285809Sscottl                         smIOSuccess,
12309285809Sscottl                         SCSI_STAT_GOOD,
12310285809Sscottl                         agNULL,
12311285809Sscottl                         satIOContext->interruptContext );
12312285809Sscottl
12313285809Sscottl      SM_DBG5(("smsatStartStopUnit: return table48 case 2 1\n"));
12314285809Sscottl      return SM_RC_SUCCESS;
12315285809Sscottl    }
12316285809Sscottl    /*
12317285809Sscottl      sends READ_VERIFY_SECTORS(_EXT)
12318285809Sscottl      sector count 1, any LBA between zero to Maximum
12319285809Sscottl    */
12320285809Sscottl    if (pSatDevData->sat48BitSupport == agTRUE)
12321285809Sscottl    {
12322285809Sscottl      /* READ VERIFY SECTOR(S) EXT*/
12323285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
12324285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12325285809Sscottl
12326285809Sscottl      fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
12327285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
12328285809Sscottl      fis->d.lbaLow         = 0x01;                   /* FIS LBA (7 :0 ) */
12329285809Sscottl      fis->d.lbaMid         = 0x00;                   /* FIS LBA (15:8 ) */
12330285809Sscottl      fis->d.lbaHigh        = 0x00;                   /* FIS LBA (23:16) */
12331285809Sscottl      fis->d.lbaLowExp      = 0x00;                   /* FIS LBA (31:24) */
12332285809Sscottl      fis->d.lbaMidExp      = 0x00;                   /* FIS LBA (39:32) */
12333285809Sscottl      fis->d.lbaHighExp     = 0x00;                   /* FIS LBA (47:40) */
12334285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
12335285809Sscottl      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12336285809Sscottl      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12337285809Sscottl      fis->d.reserved4      = 0;
12338285809Sscottl      fis->d.device         = 0x40;                   /* 01000000 */
12339285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
12340285809Sscottl      fis->d.reserved5      = 0;
12341285809Sscottl
12342285809Sscottl    }
12343285809Sscottl    else
12344285809Sscottl    {
12345285809Sscottl      /* READ VERIFY SECTOR(S)*/
12346285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
12347285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12348285809Sscottl
12349285809Sscottl      fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
12350285809Sscottl      fis->h.features       = 0;                      /* FIS features NA       */
12351285809Sscottl      fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
12352285809Sscottl      fis->d.lbaMid         = 0x00;                      /* FIS LBA (15:8 ) */
12353285809Sscottl      fis->d.lbaHigh        = 0x00;                      /* FIS LBA (23:16) */
12354285809Sscottl      fis->d.lbaLowExp      = 0;
12355285809Sscottl      fis->d.lbaMidExp      = 0;
12356285809Sscottl      fis->d.lbaHighExp     = 0;
12357285809Sscottl      fis->d.featuresExp    = 0;
12358285809Sscottl      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12359285809Sscottl      fis->d.sectorCountExp = 0;
12360285809Sscottl      fis->d.reserved4      = 0;
12361285809Sscottl      fis->d.device         = 0x40;                   /* 01000000 */
12362285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
12363285809Sscottl      fis->d.reserved5      = 0;
12364285809Sscottl
12365285809Sscottl    }
12366285809Sscottl
12367285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12368285809Sscottl
12369285809Sscottl    /* Initialize CB for SATA completion.
12370285809Sscottl     */
12371285809Sscottl    satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12372285809Sscottl
12373285809Sscottl    /*
12374285809Sscottl     * Prepare SGL and send FIS to LL layer.
12375285809Sscottl     */
12376285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
12377285809Sscottl
12378285809Sscottl    status = smsataLLIOStart( smRoot,
12379285809Sscottl                              smIORequest,
12380285809Sscottl                              smDeviceHandle,
12381285809Sscottl                              smScsiRequest,
12382285809Sscottl                              satIOContext);
12383285809Sscottl
12384285809Sscottl    SM_DBG5(("smsatStartStopUnit: return table48 case 2 2\n"));
12385285809Sscottl    return status;
12386285809Sscottl  }
12387285809Sscottl  /* case 3 */
12388285809Sscottl  else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12389285809Sscottl  {
12390285809Sscottl    if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
12391285809Sscottl    {
12392285809Sscottl      /* support for removal media */
12393285809Sscottl      /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12394285809Sscottl      if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12395285809Sscottl      {
12396285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
12397285809Sscottl
12398285809Sscottl        tdsmIOCompletedCB( smRoot,
12399285809Sscottl                           smIORequest,
12400285809Sscottl                           smIOSuccess,
12401285809Sscottl                           SCSI_STAT_GOOD,
12402285809Sscottl                           agNULL,
12403285809Sscottl                           satIOContext->interruptContext );
12404285809Sscottl
12405285809Sscottl        SM_DBG5(("smsatStartStopUnit: return table48 case 3 1\n"));
12406285809Sscottl        return SM_RC_SUCCESS;
12407285809Sscottl      }
12408285809Sscottl      /*
12409285809Sscottl        sends MEDIA EJECT
12410285809Sscottl      */
12411285809Sscottl      /* Media Eject fis */
12412285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
12413285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12414285809Sscottl
12415285809Sscottl      fis->h.command        = SAT_MEDIA_EJECT;        /* 0xED */
12416285809Sscottl      fis->h.features       = 0;                      /* FIS features NA       */
12417285809Sscottl      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
12418285809Sscottl      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
12419285809Sscottl      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
12420285809Sscottl      fis->d.lbaLowExp      = 0;
12421285809Sscottl      fis->d.lbaMidExp      = 0;
12422285809Sscottl      fis->d.lbaHighExp     = 0;
12423285809Sscottl      fis->d.featuresExp    = 0;
12424285809Sscottl      /* sector count zero */
12425285809Sscottl      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
12426285809Sscottl      fis->d.sectorCountExp = 0;
12427285809Sscottl      fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
12428285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
12429285809Sscottl      fis->d.reserved4      = 0;
12430285809Sscottl      fis->d.reserved5      = 0;
12431285809Sscottl
12432285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12433285809Sscottl
12434285809Sscottl      /* Initialize CB for SATA completion.
12435285809Sscottl       */
12436285809Sscottl      satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12437285809Sscottl
12438285809Sscottl      /*
12439285809Sscottl       * Prepare SGL and send FIS to LL layer.
12440285809Sscottl       */
12441285809Sscottl      satIOContext->reqType = agRequestType;       /* Save it */
12442285809Sscottl
12443285809Sscottl      status = smsataLLIOStart( smRoot,
12444285809Sscottl                                smIORequest,
12445285809Sscottl                                smDeviceHandle,
12446285809Sscottl                                smScsiRequest,
12447285809Sscottl                                satIOContext);
12448285809Sscottl
12449285809Sscottl      return status;
12450285809Sscottl    }
12451285809Sscottl    else
12452285809Sscottl    {
12453285809Sscottl      /* no support for removal media */
12454285809Sscottl      smsatSetSensePayload( pSense,
12455285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
12456285809Sscottl                            0,
12457285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12458285809Sscottl                            satIOContext);
12459285809Sscottl
12460285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
12461285809Sscottl
12462285809Sscottl      tdsmIOCompletedCB( smRoot,
12463285809Sscottl                         smIORequest,
12464285809Sscottl                         smIOSuccess,
12465285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
12466285809Sscottl                         satIOContext->pSmSenseData,
12467285809Sscottl                         satIOContext->interruptContext );
12468285809Sscottl
12469285809Sscottl      SM_DBG5(("smsatStartStopUnit: return Table 29 case 3 2\n"));
12470285809Sscottl      return SM_RC_SUCCESS;
12471285809Sscottl    }
12472285809Sscottl
12473285809Sscottl  }
12474285809Sscottl  /* case 4 */
12475285809Sscottl  else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */
12476285809Sscottl  {
12477285809Sscottl    smsatSetSensePayload( pSense,
12478285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12479285809Sscottl                          0,
12480285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12481285809Sscottl                          satIOContext);
12482285809Sscottl
12483285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
12484285809Sscottl
12485285809Sscottl    tdsmIOCompletedCB( smRoot,
12486285809Sscottl                       smIORequest,
12487285809Sscottl                       smIOSuccess,
12488285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
12489285809Sscottl                       satIOContext->pSmSenseData,
12490285809Sscottl                       satIOContext->interruptContext );
12491285809Sscottl
12492285809Sscottl    SM_DBG5(("smsatStartStopUnit: return Table 29 case 4\n"));
12493285809Sscottl    return SM_RC_SUCCESS;
12494285809Sscottl  }
12495285809Sscottl}
12496285809Sscottl
12497285809SscottlosGLOBAL bit32
12498285809SscottlsmsatWriteSame10(
12499285809Sscottl                  smRoot_t                  *smRoot,
12500285809Sscottl                  smIORequest_t             *smIORequest,
12501285809Sscottl                  smDeviceHandle_t          *smDeviceHandle,
12502285809Sscottl                  smScsiInitiatorRequest_t  *smScsiRequest,
12503285809Sscottl                  smSatIOContext_t            *satIOContext
12504285809Sscottl                 )
12505285809Sscottl{
12506285809Sscottl
12507285809Sscottl  bit32                     status;
12508285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
12509285809Sscottl  smDeviceData_t            *pSatDevData;
12510285809Sscottl  smScsiRspSense_t          *pSense;
12511285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
12512285809Sscottl  agsaFisRegHostToDevice_t  *fis;
12513285809Sscottl  bit32                     lba = 0;
12514285809Sscottl  bit32                     tl = 0;
12515285809Sscottl
12516285809Sscottl  pSense        = satIOContext->pSense;
12517285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
12518285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
12519285809Sscottl  fis           = satIOContext->pFis;
12520285809Sscottl
12521285809Sscottl  SM_DBG5(("smsatWriteSame10: start\n"));
12522285809Sscottl
12523285809Sscottl  /* checking CONTROL */
12524285809Sscottl    /* NACA == 1 or LINK == 1*/
12525285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
12526285809Sscottl  {
12527285809Sscottl    smsatSetSensePayload( pSense,
12528285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12529285809Sscottl                          0,
12530285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12531285809Sscottl                          satIOContext);
12532285809Sscottl
12533285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
12534285809Sscottl
12535285809Sscottl    tdsmIOCompletedCB( smRoot,
12536285809Sscottl                       smIORequest,
12537285809Sscottl                       smIOSuccess,
12538285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
12539285809Sscottl                       satIOContext->pSmSenseData,
12540285809Sscottl                       satIOContext->interruptContext );
12541285809Sscottl
12542285809Sscottl    SM_DBG1(("smsatWriteSame10: return control!!!\n"));
12543285809Sscottl    return SM_RC_SUCCESS;
12544285809Sscottl  }
12545285809Sscottl
12546285809Sscottl
12547285809Sscottl  /* checking LBDATA and PBDATA */
12548285809Sscottl  /* case 1 */
12549285809Sscottl  if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12550285809Sscottl       !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12551285809Sscottl  {
12552285809Sscottl    SM_DBG5(("smsatWriteSame10: case 1\n"));
12553285809Sscottl    /* spec 9.26.2, Table 62, p64, case 1*/
12554285809Sscottl    /*
12555285809Sscottl      normal case
12556285809Sscottl      just like write in 9.17.1
12557285809Sscottl    */
12558285809Sscottl
12559285809Sscottl    if ( pSatDevData->sat48BitSupport != agTRUE )
12560285809Sscottl    {
12561285809Sscottl      /*
12562285809Sscottl        writeSame10 but no support for 48 bit addressing
12563285809Sscottl        -> problem in transfer length. Therefore, return check condition
12564285809Sscottl      */
12565285809Sscottl      smsatSetSensePayload( pSense,
12566285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
12567285809Sscottl                            0,
12568285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12569285809Sscottl                            satIOContext);
12570285809Sscottl
12571285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
12572285809Sscottl
12573285809Sscottl      tdsmIOCompletedCB( smRoot,
12574285809Sscottl                         smIORequest,
12575285809Sscottl                         smIOSuccess,
12576285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
12577285809Sscottl                         satIOContext->pSmSenseData,
12578285809Sscottl                         satIOContext->interruptContext );
12579285809Sscottl
12580285809Sscottl      SM_DBG1(("smsatWriteSame10: return internal checking!!!\n"));
12581285809Sscottl      return SM_RC_SUCCESS;
12582285809Sscottl    }
12583285809Sscottl
12584285809Sscottl    /* cdb10; computing LBA and transfer length */
12585285809Sscottl    lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
12586285809Sscottl      + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
12587285809Sscottl    tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
12588285809Sscottl
12589285809Sscottl
12590285809Sscottl    /* Table 34, 9.1, p 46 */
12591285809Sscottl    /*
12592285809Sscottl      note: As of 2/10/2006, no support for DMA QUEUED
12593285809Sscottl    */
12594285809Sscottl
12595285809Sscottl    /*
12596285809Sscottl      Table 34, 9.1, p 46, b (footnote)
12597285809Sscottl      When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
12598285809Sscottl      return check condition
12599285809Sscottl    */
12600285809Sscottl    if (pSatDevData->satNCQ != agTRUE &&
12601285809Sscottl        pSatDevData->sat48BitSupport != agTRUE
12602285809Sscottl          )
12603285809Sscottl    {
12604285809Sscottl      if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */
12605285809Sscottl      {
12606285809Sscottl        smsatSetSensePayload( pSense,
12607285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
12608285809Sscottl                              0,
12609285809Sscottl                              SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
12610285809Sscottl                              satIOContext);
12611285809Sscottl
12612285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
12613285809Sscottl
12614285809Sscottl        tdsmIOCompletedCB( smRoot,
12615285809Sscottl                           smIORequest,
12616285809Sscottl                           smIOSuccess,
12617285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
12618285809Sscottl                           satIOContext->pSmSenseData,
12619285809Sscottl                           satIOContext->interruptContext );
12620285809Sscottl
12621285809Sscottl        SM_DBG1(("smsatWriteSame10: return LBA out of range!!!\n"));
12622285809Sscottl        return SM_RC_SUCCESS;
12623285809Sscottl      }
12624285809Sscottl    }
12625285809Sscottl
12626285809Sscottl
12627285809Sscottl    if (lba + tl <= SAT_TR_LBA_LIMIT)
12628285809Sscottl    {
12629285809Sscottl      if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
12630285809Sscottl      {
12631285809Sscottl        /* case 2 */
12632285809Sscottl        /* WRITE DMA */
12633285809Sscottl        /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
12634285809Sscottl        SM_DBG1(("smsatWriteSame10: case 1-2 !!! error due to writesame10!!!\n"));
12635285809Sscottl        smsatSetSensePayload( pSense,
12636285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
12637285809Sscottl                              0,
12638285809Sscottl                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12639285809Sscottl                              satIOContext);
12640285809Sscottl
12641285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
12642285809Sscottl
12643285809Sscottl        tdsmIOCompletedCB( smRoot,
12644285809Sscottl                           smIORequest,
12645285809Sscottl                           smIOSuccess,
12646285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
12647285809Sscottl                           satIOContext->pSmSenseData,
12648285809Sscottl                           satIOContext->interruptContext );
12649285809Sscottl        return SM_RC_SUCCESS;
12650285809Sscottl      }
12651285809Sscottl      else
12652285809Sscottl      {
12653285809Sscottl        /* case 1 */
12654285809Sscottl        /* WRITE MULTIPLE or WRITE SECTOR(S) */
12655285809Sscottl        /* WRITE SECTORS is chosen for easier implemetation */
12656285809Sscottl        /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
12657285809Sscottl        SM_DBG1(("smsatWriteSame10: case 1-1 !!! error due to writesame10!!!\n"));
12658285809Sscottl        smsatSetSensePayload( pSense,
12659285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
12660285809Sscottl                              0,
12661285809Sscottl                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12662285809Sscottl                              satIOContext);
12663285809Sscottl
12664285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
12665285809Sscottl
12666285809Sscottl        tdsmIOCompletedCB( smRoot,
12667285809Sscottl                           smIORequest,
12668285809Sscottl                           smIOSuccess,
12669285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
12670285809Sscottl                           satIOContext->pSmSenseData,
12671285809Sscottl                           satIOContext->interruptContext );
12672285809Sscottl        return SM_RC_SUCCESS;
12673285809Sscottl      }
12674285809Sscottl    } /* end of case 1 and 2 */
12675285809Sscottl
12676285809Sscottl    /* case 3 and 4 */
12677285809Sscottl    if (pSatDevData->sat48BitSupport == agTRUE)
12678285809Sscottl    {
12679285809Sscottl      if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
12680285809Sscottl      {
12681285809Sscottl        /* case 3 */
12682285809Sscottl        /* WRITE DMA EXT or WRITE DMA FUA EXT */
12683285809Sscottl        /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */
12684285809Sscottl        SM_DBG5(("smsatWriteSame10: case 1-3\n"));
12685285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
12686285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12687285809Sscottl
12688285809Sscottl        fis->h.command        = SAT_WRITE_DMA_EXT;          /* 0x35 */
12689285809Sscottl
12690285809Sscottl        fis->h.features       = 0;                      /* FIS reserve */
12691285809Sscottl        fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
12692285809Sscottl        fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
12693285809Sscottl        fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
12694285809Sscottl        fis->d.device         = 0x40;                   /* FIS LBA mode set */
12695285809Sscottl        fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
12696285809Sscottl        fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12697285809Sscottl        fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12698285809Sscottl        fis->d.featuresExp    = 0;                      /* FIS reserve */
12699285809Sscottl        if (tl == 0)
12700285809Sscottl        {
12701285809Sscottl          /* error check
12702285809Sscottl             ATA spec, p125, 6.17.29
12703285809Sscottl             pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12704285809Sscottl             and allowed value is 0x0FFFFFFF - 1
12705285809Sscottl          */
12706285809Sscottl          if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12707285809Sscottl          {
12708285809Sscottl            SM_DBG1(("smsatWriteSame10: case 3 !!! warning can't fit sectors!!!\n"));
12709285809Sscottl            smsatSetSensePayload( pSense,
12710285809Sscottl                                  SCSI_SNSKEY_ILLEGAL_REQUEST,
12711285809Sscottl                                  0,
12712285809Sscottl                                  SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12713285809Sscottl                                  satIOContext);
12714285809Sscottl
12715285809Sscottl            /*smEnqueueIO(smRoot, satIOContext);*/
12716285809Sscottl
12717285809Sscottl            tdsmIOCompletedCB( smRoot,
12718285809Sscottl                               smIORequest,
12719285809Sscottl                               smIOSuccess,
12720285809Sscottl                               SCSI_STAT_CHECK_CONDITION,
12721285809Sscottl                               satIOContext->pSmSenseData,
12722285809Sscottl                               satIOContext->interruptContext );
12723285809Sscottl            return SM_RC_SUCCESS;
12724285809Sscottl          }
12725285809Sscottl        }
12726285809Sscottl        /* one sector at a time */
12727285809Sscottl        fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12728285809Sscottl        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12729285809Sscottl        fis->d.reserved4      = 0;
12730285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
12731285809Sscottl        fis->d.reserved5      = 0;
12732285809Sscottl
12733285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
12734285809Sscottl      }
12735285809Sscottl      else
12736285809Sscottl      {
12737285809Sscottl        /* case 4 */
12738285809Sscottl        /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
12739285809Sscottl        /* WRITE SECTORS EXT is chosen for easier implemetation */
12740285809Sscottl        SM_DBG5(("smsatWriteSame10: case 1-4\n"));
12741285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
12742285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12743285809Sscottl
12744285809Sscottl        fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
12745285809Sscottl        fis->h.features       = 0;                      /* FIS reserve */
12746285809Sscottl        fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
12747285809Sscottl        fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
12748285809Sscottl        fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
12749285809Sscottl        fis->d.device         = 0x40;                   /* FIS LBA mode set */
12750285809Sscottl        fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
12751285809Sscottl        fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12752285809Sscottl        fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12753285809Sscottl        fis->d.featuresExp    = 0;                      /* FIS reserve */
12754285809Sscottl        if (tl == 0)
12755285809Sscottl        {
12756285809Sscottl          /* error check
12757285809Sscottl             ATA spec, p125, 6.17.29
12758285809Sscottl             pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12759285809Sscottl             and allowed value is 0x0FFFFFFF - 1
12760285809Sscottl          */
12761285809Sscottl          if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12762285809Sscottl          {
12763285809Sscottl            SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n"));
12764285809Sscottl            smsatSetSensePayload( pSense,
12765285809Sscottl                                  SCSI_SNSKEY_ILLEGAL_REQUEST,
12766285809Sscottl                                  0,
12767285809Sscottl                                  SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12768285809Sscottl                                  satIOContext);
12769285809Sscottl
12770285809Sscottl            /*smEnqueueIO(smRoot, satIOContext);*/
12771285809Sscottl
12772285809Sscottl            tdsmIOCompletedCB( smRoot,
12773285809Sscottl                               smIORequest,
12774285809Sscottl                               smIOSuccess,
12775285809Sscottl                               SCSI_STAT_CHECK_CONDITION,
12776285809Sscottl                               satIOContext->pSmSenseData,
12777285809Sscottl                               satIOContext->interruptContext );
12778285809Sscottl            return SM_RC_SUCCESS;
12779285809Sscottl          }
12780285809Sscottl        }
12781285809Sscottl        /* one sector at a time */
12782285809Sscottl        fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12783285809Sscottl        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12784285809Sscottl        fis->d.reserved4      = 0;
12785285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
12786285809Sscottl        fis->d.reserved5      = 0;
12787285809Sscottl
12788285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
12789285809Sscottl      }
12790285809Sscottl    }
12791285809Sscottl
12792285809Sscottl    /* case 5 */
12793285809Sscottl    if (pSatDevData->satNCQ == agTRUE)
12794285809Sscottl    {
12795285809Sscottl      /* WRITE FPDMA QUEUED */
12796285809Sscottl      if (pSatDevData->sat48BitSupport != agTRUE)
12797285809Sscottl      {
12798285809Sscottl        SM_DBG1(("smsatWriteSame10: case 1-5 !!! error NCQ but 28 bit address support!!!\n"));
12799285809Sscottl        smsatSetSensePayload( pSense,
12800285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
12801285809Sscottl                              0,
12802285809Sscottl                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12803285809Sscottl                              satIOContext);
12804285809Sscottl
12805285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
12806285809Sscottl
12807285809Sscottl        tdsmIOCompletedCB( smRoot,
12808285809Sscottl                           smIORequest,
12809285809Sscottl                           smIOSuccess,
12810285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
12811285809Sscottl                           satIOContext->pSmSenseData,
12812285809Sscottl                           satIOContext->interruptContext );
12813285809Sscottl        return SM_RC_SUCCESS;
12814285809Sscottl      }
12815285809Sscottl      SM_DBG5(("smsatWriteSame10: case 1-5\n"));
12816285809Sscottl
12817285809Sscottl      /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
12818285809Sscottl
12819285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
12820285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12821285809Sscottl      fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
12822285809Sscottl
12823285809Sscottl      if (tl == 0)
12824285809Sscottl      {
12825285809Sscottl        /* error check
12826285809Sscottl           ATA spec, p125, 6.17.29
12827285809Sscottl           pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12828285809Sscottl           and allowed value is 0x0FFFFFFF - 1
12829285809Sscottl        */
12830285809Sscottl        if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12831285809Sscottl        {
12832285809Sscottl          SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n"));
12833285809Sscottl          smsatSetSensePayload( pSense,
12834285809Sscottl                                SCSI_SNSKEY_ILLEGAL_REQUEST,
12835285809Sscottl                                0,
12836285809Sscottl                                SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12837285809Sscottl                                satIOContext);
12838285809Sscottl
12839285809Sscottl          /*smEnqueueIO(smRoot, satIOContext);*/
12840285809Sscottl
12841285809Sscottl          tdsmIOCompletedCB( smRoot,
12842285809Sscottl                             smIORequest,
12843285809Sscottl                             smIOSuccess,
12844285809Sscottl                             SCSI_STAT_CHECK_CONDITION,
12845285809Sscottl                             satIOContext->pSmSenseData,
12846285809Sscottl                             satIOContext->interruptContext );
12847285809Sscottl          return SM_RC_SUCCESS;
12848285809Sscottl        }
12849285809Sscottl      }
12850285809Sscottl      /* one sector at a time */
12851285809Sscottl      fis->h.features       = 1;            /* FIS sector count (7:0) */
12852285809Sscottl      fis->d.featuresExp    = 0;            /* FIS sector count (15:8) */
12853285809Sscottl
12854285809Sscottl
12855285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
12856285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
12857285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
12858285809Sscottl
12859285809Sscottl      /* NO FUA bit in the WRITE SAME 10 */
12860285809Sscottl      fis->d.device       = 0x40;                     /* FIS FUA clear */
12861285809Sscottl
12862285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
12863285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12864285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12865285809Sscottl      fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
12866285809Sscottl      fis->d.sectorCountExp = 0;
12867285809Sscottl      fis->d.reserved4      = 0;
12868285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
12869285809Sscottl      fis->d.reserved5      = 0;
12870285809Sscottl
12871285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
12872285809Sscottl    }
12873285809Sscottl    /* Initialize CB for SATA completion.
12874285809Sscottl     */
12875285809Sscottl    satIOContext->satCompleteCB = &smsatWriteSame10CB;
12876285809Sscottl
12877285809Sscottl    /*
12878285809Sscottl     * Prepare SGL and send FIS to LL layer.
12879285809Sscottl     */
12880285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
12881285809Sscottl
12882285809Sscottl    status = smsataLLIOStart( smRoot,
12883285809Sscottl                              smIORequest,
12884285809Sscottl                              smDeviceHandle,
12885285809Sscottl                              smScsiRequest,
12886285809Sscottl                              satIOContext);
12887285809Sscottl    return (status);
12888285809Sscottl
12889285809Sscottl
12890285809Sscottl  } /* end of case 1 */
12891285809Sscottl  else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12892285809Sscottl             (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12893285809Sscottl  {
12894285809Sscottl    /* spec 9.26.2, Table 62, p64, case 2*/
12895285809Sscottl    smsatSetSensePayload( pSense,
12896285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12897285809Sscottl                          0,
12898285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12899285809Sscottl                          satIOContext);
12900285809Sscottl
12901285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
12902285809Sscottl
12903285809Sscottl    tdsmIOCompletedCB( smRoot,
12904285809Sscottl                       smIORequest,
12905285809Sscottl                       smIOSuccess,
12906285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
12907285809Sscottl                       satIOContext->pSmSenseData,
12908285809Sscottl                       satIOContext->interruptContext );
12909285809Sscottl
12910285809Sscottl    SM_DBG5(("smsatWriteSame10: return Table 62 case 2\n"));
12911285809Sscottl    return SM_RC_SUCCESS;
12912285809Sscottl  }
12913285809Sscottl  else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12914285809Sscottl           !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12915285809Sscottl  {
12916285809Sscottl    SM_DBG5(("smsatWriteSame10: Table 62 case 3\n"));
12917285809Sscottl
12918285809Sscottl  }
12919285809Sscottl  else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12920285809Sscottl            (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */
12921285809Sscottl  {
12922285809Sscottl
12923285809Sscottl    /* spec 9.26.2, Table 62, p64, case 4*/
12924285809Sscottl    smsatSetSensePayload( pSense,
12925285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12926285809Sscottl                          0,
12927285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12928285809Sscottl                          satIOContext);
12929285809Sscottl
12930285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
12931285809Sscottl
12932285809Sscottl    tdsmIOCompletedCB( smRoot,
12933285809Sscottl                       smIORequest,
12934285809Sscottl                       smIOSuccess,
12935285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
12936285809Sscottl                       satIOContext->pSmSenseData,
12937285809Sscottl                       satIOContext->interruptContext );
12938285809Sscottl
12939285809Sscottl    SM_DBG5(("smsatWriteSame10: return Table 62 case 4\n"));
12940285809Sscottl    return SM_RC_SUCCESS;
12941285809Sscottl  }
12942285809Sscottl
12943285809Sscottl
12944285809Sscottl  return SM_RC_SUCCESS;
12945285809Sscottl}
12946285809Sscottl
12947285809SscottlosGLOBAL bit32
12948285809SscottlsmsatWriteSame16(
12949285809Sscottl                  smRoot_t                  *smRoot,
12950285809Sscottl                  smIORequest_t             *smIORequest,
12951285809Sscottl                  smDeviceHandle_t          *smDeviceHandle,
12952285809Sscottl                  smScsiInitiatorRequest_t  *smScsiRequest,
12953285809Sscottl                  smSatIOContext_t            *satIOContext
12954285809Sscottl                 )
12955285809Sscottl{
12956285809Sscottl  smScsiRspSense_t          *pSense;
12957285809Sscottl
12958285809Sscottl  pSense        = satIOContext->pSense;
12959285809Sscottl
12960285809Sscottl  SM_DBG5(("smsatWriteSame16: start\n"));
12961285809Sscottl
12962285809Sscottl
12963285809Sscottl  smsatSetSensePayload( pSense,
12964285809Sscottl                        SCSI_SNSKEY_NO_SENSE,
12965285809Sscottl                        0,
12966285809Sscottl                        SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12967285809Sscottl                        satIOContext);
12968285809Sscottl
12969285809Sscottl  /*smEnqueueIO(smRoot, satIOContext);*/
12970285809Sscottl
12971285809Sscottl  tdsmIOCompletedCB( smRoot,
12972285809Sscottl                     smIORequest, /* == &satIntIo->satOrgSmIORequest */
12973285809Sscottl                     smIOSuccess,
12974285809Sscottl                     SCSI_STAT_CHECK_CONDITION,
12975285809Sscottl                     satIOContext->pSmSenseData,
12976285809Sscottl                     satIOContext->interruptContext );
12977285809Sscottl  SM_DBG1(("smsatWriteSame16: return internal checking!!!\n"));
12978285809Sscottl  return SM_RC_SUCCESS;
12979285809Sscottl}
12980285809Sscottl
12981285809SscottlosGLOBAL bit32
12982285809SscottlsmsatLogSense(
12983285809Sscottl              smRoot_t                  *smRoot,
12984285809Sscottl              smIORequest_t             *smIORequest,
12985285809Sscottl              smDeviceHandle_t          *smDeviceHandle,
12986285809Sscottl              smScsiInitiatorRequest_t  *smScsiRequest,
12987285809Sscottl              smSatIOContext_t            *satIOContext
12988285809Sscottl             )
12989285809Sscottl{
12990285809Sscottl  bit32                     status;
12991285809Sscottl  bit32                     agRequestType;
12992285809Sscottl  smDeviceData_t            *pSatDevData;
12993285809Sscottl  smScsiRspSense_t          *pSense;
12994285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
12995285809Sscottl  agsaFisRegHostToDevice_t  *fis;
12996285809Sscottl  bit8                      *pLogPage;    /* Log Page data buffer */
12997285809Sscottl  bit32                     flag = 0;
12998285809Sscottl  bit16                     AllocLen = 0;       /* allocation length */
12999285809Sscottl  bit8                      AllLogPages[8];
13000285809Sscottl  bit16                     lenRead = 0;
13001285809Sscottl
13002285809Sscottl  pSense        = satIOContext->pSense;
13003285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
13004285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
13005285809Sscottl  fis           = satIOContext->pFis;
13006285809Sscottl  pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
13007285809Sscottl
13008285809Sscottl  SM_DBG5(("smsatLogSense: start\n"));
13009285809Sscottl
13010285809Sscottl  sm_memset(&AllLogPages, 0, 8);
13011285809Sscottl  /* checking CONTROL */
13012285809Sscottl  /* NACA == 1 or LINK == 1*/
13013285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13014285809Sscottl  {
13015285809Sscottl    smsatSetSensePayload( pSense,
13016285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
13017285809Sscottl                          0,
13018285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13019285809Sscottl                          satIOContext);
13020285809Sscottl
13021285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
13022285809Sscottl
13023285809Sscottl    tdsmIOCompletedCB( smRoot,
13024285809Sscottl                       smIORequest,
13025285809Sscottl                       smIOSuccess,
13026285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
13027285809Sscottl                       satIOContext->pSmSenseData,
13028285809Sscottl                       satIOContext->interruptContext );
13029285809Sscottl
13030285809Sscottl    SM_DBG1(("smsatLogSense: return control!!!\n"));
13031285809Sscottl    return SM_RC_SUCCESS;
13032285809Sscottl  }
13033285809Sscottl
13034285809Sscottl
13035285809Sscottl  AllocLen = ((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
13036285809Sscottl  AllocLen = MIN(AllocLen, scsiCmnd->expDataLength);
13037285809Sscottl
13038285809Sscottl  /* checking PC (Page Control) */
13039285809Sscottl  /* nothing */
13040285809Sscottl
13041285809Sscottl  /* special cases */
13042285809Sscottl  if (AllocLen == 4)
13043285809Sscottl  {
13044285809Sscottl    SM_DBG1(("smsatLogSense: AllocLen is 4!!!\n"));
13045285809Sscottl    switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
13046285809Sscottl    {
13047285809Sscottl      case LOGSENSE_SUPPORTED_LOG_PAGES:
13048285809Sscottl        SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13049285809Sscottl
13050285809Sscottl        if (pSatDevData->satSMARTFeatureSet == agTRUE)
13051285809Sscottl        {
13052285809Sscottl          /* add informational exception log */
13053285809Sscottl          flag = 1;
13054285809Sscottl          if (pSatDevData->satSMARTSelfTest == agTRUE)
13055285809Sscottl          {
13056285809Sscottl            /* add Self-Test results log page */
13057285809Sscottl            flag = 2;
13058285809Sscottl          }
13059285809Sscottl        }
13060285809Sscottl        else
13061285809Sscottl        {
13062285809Sscottl          /* only supported, no informational exception log, no  Self-Test results log page */
13063285809Sscottl          flag = 0;
13064285809Sscottl        }
13065285809Sscottl        lenRead = 4;
13066285809Sscottl        AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES;          /* page code */
13067285809Sscottl        AllLogPages[1] = 0;          /* reserved  */
13068285809Sscottl        switch (flag)
13069285809Sscottl        {
13070285809Sscottl          case 0:
13071285809Sscottl            /* only supported */
13072285809Sscottl            AllLogPages[2] = 0;          /* page length */
13073285809Sscottl            AllLogPages[3] = 1;          /* page length */
13074285809Sscottl            break;
13075285809Sscottl          case 1:
13076285809Sscottl            /* supported and informational exception log */
13077285809Sscottl            AllLogPages[2] = 0;          /* page length */
13078285809Sscottl            AllLogPages[3] = 2;          /* page length */
13079285809Sscottl            break;
13080285809Sscottl          case 2:
13081285809Sscottl            /* supported and informational exception log */
13082285809Sscottl            AllLogPages[2] = 0;          /* page length */
13083285809Sscottl            AllLogPages[3] = 3;          /* page length */
13084285809Sscottl            break;
13085285809Sscottl          default:
13086285809Sscottl            SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag));
13087285809Sscottl            break;
13088285809Sscottl        }
13089285809Sscottl        sm_memcpy(pLogPage, &AllLogPages, lenRead);
13090285809Sscottl        break;
13091285809Sscottl      case LOGSENSE_SELFTEST_RESULTS_PAGE:
13092285809Sscottl        SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13093285809Sscottl        lenRead = 4;
13094285809Sscottl        AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE;          /* page code */
13095285809Sscottl        AllLogPages[1] = 0;          /* reserved  */
13096285809Sscottl        /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */
13097285809Sscottl        AllLogPages[2] = 0x01;
13098285809Sscottl        AllLogPages[3] = 0x90;       /* page length */
13099285809Sscottl        sm_memcpy(pLogPage, &AllLogPages, lenRead);
13100285809Sscottl
13101285809Sscottl        break;
13102285809Sscottl      case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
13103285809Sscottl        SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13104285809Sscottl        lenRead = 4;
13105285809Sscottl        AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE;          /* page code */
13106285809Sscottl        AllLogPages[1] = 0;          /* reserved  */
13107285809Sscottl        AllLogPages[2] = 0;          /* page length */
13108285809Sscottl        AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3;       /* page length */
13109285809Sscottl        sm_memcpy(pLogPage, &AllLogPages, lenRead);
13110285809Sscottl        break;
13111285809Sscottl      default:
13112285809Sscottl        SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
13113285809Sscottl        smsatSetSensePayload( pSense,
13114285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
13115285809Sscottl                              0,
13116285809Sscottl                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13117285809Sscottl                              satIOContext);
13118285809Sscottl
13119285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
13120285809Sscottl
13121285809Sscottl        tdsmIOCompletedCB( smRoot,
13122285809Sscottl                           smIORequest,
13123285809Sscottl                           smIOSuccess,
13124285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
13125285809Sscottl                           satIOContext->pSmSenseData,
13126285809Sscottl                           satIOContext->interruptContext );
13127285809Sscottl        return SM_RC_SUCCESS;
13128285809Sscottl    }
13129285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
13130285809Sscottl
13131285809Sscottl    tdsmIOCompletedCB( smRoot,
13132285809Sscottl                       smIORequest,
13133285809Sscottl                       smIOSuccess,
13134285809Sscottl                       SCSI_STAT_GOOD,
13135285809Sscottl                       agNULL,
13136285809Sscottl                       satIOContext->interruptContext);
13137285809Sscottl    return SM_RC_SUCCESS;
13138285809Sscottl
13139285809Sscottl  } /* if */
13140285809Sscottl
13141285809Sscottl  /* SAT rev8 Table 11  p30*/
13142285809Sscottl  /* checking Page Code */
13143285809Sscottl  switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
13144285809Sscottl  {
13145285809Sscottl    case LOGSENSE_SUPPORTED_LOG_PAGES:
13146285809Sscottl      SM_DBG5(("smsatLogSense: case 1\n"));
13147285809Sscottl
13148285809Sscottl      if (pSatDevData->satSMARTFeatureSet == agTRUE)
13149285809Sscottl      {
13150285809Sscottl        /* add informational exception log */
13151285809Sscottl        flag = 1;
13152285809Sscottl        if (pSatDevData->satSMARTSelfTest == agTRUE)
13153285809Sscottl        {
13154285809Sscottl          /* add Self-Test results log page */
13155285809Sscottl          flag = 2;
13156285809Sscottl        }
13157285809Sscottl      }
13158285809Sscottl      else
13159285809Sscottl      {
13160285809Sscottl        /* only supported, no informational exception log, no  Self-Test results log page */
13161285809Sscottl        flag = 0;
13162285809Sscottl      }
13163285809Sscottl      AllLogPages[0] = 0;          /* page code */
13164285809Sscottl      AllLogPages[1] = 0;          /* reserved  */
13165285809Sscottl      switch (flag)
13166285809Sscottl      {
13167285809Sscottl      case 0:
13168285809Sscottl        /* only supported */
13169285809Sscottl        AllLogPages[2] = 0;          /* page length */
13170285809Sscottl        AllLogPages[3] = 1;          /* page length */
13171285809Sscottl        AllLogPages[4] = 0x00;       /* supported page list */
13172285809Sscottl        lenRead = (bit8)(MIN(AllocLen, 5));
13173285809Sscottl        break;
13174285809Sscottl      case 1:
13175285809Sscottl        /* supported and informational exception log */
13176285809Sscottl        AllLogPages[2] = 0;          /* page length */
13177285809Sscottl        AllLogPages[3] = 2;          /* page length */
13178285809Sscottl        AllLogPages[4] = 0x00;       /* supported page list */
13179285809Sscottl        AllLogPages[5] = 0x10;       /* supported page list */
13180285809Sscottl        lenRead = (bit8)(MIN(AllocLen, 6));
13181285809Sscottl        break;
13182285809Sscottl      case 2:
13183285809Sscottl        /* supported and informational exception log */
13184285809Sscottl        AllLogPages[2] = 0;          /* page length */
13185285809Sscottl        AllLogPages[3] = 3;          /* page length */
13186285809Sscottl        AllLogPages[4] = 0x00;       /* supported page list */
13187285809Sscottl        AllLogPages[5] = 0x10;       /* supported page list */
13188285809Sscottl        AllLogPages[6] = 0x2F;       /* supported page list */
13189285809Sscottl       lenRead = (bit8)(MIN(AllocLen, 7));
13190285809Sscottl       break;
13191285809Sscottl      default:
13192285809Sscottl        SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag));
13193285809Sscottl        break;
13194285809Sscottl      }
13195285809Sscottl
13196285809Sscottl      sm_memcpy(pLogPage, &AllLogPages, lenRead);
13197285809Sscottl      /* comparing allocation length to Log Page byte size */
13198285809Sscottl      /* SPC-4, 4.3.4.6, p28 */
13199285809Sscottl      if (AllocLen > lenRead )
13200285809Sscottl      {
13201285809Sscottl        SM_DBG1(("smsatLogSense: reporting underrun lenRead=0x%x AllocLen=0x%x!!!\n", lenRead, AllocLen));
13202285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
13203285809Sscottl
13204285809Sscottl        tdsmIOCompletedCB( smRoot,
13205285809Sscottl                           smIORequest,
13206285809Sscottl                           smIOUnderRun,
13207285809Sscottl                           AllocLen - lenRead,
13208285809Sscottl                           agNULL,
13209285809Sscottl                           satIOContext->interruptContext );
13210285809Sscottl      }
13211285809Sscottl      else
13212285809Sscottl      {
13213285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
13214285809Sscottl        tdsmIOCompletedCB( smRoot,
13215285809Sscottl                           smIORequest,
13216285809Sscottl                           smIOSuccess,
13217285809Sscottl                           SCSI_STAT_GOOD,
13218285809Sscottl                           agNULL,
13219285809Sscottl                           satIOContext->interruptContext);
13220285809Sscottl      }
13221285809Sscottl      break;
13222285809Sscottl    case LOGSENSE_SELFTEST_RESULTS_PAGE:
13223285809Sscottl      SM_DBG5(("smsatLogSense: case 2\n"));
13224285809Sscottl      /* checking SMART self-test */
13225285809Sscottl      if (pSatDevData->satSMARTSelfTest == agFALSE)
13226285809Sscottl      {
13227285809Sscottl        SM_DBG5(("smsatLogSense: case 2 no SMART Self Test\n"));
13228285809Sscottl        smsatSetSensePayload( pSense,
13229285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
13230285809Sscottl                              0,
13231285809Sscottl                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13232285809Sscottl                              satIOContext);
13233285809Sscottl
13234285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
13235285809Sscottl
13236285809Sscottl        tdsmIOCompletedCB( smRoot,
13237285809Sscottl                           smIORequest,
13238285809Sscottl                           smIOSuccess,
13239285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
13240285809Sscottl                           satIOContext->pSmSenseData,
13241285809Sscottl                           satIOContext->interruptContext );
13242285809Sscottl      }
13243285809Sscottl      else
13244285809Sscottl      {
13245285809Sscottl        /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */
13246285809Sscottl        if (pSatDevData->satSMARTEnabled == agFALSE)
13247285809Sscottl        {
13248285809Sscottl          SM_DBG5(("smsatLogSense: case 2 calling satSMARTEnable\n"));
13249285809Sscottl          status = smsatLogSenseAllocate(smRoot,
13250285809Sscottl                                         smIORequest,
13251285809Sscottl                                         smDeviceHandle,
13252285809Sscottl                                         smScsiRequest,
13253285809Sscottl                                         satIOContext,
13254285809Sscottl                                         0,
13255285809Sscottl                                         LOG_SENSE_0
13256285809Sscottl                                         );
13257285809Sscottl
13258285809Sscottl          return status;
13259285809Sscottl
13260285809Sscottl        }
13261285809Sscottl        else
13262285809Sscottl        {
13263285809Sscottl        /* SAT Rev 8, 10.2.4 p74 */
13264285809Sscottl        if ( pSatDevData->sat48BitSupport == agTRUE )
13265285809Sscottl        {
13266285809Sscottl          SM_DBG5(("smsatLogSense: case 2-1 sends READ LOG EXT\n"));
13267285809Sscottl          status = smsatLogSenseAllocate(smRoot,
13268285809Sscottl                                         smIORequest,
13269285809Sscottl                                         smDeviceHandle,
13270285809Sscottl                                         smScsiRequest,
13271285809Sscottl                                         satIOContext,
13272285809Sscottl                                         512,
13273285809Sscottl                                         LOG_SENSE_1
13274285809Sscottl                                         );
13275285809Sscottl
13276285809Sscottl          return status;
13277285809Sscottl        }
13278285809Sscottl        else
13279285809Sscottl        {
13280285809Sscottl          SM_DBG5(("smsatLogSense: case 2-2 sends SMART READ LOG\n"));
13281285809Sscottl          status = smsatLogSenseAllocate(smRoot,
13282285809Sscottl                                         smIORequest,
13283285809Sscottl                                         smDeviceHandle,
13284285809Sscottl                                         smScsiRequest,
13285285809Sscottl                                         satIOContext,
13286285809Sscottl                                         512,
13287285809Sscottl                                         LOG_SENSE_2
13288285809Sscottl                                         );
13289285809Sscottl
13290285809Sscottl          return status;
13291285809Sscottl        }
13292285809Sscottl      }
13293285809Sscottl      }
13294285809Sscottl      break;
13295285809Sscottl    case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
13296285809Sscottl      SM_DBG5(("smsatLogSense: case 3\n"));
13297285809Sscottl      /* checking SMART feature set */
13298285809Sscottl      if (pSatDevData->satSMARTFeatureSet == agFALSE)
13299285809Sscottl      {
13300285809Sscottl        smsatSetSensePayload( pSense,
13301285809Sscottl                              SCSI_SNSKEY_ILLEGAL_REQUEST,
13302285809Sscottl                              0,
13303285809Sscottl                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13304285809Sscottl                              satIOContext);
13305285809Sscottl
13306285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
13307285809Sscottl
13308285809Sscottl        tdsmIOCompletedCB( smRoot,
13309285809Sscottl                           smIORequest,
13310285809Sscottl                           smIOSuccess,
13311285809Sscottl                           SCSI_STAT_CHECK_CONDITION,
13312285809Sscottl                           satIOContext->pSmSenseData,
13313285809Sscottl                           satIOContext->interruptContext );
13314285809Sscottl      }
13315285809Sscottl      else
13316285809Sscottl      {
13317285809Sscottl        /* checking SMART feature enabled */
13318285809Sscottl        if (pSatDevData->satSMARTEnabled == agFALSE)
13319285809Sscottl        {
13320285809Sscottl          smsatSetSensePayload( pSense,
13321285809Sscottl                                SCSI_SNSKEY_ABORTED_COMMAND,
13322285809Sscottl                                0,
13323285809Sscottl                                SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
13324285809Sscottl                                satIOContext);
13325285809Sscottl
13326285809Sscottl          /*smEnqueueIO(smRoot, satIOContext);*/
13327285809Sscottl
13328285809Sscottl          tdsmIOCompletedCB( smRoot,
13329285809Sscottl                             smIORequest,
13330285809Sscottl                             smIOSuccess,
13331285809Sscottl                             SCSI_STAT_CHECK_CONDITION,
13332285809Sscottl                             satIOContext->pSmSenseData,
13333285809Sscottl                             satIOContext->interruptContext );
13334285809Sscottl        }
13335285809Sscottl        else
13336285809Sscottl        {
13337285809Sscottl          /* SAT Rev 8, 10.2.3 p72 */
13338285809Sscottl          SM_DBG5(("smsatLogSense: case 3 sends SMART RETURN STATUS\n"));
13339285809Sscottl
13340285809Sscottl          /* sends SMART RETURN STATUS */
13341285809Sscottl          fis->h.fisType        = 0x27;                   /* Reg host to device */
13342285809Sscottl          fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13343285809Sscottl
13344285809Sscottl          fis->h.command        = SAT_SMART;              /* 0xB0 */
13345285809Sscottl          fis->h.features       = SAT_SMART_RETURN_STATUS;/* FIS features */
13346285809Sscottl          fis->d.featuresExp    = 0;                      /* FIS reserve */
13347285809Sscottl          fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13348285809Sscottl          fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
13349285809Sscottl          fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13350285809Sscottl          fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
13351285809Sscottl          fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
13352285809Sscottl          fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13353285809Sscottl          fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
13354285809Sscottl          fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13355285809Sscottl          fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13356285809Sscottl          fis->d.control        = 0;                      /* FIS HOB bit clear */
13357285809Sscottl          fis->d.reserved4      = 0;
13358285809Sscottl          fis->d.reserved5      = 0;
13359285809Sscottl
13360285809Sscottl          agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13361285809Sscottl          /* Initialize CB for SATA completion.
13362285809Sscottl           */
13363285809Sscottl          satIOContext->satCompleteCB = &smsatLogSenseCB;
13364285809Sscottl
13365285809Sscottl          /*
13366285809Sscottl           * Prepare SGL and send FIS to LL layer.
13367285809Sscottl           */
13368285809Sscottl          satIOContext->reqType = agRequestType;       /* Save it */
13369285809Sscottl
13370285809Sscottl          status = smsataLLIOStart( smRoot,
13371285809Sscottl                                    smIORequest,
13372285809Sscottl                                    smDeviceHandle,
13373285809Sscottl                                    smScsiRequest,
13374285809Sscottl                                    satIOContext);
13375285809Sscottl
13376285809Sscottl
13377285809Sscottl          return status;
13378285809Sscottl        }
13379285809Sscottl      }
13380285809Sscottl      break;
13381285809Sscottl    default:
13382285809Sscottl      SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
13383285809Sscottl      smsatSetSensePayload( pSense,
13384285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
13385285809Sscottl                            0,
13386285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13387285809Sscottl                            satIOContext);
13388285809Sscottl
13389285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
13390285809Sscottl
13391285809Sscottl      tdsmIOCompletedCB( smRoot,
13392285809Sscottl                         smIORequest,
13393285809Sscottl                         smIOSuccess,
13394285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
13395285809Sscottl                         satIOContext->pSmSenseData,
13396285809Sscottl                         satIOContext->interruptContext );
13397285809Sscottl
13398285809Sscottl      break;
13399285809Sscottl  } /* end switch */
13400285809Sscottl
13401285809Sscottl  return SM_RC_SUCCESS;
13402285809Sscottl}
13403285809Sscottl
13404285809SscottlosGLOBAL bit32
13405285809SscottlsmsatLogSenseAllocate(
13406285809Sscottl                      smRoot_t                  *smRoot,
13407285809Sscottl                      smIORequest_t             *smIORequest,
13408285809Sscottl                      smDeviceHandle_t          *smDeviceHandle,
13409285809Sscottl                      smScsiInitiatorRequest_t  *smSCSIRequest,
13410285809Sscottl                      smSatIOContext_t            *satIOContext,
13411285809Sscottl                      bit32                     payloadSize,
13412285809Sscottl                      bit32                     flag
13413285809Sscottl                     )
13414285809Sscottl{
13415285809Sscottl  smDeviceData_t            *pSatDevData;
13416285809Sscottl  smIORequestBody_t         *smIORequestBody;
13417285809Sscottl  smSatInternalIo_t           *satIntIo = agNULL;
13418285809Sscottl  smSatIOContext_t            *satIOContext2;
13419285809Sscottl  bit32                     status;
13420285809Sscottl
13421285809Sscottl  SM_DBG5(("smsatLogSenseAllocate: start\n"));
13422285809Sscottl
13423285809Sscottl  pSatDevData       = satIOContext->pSatDevData;
13424285809Sscottl
13425285809Sscottl  /* create internal satIOContext */
13426285809Sscottl  satIntIo = smsatAllocIntIoResource( smRoot,
13427285809Sscottl                                      smIORequest, /* original request */
13428285809Sscottl                                      pSatDevData,
13429285809Sscottl                                      payloadSize,
13430285809Sscottl                                      satIntIo);
13431285809Sscottl
13432285809Sscottl  if (satIntIo == agNULL)
13433285809Sscottl  {
13434285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
13435285809Sscottl
13436285809Sscottl    tdsmIOCompletedCB( smRoot,
13437285809Sscottl                       smIORequest,
13438285809Sscottl                       smIOFailed,
13439285809Sscottl                       smDetailOtherError,
13440285809Sscottl                       agNULL,
13441285809Sscottl                       satIOContext->interruptContext );
13442285809Sscottl
13443285809Sscottl    SM_DBG1(("smsatLogSenseAllocate: fail in allocation!!!\n"));
13444285809Sscottl    return SM_RC_SUCCESS;
13445285809Sscottl  } /* end of memory allocation failure */
13446285809Sscottl
13447285809Sscottl  satIntIo->satOrgSmIORequest = smIORequest;
13448285809Sscottl  smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
13449285809Sscottl  satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);
13450285809Sscottl
13451285809Sscottl  satIOContext2->pSatDevData   = pSatDevData;
13452285809Sscottl  satIOContext2->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
13453285809Sscottl  satIOContext2->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
13454285809Sscottl  satIOContext2->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
13455285809Sscottl  satIOContext2->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
13456285809Sscottl  satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;
13457285809Sscottl  satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
13458285809Sscottl  satIOContext2->interruptContext = satIOContext->interruptContext;
13459285809Sscottl  satIOContext2->satIntIoContext  = satIntIo;
13460285809Sscottl  satIOContext2->psmDeviceHandle = smDeviceHandle;
13461285809Sscottl  satIOContext2->satOrgIOContext = satIOContext;
13462285809Sscottl
13463285809Sscottl  if (flag == LOG_SENSE_0)
13464285809Sscottl  {
13465285809Sscottl    /* SAT_SMART_ENABLE_OPERATIONS */
13466285809Sscottl    status = smsatSMARTEnable( smRoot,
13467285809Sscottl                               &(satIntIo->satIntSmIORequest),
13468285809Sscottl                               smDeviceHandle,
13469285809Sscottl                               &(satIntIo->satIntSmScsiXchg),
13470285809Sscottl                               satIOContext2);
13471285809Sscottl  }
13472285809Sscottl  else if (flag == LOG_SENSE_1)
13473285809Sscottl  {
13474285809Sscottl    /* SAT_READ_LOG_EXT */
13475285809Sscottl    status = smsatLogSense_2( smRoot,
13476285809Sscottl                              &(satIntIo->satIntSmIORequest),
13477285809Sscottl                              smDeviceHandle,
13478285809Sscottl                              &(satIntIo->satIntSmScsiXchg),
13479285809Sscottl                              satIOContext2);
13480285809Sscottl  }
13481285809Sscottl  else
13482285809Sscottl  {
13483285809Sscottl    /* SAT_SMART_READ_LOG */
13484285809Sscottl    /* SAT_READ_LOG_EXT */
13485285809Sscottl    status = smsatLogSense_3( smRoot,
13486285809Sscottl                              &(satIntIo->satIntSmIORequest),
13487285809Sscottl                              smDeviceHandle,
13488285809Sscottl                              &(satIntIo->satIntSmScsiXchg),
13489285809Sscottl                              satIOContext2);
13490285809Sscottl
13491285809Sscottl  }
13492285809Sscottl  if (status != SM_RC_SUCCESS)
13493285809Sscottl  {
13494285809Sscottl    smsatFreeIntIoResource( smRoot,
13495285809Sscottl                            pSatDevData,
13496285809Sscottl                            satIntIo);
13497285809Sscottl
13498285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
13499285809Sscottl
13500285809Sscottl    tdsmIOCompletedCB( smRoot,
13501285809Sscottl                       smIORequest,
13502285809Sscottl                       smIOFailed,
13503285809Sscottl                       smDetailOtherError,
13504285809Sscottl                       agNULL,
13505285809Sscottl                       satIOContext->interruptContext );
13506285809Sscottl    return SM_RC_SUCCESS;
13507285809Sscottl  }
13508285809Sscottl
13509285809Sscottl
13510285809Sscottl  return SM_RC_SUCCESS;
13511285809Sscottl}
13512285809Sscottl
13513285809SscottlosGLOBAL bit32
13514285809SscottlsmsatSMARTEnable(
13515285809Sscottl                 smRoot_t                  *smRoot,
13516285809Sscottl                 smIORequest_t             *smIORequest,
13517285809Sscottl                 smDeviceHandle_t          *smDeviceHandle,
13518285809Sscottl                 smScsiInitiatorRequest_t  *smScsiRequest,
13519285809Sscottl                 smSatIOContext_t            *satIOContext
13520285809Sscottl               )
13521285809Sscottl{
13522285809Sscottl  bit32                     status;
13523285809Sscottl  bit32                     agRequestType;
13524285809Sscottl  agsaFisRegHostToDevice_t  *fis;
13525285809Sscottl
13526285809Sscottl  fis               = satIOContext->pFis;
13527285809Sscottl  SM_DBG5(("smsatSMARTEnable: start\n"));
13528285809Sscottl  /*
13529285809Sscottl   * Send the SAT_SMART_ENABLE_OPERATIONS command.
13530285809Sscottl   */
13531285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
13532285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13533285809Sscottl  fis->h.command        = SAT_SMART;              /* 0xB0 */
13534285809Sscottl  fis->h.features       = SAT_SMART_ENABLE_OPERATIONS;
13535285809Sscottl  fis->d.lbaLow         = 0;
13536285809Sscottl  fis->d.lbaMid         = 0x4F;
13537285809Sscottl  fis->d.lbaHigh        = 0xC2;
13538285809Sscottl  fis->d.device         = 0;
13539285809Sscottl  fis->d.lbaLowExp      = 0;
13540285809Sscottl  fis->d.lbaMidExp      = 0;
13541285809Sscottl  fis->d.lbaHighExp     = 0;
13542285809Sscottl  fis->d.featuresExp    = 0;
13543285809Sscottl  fis->d.sectorCount    = 0;
13544285809Sscottl  fis->d.sectorCountExp = 0;
13545285809Sscottl  fis->d.reserved4      = 0;
13546285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
13547285809Sscottl  fis->d.reserved5      = 0;
13548285809Sscottl
13549285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13550285809Sscottl
13551285809Sscottl  /* Initialize CB for SATA completion.
13552285809Sscottl   */
13553285809Sscottl  satIOContext->satCompleteCB = &smsatSMARTEnableCB;
13554285809Sscottl
13555285809Sscottl  /*
13556285809Sscottl   * Prepare SGL and send FIS to LL layer.
13557285809Sscottl   */
13558285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
13559285809Sscottl
13560285809Sscottl  status = smsataLLIOStart( smRoot,
13561285809Sscottl                            smIORequest,
13562285809Sscottl                            smDeviceHandle,
13563285809Sscottl                            smScsiRequest,
13564285809Sscottl                            satIOContext);
13565285809Sscottl
13566285809Sscottl
13567285809Sscottl  return status;
13568285809Sscottl}
13569285809Sscottl
13570285809SscottlosGLOBAL bit32
13571285809SscottlsmsatLogSense_2(
13572285809Sscottl                smRoot_t                  *smRoot,
13573285809Sscottl                smIORequest_t             *smIORequest,
13574285809Sscottl                smDeviceHandle_t          *smDeviceHandle,
13575285809Sscottl                smScsiInitiatorRequest_t  *smScsiRequest,
13576285809Sscottl                smSatIOContext_t            *satIOContext
13577285809Sscottl               )
13578285809Sscottl{
13579285809Sscottl  bit32                     status;
13580285809Sscottl  bit32                     agRequestType;
13581285809Sscottl  agsaFisRegHostToDevice_t  *fis;
13582285809Sscottl
13583285809Sscottl  fis               = satIOContext->pFis;
13584285809Sscottl  SM_DBG5(("smsatLogSense_2: start\n"));
13585285809Sscottl
13586285809Sscottl  /* sends READ LOG EXT */
13587285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
13588285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13589285809Sscottl
13590285809Sscottl  fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
13591285809Sscottl  fis->h.features       = 0;                      /* FIS reserve */
13592285809Sscottl  fis->d.lbaLow         = 0x07;                   /* 0x07 */
13593285809Sscottl  fis->d.lbaMid         = 0;                      /*  */
13594285809Sscottl  fis->d.lbaHigh        = 0;                      /*  */
13595285809Sscottl  fis->d.device         = 0;                      /*  */
13596285809Sscottl  fis->d.lbaLowExp      = 0;                      /*  */
13597285809Sscottl  fis->d.lbaMidExp      = 0;                      /*  */
13598285809Sscottl  fis->d.lbaHighExp     = 0;                      /*  */
13599285809Sscottl  fis->d.featuresExp    = 0;                      /* FIS reserve */
13600285809Sscottl  fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
13601285809Sscottl  fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
13602285809Sscottl  fis->d.reserved4      = 0;
13603285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
13604285809Sscottl  fis->d.reserved5      = 0;
13605285809Sscottl
13606285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
13607285809Sscottl
13608285809Sscottl  /* Initialize CB for SATA completion.
13609285809Sscottl   */
13610285809Sscottl  satIOContext->satCompleteCB = &smsatLogSenseCB;
13611285809Sscottl
13612285809Sscottl  /*
13613285809Sscottl   * Prepare SGL and send FIS to LL layer.
13614285809Sscottl   */
13615285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
13616285809Sscottl
13617285809Sscottl  status = smsataLLIOStart( smRoot,
13618285809Sscottl                            smIORequest,
13619285809Sscottl                            smDeviceHandle,
13620285809Sscottl                            smScsiRequest,
13621285809Sscottl                            satIOContext);
13622285809Sscottl  return status;
13623285809Sscottl}
13624285809Sscottl
13625285809SscottlosGLOBAL bit32
13626285809SscottlsmsatLogSense_3(
13627285809Sscottl                smRoot_t                  *smRoot,
13628285809Sscottl                smIORequest_t             *smIORequest,
13629285809Sscottl                smDeviceHandle_t          *smDeviceHandle,
13630285809Sscottl                smScsiInitiatorRequest_t  *smScsiRequest,
13631285809Sscottl                smSatIOContext_t            *satIOContext
13632285809Sscottl               )
13633285809Sscottl{
13634285809Sscottl  bit32                     status;
13635285809Sscottl  bit32                     agRequestType;
13636285809Sscottl  agsaFisRegHostToDevice_t  *fis;
13637285809Sscottl
13638285809Sscottl  fis               = satIOContext->pFis;
13639285809Sscottl  SM_DBG5(("smsatLogSense_3: start\n"));
13640285809Sscottl  /* sends READ LOG EXT */
13641285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
13642285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13643285809Sscottl  fis->h.command        = SAT_SMART;              /* 0x2F */
13644285809Sscottl  fis->h.features       = SAT_SMART_READ_LOG;     /* 0xd5 */
13645285809Sscottl  fis->d.lbaLow         = 0x06;                   /* 0x06 */
13646285809Sscottl  fis->d.lbaMid         = 0x4F;                   /* 0x4f */
13647285809Sscottl  fis->d.lbaHigh        = 0xC2;                   /* 0xc2 */
13648285809Sscottl  fis->d.device         = 0;                      /*  */
13649285809Sscottl  fis->d.lbaLowExp      = 0;                      /*  */
13650285809Sscottl  fis->d.lbaMidExp      = 0;                      /*  */
13651285809Sscottl  fis->d.lbaHighExp     = 0;                      /*  */
13652285809Sscottl  fis->d.featuresExp    = 0;                      /* FIS reserve */
13653285809Sscottl  fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
13654285809Sscottl  fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
13655285809Sscottl  fis->d.reserved4      = 0;
13656285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
13657285809Sscottl  fis->d.reserved5      = 0;
13658285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
13659285809Sscottl  /* Initialize CB for SATA completion.
13660285809Sscottl   */
13661285809Sscottl  satIOContext->satCompleteCB = &smsatLogSenseCB;
13662285809Sscottl  /*
13663285809Sscottl   * Prepare SGL and send FIS to LL layer.
13664285809Sscottl   */
13665285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
13666285809Sscottl  status = smsataLLIOStart( smRoot,
13667285809Sscottl                            smIORequest,
13668285809Sscottl                            smDeviceHandle,
13669285809Sscottl                            smScsiRequest,
13670285809Sscottl                            satIOContext);
13671285809Sscottl  return status;
13672285809Sscottl}
13673285809Sscottl
13674285809Sscottl
13675285809SscottlosGLOBAL bit32
13676285809SscottlsmsatModeSelect6(
13677285809Sscottl                 smRoot_t                  *smRoot,
13678285809Sscottl                 smIORequest_t             *smIORequest,
13679285809Sscottl                 smDeviceHandle_t          *smDeviceHandle,
13680285809Sscottl                 smScsiInitiatorRequest_t  *smScsiRequest,
13681285809Sscottl                 smSatIOContext_t            *satIOContext
13682285809Sscottl                )
13683285809Sscottl{
13684285809Sscottl  bit32                     status;
13685285809Sscottl  bit32                     agRequestType;
13686285809Sscottl  smDeviceData_t            *pSatDevData;
13687285809Sscottl  smScsiRspSense_t          *pSense;
13688285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
13689285809Sscottl  agsaFisRegHostToDevice_t  *fis;
13690285809Sscottl  bit8                      *pLogPage;    /* Log Page data buffer */
13691285809Sscottl  bit32                     StartingIndex = 0;
13692285809Sscottl  bit8                      PageCode = 0;
13693285809Sscottl  bit32                     chkCnd = agFALSE;
13694285809Sscottl  bit32                     parameterListLen = 0;
13695285809Sscottl
13696285809Sscottl  pSense        = satIOContext->pSense;
13697285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
13698285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
13699285809Sscottl  fis           = satIOContext->pFis;
13700285809Sscottl  pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
13701285809Sscottl
13702285809Sscottl  SM_DBG5(("smsatModeSelect6: start\n"));
13703285809Sscottl
13704285809Sscottl  /* checking CONTROL */
13705285809Sscottl  /* NACA == 1 or LINK == 1*/
13706285809Sscottl  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
13707285809Sscottl  {
13708285809Sscottl    smsatSetSensePayload( pSense,
13709285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
13710285809Sscottl                          0,
13711285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13712285809Sscottl                          satIOContext);
13713285809Sscottl
13714285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
13715285809Sscottl
13716285809Sscottl    tdsmIOCompletedCB( smRoot,
13717285809Sscottl                       smIORequest,
13718285809Sscottl                       smIOSuccess,
13719285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
13720285809Sscottl                       satIOContext->pSmSenseData,
13721285809Sscottl                       satIOContext->interruptContext );
13722285809Sscottl
13723285809Sscottl    SM_DBG1(("smsatModeSelect6: return control!!!\n"));
13724285809Sscottl    return SM_RC_SUCCESS;
13725285809Sscottl  }
13726285809Sscottl
13727285809Sscottl  /* checking PF bit */
13728285809Sscottl  if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
13729285809Sscottl  {
13730285809Sscottl    smsatSetSensePayload( pSense,
13731285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
13732285809Sscottl                          0,
13733285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13734285809Sscottl                          satIOContext);
13735285809Sscottl
13736285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
13737285809Sscottl
13738285809Sscottl    tdsmIOCompletedCB( smRoot,
13739285809Sscottl                       smIORequest,
13740285809Sscottl                       smIOSuccess,
13741285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
13742285809Sscottl                       satIOContext->pSmSenseData,
13743285809Sscottl                       satIOContext->interruptContext );
13744285809Sscottl
13745285809Sscottl    SM_DBG1(("smsatModeSelect6: PF bit check!!!\n"));
13746285809Sscottl    return SM_RC_SUCCESS;
13747285809Sscottl  }
13748285809Sscottl
13749285809Sscottl  parameterListLen = scsiCmnd->cdb[4];
13750285809Sscottl  parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength);
13751285809Sscottl  if ((0 == parameterListLen) || (agNULL == pLogPage))
13752285809Sscottl  {
13753285809Sscottl    tdsmIOCompletedCB( smRoot,
13754285809Sscottl                       smIORequest,
13755285809Sscottl                       smIOSuccess,
13756285809Sscottl                       SCSI_STAT_GOOD,
13757285809Sscottl                       agNULL,
13758285809Sscottl                       satIOContext->interruptContext);
13759285809Sscottl    return SM_RC_SUCCESS;
13760285809Sscottl  }
13761285809Sscottl
13762285809Sscottl  /* checking Block Descriptor Length on Mode parameter header(6)*/
13763285809Sscottl  if (pLogPage[3] == 8)
13764285809Sscottl  {
13765285809Sscottl    /* mode parameter block descriptor exists */
13766285809Sscottl    PageCode = (bit8)(pLogPage[12] & 0x3F);   /* page code and index is 4 + 8 */
13767285809Sscottl    StartingIndex = 12;
13768285809Sscottl  }
13769285809Sscottl  else if (pLogPage[3] == 0)
13770285809Sscottl  {
13771285809Sscottl    /* mode parameter block descriptor does not exist */
13772285809Sscottl    PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */
13773285809Sscottl    StartingIndex = 4;
13774285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
13775285809Sscottl
13776285809Sscottl    tdsmIOCompletedCB( smRoot,
13777285809Sscottl                       smIORequest,
13778285809Sscottl                       smIOSuccess,
13779285809Sscottl                       SCSI_STAT_GOOD,
13780285809Sscottl                       agNULL,
13781285809Sscottl                       satIOContext->interruptContext);
13782285809Sscottl    return SM_RC_SUCCESS;
13783285809Sscottl  }
13784285809Sscottl  else
13785285809Sscottl  {
13786285809Sscottl    SM_DBG1(("smsatModeSelect6: return mode parameter block descriptor 0x%x!!!\n", pLogPage[3]));
13787285809Sscottl
13788285809Sscottl    smsatSetSensePayload( pSense,
13789285809Sscottl                          SCSI_SNSKEY_NO_SENSE,
13790285809Sscottl                          0,
13791285809Sscottl                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
13792285809Sscottl                          satIOContext);
13793285809Sscottl
13794285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
13795285809Sscottl
13796285809Sscottl    tdsmIOCompletedCB( smRoot,
13797285809Sscottl                       smIORequest,
13798285809Sscottl                       smIOSuccess,
13799285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
13800285809Sscottl                       satIOContext->pSmSenseData,
13801285809Sscottl                       satIOContext->interruptContext );
13802285809Sscottl    return SM_RC_SUCCESS;
13803285809Sscottl  }
13804285809Sscottl
13805285809Sscottl
13806285809Sscottl
13807285809Sscottl  switch (PageCode) /* page code */
13808285809Sscottl  {
13809285809Sscottl  case MODESELECT_CONTROL_PAGE:
13810285809Sscottl    SM_DBG1(("smsatModeSelect6: Control mode page!!!\n"));
13811285809Sscottl
13812285809Sscottl    if ( pLogPage[StartingIndex+1] != 0x0A ||
13813285809Sscottl         pLogPage[StartingIndex+2] != 0x02 ||
13814285809Sscottl         (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
13815285809Sscottl         (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
13816285809Sscottl         (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
13817285809Sscottl         (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
13818285809Sscottl         (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
13819285809Sscottl
13820285809Sscottl         (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
13821285809Sscottl         (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
13822285809Sscottl         (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
13823285809Sscottl         (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
13824285809Sscottl
13825285809Sscottl         pLogPage[StartingIndex+8] != 0xFF ||
13826285809Sscottl         pLogPage[StartingIndex+9] != 0xFF ||
13827285809Sscottl         pLogPage[StartingIndex+10] != 0x00 ||
13828285809Sscottl         pLogPage[StartingIndex+11] != 0x00
13829285809Sscottl       )
13830285809Sscottl    {
13831285809Sscottl      chkCnd = agTRUE;
13832285809Sscottl    }
13833285809Sscottl    if (chkCnd == agTRUE)
13834285809Sscottl    {
13835285809Sscottl      smsatSetSensePayload( pSense,
13836285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
13837285809Sscottl                            0,
13838285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13839285809Sscottl                            satIOContext);
13840285809Sscottl
13841285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
13842285809Sscottl
13843285809Sscottl      tdsmIOCompletedCB( smRoot,
13844285809Sscottl                         smIORequest,
13845285809Sscottl                         smIOSuccess,
13846285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
13847285809Sscottl                         satIOContext->pSmSenseData,
13848285809Sscottl                         satIOContext->interruptContext );
13849285809Sscottl
13850285809Sscottl      SM_DBG1(("smsatModeSelect6: unexpected values!!!\n"));
13851285809Sscottl    }
13852285809Sscottl    else
13853285809Sscottl    {
13854285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
13855285809Sscottl
13856285809Sscottl      tdsmIOCompletedCB( smRoot,
13857285809Sscottl                         smIORequest,
13858285809Sscottl                         smIOSuccess,
13859285809Sscottl                         SCSI_STAT_GOOD,
13860285809Sscottl                         agNULL,
13861285809Sscottl                         satIOContext->interruptContext);
13862285809Sscottl    }
13863285809Sscottl    return SM_RC_SUCCESS;
13864285809Sscottl    break;
13865285809Sscottl  case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
13866285809Sscottl    SM_DBG1(("smsatModeSelect6: Read-Write Error Recovery mode page!!!\n"));
13867285809Sscottl
13868285809Sscottl    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) ||
13869285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) ||
13870285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) ||
13871285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) ||
13872285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) ||
13873285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) ||
13874285809Sscottl         (pLogPage[StartingIndex + 10]) ||
13875285809Sscottl         (pLogPage[StartingIndex + 11])
13876285809Sscottl         )
13877285809Sscottl    {
13878285809Sscottl      SM_DBG5(("smsatModeSelect6: return check condition\n"));
13879285809Sscottl
13880285809Sscottl      smsatSetSensePayload( pSense,
13881285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
13882285809Sscottl                            0,
13883285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13884285809Sscottl                            satIOContext);
13885285809Sscottl
13886285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
13887285809Sscottl
13888285809Sscottl      tdsmIOCompletedCB( smRoot,
13889285809Sscottl                         smIORequest,
13890285809Sscottl                         smIOSuccess,
13891285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
13892285809Sscottl                         satIOContext->pSmSenseData,
13893285809Sscottl                         satIOContext->interruptContext );
13894285809Sscottl      return SM_RC_SUCCESS;
13895285809Sscottl    }
13896285809Sscottl    else
13897285809Sscottl    {
13898285809Sscottl      SM_DBG5(("smsatModeSelect6: return GOOD \n"));
13899285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
13900285809Sscottl
13901285809Sscottl      tdsmIOCompletedCB( smRoot,
13902285809Sscottl                         smIORequest,
13903285809Sscottl                         smIOSuccess,
13904285809Sscottl                         SCSI_STAT_GOOD,
13905285809Sscottl                         agNULL,
13906285809Sscottl                         satIOContext->interruptContext);
13907285809Sscottl      return SM_RC_SUCCESS;
13908285809Sscottl    }
13909285809Sscottl
13910285809Sscottl    break;
13911285809Sscottl  case MODESELECT_CACHING:
13912285809Sscottl    /* SAT rev8 Table67, p69*/
13913285809Sscottl    SM_DBG5(("smsatModeSelect6: Caching mode page\n"));
13914285809Sscottl    if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
13915285809Sscottl         (pLogPage[StartingIndex + 3]) ||
13916285809Sscottl         (pLogPage[StartingIndex + 4]) ||
13917285809Sscottl         (pLogPage[StartingIndex + 5]) ||
13918285809Sscottl         (pLogPage[StartingIndex + 6]) ||
13919285809Sscottl         (pLogPage[StartingIndex + 7]) ||
13920285809Sscottl         (pLogPage[StartingIndex + 8]) ||
13921285809Sscottl         (pLogPage[StartingIndex + 9]) ||
13922285809Sscottl         (pLogPage[StartingIndex + 10]) ||
13923285809Sscottl         (pLogPage[StartingIndex + 11]) ||
13924285809Sscottl
13925285809Sscottl         (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
13926285809Sscottl         (pLogPage[StartingIndex + 13]) ||
13927285809Sscottl         (pLogPage[StartingIndex + 14]) ||
13928285809Sscottl         (pLogPage[StartingIndex + 15])
13929285809Sscottl         )
13930285809Sscottl    {
13931285809Sscottl      SM_DBG1(("smsatModeSelect6: return check condition!!!\n"));
13932285809Sscottl
13933285809Sscottl      smsatSetSensePayload( pSense,
13934285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
13935285809Sscottl                            0,
13936285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13937285809Sscottl                            satIOContext);
13938285809Sscottl
13939285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
13940285809Sscottl
13941285809Sscottl      tdsmIOCompletedCB( smRoot,
13942285809Sscottl                         smIORequest,
13943285809Sscottl                         smIOSuccess,
13944285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
13945285809Sscottl                         satIOContext->pSmSenseData,
13946285809Sscottl                         satIOContext->interruptContext );
13947285809Sscottl      return SM_RC_SUCCESS;
13948285809Sscottl
13949285809Sscottl    }
13950285809Sscottl    else
13951285809Sscottl    {
13952285809Sscottl      /* sends ATA SET FEATURES based on WCE bit */
13953285809Sscottl      if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
13954285809Sscottl      {
13955285809Sscottl        SM_DBG5(("smsatModeSelect6: disable write cache\n"));
13956285809Sscottl        /* sends SET FEATURES */
13957285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
13958285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13959285809Sscottl
13960285809Sscottl        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
13961285809Sscottl        fis->h.features       = 0x82;                   /* disable write cache */
13962285809Sscottl        fis->d.lbaLow         = 0;                      /* */
13963285809Sscottl        fis->d.lbaMid         = 0;                      /* */
13964285809Sscottl        fis->d.lbaHigh        = 0;                      /* */
13965285809Sscottl        fis->d.device         = 0;                      /* */
13966285809Sscottl        fis->d.lbaLowExp      = 0;                      /* */
13967285809Sscottl        fis->d.lbaMidExp      = 0;                      /* */
13968285809Sscottl        fis->d.lbaHighExp     = 0;                      /* */
13969285809Sscottl        fis->d.featuresExp    = 0;                      /* */
13970285809Sscottl        fis->d.sectorCount    = 0;                      /* */
13971285809Sscottl        fis->d.sectorCountExp = 0;                      /* */
13972285809Sscottl        fis->d.reserved4      = 0;
13973285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
13974285809Sscottl        fis->d.reserved5      = 0;
13975285809Sscottl
13976285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13977285809Sscottl
13978285809Sscottl        /* Initialize CB for SATA completion.
13979285809Sscottl         */
13980285809Sscottl        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
13981285809Sscottl
13982285809Sscottl        /*
13983285809Sscottl         * Prepare SGL and send FIS to LL layer.
13984285809Sscottl         */
13985285809Sscottl        satIOContext->reqType = agRequestType;       /* Save it */
13986285809Sscottl
13987285809Sscottl        status = smsataLLIOStart( smRoot,
13988285809Sscottl                                  smIORequest,
13989285809Sscottl                                  smDeviceHandle,
13990285809Sscottl                                  smScsiRequest,
13991285809Sscottl                                  satIOContext);
13992285809Sscottl        return status;
13993285809Sscottl      }
13994285809Sscottl      else
13995285809Sscottl      {
13996285809Sscottl        SM_DBG5(("smsatModeSelect6: enable write cache\n"));
13997285809Sscottl        /* sends SET FEATURES */
13998285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
13999285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14000285809Sscottl
14001285809Sscottl        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
14002285809Sscottl        fis->h.features       = 0x02;                   /* enable write cache */
14003285809Sscottl        fis->d.lbaLow         = 0;                      /* */
14004285809Sscottl        fis->d.lbaMid         = 0;                      /* */
14005285809Sscottl        fis->d.lbaHigh        = 0;                      /* */
14006285809Sscottl        fis->d.device         = 0;                      /* */
14007285809Sscottl        fis->d.lbaLowExp      = 0;                      /* */
14008285809Sscottl        fis->d.lbaMidExp      = 0;                      /* */
14009285809Sscottl        fis->d.lbaHighExp     = 0;                      /* */
14010285809Sscottl        fis->d.featuresExp    = 0;                      /* */
14011285809Sscottl        fis->d.sectorCount    = 0;                      /* */
14012285809Sscottl        fis->d.sectorCountExp = 0;                      /* */
14013285809Sscottl        fis->d.reserved4      = 0;
14014285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
14015285809Sscottl        fis->d.reserved5      = 0;
14016285809Sscottl
14017285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14018285809Sscottl
14019285809Sscottl        /* Initialize CB for SATA completion.
14020285809Sscottl         */
14021285809Sscottl        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14022285809Sscottl
14023285809Sscottl        /*
14024285809Sscottl         * Prepare SGL and send FIS to LL layer.
14025285809Sscottl         */
14026285809Sscottl        satIOContext->reqType = agRequestType;       /* Save it */
14027285809Sscottl
14028285809Sscottl        status = smsataLLIOStart( smRoot,
14029285809Sscottl                                  smIORequest,
14030285809Sscottl                                  smDeviceHandle,
14031285809Sscottl                                  smScsiRequest,
14032285809Sscottl                                  satIOContext);
14033285809Sscottl        return status;
14034285809Sscottl
14035285809Sscottl      }
14036285809Sscottl    }
14037285809Sscottl    break;
14038285809Sscottl  case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
14039285809Sscottl    SM_DBG5(("smsatModeSelect6: Informational Exception Control mode page\n"));
14040285809Sscottl
14041285809Sscottl    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
14042285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
14043285809Sscottl         )
14044285809Sscottl    {
14045285809Sscottl      SM_DBG1(("smsatModeSelect6: return check condition!!! \n"));
14046285809Sscottl
14047285809Sscottl      smsatSetSensePayload( pSense,
14048285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
14049285809Sscottl                            0,
14050285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14051285809Sscottl                            satIOContext);
14052285809Sscottl
14053285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
14054285809Sscottl
14055285809Sscottl      tdsmIOCompletedCB( smRoot,
14056285809Sscottl                         smIORequest,
14057285809Sscottl                         smIOSuccess,
14058285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
14059285809Sscottl                         satIOContext->pSmSenseData,
14060285809Sscottl                         satIOContext->interruptContext );
14061285809Sscottl      return SM_RC_SUCCESS;
14062285809Sscottl    }
14063285809Sscottl    else
14064285809Sscottl    {
14065285809Sscottl      /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
14066285809Sscottl      if ( !(pLogPage[StartingIndex + 2] & 0x08) )
14067285809Sscottl      {
14068285809Sscottl        SM_DBG5(("smsatModeSelect6: enable information exceptions reporting\n"));
14069285809Sscottl        /* sends SMART ENABLE OPERATIONS */
14070285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
14071285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14072285809Sscottl
14073285809Sscottl        fis->h.command        = SAT_SMART;              /* 0xB0 */
14074285809Sscottl        fis->h.features       = SAT_SMART_ENABLE_OPERATIONS;       /* enable */
14075285809Sscottl        fis->d.lbaLow         = 0;                      /* */
14076285809Sscottl        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14077285809Sscottl        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14078285809Sscottl        fis->d.device         = 0;                      /* */
14079285809Sscottl        fis->d.lbaLowExp      = 0;                      /* */
14080285809Sscottl        fis->d.lbaMidExp      = 0;                      /* */
14081285809Sscottl        fis->d.lbaHighExp     = 0;                      /* */
14082285809Sscottl        fis->d.featuresExp    = 0;                      /* */
14083285809Sscottl        fis->d.sectorCount    = 0;                      /* */
14084285809Sscottl        fis->d.sectorCountExp = 0;                      /* */
14085285809Sscottl        fis->d.reserved4      = 0;
14086285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
14087285809Sscottl        fis->d.reserved5      = 0;
14088285809Sscottl
14089285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14090285809Sscottl
14091285809Sscottl        /* Initialize CB for SATA completion.
14092285809Sscottl         */
14093285809Sscottl        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14094285809Sscottl
14095285809Sscottl        /*
14096285809Sscottl         * Prepare SGL and send FIS to LL layer.
14097285809Sscottl         */
14098285809Sscottl        satIOContext->reqType = agRequestType;       /* Save it */
14099285809Sscottl
14100285809Sscottl        status = smsataLLIOStart( smRoot,
14101285809Sscottl                                  smIORequest,
14102285809Sscottl                                  smDeviceHandle,
14103285809Sscottl                                  smScsiRequest,
14104285809Sscottl                                  satIOContext);
14105285809Sscottl        return status;
14106285809Sscottl      }
14107285809Sscottl      else
14108285809Sscottl      {
14109285809Sscottl        SM_DBG5(("smsatModeSelect6: disable information exceptions reporting\n"));
14110285809Sscottl        /* sends SMART DISABLE OPERATIONS */
14111285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
14112285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14113285809Sscottl
14114285809Sscottl        fis->h.command        = SAT_SMART;              /* 0xB0 */
14115285809Sscottl        fis->h.features       = SAT_SMART_DISABLE_OPERATIONS; /* disable */
14116285809Sscottl        fis->d.lbaLow         = 0;                      /* */
14117285809Sscottl        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14118285809Sscottl        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14119285809Sscottl        fis->d.device         = 0;                      /* */
14120285809Sscottl        fis->d.lbaLowExp      = 0;                      /* */
14121285809Sscottl        fis->d.lbaMidExp      = 0;                      /* */
14122285809Sscottl        fis->d.lbaHighExp     = 0;                      /* */
14123285809Sscottl        fis->d.featuresExp    = 0;                      /* */
14124285809Sscottl        fis->d.sectorCount    = 0;                      /* */
14125285809Sscottl        fis->d.sectorCountExp = 0;                      /* */
14126285809Sscottl        fis->d.reserved4      = 0;
14127285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
14128285809Sscottl        fis->d.reserved5      = 0;
14129285809Sscottl
14130285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14131285809Sscottl
14132285809Sscottl        /* Initialize CB for SATA completion.
14133285809Sscottl         */
14134285809Sscottl        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14135285809Sscottl
14136285809Sscottl        /*
14137285809Sscottl         * Prepare SGL and send FIS to LL layer.
14138285809Sscottl         */
14139285809Sscottl        satIOContext->reqType = agRequestType;       /* Save it */
14140285809Sscottl
14141285809Sscottl        status = smsataLLIOStart( smRoot,
14142285809Sscottl                                  smIORequest,
14143285809Sscottl                                  smDeviceHandle,
14144285809Sscottl                                  smScsiRequest,
14145285809Sscottl                                  satIOContext);
14146285809Sscottl        return status;
14147285809Sscottl
14148285809Sscottl      }
14149285809Sscottl    }
14150285809Sscottl    break;
14151285809Sscottl  default:
14152285809Sscottl    SM_DBG1(("smsatModeSelect6: Error unknown page code 0x%x!!!\n", pLogPage[12]));
14153285809Sscottl    smsatSetSensePayload( pSense,
14154285809Sscottl                          SCSI_SNSKEY_NO_SENSE,
14155285809Sscottl                          0,
14156285809Sscottl                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14157285809Sscottl                          satIOContext);
14158285809Sscottl
14159285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
14160285809Sscottl
14161285809Sscottl    tdsmIOCompletedCB( smRoot,
14162285809Sscottl                       smIORequest,
14163285809Sscottl                       smIOSuccess,
14164285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
14165285809Sscottl                       satIOContext->pSmSenseData,
14166285809Sscottl                       satIOContext->interruptContext );
14167285809Sscottl    return SM_RC_SUCCESS;
14168285809Sscottl  }
14169285809Sscottl}
14170285809Sscottl
14171285809Sscottl
14172285809SscottlosGLOBAL bit32
14173285809SscottlsmsatModeSelect10(
14174285809Sscottl                  smRoot_t                  *smRoot,
14175285809Sscottl                  smIORequest_t             *smIORequest,
14176285809Sscottl                  smDeviceHandle_t          *smDeviceHandle,
14177285809Sscottl                  smScsiInitiatorRequest_t  *smScsiRequest,
14178285809Sscottl                  smSatIOContext_t            *satIOContext
14179285809Sscottl                 )
14180285809Sscottl{
14181285809Sscottl  bit32                     status;
14182285809Sscottl  bit32                     agRequestType;
14183285809Sscottl  smDeviceData_t            *pSatDevData;
14184285809Sscottl  smScsiRspSense_t          *pSense;
14185285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
14186285809Sscottl  agsaFisRegHostToDevice_t  *fis;
14187285809Sscottl  bit8                      *pLogPage;    /* Log Page data buffer */
14188285809Sscottl  bit16                     BlkDescLen = 0;     /* Block Descriptor Length */
14189285809Sscottl  bit32                     StartingIndex = 0;
14190285809Sscottl  bit8                      PageCode = 0;
14191285809Sscottl  bit32                     chkCnd = agFALSE;
14192285809Sscottl  bit32                     parameterListLen = 0;
14193285809Sscottl
14194285809Sscottl  pSense        = satIOContext->pSense;
14195285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
14196285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
14197285809Sscottl  fis           = satIOContext->pFis;
14198285809Sscottl  pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
14199285809Sscottl
14200285809Sscottl  SM_DBG5(("smsatModeSelect10: start\n"));
14201285809Sscottl
14202285809Sscottl  /* checking CONTROL */
14203285809Sscottl  /* NACA == 1 or LINK == 1*/
14204285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
14205285809Sscottl  {
14206285809Sscottl    smsatSetSensePayload( pSense,
14207285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14208285809Sscottl                          0,
14209285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14210285809Sscottl                          satIOContext);
14211285809Sscottl
14212285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
14213285809Sscottl
14214285809Sscottl    tdsmIOCompletedCB( smRoot,
14215285809Sscottl                       smIORequest,
14216285809Sscottl                       smIOSuccess,
14217285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
14218285809Sscottl                       satIOContext->pSmSenseData,
14219285809Sscottl                       satIOContext->interruptContext );
14220285809Sscottl
14221285809Sscottl    SM_DBG1(("smsatModeSelect10: return control!!!\n"));
14222285809Sscottl    return SM_RC_SUCCESS;
14223285809Sscottl  }
14224285809Sscottl
14225285809Sscottl  /* checking PF bit */
14226285809Sscottl  if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
14227285809Sscottl  {
14228285809Sscottl    smsatSetSensePayload( pSense,
14229285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14230285809Sscottl                          0,
14231285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14232285809Sscottl                          satIOContext);
14233285809Sscottl
14234285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
14235285809Sscottl
14236285809Sscottl    tdsmIOCompletedCB( smRoot,
14237285809Sscottl                       smIORequest,
14238285809Sscottl                       smIOSuccess,
14239285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
14240285809Sscottl                       satIOContext->pSmSenseData,
14241285809Sscottl                       satIOContext->interruptContext );
14242285809Sscottl
14243285809Sscottl    SM_DBG1(("smsatModeSelect10: PF bit check!!!\n"));
14244285809Sscottl    return SM_RC_SUCCESS;
14245285809Sscottl  }
14246285809Sscottl
14247285809Sscottl  parameterListLen = ((scsiCmnd->cdb[7]) << 8) + scsiCmnd->cdb[8];
14248285809Sscottl  parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength);
14249285809Sscottl  if ((0 == parameterListLen) || (agNULL == pLogPage))
14250285809Sscottl  {
14251285809Sscottl    tdsmIOCompletedCB( smRoot,
14252285809Sscottl                       smIORequest,
14253285809Sscottl                       smIOSuccess,
14254285809Sscottl                       SCSI_STAT_GOOD,
14255285809Sscottl                       agNULL,
14256285809Sscottl                       satIOContext->interruptContext);
14257285809Sscottl    return SM_RC_SUCCESS;
14258285809Sscottl  }
14259285809Sscottl
14260285809Sscottl  BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]);
14261285809Sscottl
14262285809Sscottl  /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/
14263285809Sscottl  if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
14264285809Sscottl  {
14265285809Sscottl    /* mode parameter block descriptor exists and length is 8 byte */
14266285809Sscottl    PageCode = (bit8)(pLogPage[16] & 0x3F);   /* page code and index is 8 + 8 */
14267285809Sscottl    StartingIndex = 16;
14268285809Sscottl  }
14269285809Sscottl  else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
14270285809Sscottl  {
14271285809Sscottl    /* mode parameter block descriptor exists and length is 16 byte */
14272285809Sscottl    PageCode = (bit8)(pLogPage[24] & 0x3F);   /* page code and index is 8 + 16 */
14273285809Sscottl    StartingIndex = 24;
14274285809Sscottl  }
14275285809Sscottl  else if (BlkDescLen == 0)
14276285809Sscottl  {
14277285809Sscottl    PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */
14278285809Sscottl    StartingIndex = 8;
14279285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
14280285809Sscottl
14281285809Sscottl    tdsmIOCompletedCB( smRoot,
14282285809Sscottl                       smIORequest,
14283285809Sscottl                       smIOSuccess,
14284285809Sscottl                       SCSI_STAT_GOOD,
14285285809Sscottl                       agNULL,
14286285809Sscottl                       satIOContext->interruptContext);
14287285809Sscottl    return SM_RC_SUCCESS;
14288285809Sscottl  }
14289285809Sscottl  else
14290285809Sscottl  {
14291285809Sscottl    SM_DBG1(("smsatModeSelect10: return mode parameter block descriptor 0x%x!!!\n",  BlkDescLen));
14292285809Sscottl    /* no more than one mode parameter block descriptor shall be supported */
14293285809Sscottl    smsatSetSensePayload( pSense,
14294285809Sscottl                          SCSI_SNSKEY_NO_SENSE,
14295285809Sscottl                          0,
14296285809Sscottl                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14297285809Sscottl                          satIOContext);
14298285809Sscottl
14299285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
14300285809Sscottl
14301285809Sscottl    tdsmIOCompletedCB( smRoot,
14302285809Sscottl                       smIORequest,
14303285809Sscottl                       smIOSuccess,
14304285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
14305285809Sscottl                       satIOContext->pSmSenseData,
14306285809Sscottl                       satIOContext->interruptContext );
14307285809Sscottl    return SM_RC_SUCCESS;
14308285809Sscottl  }
14309285809Sscottl  /*
14310285809Sscottl    for debugging only
14311285809Sscottl  */
14312285809Sscottl  if (StartingIndex == 8)
14313285809Sscottl  {
14314285809Sscottl    smhexdump("startingindex 8", (bit8 *)pLogPage, 8);
14315285809Sscottl  }
14316285809Sscottl  else if(StartingIndex == 16)
14317285809Sscottl  {
14318285809Sscottl    if (PageCode == MODESELECT_CACHING)
14319285809Sscottl    {
14320285809Sscottl      smhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
14321285809Sscottl    }
14322285809Sscottl    else
14323285809Sscottl    {
14324285809Sscottl      smhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
14325285809Sscottl    }
14326285809Sscottl  }
14327285809Sscottl  else
14328285809Sscottl  {
14329285809Sscottl    if (PageCode == MODESELECT_CACHING)
14330285809Sscottl    {
14331285809Sscottl      smhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
14332285809Sscottl    }
14333285809Sscottl    else
14334285809Sscottl    {
14335285809Sscottl      smhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
14336285809Sscottl    }
14337285809Sscottl  }
14338285809Sscottl  switch (PageCode) /* page code */
14339285809Sscottl  {
14340285809Sscottl  case MODESELECT_CONTROL_PAGE:
14341285809Sscottl    SM_DBG5(("smsatModeSelect10: Control mode page\n"));
14342285809Sscottl    /*
14343285809Sscottl      compare pLogPage to expected value (SAT Table 65, p67)
14344285809Sscottl      If not match, return check condition
14345285809Sscottl     */
14346285809Sscottl    if ( pLogPage[StartingIndex+1] != 0x0A ||
14347285809Sscottl         pLogPage[StartingIndex+2] != 0x02 ||
14348285809Sscottl         (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
14349285809Sscottl         (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
14350285809Sscottl         (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
14351285809Sscottl         (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
14352285809Sscottl         (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
14353285809Sscottl
14354285809Sscottl         (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
14355285809Sscottl         (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
14356285809Sscottl         (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
14357285809Sscottl         (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
14358285809Sscottl
14359285809Sscottl         pLogPage[StartingIndex+8] != 0xFF ||
14360285809Sscottl         pLogPage[StartingIndex+9] != 0xFF ||
14361285809Sscottl         pLogPage[StartingIndex+10] != 0x00 ||
14362285809Sscottl         pLogPage[StartingIndex+11] != 0x00
14363285809Sscottl       )
14364285809Sscottl    {
14365285809Sscottl      chkCnd = agTRUE;
14366285809Sscottl    }
14367285809Sscottl    if (chkCnd == agTRUE)
14368285809Sscottl    {
14369285809Sscottl      smsatSetSensePayload( pSense,
14370285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
14371285809Sscottl                            0,
14372285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14373285809Sscottl                            satIOContext);
14374285809Sscottl
14375285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
14376285809Sscottl
14377285809Sscottl      tdsmIOCompletedCB( smRoot,
14378285809Sscottl                         smIORequest,
14379285809Sscottl                         smIOSuccess,
14380285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
14381285809Sscottl                         satIOContext->pSmSenseData,
14382285809Sscottl                         satIOContext->interruptContext );
14383285809Sscottl
14384285809Sscottl      SM_DBG1(("smsatModeSelect10: unexpected values!!!\n"));
14385285809Sscottl    }
14386285809Sscottl    else
14387285809Sscottl    {
14388285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
14389285809Sscottl
14390285809Sscottl      tdsmIOCompletedCB( smRoot,
14391285809Sscottl                         smIORequest,
14392285809Sscottl                         smIOSuccess,
14393285809Sscottl                         SCSI_STAT_GOOD,
14394285809Sscottl                         agNULL,
14395285809Sscottl                         satIOContext->interruptContext);
14396285809Sscottl    }
14397285809Sscottl    return SM_RC_SUCCESS;
14398285809Sscottl    break;
14399285809Sscottl  case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
14400285809Sscottl    SM_DBG5(("smsatModeSelect10: Read-Write Error Recovery mode page\n"));
14401285809Sscottl
14402285809Sscottl    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) ||
14403285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) ||
14404285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) ||
14405285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) ||
14406285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) ||
14407285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) ||
14408285809Sscottl         (pLogPage[StartingIndex + 10]) ||
14409285809Sscottl         (pLogPage[StartingIndex + 11])
14410285809Sscottl         )
14411285809Sscottl    {
14412285809Sscottl      SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14413285809Sscottl
14414285809Sscottl      smsatSetSensePayload( pSense,
14415285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
14416285809Sscottl                            0,
14417285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14418285809Sscottl                            satIOContext);
14419285809Sscottl
14420285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
14421285809Sscottl
14422285809Sscottl      tdsmIOCompletedCB( smRoot,
14423285809Sscottl                         smIORequest,
14424285809Sscottl                         smIOSuccess,
14425285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
14426285809Sscottl                         satIOContext->pSmSenseData,
14427285809Sscottl                         satIOContext->interruptContext );
14428285809Sscottl      return SM_RC_SUCCESS;
14429285809Sscottl    }
14430285809Sscottl    else
14431285809Sscottl    {
14432285809Sscottl      SM_DBG2(("smsatModeSelect10: return GOOD \n"));
14433285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
14434285809Sscottl
14435285809Sscottl      tdsmIOCompletedCB( smRoot,
14436285809Sscottl                         smIORequest,
14437285809Sscottl                         smIOSuccess,
14438285809Sscottl                         SCSI_STAT_GOOD,
14439285809Sscottl                         agNULL,
14440285809Sscottl                         satIOContext->interruptContext);
14441285809Sscottl      return SM_RC_SUCCESS;
14442285809Sscottl    }
14443285809Sscottl
14444285809Sscottl    break;
14445285809Sscottl  case MODESELECT_CACHING:
14446285809Sscottl    /* SAT rev8 Table67, p69*/
14447285809Sscottl    SM_DBG5(("smsatModeSelect10: Caching mode page\n"));
14448285809Sscottl    if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
14449285809Sscottl         (pLogPage[StartingIndex + 3]) ||
14450285809Sscottl         (pLogPage[StartingIndex + 4]) ||
14451285809Sscottl         (pLogPage[StartingIndex + 5]) ||
14452285809Sscottl         (pLogPage[StartingIndex + 6]) ||
14453285809Sscottl         (pLogPage[StartingIndex + 7]) ||
14454285809Sscottl         (pLogPage[StartingIndex + 8]) ||
14455285809Sscottl         (pLogPage[StartingIndex + 9]) ||
14456285809Sscottl         (pLogPage[StartingIndex + 10]) ||
14457285809Sscottl         (pLogPage[StartingIndex + 11]) ||
14458285809Sscottl
14459285809Sscottl         (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
14460285809Sscottl         (pLogPage[StartingIndex + 13]) ||
14461285809Sscottl         (pLogPage[StartingIndex + 14]) ||
14462285809Sscottl         (pLogPage[StartingIndex + 15])
14463285809Sscottl         )
14464285809Sscottl    {
14465285809Sscottl      SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14466285809Sscottl
14467285809Sscottl      smsatSetSensePayload( pSense,
14468285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
14469285809Sscottl                            0,
14470285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14471285809Sscottl                            satIOContext);
14472285809Sscottl
14473285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
14474285809Sscottl
14475285809Sscottl      tdsmIOCompletedCB( smRoot,
14476285809Sscottl                         smIORequest,
14477285809Sscottl                         smIOSuccess,
14478285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
14479285809Sscottl                         satIOContext->pSmSenseData,
14480285809Sscottl                         satIOContext->interruptContext );
14481285809Sscottl      return SM_RC_SUCCESS;
14482285809Sscottl
14483285809Sscottl    }
14484285809Sscottl    else
14485285809Sscottl    {
14486285809Sscottl      /* sends ATA SET FEATURES based on WCE bit */
14487285809Sscottl      if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
14488285809Sscottl      {
14489285809Sscottl        SM_DBG5(("smsatModeSelect10: disable write cache\n"));
14490285809Sscottl        /* sends SET FEATURES */
14491285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
14492285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14493285809Sscottl
14494285809Sscottl        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
14495285809Sscottl        fis->h.features       = 0x82;                   /* disable write cache */
14496285809Sscottl        fis->d.lbaLow         = 0;                      /* */
14497285809Sscottl        fis->d.lbaMid         = 0;                      /* */
14498285809Sscottl        fis->d.lbaHigh        = 0;                      /* */
14499285809Sscottl        fis->d.device         = 0;                      /* */
14500285809Sscottl        fis->d.lbaLowExp      = 0;                      /* */
14501285809Sscottl        fis->d.lbaMidExp      = 0;                      /* */
14502285809Sscottl        fis->d.lbaHighExp     = 0;                      /* */
14503285809Sscottl        fis->d.featuresExp    = 0;                      /* */
14504285809Sscottl        fis->d.sectorCount    = 0;                      /* */
14505285809Sscottl        fis->d.sectorCountExp = 0;                      /* */
14506285809Sscottl        fis->d.reserved4      = 0;
14507285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
14508285809Sscottl        fis->d.reserved5      = 0;
14509285809Sscottl
14510285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14511285809Sscottl
14512285809Sscottl        /* Initialize CB for SATA completion.
14513285809Sscottl         */
14514285809Sscottl        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14515285809Sscottl
14516285809Sscottl        /*
14517285809Sscottl         * Prepare SGL and send FIS to LL layer.
14518285809Sscottl         */
14519285809Sscottl        satIOContext->reqType = agRequestType;       /* Save it */
14520285809Sscottl
14521285809Sscottl        status = smsataLLIOStart( smRoot,
14522285809Sscottl                                  smIORequest,
14523285809Sscottl                                  smDeviceHandle,
14524285809Sscottl                                  smScsiRequest,
14525285809Sscottl                                  satIOContext);
14526285809Sscottl        return status;
14527285809Sscottl      }
14528285809Sscottl      else
14529285809Sscottl      {
14530285809Sscottl        SM_DBG5(("smsatModeSelect10: enable write cache\n"));
14531285809Sscottl        /* sends SET FEATURES */
14532285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
14533285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14534285809Sscottl
14535285809Sscottl        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
14536285809Sscottl        fis->h.features       = 0x02;                   /* enable write cache */
14537285809Sscottl        fis->d.lbaLow         = 0;                      /* */
14538285809Sscottl        fis->d.lbaMid         = 0;                      /* */
14539285809Sscottl        fis->d.lbaHigh        = 0;                      /* */
14540285809Sscottl        fis->d.device         = 0;                      /* */
14541285809Sscottl        fis->d.lbaLowExp      = 0;                      /* */
14542285809Sscottl        fis->d.lbaMidExp      = 0;                      /* */
14543285809Sscottl        fis->d.lbaHighExp     = 0;                      /* */
14544285809Sscottl        fis->d.featuresExp    = 0;                      /* */
14545285809Sscottl        fis->d.sectorCount    = 0;                      /* */
14546285809Sscottl        fis->d.sectorCountExp = 0;                      /* */
14547285809Sscottl        fis->d.reserved4      = 0;
14548285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
14549285809Sscottl        fis->d.reserved5      = 0;
14550285809Sscottl
14551285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14552285809Sscottl
14553285809Sscottl        /* Initialize CB for SATA completion.
14554285809Sscottl         */
14555285809Sscottl        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14556285809Sscottl
14557285809Sscottl        /*
14558285809Sscottl         * Prepare SGL and send FIS to LL layer.
14559285809Sscottl         */
14560285809Sscottl        satIOContext->reqType = agRequestType;       /* Save it */
14561285809Sscottl
14562285809Sscottl        status = smsataLLIOStart( smRoot,
14563285809Sscottl                                  smIORequest,
14564285809Sscottl                                  smDeviceHandle,
14565285809Sscottl                                  smScsiRequest,
14566285809Sscottl                                  satIOContext);
14567285809Sscottl        return status;
14568285809Sscottl
14569285809Sscottl      }
14570285809Sscottl    }
14571285809Sscottl    break;
14572285809Sscottl  case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
14573285809Sscottl    SM_DBG5(("smsatModeSelect10: Informational Exception Control mode page\n"));
14574285809Sscottl
14575285809Sscottl    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
14576285809Sscottl         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
14577285809Sscottl         )
14578285809Sscottl    {
14579285809Sscottl      SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14580285809Sscottl
14581285809Sscottl      smsatSetSensePayload( pSense,
14582285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
14583285809Sscottl                            0,
14584285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14585285809Sscottl                            satIOContext);
14586285809Sscottl
14587285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
14588285809Sscottl
14589285809Sscottl      tdsmIOCompletedCB( smRoot,
14590285809Sscottl                         smIORequest,
14591285809Sscottl                         smIOSuccess,
14592285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
14593285809Sscottl                         satIOContext->pSmSenseData,
14594285809Sscottl                         satIOContext->interruptContext );
14595285809Sscottl      return SM_RC_SUCCESS;
14596285809Sscottl    }
14597285809Sscottl    else
14598285809Sscottl    {
14599285809Sscottl      /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
14600285809Sscottl      if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
14601285809Sscottl      {
14602285809Sscottl        SM_DBG5(("smsatModeSelect10: enable information exceptions reporting\n"));
14603285809Sscottl        /* sends SMART ENABLE OPERATIONS */
14604285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
14605285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14606285809Sscottl
14607285809Sscottl        fis->h.command        = SAT_SMART;              /* 0xB0 */
14608285809Sscottl        fis->h.features       = SAT_SMART_ENABLE_OPERATIONS;       /* enable */
14609285809Sscottl        fis->d.lbaLow         = 0;                      /* */
14610285809Sscottl        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14611285809Sscottl        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14612285809Sscottl        fis->d.device         = 0;                      /* */
14613285809Sscottl        fis->d.lbaLowExp      = 0;                      /* */
14614285809Sscottl        fis->d.lbaMidExp      = 0;                      /* */
14615285809Sscottl        fis->d.lbaHighExp     = 0;                      /* */
14616285809Sscottl        fis->d.featuresExp    = 0;                      /* */
14617285809Sscottl        fis->d.sectorCount    = 0;                      /* */
14618285809Sscottl        fis->d.sectorCountExp = 0;                      /* */
14619285809Sscottl        fis->d.reserved4      = 0;
14620285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
14621285809Sscottl        fis->d.reserved5      = 0;
14622285809Sscottl
14623285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14624285809Sscottl
14625285809Sscottl        /* Initialize CB for SATA completion.
14626285809Sscottl         */
14627285809Sscottl        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14628285809Sscottl
14629285809Sscottl        /*
14630285809Sscottl         * Prepare SGL and send FIS to LL layer.
14631285809Sscottl         */
14632285809Sscottl        satIOContext->reqType = agRequestType;       /* Save it */
14633285809Sscottl
14634285809Sscottl        status = smsataLLIOStart( smRoot,
14635285809Sscottl                                  smIORequest,
14636285809Sscottl                                  smDeviceHandle,
14637285809Sscottl                                  smScsiRequest,
14638285809Sscottl                                  satIOContext);
14639285809Sscottl        return status;
14640285809Sscottl      }
14641285809Sscottl      else
14642285809Sscottl      {
14643285809Sscottl        SM_DBG5(("smsatModeSelect10: disable information exceptions reporting\n"));
14644285809Sscottl        /* sends SMART DISABLE OPERATIONS */
14645285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
14646285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14647285809Sscottl
14648285809Sscottl        fis->h.command        = SAT_SMART;              /* 0xB0 */
14649285809Sscottl        fis->h.features       = SAT_SMART_DISABLE_OPERATIONS; /* disable */
14650285809Sscottl        fis->d.lbaLow         = 0;                      /* */
14651285809Sscottl        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14652285809Sscottl        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14653285809Sscottl        fis->d.device         = 0;                      /* */
14654285809Sscottl        fis->d.lbaLowExp      = 0;                      /* */
14655285809Sscottl        fis->d.lbaMidExp      = 0;                      /* */
14656285809Sscottl        fis->d.lbaHighExp     = 0;                      /* */
14657285809Sscottl        fis->d.featuresExp    = 0;                      /* */
14658285809Sscottl        fis->d.sectorCount    = 0;                      /* */
14659285809Sscottl        fis->d.sectorCountExp = 0;                      /* */
14660285809Sscottl        fis->d.reserved4      = 0;
14661285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
14662285809Sscottl        fis->d.reserved5      = 0;
14663285809Sscottl
14664285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14665285809Sscottl
14666285809Sscottl        /* Initialize CB for SATA completion.
14667285809Sscottl         */
14668285809Sscottl        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14669285809Sscottl
14670285809Sscottl        /*
14671285809Sscottl         * Prepare SGL and send FIS to LL layer.
14672285809Sscottl         */
14673285809Sscottl        satIOContext->reqType = agRequestType;       /* Save it */
14674285809Sscottl
14675285809Sscottl        status = smsataLLIOStart( smRoot,
14676285809Sscottl                                  smIORequest,
14677285809Sscottl                                  smDeviceHandle,
14678285809Sscottl                                  smScsiRequest,
14679285809Sscottl                                  satIOContext);
14680285809Sscottl        return status;
14681285809Sscottl
14682285809Sscottl      }
14683285809Sscottl    }
14684285809Sscottl    break;
14685285809Sscottl  default:
14686285809Sscottl    SM_DBG1(("smsatModeSelect10: Error unknown page code 0x%x!!!\n", pLogPage[12]));
14687285809Sscottl    smsatSetSensePayload( pSense,
14688285809Sscottl                          SCSI_SNSKEY_NO_SENSE,
14689285809Sscottl                          0,
14690285809Sscottl                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14691285809Sscottl                          satIOContext);
14692285809Sscottl
14693285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
14694285809Sscottl
14695285809Sscottl    tdsmIOCompletedCB( smRoot,
14696285809Sscottl                       smIORequest,
14697285809Sscottl                       smIOSuccess,
14698285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
14699285809Sscottl                       satIOContext->pSmSenseData,
14700285809Sscottl                       satIOContext->interruptContext );
14701285809Sscottl    return SM_RC_SUCCESS;
14702285809Sscottl  }
14703285809Sscottl}
14704285809Sscottl
14705285809SscottlosGLOBAL bit32
14706285809SscottlsmsatSynchronizeCache10(
14707285809Sscottl                        smRoot_t                  *smRoot,
14708285809Sscottl                        smIORequest_t             *smIORequest,
14709285809Sscottl                        smDeviceHandle_t          *smDeviceHandle,
14710285809Sscottl                        smScsiInitiatorRequest_t  *smScsiRequest,
14711285809Sscottl                        smSatIOContext_t            *satIOContext
14712285809Sscottl                       )
14713285809Sscottl{
14714285809Sscottl  bit32                     status;
14715285809Sscottl  bit32                     agRequestType;
14716285809Sscottl  smDeviceData_t            *pSatDevData;
14717285809Sscottl  smScsiRspSense_t          *pSense;
14718285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
14719285809Sscottl  agsaFisRegHostToDevice_t  *fis;
14720285809Sscottl
14721285809Sscottl  pSense        = satIOContext->pSense;
14722285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
14723285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
14724285809Sscottl  fis           = satIOContext->pFis;
14725285809Sscottl
14726285809Sscottl  SM_DBG5(("smsatSynchronizeCache10: start\n"));
14727285809Sscottl
14728285809Sscottl  /* checking CONTROL */
14729285809Sscottl  /* NACA == 1 or LINK == 1*/
14730285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
14731285809Sscottl  {
14732285809Sscottl    smsatSetSensePayload( pSense,
14733285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14734285809Sscottl                          0,
14735285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14736285809Sscottl                          satIOContext);
14737285809Sscottl
14738285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
14739285809Sscottl
14740285809Sscottl    tdsmIOCompletedCB( smRoot,
14741285809Sscottl                       smIORequest,
14742285809Sscottl                       smIOSuccess,
14743285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
14744285809Sscottl                       satIOContext->pSmSenseData,
14745285809Sscottl                       satIOContext->interruptContext );
14746285809Sscottl
14747285809Sscottl    SM_DBG1(("smsatSynchronizeCache10: return control!!!\n"));
14748285809Sscottl    return SM_RC_SUCCESS;
14749285809Sscottl  }
14750285809Sscottl
14751285809Sscottl  /* checking IMMED bit */
14752285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
14753285809Sscottl  {
14754285809Sscottl    SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n"));
14755285809Sscottl
14756285809Sscottl    /* return GOOD status first here */
14757285809Sscottl    tdsmIOCompletedCB( smRoot,
14758285809Sscottl                       smIORequest,
14759285809Sscottl                       smIOSuccess,
14760285809Sscottl                       SCSI_STAT_GOOD,
14761285809Sscottl                       agNULL,
14762285809Sscottl                       satIOContext->interruptContext);
14763285809Sscottl  }
14764285809Sscottl
14765285809Sscottl  /* sends FLUSH CACHE or FLUSH CACHE EXT */
14766285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
14767285809Sscottl  {
14768285809Sscottl    SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n"));
14769285809Sscottl    /* FLUSH CACHE EXT */
14770285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
14771285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14772285809Sscottl
14773285809Sscottl    fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
14774285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
14775285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
14776285809Sscottl    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14777285809Sscottl    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
14778285809Sscottl    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14779285809Sscottl    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
14780285809Sscottl    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14781285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14782285809Sscottl    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14783285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14784285809Sscottl    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14785285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
14786285809Sscottl    fis->d.reserved4      = 0;
14787285809Sscottl    fis->d.reserved5      = 0;
14788285809Sscottl
14789285809Sscottl  }
14790285809Sscottl  else
14791285809Sscottl  {
14792285809Sscottl    SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n"));
14793285809Sscottl    /* FLUSH CACHE */
14794285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
14795285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14796285809Sscottl
14797285809Sscottl    fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
14798285809Sscottl    fis->h.features       = 0;                      /* FIS features NA       */
14799285809Sscottl    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14800285809Sscottl    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14801285809Sscottl    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14802285809Sscottl    fis->d.lbaLowExp      = 0;
14803285809Sscottl    fis->d.lbaMidExp      = 0;
14804285809Sscottl    fis->d.lbaHighExp     = 0;
14805285809Sscottl    fis->d.featuresExp    = 0;
14806285809Sscottl    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14807285809Sscottl    fis->d.sectorCountExp = 0;
14808285809Sscottl    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14809285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
14810285809Sscottl    fis->d.reserved4      = 0;
14811285809Sscottl    fis->d.reserved5      = 0;
14812285809Sscottl
14813285809Sscottl  }
14814285809Sscottl
14815285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14816285809Sscottl
14817285809Sscottl  /* Initialize CB for SATA completion.
14818285809Sscottl   */
14819285809Sscottl  satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB;
14820285809Sscottl
14821285809Sscottl  /*
14822285809Sscottl   * Prepare SGL and send FIS to LL layer.
14823285809Sscottl   */
14824285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
14825285809Sscottl
14826285809Sscottl  status = smsataLLIOStart( smRoot,
14827285809Sscottl                            smIORequest,
14828285809Sscottl                            smDeviceHandle,
14829285809Sscottl                            smScsiRequest,
14830285809Sscottl                            satIOContext);
14831285809Sscottl
14832285809Sscottl
14833285809Sscottl  return (status);
14834285809Sscottl}
14835285809Sscottl
14836285809SscottlosGLOBAL bit32
14837285809SscottlsmsatSynchronizeCache16(
14838285809Sscottl                        smRoot_t                  *smRoot,
14839285809Sscottl                        smIORequest_t             *smIORequest,
14840285809Sscottl                        smDeviceHandle_t          *smDeviceHandle,
14841285809Sscottl                        smScsiInitiatorRequest_t  *smScsiRequest,
14842285809Sscottl                        smSatIOContext_t            *satIOContext
14843285809Sscottl                       )
14844285809Sscottl{
14845285809Sscottl  bit32                     status;
14846285809Sscottl  bit32                     agRequestType;
14847285809Sscottl  smDeviceData_t            *pSatDevData;
14848285809Sscottl  smScsiRspSense_t          *pSense;
14849285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
14850285809Sscottl  agsaFisRegHostToDevice_t  *fis;
14851285809Sscottl
14852285809Sscottl  pSense        = satIOContext->pSense;
14853285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
14854285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
14855285809Sscottl  fis           = satIOContext->pFis;
14856285809Sscottl
14857285809Sscottl  SM_DBG5(("smsatSynchronizeCache10: start\n"));
14858285809Sscottl
14859285809Sscottl  /* checking CONTROL */
14860285809Sscottl  /* NACA == 1 or LINK == 1*/
14861285809Sscottl  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
14862285809Sscottl  {
14863285809Sscottl    smsatSetSensePayload( pSense,
14864285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14865285809Sscottl                          0,
14866285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14867285809Sscottl                          satIOContext);
14868285809Sscottl
14869285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
14870285809Sscottl
14871285809Sscottl    tdsmIOCompletedCB( smRoot,
14872285809Sscottl                       smIORequest,
14873285809Sscottl                       smIOSuccess,
14874285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
14875285809Sscottl                       satIOContext->pSmSenseData,
14876285809Sscottl                       satIOContext->interruptContext );
14877285809Sscottl
14878285809Sscottl    SM_DBG1(("smsatSynchronizeCache10: return control!!!\n"));
14879285809Sscottl    return SM_RC_SUCCESS;
14880285809Sscottl  }
14881285809Sscottl
14882285809Sscottl
14883285809Sscottl  /* checking IMMED bit */
14884285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
14885285809Sscottl  {
14886285809Sscottl    SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n"));
14887285809Sscottl
14888285809Sscottl    /* return GOOD status first here */
14889285809Sscottl    tdsmIOCompletedCB( smRoot,
14890285809Sscottl                       smIORequest,
14891285809Sscottl                       smIOSuccess,
14892285809Sscottl                       SCSI_STAT_GOOD,
14893285809Sscottl                       agNULL,
14894285809Sscottl                       satIOContext->interruptContext);
14895285809Sscottl  }
14896285809Sscottl
14897285809Sscottl  /* sends FLUSH CACHE or FLUSH CACHE EXT */
14898285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
14899285809Sscottl  {
14900285809Sscottl    SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n"));
14901285809Sscottl    /* FLUSH CACHE EXT */
14902285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
14903285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14904285809Sscottl
14905285809Sscottl    fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
14906285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
14907285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
14908285809Sscottl    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14909285809Sscottl    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
14910285809Sscottl    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14911285809Sscottl    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
14912285809Sscottl    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14913285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14914285809Sscottl    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14915285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14916285809Sscottl    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14917285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
14918285809Sscottl    fis->d.reserved4      = 0;
14919285809Sscottl    fis->d.reserved5      = 0;
14920285809Sscottl
14921285809Sscottl  }
14922285809Sscottl  else
14923285809Sscottl  {
14924285809Sscottl    SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n"));
14925285809Sscottl    /* FLUSH CACHE */
14926285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
14927285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14928285809Sscottl
14929285809Sscottl    fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
14930285809Sscottl    fis->h.features       = 0;                      /* FIS features NA       */
14931285809Sscottl    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14932285809Sscottl    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14933285809Sscottl    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14934285809Sscottl    fis->d.lbaLowExp      = 0;
14935285809Sscottl    fis->d.lbaMidExp      = 0;
14936285809Sscottl    fis->d.lbaHighExp     = 0;
14937285809Sscottl    fis->d.featuresExp    = 0;
14938285809Sscottl    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14939285809Sscottl    fis->d.sectorCountExp = 0;
14940285809Sscottl    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14941285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
14942285809Sscottl    fis->d.reserved4      = 0;
14943285809Sscottl    fis->d.reserved5      = 0;
14944285809Sscottl
14945285809Sscottl  }
14946285809Sscottl
14947285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14948285809Sscottl
14949285809Sscottl  /* Initialize CB for SATA completion.
14950285809Sscottl   */
14951285809Sscottl  satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB;
14952285809Sscottl
14953285809Sscottl  /*
14954285809Sscottl   * Prepare SGL and send FIS to LL layer.
14955285809Sscottl   */
14956285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
14957285809Sscottl
14958285809Sscottl  status = smsataLLIOStart( smRoot,
14959285809Sscottl                            smIORequest,
14960285809Sscottl                            smDeviceHandle,
14961285809Sscottl                            smScsiRequest,
14962285809Sscottl                            satIOContext);
14963285809Sscottl
14964285809Sscottl
14965285809Sscottl  return (status);
14966285809Sscottl}
14967285809Sscottl
14968285809SscottlosGLOBAL bit32
14969285809SscottlsmsatWriteAndVerify10(
14970285809Sscottl                      smRoot_t                  *smRoot,
14971285809Sscottl                      smIORequest_t             *smIORequest,
14972285809Sscottl                      smDeviceHandle_t          *smDeviceHandle,
14973285809Sscottl                      smScsiInitiatorRequest_t  *smScsiRequest,
14974285809Sscottl                      smSatIOContext_t            *satIOContext
14975285809Sscottl                     )
14976285809Sscottl{
14977285809Sscottl  /*
14978285809Sscottl    combination of write10 and verify10
14979285809Sscottl  */
14980285809Sscottl
14981285809Sscottl  bit32                     status;
14982285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14983285809Sscottl  smDeviceData_t            *pSatDevData;
14984285809Sscottl  smScsiRspSense_t          *pSense;
14985285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
14986285809Sscottl  agsaFisRegHostToDevice_t  *fis;
14987285809Sscottl  bit32                     lba = 0;
14988285809Sscottl  bit32                     tl = 0;
14989285809Sscottl  bit32                     LoopNum = 1;
14990285809Sscottl  bit8                      LBA[8];
14991285809Sscottl  bit8                      TL[8];
14992285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
14993285809Sscottl
14994285809Sscottl  pSense        = satIOContext->pSense;
14995285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
14996285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
14997285809Sscottl  fis           = satIOContext->pFis;
14998285809Sscottl
14999285809Sscottl  SM_DBG5(("smsatWriteAndVerify10: start\n"));
15000285809Sscottl
15001285809Sscottl  /* checking BYTCHK bit */
15002285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15003285809Sscottl  {
15004285809Sscottl    smsatSetSensePayload( pSense,
15005285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15006285809Sscottl                          0,
15007285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15008285809Sscottl                          satIOContext);
15009285809Sscottl
15010285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
15011285809Sscottl
15012285809Sscottl    tdsmIOCompletedCB( smRoot,
15013285809Sscottl                       smIORequest,
15014285809Sscottl                       smIOSuccess,
15015285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
15016285809Sscottl                       satIOContext->pSmSenseData,
15017285809Sscottl                       satIOContext->interruptContext );
15018285809Sscottl
15019285809Sscottl    SM_DBG1(("smsatWriteAndVerify10: BYTCHK bit checking!!!\n"));
15020285809Sscottl    return SM_RC_SUCCESS;
15021285809Sscottl  }
15022285809Sscottl
15023285809Sscottl
15024285809Sscottl  /* checking CONTROL */
15025285809Sscottl  /* NACA == 1 or LINK == 1*/
15026285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
15027285809Sscottl  {
15028285809Sscottl    smsatSetSensePayload( pSense,
15029285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15030285809Sscottl                          0,
15031285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15032285809Sscottl                          satIOContext);
15033285809Sscottl
15034285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
15035285809Sscottl
15036285809Sscottl    tdsmIOCompletedCB( smRoot,
15037285809Sscottl                       smIORequest,
15038285809Sscottl                       smIOSuccess,
15039285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
15040285809Sscottl                       satIOContext->pSmSenseData,
15041285809Sscottl                       satIOContext->interruptContext );
15042285809Sscottl
15043285809Sscottl    SM_DBG1(("smsatWriteAndVerify10: return control!!!\n"));
15044285809Sscottl    return SM_RC_SUCCESS;
15045285809Sscottl  }
15046285809Sscottl
15047285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
15048285809Sscottl  sm_memset(TL, 0, sizeof(TL));
15049285809Sscottl
15050285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
15051285809Sscottl  LBA[0] = 0;                  /* MSB */
15052285809Sscottl  LBA[1] = 0;
15053285809Sscottl  LBA[2] = 0;
15054285809Sscottl  LBA[3] = 0;
15055285809Sscottl  LBA[4] = scsiCmnd->cdb[2];
15056285809Sscottl  LBA[5] = scsiCmnd->cdb[3];
15057285809Sscottl  LBA[6] = scsiCmnd->cdb[4];
15058285809Sscottl  LBA[7] = scsiCmnd->cdb[5];   /* LSB */
15059285809Sscottl
15060285809Sscottl  TL[0] = 0;
15061285809Sscottl  TL[1] = 0;
15062285809Sscottl  TL[2] = 0;
15063285809Sscottl  TL[3] = 0;
15064285809Sscottl  TL[4] = 0;
15065285809Sscottl  TL[5] = 0;
15066285809Sscottl  TL[6] = scsiCmnd->cdb[7];
15067285809Sscottl  TL[7] = scsiCmnd->cdb[8];    /* LSB */
15068285809Sscottl
15069285809Sscottl
15070285809Sscottl  /* cbd10; computing LBA and transfer length */
15071285809Sscottl  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
15072285809Sscottl    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
15073285809Sscottl  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
15074285809Sscottl
15075285809Sscottl
15076285809Sscottl  /* Table 34, 9.1, p 46 */
15077285809Sscottl  /*
15078285809Sscottl    note: As of 2/10/2006, no support for DMA QUEUED
15079285809Sscottl   */
15080285809Sscottl
15081285809Sscottl  /*
15082285809Sscottl    Table 34, 9.1, p 46, b
15083285809Sscottl    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15084285809Sscottl    return check condition
15085285809Sscottl  */
15086285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
15087285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
15088285809Sscottl      )
15089285809Sscottl  {
15090285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15091285809Sscottl    if (AllChk)
15092285809Sscottl    {
15093285809Sscottl      SM_DBG1(("smsatWriteAndVerify10: return LBA out of range!!!\n"));
15094285809Sscottl      smsatSetSensePayload( pSense,
15095285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15096285809Sscottl                            0,
15097285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15098285809Sscottl                            satIOContext);
15099285809Sscottl
15100285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
15101285809Sscottl
15102285809Sscottl      tdsmIOCompletedCB( smRoot,
15103285809Sscottl                         smIORequest,
15104285809Sscottl                         smIOSuccess,
15105285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
15106285809Sscottl                         satIOContext->pSmSenseData,
15107285809Sscottl                         satIOContext->interruptContext );
15108285809Sscottl
15109285809Sscottl    return SM_RC_SUCCESS;
15110285809Sscottl    }
15111285809Sscottl  }
15112285809Sscottl  else
15113285809Sscottl  {
15114285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15115285809Sscottl    if (AllChk)
15116285809Sscottl    {
15117285809Sscottl      SM_DBG1(("smsatWriteAndVerify10: return LBA out of range, EXT!!!\n"));
15118285809Sscottl      smsatSetSensePayload( pSense,
15119285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15120285809Sscottl                            0,
15121285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15122285809Sscottl                            satIOContext);
15123285809Sscottl
15124285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
15125285809Sscottl
15126285809Sscottl      tdsmIOCompletedCB( smRoot,
15127285809Sscottl                         smIORequest,
15128285809Sscottl                         smIOSuccess,
15129285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
15130285809Sscottl                         satIOContext->pSmSenseData,
15131285809Sscottl                         satIOContext->interruptContext );
15132285809Sscottl
15133285809Sscottl      return SM_RC_SUCCESS;
15134285809Sscottl    }
15135285809Sscottl  }
15136285809Sscottl
15137285809Sscottl
15138285809Sscottl  /* case 1 and 2 */
15139285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15140285809Sscottl    {
15141285809Sscottl      /* case 2 */
15142285809Sscottl      /* WRITE DMA*/
15143285809Sscottl      /* can't fit the transfer length */
15144285809Sscottl      SM_DBG5(("smsatWriteAndVerify10: case 2\n"));
15145285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
15146285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15147285809Sscottl      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
15148285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
15149285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15150285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15151285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15152285809Sscottl
15153285809Sscottl      /* FIS LBA mode set LBA (27:24) */
15154285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15155285809Sscottl
15156285809Sscottl      fis->d.lbaLowExp      = 0;
15157285809Sscottl      fis->d.lbaMidExp      = 0;
15158285809Sscottl      fis->d.lbaHighExp     = 0;
15159285809Sscottl      fis->d.featuresExp    = 0;
15160285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15161285809Sscottl      fis->d.sectorCountExp = 0;
15162285809Sscottl      fis->d.reserved4      = 0;
15163285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
15164285809Sscottl      fis->d.reserved5      = 0;
15165285809Sscottl
15166285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15167285809Sscottl      satIOContext->ATACmd = SAT_WRITE_DMA;
15168285809Sscottl    }
15169285809Sscottl    else
15170285809Sscottl    {
15171285809Sscottl      /* case 1 */
15172285809Sscottl      /* WRITE MULTIPLE or WRITE SECTOR(S) */
15173285809Sscottl      /* WRITE SECTORS for easier implemetation */
15174285809Sscottl      /* can't fit the transfer length */
15175285809Sscottl      SM_DBG5(("smsatWriteAndVerify10: case 1\n"));
15176285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
15177285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15178285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
15179285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
15180285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15181285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15182285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15183285809Sscottl
15184285809Sscottl      /* FIS LBA mode set LBA (27:24) */
15185285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15186285809Sscottl
15187285809Sscottl      fis->d.lbaLowExp      = 0;
15188285809Sscottl      fis->d.lbaMidExp      = 0;
15189285809Sscottl      fis->d.lbaHighExp     = 0;
15190285809Sscottl      fis->d.featuresExp    = 0;
15191285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15192285809Sscottl      fis->d.sectorCountExp = 0;
15193285809Sscottl      fis->d.reserved4      = 0;
15194285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
15195285809Sscottl      fis->d.reserved5      = 0;
15196285809Sscottl
15197285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15198285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS;
15199285809Sscottl
15200285809Sscottl  }
15201285809Sscottl
15202285809Sscottl  /* case 3 and 4 */
15203285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
15204285809Sscottl  {
15205285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15206285809Sscottl    {
15207285809Sscottl      /* case 3 */
15208285809Sscottl      /* WRITE DMA EXT or WRITE DMA FUA EXT */
15209285809Sscottl      SM_DBG5(("smsatWriteAndVerify10: case 3\n"));
15210285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
15211285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15212285809Sscottl
15213285809Sscottl      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15214285809Sscottl      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
15215285809Sscottl
15216285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
15217285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15218285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15219285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15220285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
15221285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15222285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15223285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15224285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
15225285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15226285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15227285809Sscottl      fis->d.reserved4      = 0;
15228285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
15229285809Sscottl      fis->d.reserved5      = 0;
15230285809Sscottl
15231285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15232285809Sscottl      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15233285809Sscottl    }
15234285809Sscottl    else
15235285809Sscottl    {
15236285809Sscottl      /* case 4 */
15237285809Sscottl      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15238285809Sscottl      /* WRITE SECTORS EXT for easier implemetation */
15239285809Sscottl      SM_DBG5(("smsatWriteAndVerify10: case 4\n"));
15240285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
15241285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15242285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
15243285809Sscottl
15244285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
15245285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15246285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15247285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15248285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
15249285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15250285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15251285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15252285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
15253285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15254285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15255285809Sscottl      fis->d.reserved4      = 0;
15256285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
15257285809Sscottl      fis->d.reserved5      = 0;
15258285809Sscottl
15259285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15260285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15261285809Sscottl    }
15262285809Sscottl  }
15263285809Sscottl  /* case 5 */
15264285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
15265285809Sscottl  {
15266285809Sscottl    /* WRITE FPDMA QUEUED */
15267285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
15268285809Sscottl    {
15269285809Sscottl      SM_DBG1(("smsatWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
15270285809Sscottl      smsatSetSensePayload( pSense,
15271285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15272285809Sscottl                            0,
15273285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15274285809Sscottl                            satIOContext);
15275285809Sscottl
15276285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
15277285809Sscottl
15278285809Sscottl      tdsmIOCompletedCB( smRoot,
15279285809Sscottl                         smIORequest,
15280285809Sscottl                         smIOSuccess,
15281285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
15282285809Sscottl                         satIOContext->pSmSenseData,
15283285809Sscottl                         satIOContext->interruptContext );
15284285809Sscottl      return SM_RC_SUCCESS;
15285285809Sscottl    }
15286285809Sscottl    SM_DBG5(("smsatWriteAndVerify10: case 5\n"));
15287285809Sscottl
15288285809Sscottl    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15289285809Sscottl
15290285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
15291285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15292285809Sscottl    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15293285809Sscottl    fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15294285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15295285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15296285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15297285809Sscottl
15298285809Sscottl    /* Check FUA bit */
15299285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
15300285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
15301285809Sscottl    else
15302285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
15303285809Sscottl
15304285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15305285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15306285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15307285809Sscottl    fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15308285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15309285809Sscottl    fis->d.sectorCountExp = 0;
15310285809Sscottl    fis->d.reserved4      = 0;
15311285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
15312285809Sscottl    fis->d.reserved5      = 0;
15313285809Sscottl
15314285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15315285809Sscottl    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15316285809Sscottl  }
15317285809Sscottl
15318285809Sscottl  satIOContext->currentLBA = lba;
15319285809Sscottl  satIOContext->OrgTL = tl;
15320285809Sscottl
15321285809Sscottl  /*
15322285809Sscottl    computing number of loop and remainder for tl
15323285809Sscottl    0xFF in case not ext
15324285809Sscottl    0xFFFF in case EXT
15325285809Sscottl  */
15326285809Sscottl  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15327285809Sscottl  {
15328285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFF);
15329285809Sscottl  }
15330285809Sscottl  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15331285809Sscottl           fis->h.command == SAT_WRITE_DMA_EXT     ||
15332285809Sscottl           fis->h.command == SAT_WRITE_DMA_FUA_EXT
15333285809Sscottl           )
15334285809Sscottl  {
15335285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15336285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15337285809Sscottl  }
15338285809Sscottl  else
15339285809Sscottl  {
15340285809Sscottl    /* SAT_WRITE_FPDMA_QUEUED */
15341285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15342285809Sscottl  }
15343285809Sscottl
15344285809Sscottl  satIOContext->LoopNum = LoopNum;
15345285809Sscottl
15346285809Sscottl
15347285809Sscottl  if (LoopNum == 1)
15348285809Sscottl  {
15349285809Sscottl    SM_DBG5(("smsatWriteAndVerify10: NON CHAINED data\n"));
15350285809Sscottl    /* Initialize CB for SATA completion.
15351285809Sscottl     */
15352285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
15353285809Sscottl  }
15354285809Sscottl  else
15355285809Sscottl  {
15356285809Sscottl    SM_DBG1(("smsatWriteAndVerify10: CHAINED data!!!\n"));
15357285809Sscottl    /* re-setting tl */
15358285809Sscottl    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15359285809Sscottl    {
15360285809Sscottl       fis->d.sectorCount    = 0xFF;
15361285809Sscottl    }
15362285809Sscottl    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15363285809Sscottl             fis->h.command == SAT_WRITE_DMA_EXT ||
15364285809Sscottl             fis->h.command == SAT_WRITE_DMA_FUA_EXT
15365285809Sscottl             )
15366285809Sscottl    {
15367285809Sscottl      fis->d.sectorCount    = 0xFF;
15368285809Sscottl      fis->d.sectorCountExp = 0xFF;
15369285809Sscottl    }
15370285809Sscottl    else
15371285809Sscottl    {
15372285809Sscottl      /* SAT_WRITE_FPDMA_QUEUED */
15373285809Sscottl      fis->h.features       = 0xFF;
15374285809Sscottl      fis->d.featuresExp    = 0xFF;
15375285809Sscottl    }
15376285809Sscottl
15377285809Sscottl    /* Initialize CB for SATA completion.
15378285809Sscottl     */
15379285809Sscottl    satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
15380285809Sscottl  }
15381285809Sscottl
15382285809Sscottl
15383285809Sscottl  /*
15384285809Sscottl   * Prepare SGL and send FIS to LL layer.
15385285809Sscottl   */
15386285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
15387285809Sscottl
15388285809Sscottl  status = smsataLLIOStart( smRoot,
15389285809Sscottl                            smIORequest,
15390285809Sscottl                            smDeviceHandle,
15391285809Sscottl                            smScsiRequest,
15392285809Sscottl                            satIOContext);
15393285809Sscottl  return (status);
15394285809Sscottl
15395285809Sscottl}
15396285809Sscottl
15397285809SscottlosGLOBAL bit32
15398285809SscottlsmsatWriteAndVerify12(
15399285809Sscottl                      smRoot_t                  *smRoot,
15400285809Sscottl                      smIORequest_t             *smIORequest,
15401285809Sscottl                      smDeviceHandle_t          *smDeviceHandle,
15402285809Sscottl                      smScsiInitiatorRequest_t  *smScsiRequest,
15403285809Sscottl                      smSatIOContext_t            *satIOContext
15404285809Sscottl                     )
15405285809Sscottl{
15406285809Sscottl  /*
15407285809Sscottl    combination of write12 and verify12
15408285809Sscottl    temp: since write12 is not support (due to internal checking), no support
15409285809Sscottl  */
15410285809Sscottl  bit32                     status;
15411285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15412285809Sscottl  smDeviceData_t            *pSatDevData;
15413285809Sscottl  smScsiRspSense_t          *pSense;
15414285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
15415285809Sscottl  agsaFisRegHostToDevice_t  *fis;
15416285809Sscottl  bit32                     lba = 0;
15417285809Sscottl  bit32                     tl = 0;
15418285809Sscottl  bit32                     LoopNum = 1;
15419285809Sscottl  bit8                      LBA[8];
15420285809Sscottl  bit8                      TL[8];
15421285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
15422285809Sscottl
15423285809Sscottl  pSense        = satIOContext->pSense;
15424285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
15425285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
15426285809Sscottl  fis           = satIOContext->pFis;
15427285809Sscottl
15428285809Sscottl  SM_DBG5(("smsatWriteAndVerify12: start\n"));
15429285809Sscottl
15430285809Sscottl  /* checking BYTCHK bit */
15431285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15432285809Sscottl  {
15433285809Sscottl    smsatSetSensePayload( pSense,
15434285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15435285809Sscottl                          0,
15436285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15437285809Sscottl                          satIOContext);
15438285809Sscottl
15439285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
15440285809Sscottl
15441285809Sscottl    tdsmIOCompletedCB( smRoot,
15442285809Sscottl                       smIORequest,
15443285809Sscottl                       smIOSuccess,
15444285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
15445285809Sscottl                       satIOContext->pSmSenseData,
15446285809Sscottl                       satIOContext->interruptContext );
15447285809Sscottl
15448285809Sscottl    SM_DBG1(("smsatWriteAndVerify12: BYTCHK bit checking!!!\n"));
15449285809Sscottl    return SM_RC_SUCCESS;
15450285809Sscottl  }
15451285809Sscottl
15452285809Sscottl  /* checking CONTROL */
15453285809Sscottl  /* NACA == 1 or LINK == 1*/
15454285809Sscottl  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
15455285809Sscottl  {
15456285809Sscottl    smsatSetSensePayload( pSense,
15457285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15458285809Sscottl                          0,
15459285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15460285809Sscottl                          satIOContext);
15461285809Sscottl
15462285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
15463285809Sscottl
15464285809Sscottl    tdsmIOCompletedCB( smRoot,
15465285809Sscottl                       smIORequest,
15466285809Sscottl                       smIOSuccess,
15467285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
15468285809Sscottl                       satIOContext->pSmSenseData,
15469285809Sscottl                       satIOContext->interruptContext );
15470285809Sscottl
15471285809Sscottl    SM_DBG1(("smsatWriteAndVerify12: return control!!!\n"));
15472285809Sscottl    return SM_RC_SUCCESS;
15473285809Sscottl  }
15474285809Sscottl
15475285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
15476285809Sscottl  sm_memset(TL, 0, sizeof(TL));
15477285809Sscottl
15478285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
15479285809Sscottl  LBA[0] = 0;                  /* MSB */
15480285809Sscottl  LBA[1] = 0;
15481285809Sscottl  LBA[2] = 0;
15482285809Sscottl  LBA[3] = 0;
15483285809Sscottl  LBA[4] = scsiCmnd->cdb[2];
15484285809Sscottl  LBA[5] = scsiCmnd->cdb[3];
15485285809Sscottl  LBA[6] = scsiCmnd->cdb[4];
15486285809Sscottl  LBA[7] = scsiCmnd->cdb[5];   /* LSB */
15487285809Sscottl
15488285809Sscottl  TL[0] = 0;                   /* MSB */
15489285809Sscottl  TL[1] = 0;
15490285809Sscottl  TL[2] = 0;
15491285809Sscottl  TL[3] = 0;
15492285809Sscottl  TL[4] = scsiCmnd->cdb[6];
15493285809Sscottl  TL[5] = scsiCmnd->cdb[7];
15494285809Sscottl  TL[6] = scsiCmnd->cdb[8];
15495285809Sscottl  TL[7] = scsiCmnd->cdb[9];    /* LSB */
15496285809Sscottl
15497285809Sscottl
15498285809Sscottl  lba = smsatComputeCDB12LBA(satIOContext);
15499285809Sscottl  tl = smsatComputeCDB12TL(satIOContext);
15500285809Sscottl
15501285809Sscottl
15502285809Sscottl  /* Table 34, 9.1, p 46 */
15503285809Sscottl  /*
15504285809Sscottl    note: As of 2/10/2006, no support for DMA QUEUED
15505285809Sscottl   */
15506285809Sscottl
15507285809Sscottl  /*
15508285809Sscottl    Table 34, 9.1, p 46, b
15509285809Sscottl    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15510285809Sscottl    return check condition
15511285809Sscottl  */
15512285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
15513285809Sscottl      pSatDevData->sat48BitSupport != agTRUE
15514285809Sscottl      )
15515285809Sscottl  {
15516285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15517285809Sscottl    if (AllChk)
15518285809Sscottl    {
15519285809Sscottl
15520285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
15521285809Sscottl
15522285809Sscottl
15523285809Sscottl      SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, not EXT!!!\n"));
15524285809Sscottl
15525285809Sscottl      smsatSetSensePayload( pSense,
15526285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15527285809Sscottl                            0,
15528285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15529285809Sscottl                            satIOContext);
15530285809Sscottl
15531285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
15532285809Sscottl
15533285809Sscottl      tdsmIOCompletedCB( smRoot,
15534285809Sscottl                         smIORequest,
15535285809Sscottl                         smIOSuccess,
15536285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
15537285809Sscottl                         satIOContext->pSmSenseData,
15538285809Sscottl                         satIOContext->interruptContext );
15539285809Sscottl
15540285809Sscottl    return SM_RC_SUCCESS;
15541285809Sscottl    }
15542285809Sscottl  }
15543285809Sscottl  else
15544285809Sscottl  {
15545285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15546285809Sscottl    if (AllChk)
15547285809Sscottl  {
15548285809Sscottl      SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, EXT!!!\n"));
15549285809Sscottl      smsatSetSensePayload( pSense,
15550285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15551285809Sscottl                            0,
15552285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15553285809Sscottl                            satIOContext);
15554285809Sscottl      tdsmIOCompletedCB( smRoot,
15555285809Sscottl                         smIORequest,
15556285809Sscottl                         smIOSuccess,
15557285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
15558285809Sscottl                         satIOContext->pSmSenseData,
15559285809Sscottl                         satIOContext->interruptContext );
15560285809Sscottl    return SM_RC_SUCCESS;
15561285809Sscottl    }
15562285809Sscottl  }
15563285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15564285809Sscottl    {
15565285809Sscottl      /* case 2 */
15566285809Sscottl      /* WRITE DMA*/
15567285809Sscottl      /* In case that we can't fit the transfer length, we loop */
15568285809Sscottl      SM_DBG5(("smsatWriteAndVerify12: case 2\n"));
15569285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
15570285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15571285809Sscottl      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
15572285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
15573285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15574285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15575285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15576285809Sscottl
15577285809Sscottl      /* FIS LBA mode set LBA (27:24) */
15578285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15579285809Sscottl
15580285809Sscottl      fis->d.lbaLowExp      = 0;
15581285809Sscottl      fis->d.lbaMidExp      = 0;
15582285809Sscottl      fis->d.lbaHighExp     = 0;
15583285809Sscottl      fis->d.featuresExp    = 0;
15584285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15585285809Sscottl      fis->d.sectorCountExp = 0;
15586285809Sscottl      fis->d.reserved4      = 0;
15587285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
15588285809Sscottl      fis->d.reserved5      = 0;
15589285809Sscottl
15590285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15591285809Sscottl      satIOContext->ATACmd = SAT_WRITE_DMA;
15592285809Sscottl    }
15593285809Sscottl    else
15594285809Sscottl    {
15595285809Sscottl      /* case 1 */
15596285809Sscottl      /* WRITE MULTIPLE or WRITE SECTOR(S) */
15597285809Sscottl      /* WRITE SECTORS for easier implemetation */
15598285809Sscottl      /* In case that we can't fit the transfer length, we loop */
15599285809Sscottl      SM_DBG5(("smsatWriteAndVerify12: case 1\n"));
15600285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
15601285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15602285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
15603285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
15604285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15605285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15606285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15607285809Sscottl
15608285809Sscottl      /* FIS LBA mode set LBA (27:24) */
15609285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15610285809Sscottl
15611285809Sscottl      fis->d.lbaLowExp      = 0;
15612285809Sscottl      fis->d.lbaMidExp      = 0;
15613285809Sscottl      fis->d.lbaHighExp     = 0;
15614285809Sscottl      fis->d.featuresExp    = 0;
15615285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15616285809Sscottl      fis->d.sectorCountExp = 0;
15617285809Sscottl      fis->d.reserved4      = 0;
15618285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
15619285809Sscottl      fis->d.reserved5      = 0;
15620285809Sscottl
15621285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15622285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS;
15623285809Sscottl  }
15624285809Sscottl
15625285809Sscottl  /* case 3 and 4 */
15626285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
15627285809Sscottl  {
15628285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15629285809Sscottl    {
15630285809Sscottl      /* case 3 */
15631285809Sscottl      /* WRITE DMA EXT or WRITE DMA FUA EXT */
15632285809Sscottl      SM_DBG5(("smsatWriteAndVerify12: case 3\n"));
15633285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
15634285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15635285809Sscottl
15636285809Sscottl      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15637285809Sscottl      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
15638285809Sscottl
15639285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
15640285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15641285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15642285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15643285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
15644285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15645285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15646285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15647285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
15648285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15649285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
15650285809Sscottl      fis->d.reserved4      = 0;
15651285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
15652285809Sscottl      fis->d.reserved5      = 0;
15653285809Sscottl
15654285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15655285809Sscottl      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15656285809Sscottl    }
15657285809Sscottl    else
15658285809Sscottl    {
15659285809Sscottl      /* case 4 */
15660285809Sscottl      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15661285809Sscottl      /* WRITE SECTORS EXT for easier implemetation */
15662285809Sscottl      SM_DBG5(("smsatWriteAndVerify12: case 4\n"));
15663285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
15664285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15665285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
15666285809Sscottl
15667285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
15668285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15669285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15670285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15671285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
15672285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15673285809Sscottl      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15674285809Sscottl      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15675285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
15676285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15677285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
15678285809Sscottl      fis->d.reserved4      = 0;
15679285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
15680285809Sscottl      fis->d.reserved5      = 0;
15681285809Sscottl
15682285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15683285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15684285809Sscottl    }
15685285809Sscottl  }
15686285809Sscottl
15687285809Sscottl  /* case 5 */
15688285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
15689285809Sscottl  {
15690285809Sscottl    /* WRITE FPDMA QUEUED */
15691285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
15692285809Sscottl    {
15693285809Sscottl      SM_DBG1(("smsatWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support!!!\n"));
15694285809Sscottl      smsatSetSensePayload( pSense,
15695285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15696285809Sscottl                            0,
15697285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15698285809Sscottl                            satIOContext);
15699285809Sscottl
15700285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
15701285809Sscottl
15702285809Sscottl      tdsmIOCompletedCB( smRoot,
15703285809Sscottl                         smIORequest,
15704285809Sscottl                         smIOSuccess,
15705285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
15706285809Sscottl                         satIOContext->pSmSenseData,
15707285809Sscottl                         satIOContext->interruptContext );
15708285809Sscottl      return SM_RC_SUCCESS;
15709285809Sscottl    }
15710285809Sscottl    SM_DBG6(("smsatWriteAndVerify12: case 5\n"));
15711285809Sscottl
15712285809Sscottl    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15713285809Sscottl
15714285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
15715285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15716285809Sscottl    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15717285809Sscottl    fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15718285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15719285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15720285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15721285809Sscottl
15722285809Sscottl    /* Check FUA bit */
15723285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
15724285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
15725285809Sscottl    else
15726285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
15727285809Sscottl
15728285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15729285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15730285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15731285809Sscottl    fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
15732285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15733285809Sscottl    fis->d.sectorCountExp = 0;
15734285809Sscottl    fis->d.reserved4      = 0;
15735285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
15736285809Sscottl    fis->d.reserved5      = 0;
15737285809Sscottl
15738285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15739285809Sscottl    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15740285809Sscottl  }
15741285809Sscottl
15742285809Sscottl  satIOContext->currentLBA = lba;
15743285809Sscottl//  satIOContext->OrgLBA = lba;
15744285809Sscottl  satIOContext->OrgTL = tl;
15745285809Sscottl
15746285809Sscottl  /*
15747285809Sscottl    computing number of loop and remainder for tl
15748285809Sscottl    0xFF in case not ext
15749285809Sscottl    0xFFFF in case EXT
15750285809Sscottl  */
15751285809Sscottl  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15752285809Sscottl  {
15753285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFF);
15754285809Sscottl  }
15755285809Sscottl  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15756285809Sscottl           fis->h.command == SAT_WRITE_DMA_EXT     ||
15757285809Sscottl           fis->h.command == SAT_WRITE_DMA_FUA_EXT
15758285809Sscottl           )
15759285809Sscottl  {
15760285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15761285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15762285809Sscottl  }
15763285809Sscottl  else
15764285809Sscottl  {
15765285809Sscottl    /* SAT_WRITE_FPDMA_QUEUEDK */
15766285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15767285809Sscottl  }
15768285809Sscottl
15769285809Sscottl  satIOContext->LoopNum = LoopNum;
15770285809Sscottl  satIOContext->LoopNum2 = LoopNum;
15771285809Sscottl
15772285809Sscottl
15773285809Sscottl  if (LoopNum == 1)
15774285809Sscottl  {
15775285809Sscottl    SM_DBG5(("smsatWriteAndVerify12: NON CHAINED data\n"));
15776285809Sscottl    /* Initialize CB for SATA completion.
15777285809Sscottl     */
15778285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
15779285809Sscottl  }
15780285809Sscottl  else
15781285809Sscottl  {
15782285809Sscottl    SM_DBG1(("smsatWriteAndVerify12: CHAINED data!!!\n"));
15783285809Sscottl    /* re-setting tl */
15784285809Sscottl    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15785285809Sscottl    {
15786285809Sscottl       fis->d.sectorCount    = 0xFF;
15787285809Sscottl    }
15788285809Sscottl    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15789285809Sscottl             fis->h.command == SAT_WRITE_DMA_EXT ||
15790285809Sscottl             fis->h.command == SAT_WRITE_DMA_FUA_EXT
15791285809Sscottl             )
15792285809Sscottl    {
15793285809Sscottl      fis->d.sectorCount    = 0xFF;
15794285809Sscottl      fis->d.sectorCountExp = 0xFF;
15795285809Sscottl    }
15796285809Sscottl    else
15797285809Sscottl    {
15798285809Sscottl      /* SAT_WRITE_FPDMA_QUEUED */
15799285809Sscottl      fis->h.features       = 0xFF;
15800285809Sscottl      fis->d.featuresExp    = 0xFF;
15801285809Sscottl    }
15802285809Sscottl
15803285809Sscottl    /* Initialize CB for SATA completion.
15804285809Sscottl     */
15805285809Sscottl    satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
15806285809Sscottl  }
15807285809Sscottl
15808285809Sscottl
15809285809Sscottl  /*
15810285809Sscottl   * Prepare SGL and send FIS to LL layer.
15811285809Sscottl   */
15812285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
15813285809Sscottl
15814285809Sscottl  status = smsataLLIOStart( smRoot,
15815285809Sscottl                            smIORequest,
15816285809Sscottl                            smDeviceHandle,
15817285809Sscottl                            smScsiRequest,
15818285809Sscottl                            satIOContext);
15819285809Sscottl  return (status);
15820285809Sscottl}
15821285809Sscottl
15822285809SscottlosGLOBAL bit32
15823285809SscottlsmsatWriteAndVerify16(
15824285809Sscottl                      smRoot_t                  *smRoot,
15825285809Sscottl                      smIORequest_t             *smIORequest,
15826285809Sscottl                      smDeviceHandle_t          *smDeviceHandle,
15827285809Sscottl                      smScsiInitiatorRequest_t  *smScsiRequest,
15828285809Sscottl                      smSatIOContext_t            *satIOContext
15829285809Sscottl                     )
15830285809Sscottl{
15831285809Sscottl  /*
15832285809Sscottl    combination of write16 and verify16
15833285809Sscottl    since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support
15834285809Sscottl  */
15835285809Sscottl  bit32                     status;
15836285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15837285809Sscottl  smDeviceData_t            *pSatDevData;
15838285809Sscottl  smScsiRspSense_t          *pSense;
15839285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
15840285809Sscottl  agsaFisRegHostToDevice_t  *fis;
15841285809Sscottl  bit32                     lba = 0;
15842285809Sscottl  bit32                     tl = 0;
15843285809Sscottl  bit32                     LoopNum = 1;
15844285809Sscottl  bit8                      LBA[8];
15845285809Sscottl  bit8                      TL[8];
15846285809Sscottl  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
15847285809Sscottl
15848285809Sscottl  pSense        = satIOContext->pSense;
15849285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
15850285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
15851285809Sscottl  fis           = satIOContext->pFis;
15852285809Sscottl
15853285809Sscottl  SM_DBG5(("smsatWriteAndVerify16: start\n"));
15854285809Sscottl
15855285809Sscottl  /* checking BYTCHK bit */
15856285809Sscottl  if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15857285809Sscottl  {
15858285809Sscottl    smsatSetSensePayload( pSense,
15859285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15860285809Sscottl                          0,
15861285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15862285809Sscottl                          satIOContext);
15863285809Sscottl
15864285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
15865285809Sscottl
15866285809Sscottl    tdsmIOCompletedCB( smRoot,
15867285809Sscottl                       smIORequest,
15868285809Sscottl                       smIOSuccess,
15869285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
15870285809Sscottl                       satIOContext->pSmSenseData,
15871285809Sscottl                       satIOContext->interruptContext );
15872285809Sscottl
15873285809Sscottl    SM_DBG1(("smsatWriteAndVerify16: BYTCHK bit checking!!!\n"));
15874285809Sscottl    return SM_RC_SUCCESS;
15875285809Sscottl  }
15876285809Sscottl
15877285809Sscottl
15878285809Sscottl  /* checking CONTROL */
15879285809Sscottl  /* NACA == 1 or LINK == 1*/
15880285809Sscottl  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
15881285809Sscottl  {
15882285809Sscottl    smsatSetSensePayload( pSense,
15883285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15884285809Sscottl                          0,
15885285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15886285809Sscottl                          satIOContext);
15887285809Sscottl
15888285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
15889285809Sscottl
15890285809Sscottl    tdsmIOCompletedCB( smRoot,
15891285809Sscottl                       smIORequest,
15892285809Sscottl                       smIOSuccess,
15893285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
15894285809Sscottl                       satIOContext->pSmSenseData,
15895285809Sscottl                       satIOContext->interruptContext );
15896285809Sscottl
15897285809Sscottl    SM_DBG1(("smsatWriteAndVerify16: return control!!!\n"));
15898285809Sscottl    return SM_RC_SUCCESS;
15899285809Sscottl  }
15900285809Sscottl
15901285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
15902285809Sscottl  sm_memset(TL, 0, sizeof(TL));
15903285809Sscottl
15904285809Sscottl
15905285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
15906285809Sscottl  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
15907285809Sscottl  LBA[1] = scsiCmnd->cdb[3];
15908285809Sscottl  LBA[2] = scsiCmnd->cdb[4];
15909285809Sscottl  LBA[3] = scsiCmnd->cdb[5];
15910285809Sscottl  LBA[4] = scsiCmnd->cdb[6];
15911285809Sscottl  LBA[5] = scsiCmnd->cdb[7];
15912285809Sscottl  LBA[6] = scsiCmnd->cdb[8];
15913285809Sscottl  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
15914285809Sscottl
15915285809Sscottl  TL[0] = 0;
15916285809Sscottl  TL[1] = 0;
15917285809Sscottl  TL[2] = 0;
15918285809Sscottl  TL[3] = 0;
15919285809Sscottl  TL[4] = scsiCmnd->cdb[10];   /* MSB */
15920285809Sscottl  TL[5] = scsiCmnd->cdb[11];
15921285809Sscottl  TL[6] = scsiCmnd->cdb[12];
15922285809Sscottl  TL[7] = scsiCmnd->cdb[13];   /* LSB */
15923285809Sscottl
15924285809Sscottl
15925285809Sscottl
15926285809Sscottl  lba = smsatComputeCDB16LBA(satIOContext);
15927285809Sscottl  tl = smsatComputeCDB16TL(satIOContext);
15928285809Sscottl
15929285809Sscottl
15930285809Sscottl  /* Table 34, 9.1, p 46 */
15931285809Sscottl  /*
15932285809Sscottl    note: As of 2/10/2006, no support for DMA QUEUED
15933285809Sscottl  */
15934285809Sscottl
15935285809Sscottl  /*
15936285809Sscottl    Table 34, 9.1, p 46, b
15937285809Sscottl    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15938285809Sscottl    return check condition
15939285809Sscottl  */
15940285809Sscottl  if (pSatDevData->satNCQ != agTRUE &&
15941285809Sscottl     pSatDevData->sat48BitSupport != agTRUE
15942285809Sscottl     )
15943285809Sscottl  {
15944285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15945285809Sscottl    if (AllChk)
15946285809Sscottl    {
15947285809Sscottl      SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, not EXT!!!\n"));
15948285809Sscottl      smsatSetSensePayload( pSense,
15949285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15950285809Sscottl                            0,
15951285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15952285809Sscottl                            satIOContext);
15953285809Sscottl
15954285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
15955285809Sscottl
15956285809Sscottl      tdsmIOCompletedCB( smRoot,
15957285809Sscottl                         smIORequest,
15958285809Sscottl                         smIOSuccess,
15959285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
15960285809Sscottl                         satIOContext->pSmSenseData,
15961285809Sscottl                         satIOContext->interruptContext );
15962285809Sscottl
15963285809Sscottl      return SM_RC_SUCCESS;
15964285809Sscottl    }
15965285809Sscottl  }
15966285809Sscottl  else
15967285809Sscottl  {
15968285809Sscottl    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15969285809Sscottl    if (AllChk)
15970285809Sscottl    {
15971285809Sscottl      SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, EXT!!!\n"));
15972285809Sscottl      smsatSetSensePayload( pSense,
15973285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15974285809Sscottl                            0,
15975285809Sscottl                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15976285809Sscottl                            satIOContext);
15977285809Sscottl
15978285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
15979285809Sscottl
15980285809Sscottl      tdsmIOCompletedCB( smRoot,
15981285809Sscottl                         smIORequest,
15982285809Sscottl                         smIOSuccess,
15983285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
15984285809Sscottl                         satIOContext->pSmSenseData,
15985285809Sscottl                         satIOContext->interruptContext );
15986285809Sscottl
15987285809Sscottl      return SM_RC_SUCCESS;
15988285809Sscottl    }
15989285809Sscottl  }
15990285809Sscottl
15991285809Sscottl
15992285809Sscottl  /* case 1 and 2 */
15993285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15994285809Sscottl    {
15995285809Sscottl      /* case 2 */
15996285809Sscottl      /* WRITE DMA*/
15997285809Sscottl      /* In case that we can't fit the transfer length, we loop */
15998285809Sscottl      SM_DBG5(("smsatWriteAndVerify16: case 2\n"));
15999285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
16000285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16001285809Sscottl      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
16002285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
16003285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16004285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16005285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16006285809Sscottl
16007285809Sscottl      /* FIS LBA mode set LBA (27:24) */
16008285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
16009285809Sscottl
16010285809Sscottl      fis->d.lbaLowExp      = 0;
16011285809Sscottl      fis->d.lbaMidExp      = 0;
16012285809Sscottl      fis->d.lbaHighExp     = 0;
16013285809Sscottl      fis->d.featuresExp    = 0;
16014285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16015285809Sscottl      fis->d.sectorCountExp = 0;
16016285809Sscottl      fis->d.reserved4      = 0;
16017285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
16018285809Sscottl      fis->d.reserved5      = 0;
16019285809Sscottl
16020285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16021285809Sscottl      satIOContext->ATACmd = SAT_WRITE_DMA;
16022285809Sscottl    }
16023285809Sscottl    else
16024285809Sscottl    {
16025285809Sscottl      /* case 1 */
16026285809Sscottl      /* WRITE MULTIPLE or WRITE SECTOR(S) */
16027285809Sscottl      /* WRITE SECTORS for easier implemetation */
16028285809Sscottl      /* In case that we can't fit the transfer length, we loop */
16029285809Sscottl      SM_DBG5(("smsatWriteAndVerify16: case 1\n"));
16030285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
16031285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16032285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
16033285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
16034285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16035285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16036285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16037285809Sscottl
16038285809Sscottl      /* FIS LBA mode set LBA (27:24) */
16039285809Sscottl      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
16040285809Sscottl
16041285809Sscottl      fis->d.lbaLowExp      = 0;
16042285809Sscottl      fis->d.lbaMidExp      = 0;
16043285809Sscottl      fis->d.lbaHighExp     = 0;
16044285809Sscottl      fis->d.featuresExp    = 0;
16045285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16046285809Sscottl      fis->d.sectorCountExp = 0;
16047285809Sscottl      fis->d.reserved4      = 0;
16048285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
16049285809Sscottl      fis->d.reserved5      = 0;
16050285809Sscottl
16051285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16052285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS;
16053285809Sscottl  }
16054285809Sscottl
16055285809Sscottl  /* case 3 and 4 */
16056285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
16057285809Sscottl  {
16058285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16059285809Sscottl    {
16060285809Sscottl      /* case 3 */
16061285809Sscottl      /* WRITE DMA EXT or WRITE DMA FUA EXT */
16062285809Sscottl      SM_DBG5(("smsatWriteAndVerify16: case 3\n"));
16063285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
16064285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16065285809Sscottl
16066285809Sscottl      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
16067285809Sscottl      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
16068285809Sscottl
16069285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
16070285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16071285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16072285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16073285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
16074285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
16075285809Sscottl      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
16076285809Sscottl      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
16077285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
16078285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16079285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
16080285809Sscottl      fis->d.reserved4      = 0;
16081285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
16082285809Sscottl      fis->d.reserved5      = 0;
16083285809Sscottl
16084285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16085285809Sscottl      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
16086285809Sscottl    }
16087285809Sscottl    else
16088285809Sscottl    {
16089285809Sscottl      /* case 4 */
16090285809Sscottl      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
16091285809Sscottl      /* WRITE SECTORS EXT for easier implemetation */
16092285809Sscottl      SM_DBG5(("smsatWriteAndVerify16: case 4\n"));
16093285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
16094285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16095285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
16096285809Sscottl
16097285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
16098285809Sscottl      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16099285809Sscottl      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16100285809Sscottl      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16101285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
16102285809Sscottl      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
16103285809Sscottl      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
16104285809Sscottl      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
16105285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
16106285809Sscottl      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16107285809Sscottl      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
16108285809Sscottl      fis->d.reserved4      = 0;
16109285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
16110285809Sscottl      fis->d.reserved5      = 0;
16111285809Sscottl
16112285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16113285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
16114285809Sscottl    }
16115285809Sscottl  }
16116285809Sscottl
16117285809Sscottl  /* case 5 */
16118285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
16119285809Sscottl  {
16120285809Sscottl    /* WRITE FPDMA QUEUED */
16121285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
16122285809Sscottl    {
16123285809Sscottl      SM_DBG1(("smsatWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
16124285809Sscottl      smsatSetSensePayload( pSense,
16125285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16126285809Sscottl                            0,
16127285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16128285809Sscottl                            satIOContext);
16129285809Sscottl
16130285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
16131285809Sscottl
16132285809Sscottl      tdsmIOCompletedCB( smRoot,
16133285809Sscottl                         smIORequest,
16134285809Sscottl                         smIOSuccess,
16135285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
16136285809Sscottl                         satIOContext->pSmSenseData,
16137285809Sscottl                         satIOContext->interruptContext );
16138285809Sscottl      return SM_RC_SUCCESS;
16139285809Sscottl    }
16140285809Sscottl    SM_DBG6(("smsatWriteAndVerify16: case 5\n"));
16141285809Sscottl
16142285809Sscottl    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
16143285809Sscottl
16144285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
16145285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16146285809Sscottl    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
16147285809Sscottl    fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16148285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16149285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16150285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16151285809Sscottl
16152285809Sscottl    /* Check FUA bit */
16153285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
16154285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
16155285809Sscottl    else
16156285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
16157285809Sscottl
16158285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
16159285809Sscottl    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
16160285809Sscottl    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
16161285809Sscottl    fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
16162285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
16163285809Sscottl    fis->d.sectorCountExp = 0;
16164285809Sscottl    fis->d.reserved4      = 0;
16165285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
16166285809Sscottl    fis->d.reserved5      = 0;
16167285809Sscottl
16168285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
16169285809Sscottl    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
16170285809Sscottl  }
16171285809Sscottl
16172285809Sscottl  satIOContext->currentLBA = lba;
16173285809Sscottl  satIOContext->OrgTL = tl;
16174285809Sscottl
16175285809Sscottl  /*
16176285809Sscottl    computing number of loop and remainder for tl
16177285809Sscottl    0xFF in case not ext
16178285809Sscottl    0xFFFF in case EXT
16179285809Sscottl  */
16180285809Sscottl  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
16181285809Sscottl  {
16182285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFF);
16183285809Sscottl  }
16184285809Sscottl  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
16185285809Sscottl           fis->h.command == SAT_WRITE_DMA_EXT     ||
16186285809Sscottl           fis->h.command == SAT_WRITE_DMA_FUA_EXT
16187285809Sscottl           )
16188285809Sscottl  {
16189285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
16190285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
16191285809Sscottl  }
16192285809Sscottl  else
16193285809Sscottl  {
16194285809Sscottl    /* SAT_WRITE_FPDMA_QUEUEDK */
16195285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
16196285809Sscottl  }
16197285809Sscottl
16198285809Sscottl  satIOContext->LoopNum = LoopNum;
16199285809Sscottl
16200285809Sscottl
16201285809Sscottl  if (LoopNum == 1)
16202285809Sscottl  {
16203285809Sscottl    SM_DBG5(("smsatWriteAndVerify16: NON CHAINED data\n"));
16204285809Sscottl    /* Initialize CB for SATA completion.
16205285809Sscottl     */
16206285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
16207285809Sscottl  }
16208285809Sscottl  else
16209285809Sscottl  {
16210285809Sscottl    SM_DBG1(("smsatWriteAndVerify16: CHAINED data!!!\n"));
16211285809Sscottl    /* re-setting tl */
16212285809Sscottl    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
16213285809Sscottl    {
16214285809Sscottl       fis->d.sectorCount    = 0xFF;
16215285809Sscottl    }
16216285809Sscottl    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
16217285809Sscottl             fis->h.command == SAT_WRITE_DMA_EXT ||
16218285809Sscottl             fis->h.command == SAT_WRITE_DMA_FUA_EXT
16219285809Sscottl             )
16220285809Sscottl    {
16221285809Sscottl      fis->d.sectorCount    = 0xFF;
16222285809Sscottl      fis->d.sectorCountExp = 0xFF;
16223285809Sscottl    }
16224285809Sscottl    else
16225285809Sscottl    {
16226285809Sscottl      /* SAT_WRITE_FPDMA_QUEUED */
16227285809Sscottl      fis->h.features       = 0xFF;
16228285809Sscottl      fis->d.featuresExp    = 0xFF;
16229285809Sscottl    }
16230285809Sscottl
16231285809Sscottl    /* Initialize CB for SATA completion.
16232285809Sscottl     */
16233285809Sscottl    satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
16234285809Sscottl  }
16235285809Sscottl
16236285809Sscottl
16237285809Sscottl  /*
16238285809Sscottl   * Prepare SGL and send FIS to LL layer.
16239285809Sscottl   */
16240285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
16241285809Sscottl
16242285809Sscottl  status = smsataLLIOStart( smRoot,
16243285809Sscottl                            smIORequest,
16244285809Sscottl                            smDeviceHandle,
16245285809Sscottl                            smScsiRequest,
16246285809Sscottl                            satIOContext);
16247285809Sscottl  return (status);
16248285809Sscottl}
16249285809Sscottl
16250285809SscottlosGLOBAL bit32
16251285809SscottlsmsatReadMediaSerialNumber(
16252285809Sscottl                           smRoot_t                  *smRoot,
16253285809Sscottl                           smIORequest_t             *smIORequest,
16254285809Sscottl                           smDeviceHandle_t          *smDeviceHandle,
16255285809Sscottl                           smScsiInitiatorRequest_t  *smScsiRequest,
16256285809Sscottl                           smSatIOContext_t            *satIOContext
16257285809Sscottl                          )
16258285809Sscottl{
16259285809Sscottl  bit32                     status;
16260285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16261285809Sscottl  smDeviceData_t            *pSatDevData;
16262285809Sscottl  smScsiRspSense_t          *pSense;
16263285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
16264285809Sscottl  agsaFisRegHostToDevice_t  *fis;
16265285809Sscottl  agsaSATAIdentifyData_t    *pSATAIdData;
16266285809Sscottl  bit8                      *pSerialNumber;
16267285809Sscottl  bit8                      MediaSerialNumber[64] = {0};
16268285809Sscottl  bit32                     allocationLen = 0;
16269285809Sscottl
16270285809Sscottl  pSense        = satIOContext->pSense;
16271285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
16272285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
16273285809Sscottl  fis           = satIOContext->pFis;
16274285809Sscottl  pSATAIdData   = &(pSatDevData->satIdentifyData);
16275285809Sscottl  pSerialNumber = (bit8 *) smScsiRequest->sglVirtualAddr;
16276285809Sscottl
16277285809Sscottl  SM_DBG5(("smsatReadMediaSerialNumber: start\n"));
16278285809Sscottl
16279285809Sscottl  /* checking CONTROL */
16280285809Sscottl  /* NACA == 1 or LINK == 1*/
16281285809Sscottl  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
16282285809Sscottl  {
16283285809Sscottl    smsatSetSensePayload( pSense,
16284285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16285285809Sscottl                          0,
16286285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16287285809Sscottl                          satIOContext);
16288285809Sscottl
16289285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
16290285809Sscottl
16291285809Sscottl    tdsmIOCompletedCB( smRoot,
16292285809Sscottl                       smIORequest,
16293285809Sscottl                       smIOSuccess,
16294285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
16295285809Sscottl                       satIOContext->pSmSenseData,
16296285809Sscottl                       satIOContext->interruptContext );
16297285809Sscottl
16298285809Sscottl    SM_DBG1(("smsatReadMediaSerialNumber: return control!!!\n"));
16299285809Sscottl    return SM_RC_SUCCESS;
16300285809Sscottl  }
16301285809Sscottl
16302285809Sscottl  allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
16303285809Sscottl                  (((bit32)scsiCmnd->cdb[7]) << 16) |
16304285809Sscottl                  (((bit32)scsiCmnd->cdb[8]) << 8 ) |
16305285809Sscottl                  (((bit32)scsiCmnd->cdb[9]));
16306285809Sscottl  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
16307285809Sscottl  if (allocationLen == 4)
16308285809Sscottl  {
16309285809Sscottl    if (pSATAIdData->commandSetFeatureDefault & 0x4)
16310285809Sscottl    {
16311285809Sscottl      SM_DBG1(("smsatReadMediaSerialNumber: Media serial number returning only length!!!\n"));
16312285809Sscottl      /* SPC-3 6.16 p192; filling in length */
16313285809Sscottl      MediaSerialNumber[0] = 0;
16314285809Sscottl      MediaSerialNumber[1] = 0;
16315285809Sscottl      MediaSerialNumber[2] = 0;
16316285809Sscottl      MediaSerialNumber[3] = 0x3C;
16317285809Sscottl    }
16318285809Sscottl    else
16319285809Sscottl    {
16320285809Sscottl      /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/
16321285809Sscottl      MediaSerialNumber[0] = 0;
16322285809Sscottl      MediaSerialNumber[1] = 0;
16323285809Sscottl      MediaSerialNumber[2] = 0x1;
16324285809Sscottl      MediaSerialNumber[3] = 0xfc;
16325285809Sscottl    }
16326285809Sscottl
16327285809Sscottl    sm_memcpy(pSerialNumber, MediaSerialNumber, 4);
16328285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
16329285809Sscottl
16330285809Sscottl    tdsmIOCompletedCB( smRoot,
16331285809Sscottl                       smIORequest,
16332285809Sscottl                       smIOSuccess,
16333285809Sscottl                       SCSI_STAT_GOOD,
16334285809Sscottl                       agNULL,
16335285809Sscottl                       satIOContext->interruptContext);
16336285809Sscottl
16337285809Sscottl    return SM_RC_SUCCESS;
16338285809Sscottl  }
16339285809Sscottl
16340285809Sscottl  if ( pSatDevData->IDDeviceValid == agTRUE)
16341285809Sscottl  {
16342285809Sscottl    if (pSATAIdData->commandSetFeatureDefault & 0x4)
16343285809Sscottl    {
16344285809Sscottl      /* word87 bit2 Media serial number is valid */
16345285809Sscottl      /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/
16346285809Sscottl#ifdef LOG_ENABLE
16347285809Sscottl      smhexdump("ID smsatReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
16348285809Sscottl#endif
16349285809Sscottl      /* SPC-3 6.16 p192; filling in length */
16350285809Sscottl      MediaSerialNumber[0] = 0;
16351285809Sscottl      MediaSerialNumber[1] = 0;
16352285809Sscottl      MediaSerialNumber[2] = 0;
16353285809Sscottl      MediaSerialNumber[3] = 0x3C;
16354285809Sscottl      sm_memcpy(&MediaSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
16355285809Sscottl#ifdef LOG_ENABLE
16356285809Sscottl      smhexdump("smsatReadMediaSerialNumber", (bit8*)MediaSerialNumber, 2*30 + 4);
16357285809Sscottl#endif
16358285809Sscottl      sm_memcpy(pSerialNumber, MediaSerialNumber, MIN(allocationLen, 64));
16359285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
16360285809Sscottl
16361285809Sscottl      tdsmIOCompletedCB( smRoot,
16362285809Sscottl                         smIORequest,
16363285809Sscottl                         smIOSuccess,
16364285809Sscottl                         SCSI_STAT_GOOD,
16365285809Sscottl                         agNULL,
16366285809Sscottl                         satIOContext->interruptContext);
16367285809Sscottl      return SM_RC_SUCCESS;
16368285809Sscottl
16369285809Sscottl
16370285809Sscottl    }
16371285809Sscottl    else
16372285809Sscottl    {
16373285809Sscottl     /* word87 bit2 Media serial number is NOT valid */
16374285809Sscottl      SM_DBG1(("smsatReadMediaSerialNumber: Media serial number is NOT valid!!!\n"));
16375285809Sscottl
16376285809Sscottl      if (pSatDevData->sat48BitSupport == agTRUE)
16377285809Sscottl      {
16378285809Sscottl        /* READ VERIFY SECTORS EXT */
16379285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
16380285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16381285809Sscottl        fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
16382285809Sscottl
16383285809Sscottl        fis->h.features       = 0;                      /* FIS reserve */
16384285809Sscottl        fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16385285809Sscottl        fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16386285809Sscottl        fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16387285809Sscottl        fis->d.device         = 0x40;                   /* FIS LBA mode set */
16388285809Sscottl        fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
16389285809Sscottl        fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
16390285809Sscottl        fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
16391285809Sscottl        fis->d.featuresExp    = 0;                      /* FIS reserve */
16392285809Sscottl        fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16393285809Sscottl        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16394285809Sscottl        fis->d.reserved4      = 0;
16395285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
16396285809Sscottl        fis->d.reserved5      = 0;
16397285809Sscottl
16398285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16399285809Sscottl      }
16400285809Sscottl      else
16401285809Sscottl      {
16402285809Sscottl        /* READ VERIFY SECTORS */
16403285809Sscottl        fis->h.fisType        = 0x27;                   /* Reg host to device */
16404285809Sscottl        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16405285809Sscottl        fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
16406285809Sscottl        fis->h.features       = 0;                      /* FIS reserve */
16407285809Sscottl        fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16408285809Sscottl        fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16409285809Sscottl        fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16410285809Sscottl        fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16411285809Sscottl        fis->d.lbaLowExp      = 0;
16412285809Sscottl        fis->d.lbaMidExp      = 0;
16413285809Sscottl        fis->d.lbaHighExp     = 0;
16414285809Sscottl        fis->d.featuresExp    = 0;
16415285809Sscottl        fis->d.sectorCount    = 1;                       /* FIS sector count (7:0) */
16416285809Sscottl        fis->d.sectorCountExp = 0;
16417285809Sscottl        fis->d.reserved4      = 0;
16418285809Sscottl        fis->d.control        = 0;                      /* FIS HOB bit clear */
16419285809Sscottl        fis->d.reserved5      = 0;
16420285809Sscottl
16421285809Sscottl
16422285809Sscottl        agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16423285809Sscottl      }
16424285809Sscottl      satIOContext->satCompleteCB = &smsatReadMediaSerialNumberCB;
16425285809Sscottl      satIOContext->reqType = agRequestType;       /* Save it */
16426285809Sscottl      status = smsataLLIOStart( smRoot,
16427285809Sscottl                                smIORequest,
16428285809Sscottl                                smDeviceHandle,
16429285809Sscottl                                smScsiRequest,
16430285809Sscottl                                satIOContext);
16431285809Sscottl
16432285809Sscottl      return status;
16433285809Sscottl    }
16434285809Sscottl  }
16435285809Sscottl  else
16436285809Sscottl  {
16437285809Sscottl
16438285809Sscottl    tdsmIOCompletedCB( smRoot,
16439285809Sscottl                       smIORequest,
16440285809Sscottl                       smIOFailed,
16441285809Sscottl                       smDetailOtherError,
16442285809Sscottl                       agNULL,
16443285809Sscottl                       satIOContext->interruptContext);
16444285809Sscottl
16445285809Sscottl    return SM_RC_SUCCESS;
16446285809Sscottl
16447285809Sscottl  }
16448285809Sscottl}
16449285809Sscottl
16450285809SscottlosGLOBAL bit32
16451285809SscottlsmsatReadBuffer(
16452285809Sscottl                smRoot_t                  *smRoot,
16453285809Sscottl                smIORequest_t             *smIORequest,
16454285809Sscottl                smDeviceHandle_t          *smDeviceHandle,
16455285809Sscottl                smScsiInitiatorRequest_t  *smScsiRequest,
16456285809Sscottl                smSatIOContext_t            *satIOContext
16457285809Sscottl               )
16458285809Sscottl{
16459285809Sscottl  bit32                      status = SM_RC_SUCCESS;
16460285809Sscottl  bit32                      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16461285809Sscottl  smScsiRspSense_t          *pSense;
16462285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
16463285809Sscottl  agsaFisRegHostToDevice_t  *fis;
16464285809Sscottl  bit32                      bufferOffset;
16465285809Sscottl  bit32                      tl;
16466285809Sscottl  bit8                       mode;
16467285809Sscottl  bit8                       bufferID;
16468285809Sscottl  bit8                      *pBuff;
16469285809Sscottl
16470285809Sscottl  pSense        = satIOContext->pSense;
16471285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
16472285809Sscottl  fis           = satIOContext->pFis;
16473285809Sscottl  pBuff         = (bit8 *) smScsiRequest->sglVirtualAddr;
16474285809Sscottl
16475285809Sscottl  SM_DBG5(("smsatReadBuffer: start\n"));
16476285809Sscottl
16477285809Sscottl  /* checking CONTROL */
16478285809Sscottl  /* NACA == 1 or LINK == 1*/
16479285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16480285809Sscottl  {
16481285809Sscottl    smsatSetSensePayload( pSense,
16482285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16483285809Sscottl                          0,
16484285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16485285809Sscottl                          satIOContext);
16486285809Sscottl
16487285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
16488285809Sscottl
16489285809Sscottl    tdsmIOCompletedCB( smRoot,
16490285809Sscottl                       smIORequest,
16491285809Sscottl                       smIOSuccess,
16492285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
16493285809Sscottl                       satIOContext->pSmSenseData,
16494285809Sscottl                       satIOContext->interruptContext );
16495285809Sscottl
16496285809Sscottl    SM_DBG1(("smsatReadBuffer: return control!!!\n"));
16497285809Sscottl    return SM_RC_SUCCESS;
16498285809Sscottl  }
16499285809Sscottl
16500285809Sscottl  bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16501285809Sscottl  tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16502285809Sscottl
16503285809Sscottl  mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16504285809Sscottl  bufferID = scsiCmnd->cdb[2];
16505285809Sscottl
16506285809Sscottl  if (mode == READ_BUFFER_DATA_MODE) /* 2 */
16507285809Sscottl  {
16508285809Sscottl    if (bufferID == 0 && bufferOffset == 0 && tl == 512)
16509285809Sscottl    {
16510285809Sscottl      /* send ATA READ BUFFER */
16511285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
16512285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16513285809Sscottl      fis->h.command        = SAT_READ_BUFFER;        /* 0xE4 */
16514285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
16515285809Sscottl      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16516285809Sscottl      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16517285809Sscottl      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16518285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16519285809Sscottl      fis->d.lbaLowExp      = 0;
16520285809Sscottl      fis->d.lbaMidExp      = 0;
16521285809Sscottl      fis->d.lbaHighExp     = 0;
16522285809Sscottl      fis->d.featuresExp    = 0;
16523285809Sscottl      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16524285809Sscottl      fis->d.sectorCountExp = 0;
16525285809Sscottl      fis->d.reserved4      = 0;
16526285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
16527285809Sscottl      fis->d.reserved5      = 0;
16528285809Sscottl
16529285809Sscottl
16530285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16531285809Sscottl
16532285809Sscottl      satIOContext->satCompleteCB = &smsatReadBufferCB;
16533285809Sscottl
16534285809Sscottl      satIOContext->reqType = agRequestType;       /* Save it */
16535285809Sscottl
16536285809Sscottl      status = smsataLLIOStart( smRoot,
16537285809Sscottl                                smIORequest,
16538285809Sscottl                                smDeviceHandle,
16539285809Sscottl                                smScsiRequest,
16540285809Sscottl                                satIOContext);
16541285809Sscottl      return status;
16542285809Sscottl    }
16543285809Sscottl
16544285809Sscottl    if (bufferID == 0 && bufferOffset == 0 && tl != 512)
16545285809Sscottl    {
16546285809Sscottl      smsatSetSensePayload( pSense,
16547285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16548285809Sscottl                            0,
16549285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16550285809Sscottl                            satIOContext);
16551285809Sscottl
16552285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
16553285809Sscottl
16554285809Sscottl      tdsmIOCompletedCB( smRoot,
16555285809Sscottl                         smIORequest,
16556285809Sscottl                         smIOSuccess,
16557285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
16558285809Sscottl                         satIOContext->pSmSenseData,
16559285809Sscottl                         satIOContext->interruptContext );
16560285809Sscottl
16561285809Sscottl      SM_DBG1(("smsatReadBuffer: allocation length is not 512; it is %d!!!\n", tl));
16562285809Sscottl      return SM_RC_SUCCESS;
16563285809Sscottl    }
16564285809Sscottl
16565285809Sscottl    if (bufferID == 0 && bufferOffset != 0)
16566285809Sscottl    {
16567285809Sscottl      smsatSetSensePayload( pSense,
16568285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16569285809Sscottl                            0,
16570285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16571285809Sscottl                            satIOContext);
16572285809Sscottl
16573285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
16574285809Sscottl
16575285809Sscottl      tdsmIOCompletedCB( smRoot,
16576285809Sscottl                         smIORequest,
16577285809Sscottl                         smIOSuccess,
16578285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
16579285809Sscottl                         satIOContext->pSmSenseData,
16580285809Sscottl                         satIOContext->interruptContext );
16581285809Sscottl
16582285809Sscottl      SM_DBG1(("smsatReadBuffer: buffer offset is not 0; it is %d!!!\n", bufferOffset));
16583285809Sscottl      return SM_RC_SUCCESS;
16584285809Sscottl    }
16585285809Sscottl    /* all other cases unsupported */
16586285809Sscottl    SM_DBG1(("smsatReadBuffer: unsupported case 1!!!\n"));
16587285809Sscottl    smsatSetSensePayload( pSense,
16588285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16589285809Sscottl                          0,
16590285809Sscottl                          SCSI_SNSCODE_INVALID_COMMAND,
16591285809Sscottl                          satIOContext);
16592285809Sscottl
16593285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
16594285809Sscottl
16595285809Sscottl    tdsmIOCompletedCB( smRoot,
16596285809Sscottl                       smIORequest,
16597285809Sscottl                       smIOSuccess,
16598285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
16599285809Sscottl                       satIOContext->pSmSenseData,
16600285809Sscottl                       satIOContext->interruptContext );
16601285809Sscottl
16602285809Sscottl    return SM_RC_SUCCESS;
16603285809Sscottl
16604285809Sscottl  }
16605285809Sscottl  else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */
16606285809Sscottl  {
16607285809Sscottl    if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */
16608285809Sscottl    {
16609285809Sscottl      smsatSetSensePayload( pSense,
16610285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16611285809Sscottl                            0,
16612285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16613285809Sscottl                            satIOContext);
16614285809Sscottl
16615285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
16616285809Sscottl
16617285809Sscottl      tdsmIOCompletedCB( smRoot,
16618285809Sscottl                         smIORequest,
16619285809Sscottl                         smIOSuccess,
16620285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
16621285809Sscottl                         satIOContext->pSmSenseData,
16622285809Sscottl                         satIOContext->interruptContext );
16623285809Sscottl
16624285809Sscottl      SM_DBG1(("smsatReadBuffer: tl < 4; tl is %d!!!\n", tl));
16625285809Sscottl      return SM_RC_SUCCESS;
16626285809Sscottl    }
16627285809Sscottl    if (bufferID == 0)
16628285809Sscottl    {
16629285809Sscottl      /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/
16630285809Sscottl      pBuff[0] = 0xFF;
16631285809Sscottl      pBuff[1] = 0x00;
16632285809Sscottl      pBuff[2] = 0x02;
16633285809Sscottl      pBuff[3] = 0x00;
16634285809Sscottl      if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
16635285809Sscottl      {
16636285809Sscottl        /* underrrun */
16637285809Sscottl        SM_DBG1(("smsatReadBuffer: underrun tl %d data %d!!!\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
16638285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
16639285809Sscottl
16640285809Sscottl        tdsmIOCompletedCB( smRoot,
16641285809Sscottl                           smIORequest,
16642285809Sscottl                           smIOUnderRun,
16643285809Sscottl                           tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
16644285809Sscottl                           agNULL,
16645285809Sscottl                           satIOContext->interruptContext );
16646285809Sscottl
16647285809Sscottl        return SM_RC_SUCCESS;
16648285809Sscottl      }
16649285809Sscottl      else
16650285809Sscottl      {
16651285809Sscottl        /*smEnqueueIO(smRoot, satIOContext);*/
16652285809Sscottl
16653285809Sscottl        tdsmIOCompletedCB( smRoot,
16654285809Sscottl                           smIORequest,
16655285809Sscottl                           smIOSuccess,
16656285809Sscottl                           SCSI_STAT_GOOD,
16657285809Sscottl                           agNULL,
16658285809Sscottl                           satIOContext->interruptContext);
16659285809Sscottl        return SM_RC_SUCCESS;
16660285809Sscottl      }
16661285809Sscottl    }
16662285809Sscottl    else
16663285809Sscottl    {
16664285809Sscottl      /* We don't support other than bufferID 0 */
16665285809Sscottl      smsatSetSensePayload( pSense,
16666285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16667285809Sscottl                            0,
16668285809Sscottl                            SCSI_SNSCODE_INVALID_COMMAND,
16669285809Sscottl                            satIOContext);
16670285809Sscottl
16671285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
16672285809Sscottl
16673285809Sscottl      tdsmIOCompletedCB( smRoot,
16674285809Sscottl                         smIORequest,
16675285809Sscottl                         smIOSuccess,
16676285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
16677285809Sscottl                         satIOContext->pSmSenseData,
16678285809Sscottl                         satIOContext->interruptContext );
16679285809Sscottl
16680285809Sscottl      return SM_RC_SUCCESS;
16681285809Sscottl    }
16682285809Sscottl  }
16683285809Sscottl  else
16684285809Sscottl  {
16685285809Sscottl    /* We don't support any other mode */
16686285809Sscottl    SM_DBG1(("smsatReadBuffer: unsupported mode %d!!!\n", mode));
16687285809Sscottl    smsatSetSensePayload( pSense,
16688285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16689285809Sscottl                          0,
16690285809Sscottl                          SCSI_SNSCODE_INVALID_COMMAND,
16691285809Sscottl                          satIOContext);
16692285809Sscottl
16693285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
16694285809Sscottl
16695285809Sscottl    tdsmIOCompletedCB( smRoot,
16696285809Sscottl                       smIORequest,
16697285809Sscottl                       smIOSuccess,
16698285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
16699285809Sscottl                       satIOContext->pSmSenseData,
16700285809Sscottl                       satIOContext->interruptContext );
16701285809Sscottl
16702285809Sscottl    return SM_RC_SUCCESS;
16703285809Sscottl  }
16704285809Sscottl}
16705285809Sscottl
16706285809SscottlosGLOBAL bit32
16707285809SscottlsmsatWriteBuffer(
16708285809Sscottl                 smRoot_t                  *smRoot,
16709285809Sscottl                 smIORequest_t             *smIORequest,
16710285809Sscottl                 smDeviceHandle_t          *smDeviceHandle,
16711285809Sscottl                 smScsiInitiatorRequest_t  *smScsiRequest,
16712285809Sscottl                 smSatIOContext_t            *satIOContext
16713285809Sscottl                )
16714285809Sscottl{
16715285809Sscottl#ifdef NOT_YET
16716285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16717285809Sscottl#endif
16718285809Sscottl  smScsiRspSense_t          *pSense;
16719285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
16720285809Sscottl#ifdef NOT_YET
16721285809Sscottl  agsaFisRegHostToDevice_t  *fis;
16722285809Sscottl#endif
16723285809Sscottl  bit32                     bufferOffset;
16724285809Sscottl  bit32                     parmLen;
16725285809Sscottl  bit8                      mode;
16726285809Sscottl  bit8                      bufferID;
16727285809Sscottl  bit8                      *pBuff;
16728285809Sscottl
16729285809Sscottl  pSense        = satIOContext->pSense;
16730285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
16731285809Sscottl#ifdef NOT_YET
16732285809Sscottl  fis           = satIOContext->pFis;
16733285809Sscottl#endif
16734285809Sscottl  pBuff         = (bit8 *) smScsiRequest->sglVirtualAddr;
16735285809Sscottl
16736285809Sscottl  SM_DBG5(("smsatWriteBuffer: start\n"));
16737285809Sscottl
16738285809Sscottl  /* checking CONTROL */
16739285809Sscottl  /* NACA == 1 or LINK == 1*/
16740285809Sscottl  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16741285809Sscottl  {
16742285809Sscottl    smsatSetSensePayload( pSense,
16743285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16744285809Sscottl                          0,
16745285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16746285809Sscottl                          satIOContext);
16747285809Sscottl
16748285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
16749285809Sscottl
16750285809Sscottl    tdsmIOCompletedCB( smRoot,
16751285809Sscottl                       smIORequest,
16752285809Sscottl                       smIOSuccess,
16753285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
16754285809Sscottl                       satIOContext->pSmSenseData,
16755285809Sscottl                       satIOContext->interruptContext );
16756285809Sscottl
16757285809Sscottl    SM_DBG1(("smsatWriteBuffer: return control!!!\n"));
16758285809Sscottl    return SM_RC_SUCCESS;
16759285809Sscottl  }
16760285809Sscottl
16761285809Sscottl  bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16762285809Sscottl  parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16763285809Sscottl
16764285809Sscottl  mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16765285809Sscottl  bufferID = scsiCmnd->cdb[2];
16766285809Sscottl
16767285809Sscottl  /* for debugging only */
16768285809Sscottl  smhexdump("smsatWriteBuffer pBuff", (bit8 *)pBuff, 24);
16769285809Sscottl
16770285809Sscottl  if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */
16771285809Sscottl  {
16772285809Sscottl    if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
16773285809Sscottl    {
16774285809Sscottl      SM_DBG1(("smsatWriteBuffer: sending ATA WRITE BUFFER!!!\n"));
16775285809Sscottl      /* send ATA WRITE BUFFER */
16776285809Sscottl#ifdef NOT_YET
16777285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
16778285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16779285809Sscottl      fis->h.command        = SAT_WRITE_BUFFER;       /* 0xE8 */
16780285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
16781285809Sscottl      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16782285809Sscottl      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16783285809Sscottl      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16784285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16785285809Sscottl      fis->d.lbaLowExp      = 0;
16786285809Sscottl      fis->d.lbaMidExp      = 0;
16787285809Sscottl      fis->d.lbaHighExp     = 0;
16788285809Sscottl      fis->d.featuresExp    = 0;
16789285809Sscottl      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16790285809Sscottl      fis->d.sectorCountExp = 0;
16791285809Sscottl      fis->d.reserved4      = 0;
16792285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
16793285809Sscottl      fis->d.reserved5      = 0;
16794285809Sscottl
16795285809Sscottl
16796285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16797285809Sscottl
16798285809Sscottl      satIOContext->satCompleteCB = &smsatWriteBufferCB;
16799285809Sscottl
16800285809Sscottl      satIOContext->reqType = agRequestType;       /* Save it */
16801285809Sscottl
16802285809Sscottl      status = smsataLLIOStart( smRoot,
16803285809Sscottl                                smIORequest,
16804285809Sscottl                                smDeviceHandle,
16805285809Sscottl                                smScsiRequest,
16806285809Sscottl                                satIOContext);
16807285809Sscottl      return status;
16808285809Sscottl#endif
16809285809Sscottl      /* temp */
16810285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
16811285809Sscottl
16812285809Sscottl      tdsmIOCompletedCB( smRoot,
16813285809Sscottl                         smIORequest,
16814285809Sscottl                         smIOSuccess,
16815285809Sscottl                         SCSI_STAT_GOOD,
16816285809Sscottl                         agNULL,
16817285809Sscottl                         satIOContext->interruptContext);
16818285809Sscottl      return SM_RC_SUCCESS;
16819285809Sscottl    }
16820285809Sscottl    if ( (bufferID == 0 && bufferOffset != 0) ||
16821285809Sscottl         (bufferID == 0 && parmLen != 512)
16822285809Sscottl        )
16823285809Sscottl    {
16824285809Sscottl      smsatSetSensePayload( pSense,
16825285809Sscottl                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16826285809Sscottl                            0,
16827285809Sscottl                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16828285809Sscottl                            satIOContext);
16829285809Sscottl
16830285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
16831285809Sscottl
16832285809Sscottl      tdsmIOCompletedCB( smRoot,
16833285809Sscottl                         smIORequest,
16834285809Sscottl                         smIOSuccess,
16835285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
16836285809Sscottl                         satIOContext->pSmSenseData,
16837285809Sscottl                         satIOContext->interruptContext );
16838285809Sscottl
16839285809Sscottl      SM_DBG1(("smsatWriteBuffer: wrong buffer offset %d or parameter length parmLen %d!!!\n", bufferOffset, parmLen));
16840285809Sscottl      return SM_RC_SUCCESS;
16841285809Sscottl    }
16842285809Sscottl
16843285809Sscottl    /* all other cases unsupported */
16844285809Sscottl    SM_DBG1(("smsatWriteBuffer: unsupported case 1!!!\n"));
16845285809Sscottl    smsatSetSensePayload( pSense,
16846285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16847285809Sscottl                          0,
16848285809Sscottl                          SCSI_SNSCODE_INVALID_COMMAND,
16849285809Sscottl                          satIOContext);
16850285809Sscottl
16851285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
16852285809Sscottl
16853285809Sscottl    tdsmIOCompletedCB( smRoot,
16854285809Sscottl                       smIORequest,
16855285809Sscottl                       smIOSuccess,
16856285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
16857285809Sscottl                       satIOContext->pSmSenseData,
16858285809Sscottl                       satIOContext->interruptContext );
16859285809Sscottl
16860285809Sscottl    return SM_RC_SUCCESS;
16861285809Sscottl
16862285809Sscottl  }
16863285809Sscottl  else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */
16864285809Sscottl  {
16865285809Sscottl    /* temporary */
16866285809Sscottl    SM_DBG1(("smsatWriteBuffer: not yet supported mode %d!!!\n", mode));
16867285809Sscottl    smsatSetSensePayload( pSense,
16868285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16869285809Sscottl                          0,
16870285809Sscottl                          SCSI_SNSCODE_INVALID_COMMAND,
16871285809Sscottl                          satIOContext);
16872285809Sscottl
16873285809Sscottl
16874285809Sscottl    tdsmIOCompletedCB( smRoot,
16875285809Sscottl                       smIORequest,
16876285809Sscottl                       smIOSuccess,
16877285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
16878285809Sscottl                       satIOContext->pSmSenseData,
16879285809Sscottl                       satIOContext->interruptContext );
16880285809Sscottl
16881285809Sscottl    return SM_RC_SUCCESS;
16882285809Sscottl  }
16883285809Sscottl  else
16884285809Sscottl  {
16885285809Sscottl    /* We don't support any other mode */
16886285809Sscottl    SM_DBG1(("smsatWriteBuffer: unsupported mode %d!!!\n", mode));
16887285809Sscottl    smsatSetSensePayload( pSense,
16888285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16889285809Sscottl                          0,
16890285809Sscottl                          SCSI_SNSCODE_INVALID_COMMAND,
16891285809Sscottl                          satIOContext);
16892285809Sscottl
16893285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
16894285809Sscottl
16895285809Sscottl    tdsmIOCompletedCB( smRoot,
16896285809Sscottl                       smIORequest,
16897285809Sscottl                       smIOSuccess,
16898285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
16899285809Sscottl                       satIOContext->pSmSenseData,
16900285809Sscottl                       satIOContext->interruptContext );
16901285809Sscottl
16902285809Sscottl    return SM_RC_SUCCESS;
16903285809Sscottl  }
16904285809Sscottl
16905285809Sscottl}
16906285809Sscottl
16907285809SscottlosGLOBAL bit32
16908285809SscottlsmsatReassignBlocks(
16909285809Sscottl                    smRoot_t                  *smRoot,
16910285809Sscottl                    smIORequest_t             *smIORequest,
16911285809Sscottl                    smDeviceHandle_t          *smDeviceHandle,
16912285809Sscottl                    smScsiInitiatorRequest_t  *smScsiRequest,
16913285809Sscottl                    smSatIOContext_t            *satIOContext
16914285809Sscottl                   )
16915285809Sscottl{
16916285809Sscottl  /*
16917285809Sscottl    assumes all LBA fits in ATA command; no boundary condition is checked here yet
16918285809Sscottl  */
16919285809Sscottl  bit32                     status;
16920285809Sscottl  bit32                     agRequestType;
16921285809Sscottl  smDeviceData_t            *pSatDevData;
16922285809Sscottl  smScsiRspSense_t          *pSense;
16923285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
16924285809Sscottl  agsaFisRegHostToDevice_t  *fis;
16925285809Sscottl  bit8                      *pParmList;    /* Log Page data buffer */
16926285809Sscottl  bit8                      LongLBA;
16927285809Sscottl  bit8                      LongList;
16928285809Sscottl  bit32                     defectListLen;
16929285809Sscottl  bit8                      LBA[8];
16930285809Sscottl  bit32                     startingIndex;
16931285809Sscottl
16932285809Sscottl  pSense        = satIOContext->pSense;
16933285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
16934285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
16935285809Sscottl  fis           = satIOContext->pFis;
16936285809Sscottl  pParmList     = (bit8 *) smScsiRequest->sglVirtualAddr;
16937285809Sscottl
16938285809Sscottl  SM_DBG5(("smsatReassignBlocks: start\n"));
16939285809Sscottl
16940285809Sscottl  /* checking CONTROL */
16941285809Sscottl  /* NACA == 1 or LINK == 1*/
16942285809Sscottl  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
16943285809Sscottl  {
16944285809Sscottl    smsatSetSensePayload( pSense,
16945285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16946285809Sscottl                          0,
16947285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16948285809Sscottl                          satIOContext);
16949285809Sscottl
16950285809Sscottl    /*smEnqueueIO(smRoot, satIOContext);*/
16951285809Sscottl
16952285809Sscottl    tdsmIOCompletedCB( smRoot,
16953285809Sscottl                       smIORequest,
16954285809Sscottl                       smIOSuccess,
16955285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
16956285809Sscottl                       satIOContext->pSmSenseData,
16957285809Sscottl                       satIOContext->interruptContext );
16958285809Sscottl
16959285809Sscottl    SM_DBG1(("smsatReassignBlocks: return control!!!\n"));
16960285809Sscottl    return SM_RC_SUCCESS;
16961285809Sscottl  }
16962285809Sscottl
16963285809Sscottl  sm_memset(satIOContext->LBA, 0, 8);
16964285809Sscottl  satIOContext->ParmIndex = 0;
16965285809Sscottl  satIOContext->ParmLen = 0;
16966285809Sscottl
16967285809Sscottl  LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK);
16968285809Sscottl  LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16969285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
16970285809Sscottl
16971285809Sscottl  if (LongList == 0)
16972285809Sscottl  {
16973285809Sscottl    defectListLen = (pParmList[2] << 8) + pParmList[3];
16974285809Sscottl  }
16975285809Sscottl  else
16976285809Sscottl  {
16977285809Sscottl    defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2))
16978285809Sscottl                  + (pParmList[2] << 8) + pParmList[3];
16979285809Sscottl  }
16980285809Sscottl  /* SBC 5.16.2, p61*/
16981285809Sscottl  satIOContext->ParmLen = defectListLen + 4 /* header size */;
16982285809Sscottl
16983285809Sscottl  startingIndex = 4;
16984285809Sscottl
16985285809Sscottl  if (LongLBA == 0)
16986285809Sscottl  {
16987285809Sscottl    LBA[4] = pParmList[startingIndex];   /* MSB */
16988285809Sscottl    LBA[5] = pParmList[startingIndex+1];
16989285809Sscottl    LBA[6] = pParmList[startingIndex+2];
16990285809Sscottl    LBA[7] = pParmList[startingIndex+3];  /* LSB */
16991285809Sscottl    startingIndex = startingIndex + 4;
16992285809Sscottl  }
16993285809Sscottl  else
16994285809Sscottl  {
16995285809Sscottl    LBA[0] = pParmList[startingIndex];    /* MSB */
16996285809Sscottl    LBA[1] = pParmList[startingIndex+1];
16997285809Sscottl    LBA[2] = pParmList[startingIndex+2];
16998285809Sscottl    LBA[3] = pParmList[startingIndex+3];
16999285809Sscottl    LBA[4] = pParmList[startingIndex+4];
17000285809Sscottl    LBA[5] = pParmList[startingIndex+5];
17001285809Sscottl    LBA[6] = pParmList[startingIndex+6];
17002285809Sscottl    LBA[7] = pParmList[startingIndex+7];  /* LSB */
17003285809Sscottl    startingIndex = startingIndex + 8;
17004285809Sscottl  }
17005285809Sscottl
17006285809Sscottl  smhexdump("smsatReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen);
17007285809Sscottl
17008285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
17009285809Sscottl  {
17010285809Sscottl    /* sends READ VERIFY SECTOR(S) EXT*/
17011285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17012285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17013285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17014285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17015285809Sscottl    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
17016285809Sscottl    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
17017285809Sscottl    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
17018285809Sscottl    fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
17019285809Sscottl    fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
17020285809Sscottl    fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
17021285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
17022285809Sscottl    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
17023285809Sscottl    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
17024285809Sscottl    fis->d.reserved4      = 0;
17025285809Sscottl    fis->d.device         = 0x40;                   /* 01000000 */
17026285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17027285809Sscottl    fis->d.reserved5      = 0;
17028285809Sscottl  }
17029285809Sscottl  else
17030285809Sscottl  {
17031285809Sscottl    /* READ VERIFY SECTOR(S)*/
17032285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17033285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17034285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
17035285809Sscottl    fis->h.features       = 0;                      /* FIS features NA       */
17036285809Sscottl    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
17037285809Sscottl    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
17038285809Sscottl    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
17039285809Sscottl    fis->d.lbaLowExp      = 0;
17040285809Sscottl    fis->d.lbaMidExp      = 0;
17041285809Sscottl    fis->d.lbaHighExp     = 0;
17042285809Sscottl    fis->d.featuresExp    = 0;
17043285809Sscottl    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
17044285809Sscottl    fis->d.sectorCountExp = 0;
17045285809Sscottl    fis->d.reserved4      = 0;
17046285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
17047285809Sscottl                            /* DEV and LBA 27:24 */
17048285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17049285809Sscottl    fis->d.reserved5      = 0;
17050285809Sscottl  }
17051285809Sscottl
17052285809Sscottl  sm_memcpy(satIOContext->LBA, LBA, 8);
17053285809Sscottl  satIOContext->ParmIndex = startingIndex;
17054285809Sscottl
17055285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17056285809Sscottl
17057285809Sscottl  /* Initialize CB for SATA completion.
17058285809Sscottl   */
17059285809Sscottl  satIOContext->satCompleteCB = &smsatReassignBlocksCB;
17060285809Sscottl
17061285809Sscottl  /*
17062285809Sscottl   * Prepare SGL and send FIS to LL layer.
17063285809Sscottl   */
17064285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
17065285809Sscottl
17066285809Sscottl  status = smsataLLIOStart( smRoot,
17067285809Sscottl                            smIORequest,
17068285809Sscottl                            smDeviceHandle,
17069285809Sscottl                            smScsiRequest,
17070285809Sscottl                            satIOContext);
17071285809Sscottl
17072285809Sscottl  return status;
17073285809Sscottl}
17074285809Sscottl
17075285809SscottlosGLOBAL bit32
17076285809SscottlsmsatRead_1(
17077285809Sscottl            smRoot_t                  *smRoot,
17078285809Sscottl            smIORequest_t             *smIORequest,
17079285809Sscottl            smDeviceHandle_t          *smDeviceHandle,
17080285809Sscottl            smScsiInitiatorRequest_t  *smScsiRequest,
17081285809Sscottl            smSatIOContext_t            *satIOContext
17082285809Sscottl          )
17083285809Sscottl{
17084285809Sscottl  /*
17085285809Sscottl    Assumption: error check on lba and tl has been done in satRead*()
17086285809Sscottl    lba = lba + tl;
17087285809Sscottl  */
17088285809Sscottl  bit32                     status;
17089285809Sscottl  smSatIOContext_t            *satOrgIOContext = agNULL;
17090285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
17091285809Sscottl  agsaFisRegHostToDevice_t  *fis;
17092285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17093285809Sscottl  bit32                     lba = 0;
17094285809Sscottl  bit32                     DenomTL = 0xFF;
17095285809Sscottl  bit32                     Remainder = 0;
17096285809Sscottl  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
17097285809Sscottl
17098285809Sscottl  SM_DBG2(("smsatRead_1: start\n"));
17099285809Sscottl
17100285809Sscottl  fis             = satIOContext->pFis;
17101285809Sscottl  satOrgIOContext = satIOContext->satOrgIOContext;
17102285809Sscottl  scsiCmnd        = satOrgIOContext->pScsiCmnd;
17103285809Sscottl
17104285809Sscottl  sm_memset(LBA,0, sizeof(LBA));
17105285809Sscottl
17106285809Sscottl  switch (satOrgIOContext->ATACmd)
17107285809Sscottl  {
17108285809Sscottl  case SAT_READ_DMA:
17109285809Sscottl    DenomTL = 0x100;
17110285809Sscottl    break;
17111285809Sscottl  case SAT_READ_SECTORS:
17112285809Sscottl    DenomTL = 0x100;
17113285809Sscottl    break;
17114285809Sscottl  case SAT_READ_DMA_EXT:
17115285809Sscottl    DenomTL = 0xFFFF;
17116285809Sscottl    break;
17117285809Sscottl  case SAT_READ_SECTORS_EXT:
17118285809Sscottl    DenomTL = 0xFFFF;
17119285809Sscottl    break;
17120285809Sscottl  case SAT_READ_FPDMA_QUEUED:
17121285809Sscottl    DenomTL = 0xFFFF;
17122285809Sscottl    break;
17123285809Sscottl  default:
17124285809Sscottl    SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17125285809Sscottl    return SM_RC_FAILURE;
17126285809Sscottl    break;
17127285809Sscottl  }
17128285809Sscottl
17129285809Sscottl  Remainder = satOrgIOContext->OrgTL % DenomTL;
17130285809Sscottl  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
17131285809Sscottl  lba = satOrgIOContext->currentLBA;
17132285809Sscottl
17133285809Sscottl  LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3));
17134285809Sscottl  LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2));
17135285809Sscottl  LBA[2] = (bit8)((lba & 0xFF00) >> 8);
17136285809Sscottl  LBA[3] = (bit8)(lba & 0xFF);
17137285809Sscottl
17138285809Sscottl  switch (satOrgIOContext->ATACmd)
17139285809Sscottl  {
17140285809Sscottl  case SAT_READ_DMA:
17141285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17142285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17143285809Sscottl    fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
17144285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17145285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17146285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17147285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17148285809Sscottl    fis->d.device         =
17149285809Sscottl      (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
17150285809Sscottl    fis->d.lbaLowExp      = 0;
17151285809Sscottl    fis->d.lbaMidExp      = 0;
17152285809Sscottl    fis->d.lbaHighExp     = 0;
17153285809Sscottl    fis->d.featuresExp    = 0;
17154285809Sscottl
17155285809Sscottl    if (satOrgIOContext->LoopNum == 1)
17156285809Sscottl    {
17157285809Sscottl      /* last loop */
17158285809Sscottl      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
17159285809Sscottl    }
17160285809Sscottl    else
17161285809Sscottl    {
17162285809Sscottl      fis->d.sectorCount    = 0x0;                  /* FIS sector count (7:0) */
17163285809Sscottl    }
17164285809Sscottl
17165285809Sscottl    fis->d.sectorCountExp = 0;
17166285809Sscottl    fis->d.reserved4      = 0;
17167285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17168285809Sscottl    fis->d.reserved5      = 0;
17169285809Sscottl
17170285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17171285809Sscottl
17172285809Sscottl    break;
17173285809Sscottl  case SAT_READ_SECTORS:
17174285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17175285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17176285809Sscottl    fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
17177285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17178285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17179285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17180285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17181285809Sscottl    fis->d.device         =
17182285809Sscottl      (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
17183285809Sscottl    fis->d.lbaLowExp      = 0;
17184285809Sscottl    fis->d.lbaMidExp      = 0;
17185285809Sscottl    fis->d.lbaHighExp     = 0;
17186285809Sscottl    fis->d.featuresExp    = 0;
17187285809Sscottl    if (satOrgIOContext->LoopNum == 1)
17188285809Sscottl    {
17189285809Sscottl      /* last loop */
17190285809Sscottl      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
17191285809Sscottl    }
17192285809Sscottl    else
17193285809Sscottl    {
17194285809Sscottl      fis->d.sectorCount    = 0x0;                   /* FIS sector count (7:0) */
17195285809Sscottl    }
17196285809Sscottl    fis->d.sectorCountExp = 0;
17197285809Sscottl    fis->d.reserved4      = 0;
17198285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17199285809Sscottl    fis->d.reserved5      = 0;
17200285809Sscottl
17201285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
17202285809Sscottl
17203285809Sscottl    break;
17204285809Sscottl  case SAT_READ_DMA_EXT:
17205285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17206285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17207285809Sscottl    fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
17208285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17209285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17210285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17211285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17212285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set */
17213285809Sscottl    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17214285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17215285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17216285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
17217285809Sscottl    if (satOrgIOContext->LoopNum == 1)
17218285809Sscottl    {
17219285809Sscottl      /* last loop */
17220285809Sscottl      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17221285809Sscottl      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17222285809Sscottl
17223285809Sscottl    }
17224285809Sscottl    else
17225285809Sscottl    {
17226285809Sscottl      fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
17227285809Sscottl      fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
17228285809Sscottl    }
17229285809Sscottl    fis->d.reserved4      = 0;
17230285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17231285809Sscottl    fis->d.reserved5      = 0;
17232285809Sscottl
17233285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17234285809Sscottl
17235285809Sscottl    break;
17236285809Sscottl  case SAT_READ_SECTORS_EXT:
17237285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17238285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17239285809Sscottl    fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
17240285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17241285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17242285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17243285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17244285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set */
17245285809Sscottl    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17246285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17247285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17248285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
17249285809Sscottl    if (satOrgIOContext->LoopNum == 1)
17250285809Sscottl    {
17251285809Sscottl      /* last loop */
17252285809Sscottl      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17253285809Sscottl      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);  /* FIS sector count (15:8) */
17254285809Sscottl    }
17255285809Sscottl    else
17256285809Sscottl    {
17257285809Sscottl      fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
17258285809Sscottl      fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
17259285809Sscottl    }
17260285809Sscottl    fis->d.reserved4      = 0;
17261285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17262285809Sscottl    fis->d.reserved5      = 0;
17263285809Sscottl
17264285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
17265285809Sscottl    break;
17266285809Sscottl  case SAT_READ_FPDMA_QUEUED:
17267285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17268285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17269285809Sscottl    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
17270285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17271285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17272285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17273285809Sscottl
17274285809Sscottl    /* Check FUA bit */
17275285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
17276285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
17277285809Sscottl    else
17278285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
17279285809Sscottl
17280285809Sscottl    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17281285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17282285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17283285809Sscottl    if (satOrgIOContext->LoopNum == 1)
17284285809Sscottl    {
17285285809Sscottl      /* last loop */
17286285809Sscottl      fis->h.features       = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
17287285809Sscottl      fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17288285809Sscottl    }
17289285809Sscottl    else
17290285809Sscottl    {
17291285809Sscottl      fis->h.features       = 0xFF;       /* FIS sector count (7:0) */
17292285809Sscottl      fis->d.featuresExp    = 0xFF;       /* FIS sector count (15:8) */
17293285809Sscottl    }
17294285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
17295285809Sscottl    fis->d.sectorCountExp = 0;
17296285809Sscottl    fis->d.reserved4      = 0;
17297285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17298285809Sscottl    fis->d.reserved5      = 0;
17299285809Sscottl
17300285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
17301285809Sscottl    break;
17302285809Sscottl  default:
17303285809Sscottl    SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17304285809Sscottl    return SM_RC_FAILURE;
17305285809Sscottl    break;
17306285809Sscottl  }
17307285809Sscottl
17308285809Sscottl  /* Initialize CB for SATA completion.
17309285809Sscottl   */
17310285809Sscottl  /* chained data */
17311285809Sscottl  satIOContext->satCompleteCB = &smsatChainedDataIOCB;
17312285809Sscottl
17313285809Sscottl  if (satOrgIOContext->ATACmd == SAT_READ_DMA || satOrgIOContext->ATACmd == SAT_READ_SECTORS)
17314285809Sscottl  {
17315285809Sscottl    smsatSplitSGL(smRoot,
17316285809Sscottl                  smIORequest,
17317285809Sscottl                  smDeviceHandle,
17318285809Sscottl                  (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17319285809Sscottl                  satOrgIOContext,
17320285809Sscottl                  NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/
17321285809Sscottl                  (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17322285809Sscottl                  agFALSE);
17323285809Sscottl  }
17324285809Sscottl  else
17325285809Sscottl  {
17326285809Sscottl    smsatSplitSGL(smRoot,
17327285809Sscottl                  smIORequest,
17328285809Sscottl                  smDeviceHandle,
17329285809Sscottl                  (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17330285809Sscottl                  satOrgIOContext,
17331285809Sscottl                  BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/
17332285809Sscottl                  (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17333285809Sscottl                  agFALSE);
17334285809Sscottl  }
17335285809Sscottl
17336285809Sscottl  /*
17337285809Sscottl   * Prepare SGL and send FIS to LL layer.
17338285809Sscottl   */
17339285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
17340285809Sscottl
17341285809Sscottl  status = smsataLLIOStart( smRoot,
17342285809Sscottl                            smIORequest,
17343285809Sscottl                            smDeviceHandle,
17344285809Sscottl                            (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest,
17345285809Sscottl                            satIOContext);
17346285809Sscottl
17347285809Sscottl  SM_DBG5(("smsatRead_1: return\n"));
17348285809Sscottl  return (status);
17349285809Sscottl}
17350285809Sscottl
17351285809SscottlosGLOBAL bit32
17352285809SscottlsmsatWrite_1(
17353285809Sscottl             smRoot_t                  *smRoot,
17354285809Sscottl             smIORequest_t             *smIORequest,
17355285809Sscottl             smDeviceHandle_t          *smDeviceHandle,
17356285809Sscottl             smScsiInitiatorRequest_t  *smScsiRequest,
17357285809Sscottl             smSatIOContext_t            *satIOContext
17358285809Sscottl           )
17359285809Sscottl{
17360285809Sscottl  /*
17361285809Sscottl    Assumption: error check on lba and tl has been done in satWrite*()
17362285809Sscottl    lba = lba + tl;
17363285809Sscottl  */
17364285809Sscottl  bit32                     status;
17365285809Sscottl  smSatIOContext_t            *satOrgIOContext = agNULL;
17366285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
17367285809Sscottl  agsaFisRegHostToDevice_t  *fis;
17368285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17369285809Sscottl  bit32                     lba = 0;
17370285809Sscottl  bit32                     DenomTL = 0xFF;
17371285809Sscottl  bit32                     Remainder = 0;
17372285809Sscottl  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
17373285809Sscottl
17374285809Sscottl  SM_DBG2(("smsatWrite_1: start\n"));
17375285809Sscottl
17376285809Sscottl  fis             = satIOContext->pFis;
17377285809Sscottl  satOrgIOContext = satIOContext->satOrgIOContext;
17378285809Sscottl  scsiCmnd        = satOrgIOContext->pScsiCmnd;
17379285809Sscottl
17380285809Sscottl  sm_memset(LBA,0, sizeof(LBA));
17381285809Sscottl
17382285809Sscottl  switch (satOrgIOContext->ATACmd)
17383285809Sscottl  {
17384285809Sscottl  case SAT_WRITE_DMA:
17385285809Sscottl    DenomTL = 0x100;
17386285809Sscottl    break;
17387285809Sscottl  case SAT_WRITE_SECTORS:
17388285809Sscottl    DenomTL = 0x100;
17389285809Sscottl    break;
17390285809Sscottl  case SAT_WRITE_DMA_EXT:
17391285809Sscottl    DenomTL = 0xFFFF;
17392285809Sscottl    break;
17393285809Sscottl  case SAT_WRITE_DMA_FUA_EXT:
17394285809Sscottl    DenomTL = 0xFFFF;
17395285809Sscottl    break;
17396285809Sscottl  case SAT_WRITE_SECTORS_EXT:
17397285809Sscottl    DenomTL = 0xFFFF;
17398285809Sscottl    break;
17399285809Sscottl  case SAT_WRITE_FPDMA_QUEUED:
17400285809Sscottl    DenomTL = 0xFFFF;
17401285809Sscottl    break;
17402285809Sscottl  default:
17403285809Sscottl    SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17404285809Sscottl    return SM_RC_FAILURE;
17405285809Sscottl    break;
17406285809Sscottl  }
17407285809Sscottl
17408285809Sscottl  Remainder = satOrgIOContext->OrgTL % DenomTL;
17409285809Sscottl  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
17410285809Sscottl  lba = satOrgIOContext->currentLBA;
17411285809Sscottl
17412285809Sscottl
17413285809Sscottl  LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3));
17414285809Sscottl  LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2));
17415285809Sscottl  LBA[2] = (bit8)((lba & 0xFF00) >> 8);
17416285809Sscottl  LBA[3] = (bit8)(lba & 0xFF);
17417285809Sscottl
17418285809Sscottl  switch (satOrgIOContext->ATACmd)
17419285809Sscottl  {
17420285809Sscottl  case SAT_WRITE_DMA:
17421285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17422285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
17423285809Sscottl    fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
17424285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17425285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17426285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17427285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17428285809Sscottl
17429285809Sscottl    /* FIS LBA mode set LBA (27:24) */
17430285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
17431285809Sscottl
17432285809Sscottl    fis->d.lbaLowExp      = 0;
17433285809Sscottl    fis->d.lbaMidExp      = 0;
17434285809Sscottl    fis->d.lbaHighExp     = 0;
17435285809Sscottl    fis->d.featuresExp    = 0;
17436285809Sscottl    if (satOrgIOContext->LoopNum == 1)
17437285809Sscottl    {
17438285809Sscottl      /* last loop */
17439285809Sscottl      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
17440285809Sscottl    }
17441285809Sscottl    else
17442285809Sscottl    {
17443285809Sscottl      fis->d.sectorCount    = 0x0;                   /* FIS sector count (7:0) */
17444285809Sscottl    }
17445285809Sscottl    fis->d.sectorCountExp = 0;
17446285809Sscottl    fis->d.reserved4      = 0;
17447285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17448285809Sscottl    fis->d.reserved5      = 0;
17449285809Sscottl
17450285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17451285809Sscottl
17452285809Sscottl    break;
17453285809Sscottl  case SAT_WRITE_SECTORS:
17454285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17455285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
17456285809Sscottl    fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
17457285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17458285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17459285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17460285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17461285809Sscottl
17462285809Sscottl    /* FIS LBA mode set LBA (27:24) */
17463285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
17464285809Sscottl
17465285809Sscottl    fis->d.lbaLowExp      = 0;
17466285809Sscottl    fis->d.lbaMidExp      = 0;
17467285809Sscottl    fis->d.lbaHighExp     = 0;
17468285809Sscottl    fis->d.featuresExp    = 0;
17469285809Sscottl    if (satOrgIOContext->LoopNum == 1)
17470285809Sscottl    {
17471285809Sscottl      /* last loop */
17472285809Sscottl      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
17473285809Sscottl    }
17474285809Sscottl    else
17475285809Sscottl    {
17476285809Sscottl      fis->d.sectorCount    = 0x0;                 /* FIS sector count (7:0) */
17477285809Sscottl    }
17478285809Sscottl    fis->d.sectorCountExp = 0;
17479285809Sscottl    fis->d.reserved4      = 0;
17480285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17481285809Sscottl    fis->d.reserved5      = 0;
17482285809Sscottl
17483285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
17484285809Sscottl
17485285809Sscottl    break;
17486285809Sscottl  case SAT_WRITE_DMA_EXT:
17487285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17488285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17489285809Sscottl    fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
17490285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17491285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17492285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17493285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17494285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set */
17495285809Sscottl    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17496285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17497285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17498285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
17499285809Sscottl    if (satOrgIOContext->LoopNum == 1)
17500285809Sscottl    {
17501285809Sscottl      /* last loop */
17502285809Sscottl      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
17503285809Sscottl      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17504285809Sscottl    }
17505285809Sscottl    else
17506285809Sscottl    {
17507285809Sscottl      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
17508285809Sscottl      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
17509285809Sscottl    }
17510285809Sscottl    fis->d.reserved4      = 0;
17511285809Sscottl    fis->d.control        = 0;                       /* FIS HOB bit clear */
17512285809Sscottl    fis->d.reserved5      = 0;
17513285809Sscottl
17514285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17515285809Sscottl
17516285809Sscottl    break;
17517285809Sscottl  case SAT_WRITE_SECTORS_EXT:
17518285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17519285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17520285809Sscottl    fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
17521285809Sscottl
17522285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17523285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17524285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17525285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17526285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set */
17527285809Sscottl    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17528285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17529285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17530285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
17531285809Sscottl    if (satOrgIOContext->LoopNum == 1)
17532285809Sscottl    {
17533285809Sscottl      /* last loop */
17534285809Sscottl      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17535285809Sscottl      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
17536285809Sscottl    }
17537285809Sscottl    else
17538285809Sscottl    {
17539285809Sscottl      fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
17540285809Sscottl      fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
17541285809Sscottl    }
17542285809Sscottl    fis->d.reserved4      = 0;
17543285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17544285809Sscottl    fis->d.reserved5      = 0;
17545285809Sscottl
17546285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
17547285809Sscottl
17548285809Sscottl    break;
17549285809Sscottl  case SAT_WRITE_FPDMA_QUEUED:
17550285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17551285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17552285809Sscottl    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
17553285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17554285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17555285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17556285809Sscottl
17557285809Sscottl    /* Check FUA bit */
17558285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
17559285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
17560285809Sscottl    else
17561285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
17562285809Sscottl
17563285809Sscottl    fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
17564285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17565285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17566285809Sscottl    if (satOrgIOContext->LoopNum == 1)
17567285809Sscottl    {
17568285809Sscottl      /* last loop */
17569285809Sscottl      fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17570285809Sscottl      fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17571285809Sscottl    }
17572285809Sscottl    else
17573285809Sscottl    {
17574285809Sscottl      fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
17575285809Sscottl      fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
17576285809Sscottl    }
17577285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
17578285809Sscottl    fis->d.sectorCountExp = 0;
17579285809Sscottl    fis->d.reserved4      = 0;
17580285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17581285809Sscottl    fis->d.reserved5      = 0;
17582285809Sscottl
17583285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
17584285809Sscottl    break;
17585285809Sscottl
17586285809Sscottl  default:
17587285809Sscottl    SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17588285809Sscottl    return SM_RC_FAILURE;
17589285809Sscottl    break;
17590285809Sscottl  }
17591285809Sscottl
17592285809Sscottl  /* Initialize CB for SATA completion.
17593285809Sscottl   */
17594285809Sscottl  /* chained data */
17595285809Sscottl  satIOContext->satCompleteCB = &smsatChainedDataIOCB;
17596285809Sscottl
17597285809Sscottl  if (satOrgIOContext->ATACmd == SAT_WRITE_DMA || satOrgIOContext->ATACmd == SAT_WRITE_SECTORS)
17598285809Sscottl  {
17599285809Sscottl    smsatSplitSGL(smRoot,
17600285809Sscottl                  smIORequest,
17601285809Sscottl                  smDeviceHandle,
17602285809Sscottl                  (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17603285809Sscottl                  satOrgIOContext,
17604285809Sscottl                  NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/
17605285809Sscottl                  (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17606285809Sscottl                  agFALSE);
17607285809Sscottl  }
17608285809Sscottl  else
17609285809Sscottl  {
17610285809Sscottl    smsatSplitSGL(smRoot,
17611285809Sscottl                  smIORequest,
17612285809Sscottl                  smDeviceHandle,
17613285809Sscottl                  (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17614285809Sscottl                  satOrgIOContext,
17615285809Sscottl                  BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/
17616285809Sscottl                  (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17617285809Sscottl                  agFALSE);
17618285809Sscottl  }
17619285809Sscottl
17620285809Sscottl  /*
17621285809Sscottl   * Prepare SGL and send FIS to LL layer.
17622285809Sscottl   */
17623285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
17624285809Sscottl
17625285809Sscottl  status = smsataLLIOStart( smRoot,
17626285809Sscottl                            smIORequest,
17627285809Sscottl                            smDeviceHandle,
17628285809Sscottl                            (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest,
17629285809Sscottl                            satIOContext);
17630285809Sscottl
17631285809Sscottl  SM_DBG5(("smsatWrite_1: return\n"));
17632285809Sscottl  return (status);
17633285809Sscottl}
17634285809Sscottl
17635285809SscottlosGLOBAL bit32
17636285809SscottlsmsatPassthrough(
17637285809Sscottl                    smRoot_t                  *smRoot,
17638285809Sscottl                    smIORequest_t             *smIORequest,
17639285809Sscottl                    smDeviceHandle_t          *smDeviceHandle,
17640285809Sscottl                    smScsiInitiatorRequest_t  *smScsiRequest,
17641285809Sscottl                    smSatIOContext_t            *satIOContext
17642285809Sscottl                   )
17643285809Sscottl{
17644285809Sscottl  smScsiRspSense_t          *pSense;
17645285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
17646285809Sscottl  smDeviceData_t            *pSatDevData;
17647285809Sscottl  agsaFisRegHostToDevice_t	  *fis;
17648285809Sscottl  bit32                      status;
17649285809Sscottl  bit32 					agRequestType;
17650285809Sscottl  smAtaPassThroughHdr_t       ataPassThroughHdr;
17651285809Sscottl
17652285809Sscottl
17653285809Sscottl  pSense      = satIOContext->pSense;
17654285809Sscottl  scsiCmnd    = &smScsiRequest->scsiCmnd;
17655285809Sscottl  pSatDevData = satIOContext->pSatDevData;
17656285809Sscottl  fis           = satIOContext->pFis;
17657285809Sscottl
17658285809Sscottl  SM_DBG1(("smsatPassthrough: START!!!\n"));
17659285809Sscottl
17660285809Sscottl  osti_memset(&ataPassThroughHdr, 0 , sizeof(smAtaPassThroughHdr_t));
17661285809Sscottl
17662285809Sscottl  ataPassThroughHdr.opc = scsiCmnd->cdb[0];
17663285809Sscottl  ataPassThroughHdr.mulCount = scsiCmnd->cdb[1] >> 5;
17664285809Sscottl  ataPassThroughHdr.proto = (scsiCmnd->cdb[1] >> 1) & 0x0F;
17665285809Sscottl  ataPassThroughHdr.extend = scsiCmnd->cdb[1] & 1;
17666285809Sscottl  ataPassThroughHdr.offline = scsiCmnd->cdb[2] >> 6;
17667285809Sscottl  ataPassThroughHdr.ckCond = (scsiCmnd->cdb[2] >> 5) & 1;
17668285809Sscottl  ataPassThroughHdr.tType = (scsiCmnd->cdb[2] >> 4) & 1;
17669285809Sscottl  ataPassThroughHdr.tDir = (scsiCmnd->cdb[2] >> 3) & 1;
17670285809Sscottl  ataPassThroughHdr.byteBlock = (scsiCmnd->cdb[2] >> 2) & 1;
17671285809Sscottl  ataPassThroughHdr.tlength = scsiCmnd->cdb[2] & 0x3;
17672285809Sscottl
17673285809Sscottl  switch(ataPassThroughHdr.proto)
17674285809Sscottl  {
17675285809Sscottl    case 0:
17676285809Sscottl    case 9:
17677285809Sscottl    	    agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;	//Device Reset
17678285809Sscottl	    break;
17679285809Sscottl    case 1:
17680285809Sscottl       	    agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;		//Software reset
17681285809Sscottl	    break;
17682285809Sscottl    case 3:
17683285809Sscottl            agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;	//Non Data mode
17684285809Sscottl	    break;
17685285809Sscottl    case 4:
17686285809Sscottl       	    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;	//IO_Data_In mode
17687285809Sscottl	    break;
17688285809Sscottl    case 5:
17689285809Sscottl            agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;		//PIO_Data_out
17690285809Sscottl            break;
17691285809Sscottl    case 6:
17692285809Sscottl            agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;	//DMA READ and WRITE
17693285809Sscottl            break;
17694285809Sscottl    case 8:
17695285809Sscottl            agRequestType = AGSA_SATA_ATAP_EXECDEVDIAG; 	//device diagnostic
17696285809Sscottl	    break;
17697285809Sscottl    case 12:
17698285809Sscottl            agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;		//FPDMA Read and Write
17699285809Sscottl            break;
17700285809Sscottl    default:
17701285809Sscottl            agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;	//Default Non Data Mode
17702285809Sscottl            break;
17703285809Sscottl  }
17704285809Sscottl
17705285809Sscottl
17706285809Sscottl  if((ataPassThroughHdr.tlength == 0) && (agRequestType != AGSA_SATA_PROTOCOL_NON_DATA))
17707285809Sscottl  {
17708285809Sscottl    SM_DBG1(("smsatPassthrough SCSI_SNSCODE_INVALID_FIELD_IN_CDB\n"));
17709285809Sscottl
17710285809Sscottl    smsatSetSensePayload( pSense,
17711285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
17712285809Sscottl                          0,
17713285809Sscottl			  SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
17714285809Sscottl                          satIOContext);
17715285809Sscottl
17716285809Sscottl    tdsmIOCompletedCB( smRoot,
17717285809Sscottl                       smIORequest,
17718285809Sscottl                       smIOSuccess,
17719285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
17720285809Sscottl                       satIOContext->pSmSenseData,
17721285809Sscottl                       satIOContext->interruptContext );
17722285809Sscottl
17723285809Sscottl    return SM_RC_SUCCESS;
17724285809Sscottl  }
17725285809Sscottl
17726285809Sscottl  if(scsiCmnd->cdb[0] == 0xA1)
17727285809Sscottl  {
17728285809Sscottl    SM_DBG1(("smsatPassthrough A1h: COMMAND: %x  FEATURE: %x \n",scsiCmnd->cdb[9],scsiCmnd->cdb[3]));
17729285809Sscottl
17730285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17731285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17732285809Sscottl    fis->h.features       = scsiCmnd->cdb[3];
17733285809Sscottl    fis->d.sectorCount	  = scsiCmnd->cdb[4];		  /* 0x01  FIS sector count (7:0) */
17734285809Sscottl    fis->d.lbaLow 		  = scsiCmnd->cdb[5];		  /* Reading LBA  FIS LBA (7 :0 ) */
17735285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[6];
17736285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[7];
17737285809Sscottl    fis->d.device         = scsiCmnd->cdb[8];
17738285809Sscottl    fis->h.command		  = scsiCmnd->cdb[9];
17739285809Sscottl    fis->d.featuresExp	  = 0;
17740285809Sscottl    fis->d.sectorCountExp = 0;
17741285809Sscottl    fis->d.lbaLowExp	  = 0;
17742285809Sscottl    fis->d.lbaMidExp	  = 0;
17743285809Sscottl    fis->d.lbaHighExp 	  = 0;
17744285809Sscottl    fis->d.reserved4	  = 0;
17745285809Sscottl    fis->d.control		  = 0;					  /* FIS HOB bit clear */
17746285809Sscottl    fis->d.reserved5	  = 0;
17747285809Sscottl
17748285809Sscottl    /* Initialize CB for SATA completion*/
17749285809Sscottl    satIOContext->satCompleteCB = &smsatPassthroughCB;
17750285809Sscottl
17751285809Sscottl    /*
17752285809Sscottl        * Prepare SGL and send FIS to LL layer.
17753285809Sscottl    */
17754285809Sscottl
17755285809Sscottl    satIOContext->reqType = agRequestType;
17756285809Sscottl    status = smsataLLIOStart( smRoot,
17757285809Sscottl                              smIORequest,
17758285809Sscottl	                      smDeviceHandle,
17759285809Sscottl			      smScsiRequest,
17760285809Sscottl                              satIOContext);
17761285809Sscottl    return status;
17762285809Sscottl
17763285809Sscottl   }
17764285809Sscottl   else if(scsiCmnd->cdb[0] == 0x85)
17765285809Sscottl   {
17766285809Sscottl     SM_DBG1(("smsatPassthrough 85h: COMMAND: %x  FEATURE: %x \n",scsiCmnd->cdb[14],scsiCmnd->cdb[4]));
17767285809Sscottl
17768285809Sscottl     fis->h.fisType        = 0x27;                   /* Reg host to device */
17769285809Sscottl     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17770285809Sscottl
17771285809Sscottl     if(1 == ataPassThroughHdr.extend)
17772285809Sscottl     {
17773285809Sscottl       fis->d.featuresExp    = scsiCmnd->cdb[3];
17774285809Sscottl       fis->d.sectorCountExp = scsiCmnd->cdb[5];
17775285809Sscottl       fis->d.lbaMidExp      = scsiCmnd->cdb[9];
17776285809Sscottl       fis->d.lbaHighExp     = scsiCmnd->cdb[11];
17777285809Sscottl       fis->d.lbaLowExp      = scsiCmnd->cdb[7];
17778285809Sscottl     }
17779285809Sscottl     fis->h.features = scsiCmnd->cdb[4];
17780285809Sscottl     fis->d.sectorCount = scsiCmnd->cdb[6];
17781285809Sscottl     fis->d.lbaLow = scsiCmnd->cdb[8];
17782285809Sscottl     fis->d.lbaMid = scsiCmnd->cdb[10];
17783285809Sscottl     fis->d.lbaHigh = scsiCmnd->cdb[12];
17784285809Sscottl     fis->d.device  = scsiCmnd->cdb[13];
17785285809Sscottl     fis->h.command = scsiCmnd->cdb[14];
17786285809Sscottl     fis->d.reserved4 = 0;
17787285809Sscottl     fis->d.control = 0;
17788285809Sscottl     fis->d.reserved5	  = 0;
17789285809Sscottl
17790285809Sscottl
17791285809Sscottl     /* Initialize CB for SATA completion.
17792285809Sscottl      */
17793285809Sscottl
17794285809Sscottl     satIOContext->satCompleteCB = &smsatPassthroughCB;
17795285809Sscottl
17796285809Sscottl     /*
17797285809Sscottl       * Prepare SGL and send FIS to LL layer.
17798285809Sscottl      */
17799285809Sscottl     satIOContext->reqType = agRequestType;
17800285809Sscottl     status = smsataLLIOStart( smRoot,
17801285809Sscottl                               smIORequest,
17802285809Sscottl                               smDeviceHandle,
17803285809Sscottl                               smScsiRequest,
17804285809Sscottl                               satIOContext);
17805285809Sscottl     return status;
17806285809Sscottl
17807285809Sscottl   }
17808285809Sscottl   else
17809285809Sscottl   {
17810285809Sscottl     SM_DBG1(("smsatPassthrough : INVALD PASSTHROUGH!!!\n"));
17811285809Sscottl     smsatSetSensePayload( pSense,
17812285809Sscottl                          SCSI_SNSKEY_ILLEGAL_REQUEST,
17813285809Sscottl                          0,
17814285809Sscottl                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
17815285809Sscottl                          satIOContext);
17816285809Sscottl     tdsmIOCompletedCB( smRoot,
17817285809Sscottl                       smIORequest,
17818285809Sscottl                       smIOSuccess,
17819285809Sscottl                       SCSI_STAT_CHECK_CONDITION,
17820285809Sscottl                       satIOContext->pSmSenseData,
17821285809Sscottl                       satIOContext->interruptContext );
17822285809Sscottl
17823285809Sscottl     SM_DBG1(("smsatPassthrough : return control!!!\n"));
17824285809Sscottl
17825285809Sscottl     return SM_RC_SUCCESS;
17826285809Sscottl   }
17827285809Sscottl}
17828285809Sscottl
17829285809SscottlosGLOBAL bit32
17830285809SscottlsmsatNonChainedWriteNVerify_Verify(
17831285809Sscottl                                   smRoot_t                  *smRoot,
17832285809Sscottl                                   smIORequest_t             *smIORequest,
17833285809Sscottl                                   smDeviceHandle_t          *smDeviceHandle,
17834285809Sscottl                                   smScsiInitiatorRequest_t  *smScsiRequest,
17835285809Sscottl                                   smSatIOContext_t            *satIOContext
17836285809Sscottl                                  )
17837285809Sscottl{
17838285809Sscottl  bit32                     status;
17839285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17840285809Sscottl  smDeviceData_t            *pSatDevData;
17841285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
17842285809Sscottl  agsaFisRegHostToDevice_t  *fis;
17843285809Sscottl
17844285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
17845285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
17846285809Sscottl  fis           = satIOContext->pFis;
17847285809Sscottl  SM_DBG5(("smsatNonChainedWriteNVerify_Verify: start\n"));
17848285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
17849285809Sscottl  {
17850285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17851285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17852285809Sscottl
17853285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17854285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17855285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
17856285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
17857285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
17858285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
17859285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
17860285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17861285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17862285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
17863285809Sscottl    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
17864285809Sscottl    fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
17865285809Sscottl
17866285809Sscottl    fis->d.reserved4      = 0;
17867285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17868285809Sscottl    fis->d.reserved5      = 0;
17869285809Sscottl
17870285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17871285809Sscottl
17872285809Sscottl    /* Initialize CB for SATA completion.
17873285809Sscottl     */
17874285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
17875285809Sscottl
17876285809Sscottl    /*
17877285809Sscottl     * Prepare SGL and send FIS to LL layer.
17878285809Sscottl     */
17879285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
17880285809Sscottl
17881285809Sscottl    status = smsataLLIOStart( smRoot,
17882285809Sscottl                              smIORequest,
17883285809Sscottl                              smDeviceHandle,
17884285809Sscottl                              smScsiRequest,
17885285809Sscottl                              satIOContext);
17886285809Sscottl
17887285809Sscottl
17888285809Sscottl    SM_DBG1(("smsatNonChainedWriteNVerify_Verify: return status %d!!!\n", status));
17889285809Sscottl    return (status);
17890285809Sscottl  }
17891285809Sscottl  else
17892285809Sscottl  {
17893285809Sscottl    /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
17894285809Sscottl    SM_DBG1(("smsatNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS!!!\n"));
17895285809Sscottl    return SM_RC_FAILURE;
17896285809Sscottl  }
17897285809Sscottl}
17898285809Sscottl
17899285809SscottlosGLOBAL bit32
17900285809SscottlsmsatChainedWriteNVerify_Start_Verify(
17901285809Sscottl                                      smRoot_t                  *smRoot,
17902285809Sscottl                                      smIORequest_t             *smIORequest,
17903285809Sscottl                                      smDeviceHandle_t          *smDeviceHandle,
17904285809Sscottl                                      smScsiInitiatorRequest_t  *smScsiRequest,
17905285809Sscottl                                      smSatIOContext_t            *satIOContext
17906285809Sscottl                                     )
17907285809Sscottl{
17908285809Sscottl  /*
17909285809Sscottl    deal with transfer length; others have been handled previously at this point;
17910285809Sscottl    no LBA check; no range check;
17911285809Sscottl  */
17912285809Sscottl  bit32                     status;
17913285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17914285809Sscottl  smDeviceData_t            *pSatDevData;
17915285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
17916285809Sscottl  agsaFisRegHostToDevice_t  *fis;
17917285809Sscottl  bit32                     lba = 0;
17918285809Sscottl  bit32                     tl = 0;
17919285809Sscottl  bit32                     LoopNum = 1;
17920285809Sscottl  bit8                      LBA[4];
17921285809Sscottl  bit8                      TL[4];
17922285809Sscottl
17923285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
17924285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
17925285809Sscottl  fis           = satIOContext->pFis;
17926285809Sscottl
17927285809Sscottl  SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: start\n"));
17928285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
17929285809Sscottl  sm_memset(TL, 0, sizeof(TL));
17930285809Sscottl  /* do not use memcpy due to indexing in LBA and TL */
17931285809Sscottl  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
17932285809Sscottl  LBA[1] = scsiCmnd->cdb[3];
17933285809Sscottl  LBA[2] = scsiCmnd->cdb[4];
17934285809Sscottl  LBA[3] = scsiCmnd->cdb[5];  /* LSB */
17935285809Sscottl  TL[0] = scsiCmnd->cdb[6];   /* MSB */
17936285809Sscottl  TL[1] = scsiCmnd->cdb[7];
17937285809Sscottl  TL[2] = scsiCmnd->cdb[7];
17938285809Sscottl  TL[3] = scsiCmnd->cdb[8];   /* LSB */
17939285809Sscottl  lba = smsatComputeCDB12LBA(satIOContext);
17940285809Sscottl  tl = smsatComputeCDB12TL(satIOContext);
17941285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
17942285809Sscottl  {
17943285809Sscottl    SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n"));
17944285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17945285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17946285809Sscottl
17947285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17948285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17949285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
17950285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
17951285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
17952285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
17953285809Sscottl    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
17954285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17955285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17956285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
17957285809Sscottl    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
17958285809Sscottl    fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
17959285809Sscottl
17960285809Sscottl    fis->d.reserved4      = 0;
17961285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17962285809Sscottl    fis->d.reserved5      = 0;
17963285809Sscottl
17964285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17965285809Sscottl    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
17966285809Sscottl  }
17967285809Sscottl  else
17968285809Sscottl  {
17969285809Sscottl    SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n"));
17970285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
17971285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
17972285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
17973285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
17974285809Sscottl    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
17975285809Sscottl    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
17976285809Sscottl    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
17977285809Sscottl      /* FIS LBA mode set LBA (27:24) */
17978285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
17979285809Sscottl    fis->d.lbaLowExp      = 0;
17980285809Sscottl    fis->d.lbaMidExp      = 0;
17981285809Sscottl    fis->d.lbaHighExp     = 0;
17982285809Sscottl    fis->d.featuresExp    = 0;
17983285809Sscottl    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
17984285809Sscottl    fis->d.sectorCountExp = 0;
17985285809Sscottl    fis->d.reserved4      = 0;
17986285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
17987285809Sscottl    fis->d.reserved5      = 0;
17988285809Sscottl
17989285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17990285809Sscottl    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
17991285809Sscottl
17992285809Sscottl }
17993285809Sscottl
17994285809Sscottl  satIOContext->currentLBA = lba;
17995285809Sscottl  satIOContext->OrgTL = tl;
17996285809Sscottl
17997285809Sscottl  /*
17998285809Sscottl    computing number of loop and remainder for tl
17999285809Sscottl    0xFF in case not ext
18000285809Sscottl    0xFFFF in case EXT
18001285809Sscottl  */
18002285809Sscottl  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
18003285809Sscottl  {
18004285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFF);
18005285809Sscottl  }
18006285809Sscottl  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
18007285809Sscottl  {
18008285809Sscottl    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
18009285809Sscottl    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
18010285809Sscottl  }
18011285809Sscottl  else
18012285809Sscottl  {
18013285809Sscottl    SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
18014285809Sscottl    LoopNum = 1;
18015285809Sscottl  }
18016285809Sscottl
18017285809Sscottl  satIOContext->LoopNum = LoopNum;
18018285809Sscottl
18019285809Sscottl  if (LoopNum == 1)
18020285809Sscottl  {
18021285809Sscottl    SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
18022285809Sscottl    /* Initialize CB for SATA completion.
18023285809Sscottl     */
18024285809Sscottl    satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
18025285809Sscottl  }
18026285809Sscottl  else
18027285809Sscottl  {
18028285809Sscottl    SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: CHAINED data!!!\n"));
18029285809Sscottl    /* re-setting tl */
18030285809Sscottl    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
18031285809Sscottl    {
18032285809Sscottl       fis->d.sectorCount    = 0xFF;
18033285809Sscottl    }
18034285809Sscottl    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
18035285809Sscottl    {
18036285809Sscottl      fis->d.sectorCount    = 0xFF;
18037285809Sscottl      fis->d.sectorCountExp = 0xFF;
18038285809Sscottl    }
18039285809Sscottl    else
18040285809Sscottl    {
18041285809Sscottl      SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
18042285809Sscottl    }
18043285809Sscottl
18044285809Sscottl    /* Initialize CB for SATA completion.
18045285809Sscottl     */
18046285809Sscottl    satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18047285809Sscottl  }
18048285809Sscottl
18049285809Sscottl
18050285809Sscottl  /*
18051285809Sscottl   * Prepare SGL and send FIS to LL layer.
18052285809Sscottl   */
18053285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
18054285809Sscottl
18055285809Sscottl  status = smsataLLIOStart( smRoot,
18056285809Sscottl                            smIORequest,
18057285809Sscottl                            smDeviceHandle,
18058285809Sscottl                            smScsiRequest,
18059285809Sscottl                            satIOContext);
18060285809Sscottl  return (status);
18061285809Sscottl
18062285809Sscottl
18063285809Sscottl}
18064285809Sscottl
18065285809SscottlosGLOBAL bit32
18066285809SscottlsmsatChainedWriteNVerify_Write(
18067285809Sscottl                               smRoot_t                  *smRoot,
18068285809Sscottl                               smIORequest_t             *smIORequest,
18069285809Sscottl                               smDeviceHandle_t          *smDeviceHandle,
18070285809Sscottl                               smScsiInitiatorRequest_t  *smScsiRequest,
18071285809Sscottl                               smSatIOContext_t            *satIOContext
18072285809Sscottl                              )
18073285809Sscottl{
18074285809Sscottl  /*
18075285809Sscottl    Assumption: error check on lba and tl has been done in satWrite*()
18076285809Sscottl    lba = lba + tl;
18077285809Sscottl  */
18078285809Sscottl  bit32                     status;
18079285809Sscottl  smSatIOContext_t            *satOrgIOContext = agNULL;
18080285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
18081285809Sscottl  agsaFisRegHostToDevice_t  *fis;
18082285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18083285809Sscottl  bit32                     lba = 0;
18084285809Sscottl  bit32                     DenomTL = 0xFF;
18085285809Sscottl  bit32                     Remainder = 0;
18086285809Sscottl  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
18087285809Sscottl
18088285809Sscottl  SM_DBG1(("smsatChainedWriteNVerify_Write: start\n"));
18089285809Sscottl
18090285809Sscottl  fis             = satIOContext->pFis;
18091285809Sscottl  satOrgIOContext = satIOContext->satOrgIOContext;
18092285809Sscottl  scsiCmnd        = satOrgIOContext->pScsiCmnd;
18093285809Sscottl
18094285809Sscottl
18095285809Sscottl  sm_memset(LBA,0, sizeof(LBA));
18096285809Sscottl
18097285809Sscottl  switch (satOrgIOContext->ATACmd)
18098285809Sscottl  {
18099285809Sscottl  case SAT_WRITE_DMA:
18100285809Sscottl    DenomTL = 0xFF;
18101285809Sscottl    break;
18102285809Sscottl  case SAT_WRITE_SECTORS:
18103285809Sscottl    DenomTL = 0xFF;
18104285809Sscottl    break;
18105285809Sscottl  case SAT_WRITE_DMA_EXT:
18106285809Sscottl    DenomTL = 0xFFFF;
18107285809Sscottl    break;
18108285809Sscottl  case SAT_WRITE_DMA_FUA_EXT:
18109285809Sscottl    DenomTL = 0xFFFF;
18110285809Sscottl    break;
18111285809Sscottl  case SAT_WRITE_SECTORS_EXT:
18112285809Sscottl    DenomTL = 0xFFFF;
18113285809Sscottl    break;
18114285809Sscottl  case SAT_WRITE_FPDMA_QUEUED:
18115285809Sscottl    DenomTL = 0xFFFF;
18116285809Sscottl    break;
18117285809Sscottl  default:
18118285809Sscottl    SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18119285809Sscottl    return SM_RC_FAILURE;
18120285809Sscottl    break;
18121285809Sscottl  }
18122285809Sscottl
18123285809Sscottl  Remainder = satOrgIOContext->OrgTL % DenomTL;
18124285809Sscottl  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18125285809Sscottl  lba = satOrgIOContext->currentLBA;
18126285809Sscottl
18127285809Sscottl  LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18128285809Sscottl  LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18129285809Sscottl  LBA[2] = (bit8)((lba & 0xF0) >> 8);
18130285809Sscottl  LBA[3] = (bit8)(lba & 0xF);               /* LSB */
18131285809Sscottl
18132285809Sscottl  switch (satOrgIOContext->ATACmd)
18133285809Sscottl  {
18134285809Sscottl  case SAT_WRITE_DMA:
18135285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18136285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18137285809Sscottl    fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
18138285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
18139285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18140285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18141285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18142285809Sscottl
18143285809Sscottl    /* FIS LBA mode set LBA (27:24) */
18144285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18145285809Sscottl
18146285809Sscottl    fis->d.lbaLowExp      = 0;
18147285809Sscottl    fis->d.lbaMidExp      = 0;
18148285809Sscottl    fis->d.lbaHighExp     = 0;
18149285809Sscottl    fis->d.featuresExp    = 0;
18150285809Sscottl    if (satOrgIOContext->LoopNum == 1)
18151285809Sscottl    {
18152285809Sscottl      /* last loop */
18153285809Sscottl      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
18154285809Sscottl    }
18155285809Sscottl    else
18156285809Sscottl    {
18157285809Sscottl      fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
18158285809Sscottl    }
18159285809Sscottl    fis->d.sectorCountExp = 0;
18160285809Sscottl    fis->d.reserved4      = 0;
18161285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
18162285809Sscottl    fis->d.reserved5      = 0;
18163285809Sscottl
18164285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18165285809Sscottl
18166285809Sscottl    break;
18167285809Sscottl  case SAT_WRITE_SECTORS:
18168285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18169285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18170285809Sscottl    fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
18171285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
18172285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18173285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18174285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18175285809Sscottl
18176285809Sscottl    /* FIS LBA mode set LBA (27:24) */
18177285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18178285809Sscottl
18179285809Sscottl    fis->d.lbaLowExp      = 0;
18180285809Sscottl    fis->d.lbaMidExp      = 0;
18181285809Sscottl    fis->d.lbaHighExp     = 0;
18182285809Sscottl    fis->d.featuresExp    = 0;
18183285809Sscottl    if (satOrgIOContext->LoopNum == 1)
18184285809Sscottl    {
18185285809Sscottl      /* last loop */
18186285809Sscottl      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
18187285809Sscottl    }
18188285809Sscottl    else
18189285809Sscottl    {
18190285809Sscottl      fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
18191285809Sscottl    }
18192285809Sscottl    fis->d.sectorCountExp = 0;
18193285809Sscottl    fis->d.reserved4      = 0;
18194285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
18195285809Sscottl    fis->d.reserved5      = 0;
18196285809Sscottl
18197285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18198285809Sscottl
18199285809Sscottl    break;
18200285809Sscottl  case SAT_WRITE_DMA_EXT:
18201285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18202285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18203285809Sscottl    fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
18204285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
18205285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18206285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18207285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18208285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set */
18209285809Sscottl    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18210285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18211285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18212285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
18213285809Sscottl    if (satOrgIOContext->LoopNum == 1)
18214285809Sscottl    {
18215285809Sscottl      /* last loop */
18216285809Sscottl      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
18217285809Sscottl      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18218285809Sscottl    }
18219285809Sscottl    else
18220285809Sscottl    {
18221285809Sscottl      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
18222285809Sscottl      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
18223285809Sscottl    }
18224285809Sscottl    fis->d.reserved4      = 0;
18225285809Sscottl    fis->d.control        = 0;                       /* FIS HOB bit clear */
18226285809Sscottl    fis->d.reserved5      = 0;
18227285809Sscottl
18228285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18229285809Sscottl
18230285809Sscottl    break;
18231285809Sscottl  case SAT_WRITE_SECTORS_EXT:
18232285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18233285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18234285809Sscottl    fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
18235285809Sscottl
18236285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
18237285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18238285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18239285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18240285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set */
18241285809Sscottl    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18242285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18243285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18244285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
18245285809Sscottl    if (satOrgIOContext->LoopNum == 1)
18246285809Sscottl    {
18247285809Sscottl      /* last loop */
18248285809Sscottl      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
18249285809Sscottl      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
18250285809Sscottl    }
18251285809Sscottl    else
18252285809Sscottl    {
18253285809Sscottl      fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
18254285809Sscottl      fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
18255285809Sscottl    }
18256285809Sscottl    fis->d.reserved4      = 0;
18257285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
18258285809Sscottl    fis->d.reserved5      = 0;
18259285809Sscottl
18260285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18261285809Sscottl
18262285809Sscottl    break;
18263285809Sscottl  case SAT_WRITE_FPDMA_QUEUED:
18264285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18265285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18266285809Sscottl    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
18267285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18268285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18269285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18270285809Sscottl
18271285809Sscottl    /* Check FUA bit */
18272285809Sscottl    if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
18273285809Sscottl      fis->d.device       = 0xC0;                   /* FIS FUA set */
18274285809Sscottl    else
18275285809Sscottl      fis->d.device       = 0x40;                   /* FIS FUA clear */
18276285809Sscottl
18277285809Sscottl    fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
18278285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18279285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18280285809Sscottl    if (satOrgIOContext->LoopNum == 1)
18281285809Sscottl    {
18282285809Sscottl      /* last loop */
18283285809Sscottl      fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
18284285809Sscottl      fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18285285809Sscottl    }
18286285809Sscottl    else
18287285809Sscottl    {
18288285809Sscottl      fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
18289285809Sscottl      fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
18290285809Sscottl    }
18291285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
18292285809Sscottl    fis->d.sectorCountExp = 0;
18293285809Sscottl    fis->d.reserved4      = 0;
18294285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
18295285809Sscottl    fis->d.reserved5      = 0;
18296285809Sscottl
18297285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
18298285809Sscottl    break;
18299285809Sscottl
18300285809Sscottl  default:
18301285809Sscottl    SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18302285809Sscottl    return SM_RC_FAILURE;
18303285809Sscottl    break;
18304285809Sscottl  }
18305285809Sscottl
18306285809Sscottl  /* Initialize CB for SATA completion.
18307285809Sscottl   */
18308285809Sscottl  /* chained data */
18309285809Sscottl  satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18310285809Sscottl
18311285809Sscottl
18312285809Sscottl  /*
18313285809Sscottl   * Prepare SGL and send FIS to LL layer.
18314285809Sscottl   */
18315285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
18316285809Sscottl
18317285809Sscottl  status = smsataLLIOStart( smRoot,
18318285809Sscottl                            smIORequest,
18319285809Sscottl                            smDeviceHandle,
18320285809Sscottl                            smScsiRequest,
18321285809Sscottl                            satIOContext);
18322285809Sscottl
18323285809Sscottl  SM_DBG5(("satChainedWriteNVerify_Write: return\n"));
18324285809Sscottl  return (status);
18325285809Sscottl}
18326285809Sscottl
18327285809SscottlosGLOBAL bit32
18328285809SscottlsmsatChainedWriteNVerify_Verify(
18329285809Sscottl                                smRoot_t                  *smRoot,
18330285809Sscottl                                smIORequest_t             *smIORequest,
18331285809Sscottl                                smDeviceHandle_t          *smDeviceHandle,
18332285809Sscottl                                smScsiInitiatorRequest_t  *smScsiRequest,
18333285809Sscottl                                smSatIOContext_t            *satIOContext
18334285809Sscottl                               )
18335285809Sscottl{
18336285809Sscottl  bit32                     status;
18337285809Sscottl  smSatIOContext_t         *satOrgIOContext = agNULL;
18338285809Sscottl  agsaFisRegHostToDevice_t *fis;
18339285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18340285809Sscottl  bit32                     lba = 0;
18341285809Sscottl  bit32                     DenomTL = 0xFF;
18342285809Sscottl  bit32                     Remainder = 0;
18343285809Sscottl  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
18344285809Sscottl
18345285809Sscottl  SM_DBG2(("smsatChainedWriteNVerify_Verify: start\n"));
18346285809Sscottl  fis             = satIOContext->pFis;
18347285809Sscottl  satOrgIOContext = satIOContext->satOrgIOContext;
18348285809Sscottl  sm_memset(LBA,0, sizeof(LBA));
18349285809Sscottl  switch (satOrgIOContext->ATACmd)
18350285809Sscottl  {
18351285809Sscottl  case SAT_READ_VERIFY_SECTORS:
18352285809Sscottl    DenomTL = 0xFF;
18353285809Sscottl    break;
18354285809Sscottl  case SAT_READ_VERIFY_SECTORS_EXT:
18355285809Sscottl    DenomTL = 0xFFFF;
18356285809Sscottl    break;
18357285809Sscottl  default:
18358285809Sscottl    SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18359285809Sscottl    return SM_RC_FAILURE;
18360285809Sscottl    break;
18361285809Sscottl  }
18362285809Sscottl
18363285809Sscottl  Remainder = satOrgIOContext->OrgTL % DenomTL;
18364285809Sscottl  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18365285809Sscottl  lba = satOrgIOContext->currentLBA;
18366285809Sscottl
18367285809Sscottl  LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18368285809Sscottl  LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18369285809Sscottl  LBA[2] = (bit8)((lba & 0xF0) >> 8);
18370285809Sscottl  LBA[3] = (bit8)(lba & 0xF);               /* LSB */
18371285809Sscottl
18372285809Sscottl  switch (satOrgIOContext->ATACmd)
18373285809Sscottl  {
18374285809Sscottl  case SAT_READ_VERIFY_SECTORS:
18375285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18376285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18377285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
18378285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
18379285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18380285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18381285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18382285809Sscottl
18383285809Sscottl    /* FIS LBA mode set LBA (27:24) */
18384285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18385285809Sscottl
18386285809Sscottl    fis->d.lbaLowExp      = 0;
18387285809Sscottl    fis->d.lbaMidExp      = 0;
18388285809Sscottl    fis->d.lbaHighExp     = 0;
18389285809Sscottl    fis->d.featuresExp    = 0;
18390285809Sscottl    if (satOrgIOContext->LoopNum == 1)
18391285809Sscottl    {
18392285809Sscottl      /* last loop */
18393285809Sscottl      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
18394285809Sscottl    }
18395285809Sscottl    else
18396285809Sscottl    {
18397285809Sscottl      fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
18398285809Sscottl    }
18399285809Sscottl    fis->d.sectorCountExp = 0;
18400285809Sscottl    fis->d.reserved4      = 0;
18401285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
18402285809Sscottl    fis->d.reserved5      = 0;
18403285809Sscottl
18404285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18405285809Sscottl
18406285809Sscottl    break;
18407285809Sscottl  case SAT_READ_VERIFY_SECTORS_EXT:
18408285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18409285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18410285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
18411285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
18412285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18413285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18414285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18415285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set */
18416285809Sscottl    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18417285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18418285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18419285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
18420285809Sscottl    if (satOrgIOContext->LoopNum == 1)
18421285809Sscottl    {
18422285809Sscottl      /* last loop */
18423285809Sscottl      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
18424285809Sscottl      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18425285809Sscottl    }
18426285809Sscottl    else
18427285809Sscottl    {
18428285809Sscottl      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
18429285809Sscottl      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
18430285809Sscottl    }
18431285809Sscottl    fis->d.reserved4      = 0;
18432285809Sscottl    fis->d.control        = 0;                       /* FIS HOB bit clear */
18433285809Sscottl    fis->d.reserved5      = 0;
18434285809Sscottl
18435285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18436285809Sscottl
18437285809Sscottl    break;
18438285809Sscottl
18439285809Sscottl  default:
18440285809Sscottl    SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18441285809Sscottl    return SM_RC_FAILURE;
18442285809Sscottl    break;
18443285809Sscottl  }
18444285809Sscottl
18445285809Sscottl  /* Initialize CB for SATA completion.
18446285809Sscottl   */
18447285809Sscottl  /* chained data */
18448285809Sscottl  satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18449285809Sscottl
18450285809Sscottl
18451285809Sscottl  /*
18452285809Sscottl   * Prepare SGL and send FIS to LL layer.
18453285809Sscottl   */
18454285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
18455285809Sscottl
18456285809Sscottl  status = smsataLLIOStart( smRoot,
18457285809Sscottl                            smIORequest,
18458285809Sscottl                            smDeviceHandle,
18459285809Sscottl                            smScsiRequest,
18460285809Sscottl                            satIOContext);
18461285809Sscottl
18462285809Sscottl  SM_DBG5(("smsatChainedWriteNVerify_Verify: return\n"));
18463285809Sscottl  return (status);
18464285809Sscottl}
18465285809Sscottl
18466285809SscottlosGLOBAL bit32
18467285809SscottlsmsatChainedVerify(
18468285809Sscottl                    smRoot_t                  *smRoot,
18469285809Sscottl                    smIORequest_t             *smIORequest,
18470285809Sscottl                    smDeviceHandle_t          *smDeviceHandle,
18471285809Sscottl                    smScsiInitiatorRequest_t  *smScsiRequest,
18472285809Sscottl                    smSatIOContext_t            *satIOContext
18473285809Sscottl       )
18474285809Sscottl{
18475285809Sscottl  bit32                     status;
18476285809Sscottl  smSatIOContext_t         *satOrgIOContext = agNULL;
18477285809Sscottl  agsaFisRegHostToDevice_t *fis;
18478285809Sscottl  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18479285809Sscottl  bit32                     lba = 0;
18480285809Sscottl  bit32                     DenomTL = 0xFF;
18481285809Sscottl  bit32                     Remainder = 0;
18482285809Sscottl  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
18483285809Sscottl
18484285809Sscottl  SM_DBG2(("smsatChainedVerify: start\n"));
18485285809Sscottl  fis             = satIOContext->pFis;
18486285809Sscottl  satOrgIOContext = satIOContext->satOrgIOContext;
18487285809Sscottl  sm_memset(LBA,0, sizeof(LBA));
18488285809Sscottl  switch (satOrgIOContext->ATACmd)
18489285809Sscottl  {
18490285809Sscottl  case SAT_READ_VERIFY_SECTORS:
18491285809Sscottl    DenomTL = 0xFF;
18492285809Sscottl    break;
18493285809Sscottl  case SAT_READ_VERIFY_SECTORS_EXT:
18494285809Sscottl    DenomTL = 0xFFFF;
18495285809Sscottl    break;
18496285809Sscottl  default:
18497285809Sscottl    SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18498285809Sscottl    return tiError;
18499285809Sscottl    break;
18500285809Sscottl  }
18501285809Sscottl
18502285809Sscottl  Remainder = satOrgIOContext->OrgTL % DenomTL;
18503285809Sscottl  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18504285809Sscottl  lba = satOrgIOContext->currentLBA;
18505285809Sscottl
18506285809Sscottl  LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18507285809Sscottl  LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18508285809Sscottl  LBA[2] = (bit8)((lba & 0xF0) >> 8);
18509285809Sscottl  LBA[3] = (bit8)(lba & 0xF);               /* LSB */
18510285809Sscottl
18511285809Sscottl  switch (satOrgIOContext->ATACmd)
18512285809Sscottl  {
18513285809Sscottl  case SAT_READ_VERIFY_SECTORS:
18514285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18515285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18516285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
18517285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
18518285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18519285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18520285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18521285809Sscottl
18522285809Sscottl    /* FIS LBA mode set LBA (27:24) */
18523285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18524285809Sscottl
18525285809Sscottl    fis->d.lbaLowExp      = 0;
18526285809Sscottl    fis->d.lbaMidExp      = 0;
18527285809Sscottl    fis->d.lbaHighExp     = 0;
18528285809Sscottl    fis->d.featuresExp    = 0;
18529285809Sscottl    if (satOrgIOContext->LoopNum == 1)
18530285809Sscottl    {
18531285809Sscottl      /* last loop */
18532285809Sscottl      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
18533285809Sscottl    }
18534285809Sscottl    else
18535285809Sscottl    {
18536285809Sscottl      fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
18537285809Sscottl    }
18538285809Sscottl    fis->d.sectorCountExp = 0;
18539285809Sscottl    fis->d.reserved4      = 0;
18540285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
18541285809Sscottl    fis->d.reserved5      = 0;
18542285809Sscottl
18543285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18544285809Sscottl
18545285809Sscottl    break;
18546285809Sscottl  case SAT_READ_VERIFY_SECTORS_EXT:
18547285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18548285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18549285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
18550285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
18551285809Sscottl    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18552285809Sscottl    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18553285809Sscottl    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18554285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set */
18555285809Sscottl    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18556285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18557285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18558285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
18559285809Sscottl    if (satOrgIOContext->LoopNum == 1)
18560285809Sscottl    {
18561285809Sscottl      /* last loop */
18562285809Sscottl      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
18563285809Sscottl      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18564285809Sscottl    }
18565285809Sscottl    else
18566285809Sscottl    {
18567285809Sscottl      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
18568285809Sscottl      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
18569285809Sscottl    }
18570285809Sscottl    fis->d.reserved4      = 0;
18571285809Sscottl    fis->d.control        = 0;                       /* FIS HOB bit clear */
18572285809Sscottl    fis->d.reserved5      = 0;
18573285809Sscottl
18574285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18575285809Sscottl
18576285809Sscottl    break;
18577285809Sscottl
18578285809Sscottl  default:
18579285809Sscottl    SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18580285809Sscottl    return tiError;
18581285809Sscottl    break;
18582285809Sscottl  }
18583285809Sscottl
18584285809Sscottl  /* Initialize CB for SATA completion.
18585285809Sscottl   */
18586285809Sscottl  /* chained data */
18587285809Sscottl  satIOContext->satCompleteCB = &smsatChainedVerifyCB;
18588285809Sscottl
18589285809Sscottl
18590285809Sscottl  /*
18591285809Sscottl   * Prepare SGL and send FIS to LL layer.
18592285809Sscottl   */
18593285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
18594285809Sscottl
18595285809Sscottl  status = smsataLLIOStart( smRoot,
18596285809Sscottl                            smIORequest,
18597285809Sscottl                            smDeviceHandle,
18598285809Sscottl                            smScsiRequest,
18599285809Sscottl                            satIOContext);
18600285809Sscottl
18601285809Sscottl  SM_DBG5(("satChainedVerify: return\n"));
18602285809Sscottl  return (status);
18603285809Sscottl}
18604285809Sscottl
18605285809SscottlosGLOBAL bit32
18606285809SscottlsmsatWriteSame10_1(
18607285809Sscottl                    smRoot_t                  *smRoot,
18608285809Sscottl                    smIORequest_t             *smIORequest,
18609285809Sscottl                    smDeviceHandle_t          *smDeviceHandle,
18610285809Sscottl                    smScsiInitiatorRequest_t  *smScsiRequest,
18611285809Sscottl                    smSatIOContext_t            *satIOContext,
18612285809Sscottl                    bit32                     lba
18613285809Sscottl                  )
18614285809Sscottl{
18615285809Sscottl  /*
18616285809Sscottl    sends SAT_WRITE_DMA_EXT
18617285809Sscottl  */
18618285809Sscottl
18619285809Sscottl  bit32                     status;
18620285809Sscottl  bit32                     agRequestType;
18621285809Sscottl  agsaFisRegHostToDevice_t  *fis;
18622285809Sscottl  bit8                      lba1, lba2 ,lba3, lba4;
18623285809Sscottl
18624285809Sscottl  SM_DBG5(("smsatWriteSame10_1: start\n"));
18625285809Sscottl  fis               = satIOContext->pFis;
18626285809Sscottl  /* MSB */
18627285809Sscottl  lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18628285809Sscottl  lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18629285809Sscottl  lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18630285809Sscottl  /* LSB */
18631285809Sscottl  lba4 = (bit8)(lba & 0x000000FF);
18632285809Sscottl  /* SAT_WRITE_DMA_EXT */
18633285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
18634285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18635285809Sscottl  fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
18636285809Sscottl  fis->h.features       = 0;                      /* FIS reserve */
18637285809Sscottl  fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
18638285809Sscottl  fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
18639285809Sscottl  fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
18640285809Sscottl  fis->d.device         = 0x40;                   /* FIS LBA mode set */
18641285809Sscottl  fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
18642285809Sscottl  fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18643285809Sscottl  fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18644285809Sscottl  fis->d.featuresExp    = 0;                      /* FIS reserve */
18645285809Sscottl  /* one sector at a time */
18646285809Sscottl  fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18647285809Sscottl  fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18648285809Sscottl  fis->d.reserved4      = 0;
18649285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
18650285809Sscottl  fis->d.reserved5      = 0;
18651285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18652285809Sscottl  /* Initialize CB for SATA completion.
18653285809Sscottl   */
18654285809Sscottl  satIOContext->satCompleteCB = &smsatWriteSame10CB;
18655285809Sscottl  /*
18656285809Sscottl   * Prepare SGL and send FIS to LL layer.
18657285809Sscottl   */
18658285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
18659285809Sscottl  status = smsataLLIOStart( smRoot,
18660285809Sscottl                            smIORequest,
18661285809Sscottl                            smDeviceHandle,
18662285809Sscottl                            smScsiRequest,
18663285809Sscottl                            satIOContext);
18664285809Sscottl  SM_DBG5(("smsatWriteSame10_1 return status %d\n", status));
18665285809Sscottl  return status;
18666285809Sscottl}
18667285809Sscottl
18668285809Sscottl
18669285809SscottlosGLOBAL bit32
18670285809SscottlsmsatWriteSame10_2(
18671285809Sscottl                    smRoot_t                  *smRoot,
18672285809Sscottl                    smIORequest_t             *smIORequest,
18673285809Sscottl                    smDeviceHandle_t          *smDeviceHandle,
18674285809Sscottl                    smScsiInitiatorRequest_t  *smScsiRequest,
18675285809Sscottl                    smSatIOContext_t            *satIOContext,
18676285809Sscottl                    bit32                     lba
18677285809Sscottl                  )
18678285809Sscottl{
18679285809Sscottl  /*
18680285809Sscottl    sends SAT_WRITE_SECTORS_EXT
18681285809Sscottl  */
18682285809Sscottl
18683285809Sscottl  bit32                     status;
18684285809Sscottl  bit32                     agRequestType;
18685285809Sscottl  agsaFisRegHostToDevice_t  *fis;
18686285809Sscottl  bit8                      lba1, lba2 ,lba3, lba4;
18687285809Sscottl
18688285809Sscottl  SM_DBG5(("smsatWriteSame10_2: start\n"));
18689285809Sscottl  fis               = satIOContext->pFis;
18690285809Sscottl  /* MSB */
18691285809Sscottl  lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18692285809Sscottl  lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18693285809Sscottl  lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18694285809Sscottl  /* LSB */
18695285809Sscottl  lba4 = (bit8)(lba & 0x000000FF);
18696285809Sscottl  /* SAT_WRITE_SECTORS_EXT */
18697285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
18698285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18699285809Sscottl  fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
18700285809Sscottl  fis->h.features       = 0;                      /* FIS reserve */
18701285809Sscottl  fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
18702285809Sscottl  fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
18703285809Sscottl  fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
18704285809Sscottl  fis->d.device         = 0x40;                   /* FIS LBA mode set */
18705285809Sscottl  fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
18706285809Sscottl  fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18707285809Sscottl  fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18708285809Sscottl  fis->d.featuresExp    = 0;                      /* FIS reserve */
18709285809Sscottl  /* one sector at a time */
18710285809Sscottl  fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18711285809Sscottl  fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18712285809Sscottl  fis->d.reserved4      = 0;
18713285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
18714285809Sscottl  fis->d.reserved5      = 0;
18715285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18716285809Sscottl  /* Initialize CB for SATA completion.
18717285809Sscottl   */
18718285809Sscottl  satIOContext->satCompleteCB = &smsatWriteSame10CB;
18719285809Sscottl  /*
18720285809Sscottl   * Prepare SGL and send FIS to LL layer.
18721285809Sscottl   */
18722285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
18723285809Sscottl  status = smsataLLIOStart( smRoot,
18724285809Sscottl                            smIORequest,
18725285809Sscottl                            smDeviceHandle,
18726285809Sscottl                            smScsiRequest,
18727285809Sscottl                            satIOContext);
18728285809Sscottl  SM_DBG5(("smsatWriteSame10_2 return status %d\n", status));
18729285809Sscottl  return status;
18730285809Sscottl}
18731285809Sscottl
18732285809Sscottl
18733285809SscottlosGLOBAL bit32
18734285809SscottlsmsatWriteSame10_3(
18735285809Sscottl                    smRoot_t                  *smRoot,
18736285809Sscottl                    smIORequest_t             *smIORequest,
18737285809Sscottl                    smDeviceHandle_t          *smDeviceHandle,
18738285809Sscottl                    smScsiInitiatorRequest_t  *smScsiRequest,
18739285809Sscottl                    smSatIOContext_t            *satIOContext,
18740285809Sscottl                    bit32                     lba
18741285809Sscottl                  )
18742285809Sscottl{
18743285809Sscottl  /*
18744285809Sscottl    sends SAT_WRITE_FPDMA_QUEUED
18745285809Sscottl  */
18746285809Sscottl
18747285809Sscottl  bit32                     status;
18748285809Sscottl  bit32                     agRequestType;
18749285809Sscottl  agsaFisRegHostToDevice_t  *fis;
18750285809Sscottl  bit8                      lba1, lba2 ,lba3, lba4;
18751285809Sscottl
18752285809Sscottl  SM_DBG5(("smsatWriteSame10_3: start\n"));
18753285809Sscottl  fis               = satIOContext->pFis;
18754285809Sscottl  /* MSB */
18755285809Sscottl  lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18756285809Sscottl  lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18757285809Sscottl  lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18758285809Sscottl  /* LSB */
18759285809Sscottl  lba4 = (bit8)(lba & 0x000000FF);
18760285809Sscottl
18761285809Sscottl  /* SAT_WRITE_FPDMA_QUEUED */
18762285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
18763285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18764285809Sscottl  fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
18765285809Sscottl
18766285809Sscottl
18767285809Sscottl  /* one sector at a time */
18768285809Sscottl  fis->h.features       = 1;                      /* FIS sector count (7:0) */
18769285809Sscottl  fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
18770285809Sscottl
18771285809Sscottl  fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
18772285809Sscottl  fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
18773285809Sscottl  fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
18774285809Sscottl  /* NO FUA bit in the WRITE SAME 10 */
18775285809Sscottl  fis->d.device         = 0x40;                   /* FIS FUA clear */
18776285809Sscottl  fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
18777285809Sscottl  fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18778285809Sscottl  fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18779285809Sscottl  fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
18780285809Sscottl  fis->d.sectorCountExp = 0;
18781285809Sscottl  fis->d.reserved4      = 0;
18782285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
18783285809Sscottl  fis->d.reserved5      = 0;
18784285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
18785285809Sscottl
18786285809Sscottl  /* Initialize CB for SATA completion.
18787285809Sscottl   */
18788285809Sscottl  satIOContext->satCompleteCB = &smsatWriteSame10CB;
18789285809Sscottl  /*
18790285809Sscottl   * Prepare SGL and send FIS to LL layer.
18791285809Sscottl   */
18792285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
18793285809Sscottl  status = smsataLLIOStart( smRoot,
18794285809Sscottl                            smIORequest,
18795285809Sscottl                            smDeviceHandle,
18796285809Sscottl                            smScsiRequest,
18797285809Sscottl                            satIOContext);
18798285809Sscottl
18799285809Sscottl  SM_DBG5(("smsatWriteSame10_3 return status %d\n", status));
18800285809Sscottl  return status;
18801285809Sscottl}
18802285809Sscottl
18803285809SscottlosGLOBAL bit32
18804285809SscottlsmsatStartStopUnit_1(
18805285809Sscottl                     smRoot_t                  *smRoot,
18806285809Sscottl                     smIORequest_t             *smIORequest,
18807285809Sscottl                     smDeviceHandle_t          *smDeviceHandle,
18808285809Sscottl                     smScsiInitiatorRequest_t  *smScsiRequest,
18809285809Sscottl                     smSatIOContext_t            *satIOContext
18810285809Sscottl        )
18811285809Sscottl{
18812285809Sscottl  /*
18813285809Sscottl    SAT Rev 8, Table 48, 9.11.3 p55
18814285809Sscottl    sends STANDBY
18815285809Sscottl  */
18816285809Sscottl  bit32                     status;
18817285809Sscottl  bit32                     agRequestType;
18818285809Sscottl  agsaFisRegHostToDevice_t  *fis;
18819285809Sscottl
18820285809Sscottl  SM_DBG5(("smsatStartStopUnit_1: start\n"));
18821285809Sscottl  fis               = satIOContext->pFis;
18822285809Sscottl  /* STANDBY */
18823285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
18824285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18825285809Sscottl  fis->h.command        = SAT_STANDBY;            /* 0xE2 */
18826285809Sscottl  fis->h.features       = 0;                      /* FIS features NA       */
18827285809Sscottl  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
18828285809Sscottl  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
18829285809Sscottl  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
18830285809Sscottl  fis->d.lbaLowExp      = 0;
18831285809Sscottl  fis->d.lbaMidExp      = 0;
18832285809Sscottl  fis->d.lbaHighExp     = 0;
18833285809Sscottl  fis->d.featuresExp    = 0;
18834285809Sscottl  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
18835285809Sscottl  fis->d.sectorCountExp = 0;
18836285809Sscottl  fis->d.reserved4      = 0;
18837285809Sscottl  fis->d.device         = 0;                      /* 0 */
18838285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
18839285809Sscottl  fis->d.reserved5      = 0;
18840285809Sscottl
18841285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18842285809Sscottl
18843285809Sscottl  /* Initialize CB for SATA completion.
18844285809Sscottl   */
18845285809Sscottl  satIOContext->satCompleteCB = &smsatStartStopUnitCB;
18846285809Sscottl
18847285809Sscottl  /*
18848285809Sscottl   * Prepare SGL and send FIS to LL layer.
18849285809Sscottl   */
18850285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
18851285809Sscottl
18852285809Sscottl  status = smsataLLIOStart( smRoot,
18853285809Sscottl                            smIORequest,
18854285809Sscottl                            smDeviceHandle,
18855285809Sscottl                            smScsiRequest,
18856285809Sscottl                            satIOContext);
18857285809Sscottl
18858285809Sscottl  SM_DBG5(("smsatStartStopUnit_1 return status %d\n", status));
18859285809Sscottl  return status;
18860285809Sscottl}
18861285809Sscottl
18862285809SscottlosGLOBAL bit32
18863285809SscottlsmsatSendDiagnostic_1(
18864285809Sscottl                      smRoot_t                  *smRoot,
18865285809Sscottl                      smIORequest_t             *smIORequest,
18866285809Sscottl                      smDeviceHandle_t          *smDeviceHandle,
18867285809Sscottl                      smScsiInitiatorRequest_t  *smScsiRequest,
18868285809Sscottl                      smSatIOContext_t            *satIOContext
18869285809Sscottl         )
18870285809Sscottl{
18871285809Sscottl  /*
18872285809Sscottl    SAT Rev9, Table29, p41
18873285809Sscottl    send 2nd SAT_READ_VERIFY_SECTORS(_EXT)
18874285809Sscottl  */
18875285809Sscottl  bit32                     status;
18876285809Sscottl  bit32                     agRequestType;
18877285809Sscottl  smDeviceData_t            *pSatDevData;
18878285809Sscottl  agsaFisRegHostToDevice_t  *fis;
18879285809Sscottl
18880285809Sscottl  SM_DBG5(("smsatSendDiagnostic_1: start\n"));
18881285809Sscottl  pSatDevData       = satIOContext->pSatDevData;
18882285809Sscottl  fis               = satIOContext->pFis;
18883285809Sscottl  /*
18884285809Sscottl    sector count 1, LBA MAX
18885285809Sscottl  */
18886285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
18887285809Sscottl  {
18888285809Sscottl    /* sends READ VERIFY SECTOR(S) EXT*/
18889285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18890285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18891285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
18892285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
18893285809Sscottl    fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
18894285809Sscottl    fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
18895285809Sscottl    fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
18896285809Sscottl    fis->d.lbaLowExp      = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */
18897285809Sscottl    fis->d.lbaMidExp      = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */
18898285809Sscottl    fis->d.lbaHighExp     = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */
18899285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
18900285809Sscottl    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18901285809Sscottl    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18902285809Sscottl    fis->d.reserved4      = 0;
18903285809Sscottl    fis->d.device         = 0x40;                   /* 01000000 */
18904285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
18905285809Sscottl    fis->d.reserved5      = 0;
18906285809Sscottl
18907285809Sscottl  }
18908285809Sscottl  else
18909285809Sscottl  {
18910285809Sscottl    /* READ VERIFY SECTOR(S)*/
18911285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18912285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18913285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
18914285809Sscottl    fis->h.features       = 0;                      /* FIS features NA       */
18915285809Sscottl    fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
18916285809Sscottl    fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
18917285809Sscottl    fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
18918285809Sscottl    fis->d.lbaLowExp      = 0;
18919285809Sscottl    fis->d.lbaMidExp      = 0;
18920285809Sscottl    fis->d.lbaHighExp     = 0;
18921285809Sscottl    fis->d.featuresExp    = 0;
18922285809Sscottl    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18923285809Sscottl    fis->d.sectorCountExp = 0;
18924285809Sscottl    fis->d.reserved4      = 0;
18925285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF));
18926285809Sscottl                            /* DEV and LBA 27:24 */
18927285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
18928285809Sscottl    fis->d.reserved5      = 0;
18929285809Sscottl
18930285809Sscottl  }
18931285809Sscottl
18932285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18933285809Sscottl
18934285809Sscottl  /* Initialize CB for SATA completion.
18935285809Sscottl   */
18936285809Sscottl  satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
18937285809Sscottl
18938285809Sscottl  /*
18939285809Sscottl   * Prepare SGL and send FIS to LL layer.
18940285809Sscottl   */
18941285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
18942285809Sscottl
18943285809Sscottl  status = smsataLLIOStart( smRoot,
18944285809Sscottl                            smIORequest,
18945285809Sscottl                            smDeviceHandle,
18946285809Sscottl                            smScsiRequest,
18947285809Sscottl                            satIOContext);
18948285809Sscottl
18949285809Sscottl
18950285809Sscottl  return status;
18951285809Sscottl}
18952285809Sscottl
18953285809SscottlosGLOBAL bit32
18954285809SscottlsmsatSendDiagnostic_2(
18955285809Sscottl                      smRoot_t                  *smRoot,
18956285809Sscottl                      smIORequest_t             *smIORequest,
18957285809Sscottl                      smDeviceHandle_t          *smDeviceHandle,
18958285809Sscottl                      smScsiInitiatorRequest_t  *smScsiRequest,
18959285809Sscottl                      smSatIOContext_t            *satIOContext
18960285809Sscottl         )
18961285809Sscottl{
18962285809Sscottl  /*
18963285809Sscottl    SAT Rev9, Table29, p41
18964285809Sscottl    send 3rd SAT_READ_VERIFY_SECTORS(_EXT)
18965285809Sscottl  */
18966285809Sscottl  bit32                     status;
18967285809Sscottl  bit32                     agRequestType;
18968285809Sscottl  smDeviceData_t            *pSatDevData;
18969285809Sscottl  agsaFisRegHostToDevice_t  *fis;
18970285809Sscottl
18971285809Sscottl  SM_DBG5(("smsatSendDiagnostic_2: start\n"));
18972285809Sscottl
18973285809Sscottl  pSatDevData       = satIOContext->pSatDevData;
18974285809Sscottl  fis               = satIOContext->pFis;
18975285809Sscottl  /*
18976285809Sscottl    sector count 1, LBA Random
18977285809Sscottl  */
18978285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
18979285809Sscottl  {
18980285809Sscottl    /* sends READ VERIFY SECTOR(S) EXT*/
18981285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
18982285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18983285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
18984285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
18985285809Sscottl    fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
18986285809Sscottl    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
18987285809Sscottl    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
18988285809Sscottl    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
18989285809Sscottl    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18990285809Sscottl    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18991285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
18992285809Sscottl    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18993285809Sscottl    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18994285809Sscottl    fis->d.reserved4      = 0;
18995285809Sscottl    fis->d.device         = 0x40;                   /* 01000000 */
18996285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
18997285809Sscottl    fis->d.reserved5      = 0;
18998285809Sscottl
18999285809Sscottl  }
19000285809Sscottl  else
19001285809Sscottl  {
19002285809Sscottl    /* READ VERIFY SECTOR(S)*/
19003285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
19004285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19005285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
19006285809Sscottl    fis->h.features       = 0;                      /* FIS features NA       */
19007285809Sscottl    fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
19008285809Sscottl    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19009285809Sscottl    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19010285809Sscottl    fis->d.lbaLowExp      = 0;
19011285809Sscottl    fis->d.lbaMidExp      = 0;
19012285809Sscottl    fis->d.lbaHighExp     = 0;
19013285809Sscottl    fis->d.featuresExp    = 0;
19014285809Sscottl    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19015285809Sscottl    fis->d.sectorCountExp = 0;
19016285809Sscottl    fis->d.reserved4      = 0;
19017285809Sscottl    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
19018285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
19019285809Sscottl    fis->d.reserved5      = 0;
19020285809Sscottl
19021285809Sscottl  }
19022285809Sscottl
19023285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19024285809Sscottl
19025285809Sscottl  /* Initialize CB for SATA completion.
19026285809Sscottl   */
19027285809Sscottl  satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
19028285809Sscottl
19029285809Sscottl  /*
19030285809Sscottl   * Prepare SGL and send FIS to LL layer.
19031285809Sscottl   */
19032285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
19033285809Sscottl
19034285809Sscottl  status = smsataLLIOStart( smRoot,
19035285809Sscottl                            smIORequest,
19036285809Sscottl                            smDeviceHandle,
19037285809Sscottl                            smScsiRequest,
19038285809Sscottl                            satIOContext);
19039285809Sscottl
19040285809Sscottl
19041285809Sscottl  return status;
19042285809Sscottl}
19043285809Sscottl
19044285809SscottlosGLOBAL bit32
19045285809SscottlsmsatModeSelect6n10_1(
19046285809Sscottl                      smRoot_t                  *smRoot,
19047285809Sscottl                      smIORequest_t             *smIORequest,
19048285809Sscottl                      smDeviceHandle_t          *smDeviceHandle,
19049285809Sscottl                      smScsiInitiatorRequest_t  *smScsiRequest,
19050285809Sscottl                      smSatIOContext_t            *satIOContext
19051285809Sscottl         )
19052285809Sscottl{
19053285809Sscottl  /* sends either ATA SET FEATURES based on DRA bit */
19054285809Sscottl  bit32                     status;
19055285809Sscottl  bit32                     agRequestType;
19056285809Sscottl  agsaFisRegHostToDevice_t  *fis;
19057285809Sscottl  bit8                      *pLogPage;    /* Log Page data buffer */
19058285809Sscottl  bit32                     StartingIndex = 0;
19059285809Sscottl
19060285809Sscottl  fis           = satIOContext->pFis;
19061285809Sscottl  pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
19062285809Sscottl  SM_DBG5(("smsatModeSelect6n10_1: start\n"));
19063285809Sscottl
19064285809Sscottl  if (pLogPage[3] == 8)
19065285809Sscottl  {
19066285809Sscottl    /* mode parameter block descriptor exists */
19067285809Sscottl    StartingIndex = 12;
19068285809Sscottl  }
19069285809Sscottl  else
19070285809Sscottl  {
19071285809Sscottl    /* mode parameter block descriptor does not exist */
19072285809Sscottl    StartingIndex = 4;
19073285809Sscottl  }
19074285809Sscottl
19075285809Sscottl  /* sends ATA SET FEATURES based on DRA bit */
19076285809Sscottl  if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
19077285809Sscottl  {
19078285809Sscottl    SM_DBG5(("smsatModeSelect6n10_1: enable read look-ahead feature\n"));
19079285809Sscottl    /* sends SET FEATURES */
19080285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
19081285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19082285809Sscottl
19083285809Sscottl    fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19084285809Sscottl    fis->h.features       = 0xAA;                   /* enable read look-ahead */
19085285809Sscottl    fis->d.lbaLow         = 0;                      /* */
19086285809Sscottl    fis->d.lbaMid         = 0;                      /* */
19087285809Sscottl    fis->d.lbaHigh        = 0;                      /* */
19088285809Sscottl    fis->d.device         = 0;                      /* */
19089285809Sscottl    fis->d.lbaLowExp      = 0;                      /* */
19090285809Sscottl    fis->d.lbaMidExp      = 0;                      /* */
19091285809Sscottl    fis->d.lbaHighExp     = 0;                      /* */
19092285809Sscottl    fis->d.featuresExp    = 0;                      /* */
19093285809Sscottl    fis->d.sectorCount    = 0;                      /* */
19094285809Sscottl    fis->d.sectorCountExp = 0;                      /* */
19095285809Sscottl    fis->d.reserved4      = 0;
19096285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
19097285809Sscottl    fis->d.reserved5      = 0;
19098285809Sscottl
19099285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19100285809Sscottl
19101285809Sscottl    /* Initialize CB for SATA completion.
19102285809Sscottl     */
19103285809Sscottl    satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
19104285809Sscottl
19105285809Sscottl    /*
19106285809Sscottl     * Prepare SGL and send FIS to LL layer.
19107285809Sscottl     */
19108285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
19109285809Sscottl
19110285809Sscottl  status = smsataLLIOStart( smRoot,
19111285809Sscottl                            smIORequest,
19112285809Sscottl                            smDeviceHandle,
19113285809Sscottl                            smScsiRequest,
19114285809Sscottl                            satIOContext);
19115285809Sscottl    return status;
19116285809Sscottl  }
19117285809Sscottl  else
19118285809Sscottl  {
19119285809Sscottl    SM_DBG5(("smsatModeSelect6n10_1: disable read look-ahead feature\n"));
19120285809Sscottl        /* sends SET FEATURES */
19121285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
19122285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19123285809Sscottl
19124285809Sscottl    fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19125285809Sscottl    fis->h.features       = 0x55;                   /* disable read look-ahead */
19126285809Sscottl    fis->d.lbaLow         = 0;                      /* */
19127285809Sscottl    fis->d.lbaMid         = 0;                      /* */
19128285809Sscottl    fis->d.lbaHigh        = 0;                      /* */
19129285809Sscottl    fis->d.device         = 0;                      /* */
19130285809Sscottl    fis->d.lbaLowExp      = 0;                      /* */
19131285809Sscottl    fis->d.lbaMidExp      = 0;                      /* */
19132285809Sscottl    fis->d.lbaHighExp     = 0;                      /* */
19133285809Sscottl    fis->d.featuresExp    = 0;                      /* */
19134285809Sscottl    fis->d.sectorCount    = 0;                      /* */
19135285809Sscottl    fis->d.sectorCountExp = 0;                      /* */
19136285809Sscottl    fis->d.reserved4      = 0;
19137285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
19138285809Sscottl    fis->d.reserved5      = 0;
19139285809Sscottl
19140285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19141285809Sscottl
19142285809Sscottl    /* Initialize CB for SATA completion.
19143285809Sscottl     */
19144285809Sscottl    satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
19145285809Sscottl
19146285809Sscottl    /*
19147285809Sscottl     * Prepare SGL and send FIS to LL layer.
19148285809Sscottl     */
19149285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
19150285809Sscottl
19151285809Sscottl  status = smsataLLIOStart( smRoot,
19152285809Sscottl                            smIORequest,
19153285809Sscottl                            smDeviceHandle,
19154285809Sscottl                            smScsiRequest,
19155285809Sscottl                            satIOContext);
19156285809Sscottl    return status;
19157285809Sscottl  }
19158285809Sscottl}
19159285809Sscottl
19160285809Sscottl
19161285809SscottlosGLOBAL bit32
19162285809SscottlsmsatLogSense_1(
19163285809Sscottl                smRoot_t                  *smRoot,
19164285809Sscottl                smIORequest_t             *smIORequest,
19165285809Sscottl                smDeviceHandle_t          *smDeviceHandle,
19166285809Sscottl                smScsiInitiatorRequest_t  *smScsiRequest,
19167285809Sscottl                smSatIOContext_t            *satIOContext
19168285809Sscottl               )
19169285809Sscottl{
19170285809Sscottl  bit32                     status;
19171285809Sscottl  bit32                     agRequestType;
19172285809Sscottl  smDeviceData_t            *pSatDevData;
19173285809Sscottl  agsaFisRegHostToDevice_t  *fis;
19174285809Sscottl
19175285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
19176285809Sscottl  fis           = satIOContext->pFis;
19177285809Sscottl
19178285809Sscottl  SM_DBG5(("smsatLogSense_1: start\n"));
19179285809Sscottl
19180285809Sscottl  /* SAT Rev 8, 10.2.4 p74 */
19181285809Sscottl  if ( pSatDevData->sat48BitSupport == agTRUE )
19182285809Sscottl  {
19183285809Sscottl    SM_DBG5(("smsatLogSense_1: case 2-1 sends READ LOG EXT\n"));
19184285809Sscottl    /* sends READ LOG EXT */
19185285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
19186285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19187285809Sscottl
19188285809Sscottl    fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
19189285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
19190285809Sscottl    fis->d.lbaLow         = 0x07;                   /* 0x07 */
19191285809Sscottl    fis->d.lbaMid         = 0;                      /*  */
19192285809Sscottl    fis->d.lbaHigh        = 0;                      /*  */
19193285809Sscottl    fis->d.device         = 0;                      /*  */
19194285809Sscottl    fis->d.lbaLowExp      = 0;                      /*  */
19195285809Sscottl    fis->d.lbaMidExp      = 0;                      /*  */
19196285809Sscottl    fis->d.lbaHighExp     = 0;                      /*  */
19197285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
19198285809Sscottl    fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
19199285809Sscottl    fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
19200285809Sscottl    fis->d.reserved4      = 0;
19201285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
19202285809Sscottl    fis->d.reserved5      = 0;
19203285809Sscottl
19204285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19205285809Sscottl
19206285809Sscottl    /* Initialize CB for SATA completion.
19207285809Sscottl     */
19208285809Sscottl    satIOContext->satCompleteCB = &smsatLogSenseCB;
19209285809Sscottl
19210285809Sscottl    /*
19211285809Sscottl     * Prepare SGL and send FIS to LL layer.
19212285809Sscottl     */
19213285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
19214285809Sscottl
19215285809Sscottl  status = smsataLLIOStart( smRoot,
19216285809Sscottl                            smIORequest,
19217285809Sscottl                            smDeviceHandle,
19218285809Sscottl                            smScsiRequest,
19219285809Sscottl                            satIOContext);
19220285809Sscottl    return status;
19221285809Sscottl
19222285809Sscottl  }
19223285809Sscottl  else
19224285809Sscottl  {
19225285809Sscottl    SM_DBG5(("smsatLogSense_1: case 2-2 sends SMART READ LOG\n"));
19226285809Sscottl    /* sends SMART READ LOG */
19227285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
19228285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19229285809Sscottl
19230285809Sscottl    fis->h.command        = SAT_SMART;              /* 0x2F */
19231285809Sscottl    fis->h.features       = SAT_SMART_READ_LOG;     /* 0xd5 */
19232285809Sscottl    fis->d.lbaLow         = 0x06;                   /* 0x06 */
19233285809Sscottl    fis->d.lbaMid         = 0x00;                   /* 0x4f */
19234285809Sscottl    fis->d.lbaHigh        = 0x00;                   /* 0xc2 */
19235285809Sscottl    fis->d.device         = 0;                      /*  */
19236285809Sscottl    fis->d.lbaLowExp      = 0;                      /*  */
19237285809Sscottl    fis->d.lbaMidExp      = 0;                      /*  */
19238285809Sscottl    fis->d.lbaHighExp     = 0;                      /*  */
19239285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
19240285809Sscottl    fis->d.sectorCount    = 0x01;                      /*  */
19241285809Sscottl    fis->d.sectorCountExp = 0x00;                      /*  */
19242285809Sscottl    fis->d.reserved4      = 0;
19243285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
19244285809Sscottl    fis->d.reserved5      = 0;
19245285809Sscottl
19246285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19247285809Sscottl
19248285809Sscottl    /* Initialize CB for SATA completion.
19249285809Sscottl     */
19250285809Sscottl    satIOContext->satCompleteCB = &smsatLogSenseCB;
19251285809Sscottl
19252285809Sscottl    /*
19253285809Sscottl     * Prepare SGL and send FIS to LL layer.
19254285809Sscottl     */
19255285809Sscottl    satIOContext->reqType = agRequestType;       /* Save it */
19256285809Sscottl
19257285809Sscottl  status = smsataLLIOStart( smRoot,
19258285809Sscottl                            smIORequest,
19259285809Sscottl                            smDeviceHandle,
19260285809Sscottl                            smScsiRequest,
19261285809Sscottl                            satIOContext);
19262285809Sscottl    return status;
19263285809Sscottl
19264285809Sscottl  }
19265285809Sscottl}
19266285809Sscottl
19267285809SscottlosGLOBAL bit32
19268285809SscottlsmsatReassignBlocks_2(
19269285809Sscottl                      smRoot_t                  *smRoot,
19270285809Sscottl                      smIORequest_t             *smIORequest,
19271285809Sscottl                      smDeviceHandle_t          *smDeviceHandle,
19272285809Sscottl                      smScsiInitiatorRequest_t  *smScsiRequest,
19273285809Sscottl                      smSatIOContext_t            *satIOContext,
19274285809Sscottl                      bit8                      *LBA
19275285809Sscottl                     )
19276285809Sscottl{
19277285809Sscottl  /*
19278285809Sscottl    assumes all LBA fits in ATA command; no boundary condition is checked here yet
19279285809Sscottl    tiScsiRequest is TD generated for writing
19280285809Sscottl  */
19281285809Sscottl  bit32                     status;
19282285809Sscottl  bit32                     agRequestType;
19283285809Sscottl  smDeviceData_t            *pSatDevData;
19284285809Sscottl  smScsiRspSense_t          *pSense;
19285285809Sscottl  agsaFisRegHostToDevice_t  *fis;
19286285809Sscottl
19287285809Sscottl  pSense        = satIOContext->pSense;
19288285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
19289285809Sscottl  fis           = satIOContext->pFis;
19290285809Sscottl  SM_DBG5(("smsatReassignBlocks_2: start\n"));
19291285809Sscottl
19292285809Sscottl  if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
19293285809Sscottl  {
19294285809Sscottl    /* case 2 */
19295285809Sscottl    /* WRITE DMA*/
19296285809Sscottl    /* can't fit the transfer length */
19297285809Sscottl    SM_DBG5(("smsatReassignBlocks_2: case 2\n"));
19298285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
19299285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
19300285809Sscottl    fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
19301285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
19302285809Sscottl    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19303285809Sscottl    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19304285809Sscottl    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19305285809Sscottl
19306285809Sscottl    /* FIS LBA mode set LBA (27:24) */
19307285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19308285809Sscottl
19309285809Sscottl    fis->d.lbaLowExp      = 0;
19310285809Sscottl    fis->d.lbaMidExp      = 0;
19311285809Sscottl    fis->d.lbaHighExp     = 0;
19312285809Sscottl    fis->d.featuresExp    = 0;
19313285809Sscottl    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19314285809Sscottl    fis->d.sectorCountExp = 0;
19315285809Sscottl    fis->d.reserved4      = 0;
19316285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
19317285809Sscottl    fis->d.reserved5      = 0;
19318285809Sscottl
19319285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
19320285809Sscottl    satIOContext->ATACmd = SAT_WRITE_DMA;
19321285809Sscottl  }
19322285809Sscottl  else
19323285809Sscottl  {
19324285809Sscottl    /* case 1 */
19325285809Sscottl    /* WRITE MULTIPLE or WRITE SECTOR(S) */
19326285809Sscottl    /* WRITE SECTORS for easier implemetation */
19327285809Sscottl    /* can't fit the transfer length */
19328285809Sscottl    SM_DBG5(("smsatReassignBlocks_2: case 1\n"));
19329285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
19330285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
19331285809Sscottl    fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
19332285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
19333285809Sscottl    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19334285809Sscottl    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19335285809Sscottl    fis->d.lbaHigh        = LBA[7];                 /* FIS LBA (23:16) */
19336285809Sscottl
19337285809Sscottl    /* FIS LBA mode set LBA (27:24) */
19338285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19339285809Sscottl
19340285809Sscottl    fis->d.lbaLowExp      = 0;
19341285809Sscottl    fis->d.lbaMidExp      = 0;
19342285809Sscottl    fis->d.lbaHighExp     = 0;
19343285809Sscottl    fis->d.featuresExp    = 0;
19344285809Sscottl    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19345285809Sscottl    fis->d.sectorCountExp = 0;
19346285809Sscottl    fis->d.reserved4      = 0;
19347285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
19348285809Sscottl    fis->d.reserved5      = 0;
19349285809Sscottl
19350285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
19351285809Sscottl    satIOContext->ATACmd = SAT_WRITE_SECTORS;
19352285809Sscottl  }
19353285809Sscottl
19354285809Sscottl  /* case 3 and 4 */
19355285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
19356285809Sscottl  {
19357285809Sscottl    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
19358285809Sscottl    {
19359285809Sscottl      /* case 3 */
19360285809Sscottl      /* WRITE DMA EXT or WRITE DMA FUA EXT */
19361285809Sscottl      SM_DBG5(("smsatReassignBlocks_2: case 3\n"));
19362285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
19363285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19364285809Sscottl
19365285809Sscottl      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
19366285809Sscottl      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
19367285809Sscottl      satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
19368285809Sscottl
19369285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
19370285809Sscottl      fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19371285809Sscottl      fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19372285809Sscottl      fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19373285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
19374285809Sscottl      fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19375285809Sscottl      fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19376285809Sscottl      fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19377285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
19378285809Sscottl      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19379285809Sscottl      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
19380285809Sscottl      fis->d.reserved4      = 0;
19381285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
19382285809Sscottl      fis->d.reserved5      = 0;
19383285809Sscottl
19384285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
19385285809Sscottl    }
19386285809Sscottl    else
19387285809Sscottl    {
19388285809Sscottl      /* case 4 */
19389285809Sscottl      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
19390285809Sscottl      /* WRITE SECTORS EXT for easier implemetation */
19391285809Sscottl      SM_DBG5(("smsatReassignBlocks_2: case 4\n"));
19392285809Sscottl      fis->h.fisType        = 0x27;                   /* Reg host to device */
19393285809Sscottl      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19394285809Sscottl      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
19395285809Sscottl
19396285809Sscottl      fis->h.features       = 0;                      /* FIS reserve */
19397285809Sscottl      fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19398285809Sscottl      fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19399285809Sscottl      fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19400285809Sscottl      fis->d.device         = 0x40;                   /* FIS LBA mode set */
19401285809Sscottl      fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19402285809Sscottl      fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19403285809Sscottl      fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19404285809Sscottl      fis->d.featuresExp    = 0;                      /* FIS reserve */
19405285809Sscottl      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19406285809Sscottl      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
19407285809Sscottl      fis->d.reserved4      = 0;
19408285809Sscottl      fis->d.control        = 0;                      /* FIS HOB bit clear */
19409285809Sscottl      fis->d.reserved5      = 0;
19410285809Sscottl
19411285809Sscottl      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
19412285809Sscottl      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
19413285809Sscottl    }
19414285809Sscottl  }
19415285809Sscottl  /* case 5 */
19416285809Sscottl  if (pSatDevData->satNCQ == agTRUE)
19417285809Sscottl  {
19418285809Sscottl    /* WRITE FPDMA QUEUED */
19419285809Sscottl    if (pSatDevData->sat48BitSupport != agTRUE)
19420285809Sscottl    {
19421285809Sscottl      SM_DBG5(("smsatReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
19422285809Sscottl      smsatSetSensePayload( pSense,
19423285809Sscottl                            SCSI_SNSKEY_HARDWARE_ERROR,
19424285809Sscottl                            0,
19425285809Sscottl                            SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
19426285809Sscottl                            satIOContext);
19427285809Sscottl
19428285809Sscottl      /*smEnqueueIO(smRoot, satIOContext);*/
19429285809Sscottl
19430285809Sscottl      tdsmIOCompletedCB( smRoot,
19431285809Sscottl                         smIORequest,
19432285809Sscottl                         smIOSuccess,
19433285809Sscottl                         SCSI_STAT_CHECK_CONDITION,
19434285809Sscottl                         satIOContext->pSmSenseData,
19435285809Sscottl                         satIOContext->interruptContext );
19436285809Sscottl      return SM_RC_SUCCESS;
19437285809Sscottl    }
19438285809Sscottl    SM_DBG6(("satWrite10: case 5\n"));
19439285809Sscottl
19440285809Sscottl    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
19441285809Sscottl
19442285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
19443285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19444285809Sscottl    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
19445285809Sscottl    fis->h.features       = 1;                      /* FIS sector count (7:0) */
19446285809Sscottl    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19447285809Sscottl    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19448285809Sscottl    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19449285809Sscottl
19450285809Sscottl    /* Check FUA bit */
19451285809Sscottl    fis->d.device       = 0x40;                     /* FIS FUA clear */
19452285809Sscottl
19453285809Sscottl    fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19454285809Sscottl    fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19455285809Sscottl    fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19456285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
19457285809Sscottl    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
19458285809Sscottl    fis->d.sectorCountExp = 0;
19459285809Sscottl    fis->d.reserved4      = 0;
19460285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
19461285809Sscottl    fis->d.reserved5      = 0;
19462285809Sscottl
19463285809Sscottl    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
19464285809Sscottl    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
19465285809Sscottl  }
19466285809Sscottl
19467285809Sscottl  satIOContext->satCompleteCB = &smsatReassignBlocksCB;
19468285809Sscottl
19469285809Sscottl  /*
19470285809Sscottl   * Prepare SGL and send FIS to LL layer.
19471285809Sscottl   */
19472285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
19473285809Sscottl
19474285809Sscottl  status = smsataLLIOStart( smRoot,
19475285809Sscottl                            smIORequest,
19476285809Sscottl                            smDeviceHandle,
19477285809Sscottl                            /* not the original, should be the TD generated one */
19478285809Sscottl                            smScsiRequest,
19479285809Sscottl                            satIOContext);
19480285809Sscottl  return (status);
19481285809Sscottl}
19482285809Sscottl
19483285809SscottlosGLOBAL bit32
19484285809SscottlsmsatReassignBlocks_1(
19485285809Sscottl                      smRoot_t                  *smRoot,
19486285809Sscottl                      smIORequest_t             *smIORequest,
19487285809Sscottl                      smDeviceHandle_t          *smDeviceHandle,
19488285809Sscottl                      smScsiInitiatorRequest_t  *smScsiRequest,
19489285809Sscottl                      smSatIOContext_t            *satIOContext,
19490285809Sscottl                      smSatIOContext_t            *satOrgIOContext
19491285809Sscottl                     )
19492285809Sscottl{
19493285809Sscottl  /*
19494285809Sscottl    assumes all LBA fits in ATA command; no boundary condition is checked here yet
19495285809Sscottl    tiScsiRequest is OS generated; needs for accessing parameter list
19496285809Sscottl  */
19497285809Sscottl  bit32                     agRequestType;
19498285809Sscottl  smDeviceData_t            *pSatDevData;
19499285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
19500285809Sscottl  agsaFisRegHostToDevice_t  *fis;
19501285809Sscottl  bit8                      *pParmList;    /* Log Page data buffer */
19502285809Sscottl  bit8                      LongLBA;
19503285809Sscottl  bit8                      LBA[8];
19504285809Sscottl  bit32                     startingIndex;
19505285809Sscottl
19506285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
19507285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
19508285809Sscottl  fis           = satIOContext->pFis;
19509285809Sscottl  pParmList     = (bit8 *) smScsiRequest->sglVirtualAddr;
19510285809Sscottl  SM_DBG5(("smsatReassignBlocks_1: start\n"));
19511285809Sscottl  LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
19512285809Sscottl  sm_memset(LBA, 0, sizeof(LBA));
19513285809Sscottl  startingIndex = satOrgIOContext->ParmIndex;
19514285809Sscottl  if (LongLBA == 0)
19515285809Sscottl  {
19516285809Sscottl    LBA[4] = pParmList[startingIndex];
19517285809Sscottl    LBA[5] = pParmList[startingIndex+1];
19518285809Sscottl    LBA[6] = pParmList[startingIndex+2];
19519285809Sscottl    LBA[7] = pParmList[startingIndex+3];
19520285809Sscottl    startingIndex = startingIndex + 4;
19521285809Sscottl  }
19522285809Sscottl  else
19523285809Sscottl  {
19524285809Sscottl    LBA[0] = pParmList[startingIndex];
19525285809Sscottl    LBA[1] = pParmList[startingIndex+1];
19526285809Sscottl    LBA[2] = pParmList[startingIndex+2];
19527285809Sscottl    LBA[3] = pParmList[startingIndex+3];
19528285809Sscottl    LBA[4] = pParmList[startingIndex+4];
19529285809Sscottl    LBA[5] = pParmList[startingIndex+5];
19530285809Sscottl    LBA[6] = pParmList[startingIndex+6];
19531285809Sscottl    LBA[7] = pParmList[startingIndex+7];
19532285809Sscottl    startingIndex = startingIndex + 8;
19533285809Sscottl  }
19534285809Sscottl
19535285809Sscottl  if (pSatDevData->sat48BitSupport == agTRUE)
19536285809Sscottl  {
19537285809Sscottl    /* sends READ VERIFY SECTOR(S) EXT*/
19538285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
19539285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19540285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
19541285809Sscottl    fis->h.features       = 0;                      /* FIS reserve */
19542285809Sscottl    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19543285809Sscottl    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19544285809Sscottl    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19545285809Sscottl    fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19546285809Sscottl    fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19547285809Sscottl    fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19548285809Sscottl    fis->d.featuresExp    = 0;                      /* FIS reserve */
19549285809Sscottl    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19550285809Sscottl    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
19551285809Sscottl    fis->d.reserved4      = 0;
19552285809Sscottl    fis->d.device         = 0x40;                   /* 01000000 */
19553285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
19554285809Sscottl    fis->d.reserved5      = 0;
19555285809Sscottl  }
19556285809Sscottl  else
19557285809Sscottl  {
19558285809Sscottl    /* READ VERIFY SECTOR(S)*/
19559285809Sscottl    fis->h.fisType        = 0x27;                   /* Reg host to device */
19560285809Sscottl    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19561285809Sscottl    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
19562285809Sscottl    fis->h.features       = 0;                      /* FIS features NA       */
19563285809Sscottl    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19564285809Sscottl    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19565285809Sscottl    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19566285809Sscottl    fis->d.lbaLowExp      = 0;
19567285809Sscottl    fis->d.lbaMidExp      = 0;
19568285809Sscottl    fis->d.lbaHighExp     = 0;
19569285809Sscottl    fis->d.featuresExp    = 0;
19570285809Sscottl    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19571285809Sscottl    fis->d.sectorCountExp = 0;
19572285809Sscottl    fis->d.reserved4      = 0;
19573285809Sscottl    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19574285809Sscottl                            /* DEV and LBA 27:24 */
19575285809Sscottl    fis->d.control        = 0;                      /* FIS HOB bit clear */
19576285809Sscottl    fis->d.reserved5      = 0;
19577285809Sscottl  }
19578285809Sscottl
19579285809Sscottl  sm_memcpy(satOrgIOContext->LBA, LBA, 8);
19580285809Sscottl  satOrgIOContext->ParmIndex = startingIndex;
19581285809Sscottl
19582285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19583285809Sscottl
19584285809Sscottl  /* Initialize CB for SATA completion.
19585285809Sscottl   */
19586285809Sscottl  satIOContext->satCompleteCB = &smsatReassignBlocksCB;
19587285809Sscottl
19588285809Sscottl  /*
19589285809Sscottl   * Prepare SGL and send FIS to LL layer.
19590285809Sscottl   */
19591285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
19592285809Sscottl
19593285809Sscottl  smsataLLIOStart( smRoot,
19594285809Sscottl                            smIORequest,
19595285809Sscottl                            smDeviceHandle,
19596285809Sscottl                            smScsiRequest,
19597285809Sscottl                            satIOContext);
19598285809Sscottl
19599285809Sscottl  return SM_RC_SUCCESS;
19600285809Sscottl}
19601285809Sscottl
19602285809SscottlosGLOBAL bit32
19603285809SscottlsmsatSendReadLogExt(
19604285809Sscottl                     smRoot_t                  *smRoot,
19605285809Sscottl                     smIORequest_t             *smIORequest,
19606285809Sscottl                     smDeviceHandle_t          *smDeviceHandle,
19607285809Sscottl                     smScsiInitiatorRequest_t  *smScsiRequest,
19608285809Sscottl                     smSatIOContext_t            *satIOContext
19609285809Sscottl       )
19610285809Sscottl{
19611285809Sscottl  bit32                     status;
19612285809Sscottl  bit32                     agRequestType;
19613285809Sscottl  agsaFisRegHostToDevice_t  *fis;
19614285809Sscottl
19615285809Sscottl  fis           = satIOContext->pFis;
19616285809Sscottl  SM_DBG1(("smsatSendReadLogExt: start\n"));
19617285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
19618285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19619285809Sscottl  fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
19620285809Sscottl  fis->h.features       = 0;                      /* FIS reserve */
19621285809Sscottl  fis->d.lbaLow         = 0x10;                   /* Page number */
19622285809Sscottl  fis->d.lbaMid         = 0;                      /*  */
19623285809Sscottl  fis->d.lbaHigh        = 0;                      /*  */
19624285809Sscottl  fis->d.device         = 0;                      /* DEV is ignored in SATA */
19625285809Sscottl  fis->d.lbaLowExp      = 0;                      /*  */
19626285809Sscottl  fis->d.lbaMidExp      = 0;                      /*  */
19627285809Sscottl  fis->d.lbaHighExp     = 0;                      /*  */
19628285809Sscottl  fis->d.featuresExp    = 0;                      /* FIS reserve */
19629285809Sscottl  fis->d.sectorCount    = 0x01;                   /*  1 sector counts*/
19630285809Sscottl  fis->d.sectorCountExp = 0x00;                   /*  1 sector counts */
19631285809Sscottl  fis->d.reserved4      = 0;
19632285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
19633285809Sscottl  fis->d.reserved5      = 0;
19634285809Sscottl
19635285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19636285809Sscottl
19637285809Sscottl  /* Initialize CB for SATA completion.
19638285809Sscottl   */
19639285809Sscottl  satIOContext->satCompleteCB = &smsatReadLogExtCB;
19640285809Sscottl
19641285809Sscottl  /*
19642285809Sscottl   * Prepare SGL and send FIS to LL layer.
19643285809Sscottl   */
19644285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
19645285809Sscottl
19646285809Sscottl  status = smsataLLIOStart( smRoot,
19647285809Sscottl                            smIORequest,
19648285809Sscottl                            smDeviceHandle,
19649285809Sscottl                            smScsiRequest,
19650285809Sscottl                            satIOContext);
19651285809Sscottl
19652285809Sscottl  SM_DBG1(("smsatSendReadLogExt: end status %d!!!\n", status));
19653285809Sscottl
19654285809Sscottl  return (status);
19655285809Sscottl}
19656285809Sscottl
19657285809SscottlosGLOBAL bit32
19658285809SscottlsmsatCheckPowerMode(
19659285809Sscottl                     smRoot_t                  *smRoot,
19660285809Sscottl                     smIORequest_t             *smIORequest,
19661285809Sscottl                     smDeviceHandle_t          *smDeviceHandle,
19662285809Sscottl                     smScsiInitiatorRequest_t  *smScsiRequest,
19663285809Sscottl                     smSatIOContext_t          *satIOContext
19664285809Sscottl       )
19665285809Sscottl{
19666285809Sscottl  /*
19667285809Sscottl    sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands
19668285809Sscottl    internally generated - no directly corresponding scsi
19669285809Sscottl  */
19670285809Sscottl  bit32                     status;
19671285809Sscottl  bit32                     agRequestType;
19672285809Sscottl  agsaFisRegHostToDevice_t  *fis;
19673285809Sscottl
19674285809Sscottl  fis           = satIOContext->pFis;
19675285809Sscottl  SM_DBG1(("smsatCheckPowerMode: start\n"));
19676285809Sscottl  /*
19677285809Sscottl   * Send the ATA CHECK POWER MODE command.
19678285809Sscottl   */
19679285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
19680285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19681285809Sscottl  fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
19682285809Sscottl  fis->h.features       = 0;
19683285809Sscottl  fis->d.lbaLow         = 0;
19684285809Sscottl  fis->d.lbaMid         = 0;
19685285809Sscottl  fis->d.lbaHigh        = 0;
19686285809Sscottl  fis->d.device         = 0;
19687285809Sscottl  fis->d.lbaLowExp      = 0;
19688285809Sscottl  fis->d.lbaMidExp      = 0;
19689285809Sscottl  fis->d.lbaHighExp     = 0;
19690285809Sscottl  fis->d.featuresExp    = 0;
19691285809Sscottl  fis->d.sectorCount    = 0;
19692285809Sscottl  fis->d.sectorCountExp = 0;
19693285809Sscottl  fis->d.reserved4      = 0;
19694285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
19695285809Sscottl  fis->d.reserved5      = 0;
19696285809Sscottl
19697285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19698285809Sscottl
19699285809Sscottl  /* Initialize CB for SATA completion.
19700285809Sscottl   */
19701285809Sscottl  satIOContext->satCompleteCB = &smsatCheckPowerModeCB;
19702285809Sscottl
19703285809Sscottl  /*
19704285809Sscottl   * Prepare SGL and send FIS to LL layer.
19705285809Sscottl   */
19706285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
19707285809Sscottl
19708285809Sscottl  status = smsataLLIOStart( smRoot,
19709285809Sscottl                            smIORequest,
19710285809Sscottl                            smDeviceHandle,
19711285809Sscottl                            smScsiRequest,
19712285809Sscottl                            satIOContext);
19713285809Sscottl
19714285809Sscottl  SM_DBG5(("smsatCheckPowerMode: return\n"));
19715285809Sscottl
19716285809Sscottl  return status;
19717285809Sscottl}
19718285809Sscottl
19719285809SscottlosGLOBAL bit32
19720285809SscottlsmsatResetDevice(
19721285809Sscottl                  smRoot_t                  *smRoot,
19722285809Sscottl                  smIORequest_t             *smIORequest,
19723285809Sscottl                  smDeviceHandle_t          *smDeviceHandle,
19724285809Sscottl                  smScsiInitiatorRequest_t  *smScsiRequest, /* NULL */
19725285809Sscottl                  smSatIOContext_t            *satIOContext
19726285809Sscottl                )
19727285809Sscottl{
19728285809Sscottl  bit32                     status;
19729285809Sscottl  bit32                     agRequestType;
19730285809Sscottl  agsaFisRegHostToDevice_t  *fis;
19731285809Sscottl#ifdef  TD_DEBUG_ENABLE
19732285809Sscottl  smIORequestBody_t         *smIORequestBody;
19733285809Sscottl  smSatInternalIo_t           *satIntIoContext;
19734285809Sscottl#endif
19735285809Sscottl
19736285809Sscottl  fis           = satIOContext->pFis;
19737285809Sscottl  SM_DBG1(("smsatResetDevice: start\n"));
19738285809Sscottl#ifdef  TD_DEBUG_ENABLE
19739285809Sscottl  satIntIoContext = satIOContext->satIntIoContext;
19740285809Sscottl  smIORequestBody = satIntIoContext->satIntRequestBody;
19741285809Sscottl#endif
19742285809Sscottl  SM_DBG5(("smsatResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody));
19743285809Sscottl  /* any fis should work */
19744285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
19745285809Sscottl  fis->h.c_pmPort       = 0;                      /* C Bit is not set */
19746285809Sscottl  fis->h.command        = 0;                      /* any command */
19747285809Sscottl  fis->h.features       = 0;                      /* FIS reserve */
19748285809Sscottl  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
19749285809Sscottl  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19750285809Sscottl  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19751285809Sscottl  fis->d.device         = 0;                      /* FIS LBA mode  */
19752285809Sscottl  fis->d.lbaLowExp      = 0;
19753285809Sscottl  fis->d.lbaMidExp      = 0;
19754285809Sscottl  fis->d.lbaHighExp     = 0;
19755285809Sscottl  fis->d.featuresExp    = 0;
19756285809Sscottl  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
19757285809Sscottl  fis->d.sectorCountExp = 0;
19758285809Sscottl  fis->d.reserved4      = 0;
19759285809Sscottl  fis->d.control        = 0x4;                    /* SRST bit is set  */
19760285809Sscottl  fis->d.reserved5      = 0;
19761285809Sscottl
19762285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
19763285809Sscottl
19764285809Sscottl  /* Initialize CB for SATA completion.
19765285809Sscottl   */
19766285809Sscottl  satIOContext->satCompleteCB = &smsatResetDeviceCB;
19767285809Sscottl
19768285809Sscottl  /*
19769285809Sscottl   * Prepare SGL and send FIS to LL layer.
19770285809Sscottl   */
19771285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
19772285809Sscottl
19773285809Sscottl#ifdef SM_INTERNAL_DEBUG
19774285809Sscottl  smhexdump("smsatResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19775285809Sscottl#ifdef  TD_DEBUG_ENABLE
19776285809Sscottl  smhexdump("smsatResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19777285809Sscottl#endif
19778285809Sscottl#endif
19779285809Sscottl
19780285809Sscottl  status = smsataLLIOStart( smRoot,
19781285809Sscottl                            smIORequest,
19782285809Sscottl                            smDeviceHandle,
19783285809Sscottl                            smScsiRequest,
19784285809Sscottl                            satIOContext);
19785285809Sscottl
19786285809Sscottl  SM_DBG6(("smsatResetDevice: end status %d\n", status));
19787285809Sscottl  return status;
19788285809Sscottl}
19789285809Sscottl
19790285809SscottlosGLOBAL bit32
19791285809SscottlsmsatDeResetDevice(
19792285809Sscottl                    smRoot_t                  *smRoot,
19793285809Sscottl                    smIORequest_t             *smIORequest,
19794285809Sscottl                    smDeviceHandle_t          *smDeviceHandle,
19795285809Sscottl                    smScsiInitiatorRequest_t  *smScsiRequest,
19796285809Sscottl                    smSatIOContext_t            *satIOContext
19797285809Sscottl                   )
19798285809Sscottl{
19799285809Sscottl  bit32                     status;
19800285809Sscottl  bit32                     agRequestType;
19801285809Sscottl  agsaFisRegHostToDevice_t  *fis;
19802285809Sscottl#ifdef  TD_DEBUG_ENABLE
19803285809Sscottl  smIORequestBody_t         *smIORequestBody;
19804285809Sscottl  smSatInternalIo_t           *satIntIoContext;
19805285809Sscottl#endif
19806285809Sscottl
19807285809Sscottl  fis           = satIOContext->pFis;
19808285809Sscottl  SM_DBG1(("smsatDeResetDevice: start\n"));
19809285809Sscottl#ifdef  TD_DEBUG_ENABLE
19810285809Sscottl  satIntIoContext = satIOContext->satIntIoContext;
19811285809Sscottl  smIORequestBody = satIntIoContext->satIntRequestBody;
19812285809Sscottl#endif
19813285809Sscottl  SM_DBG5(("smsatDeResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody));
19814285809Sscottl  /* any fis should work */
19815285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
19816285809Sscottl  fis->h.c_pmPort       = 0;                      /* C Bit is not set */
19817285809Sscottl  fis->h.command        = 0;                      /* any command */
19818285809Sscottl  fis->h.features       = 0;                      /* FIS reserve */
19819285809Sscottl  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
19820285809Sscottl  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19821285809Sscottl  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19822285809Sscottl  fis->d.device         = 0;                      /* FIS LBA mode  */
19823285809Sscottl  fis->d.lbaLowExp      = 0;
19824285809Sscottl  fis->d.lbaMidExp      = 0;
19825285809Sscottl  fis->d.lbaHighExp     = 0;
19826285809Sscottl  fis->d.featuresExp    = 0;
19827285809Sscottl  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
19828285809Sscottl  fis->d.sectorCountExp = 0;
19829285809Sscottl  fis->d.reserved4      = 0;
19830285809Sscottl  fis->d.control        = 0;                    /* SRST bit is not set  */
19831285809Sscottl  fis->d.reserved5      = 0;
19832285809Sscottl
19833285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT;
19834285809Sscottl
19835285809Sscottl  /* Initialize CB for SATA completion.
19836285809Sscottl   */
19837285809Sscottl  satIOContext->satCompleteCB = &smsatDeResetDeviceCB;
19838285809Sscottl
19839285809Sscottl  /*
19840285809Sscottl   * Prepare SGL and send FIS to LL layer.
19841285809Sscottl   */
19842285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
19843285809Sscottl
19844285809Sscottl#ifdef SM_INTERNAL_DEBUG
19845285809Sscottl  smhexdump("smsatDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19846285809Sscottl#ifdef  TD_DEBUG_ENABLE
19847285809Sscottl  smhexdump("smsatDeResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19848285809Sscottl#endif
19849285809Sscottl#endif
19850285809Sscottl
19851285809Sscottl  status = smsataLLIOStart( smRoot,
19852285809Sscottl                            smIORequest,
19853285809Sscottl                            smDeviceHandle,
19854285809Sscottl                            smScsiRequest,
19855285809Sscottl                            satIOContext);
19856285809Sscottl
19857285809Sscottl  SM_DBG6(("smsatDeResetDevice: end status %d\n", status));
19858285809Sscottl  return status;
19859285809Sscottl}
19860285809Sscottl
19861285809Sscottl/* set feature for auto activate */
19862285809SscottlosGLOBAL bit32
19863285809SscottlsmsatSetFeaturesAA(
19864285809Sscottl           smRoot_t                  *smRoot,
19865285809Sscottl           smIORequest_t             *smIORequest,
19866285809Sscottl           smDeviceHandle_t          *smDeviceHandle,
19867285809Sscottl           smScsiInitiatorRequest_t  *smScsiRequest,
19868285809Sscottl           smSatIOContext_t          *satIOContext
19869285809Sscottl           )
19870285809Sscottl{
19871285809Sscottl  bit32                     status = SM_RC_FAILURE;
19872285809Sscottl  bit32                     agRequestType;
19873285809Sscottl  agsaFisRegHostToDevice_t  *fis;
19874285809Sscottl
19875285809Sscottl  fis           = satIOContext->pFis;
19876285809Sscottl  SM_DBG2(("smsatSetFeaturesAA: start\n"));
19877285809Sscottl  /*
19878285809Sscottl   * Send the Set Features command.
19879285809Sscottl   * See SATA II 1.0a spec
19880285809Sscottl   */
19881285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
19882285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19883285809Sscottl  fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19884285809Sscottl  fis->h.features       = 0x10;                   /* enable SATA feature */
19885285809Sscottl  fis->d.lbaLow         = 0;
19886285809Sscottl  fis->d.lbaMid         = 0;
19887285809Sscottl  fis->d.lbaHigh        = 0;
19888285809Sscottl  fis->d.device         = 0;
19889285809Sscottl  fis->d.lbaLowExp      = 0;
19890285809Sscottl  fis->d.lbaMidExp      = 0;
19891285809Sscottl  fis->d.lbaHighExp     = 0;
19892285809Sscottl  fis->d.featuresExp    = 0;
19893285809Sscottl  fis->d.sectorCount    = 0x02;                   /* DMA Setup FIS Auto-Activate */
19894285809Sscottl  fis->d.sectorCountExp = 0;
19895285809Sscottl  fis->d.reserved4      = 0;
19896285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
19897285809Sscottl  fis->d.reserved5      = 0;
19898285809Sscottl
19899285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19900285809Sscottl
19901285809Sscottl  /* Initialize CB for SATA completion.
19902285809Sscottl   */
19903285809Sscottl  satIOContext->satCompleteCB = &smsatSetFeaturesAACB;
19904285809Sscottl
19905285809Sscottl  /*
19906285809Sscottl   * Prepare SGL and send FIS to LL layer.
19907285809Sscottl   */
19908285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
19909285809Sscottl
19910285809Sscottl  status = smsataLLIOStart( smRoot,
19911285809Sscottl                          smIORequest,
19912285809Sscottl                          smDeviceHandle,
19913285809Sscottl                          smScsiRequest,
19914285809Sscottl                          satIOContext);
19915285809Sscottl
19916285809Sscottl  /* debugging code */
19917285809Sscottl  if (smIORequest->tdData == smIORequest->smData)
19918285809Sscottl  {
19919285809Sscottl    SM_DBG1(("smsatSetFeaturesAA: incorrect smIORequest\n"));
19920285809Sscottl  }
19921285809Sscottl  SM_DBG2(("smsatSetFeatures: return\n"));
19922285809Sscottl  return status;
19923285809Sscottl}
19924285809Sscottl
19925285809Sscottl
19926285809Sscottl/* set feature for DMA transfer mode*/
19927285809SscottlosGLOBAL bit32
19928285809SscottlsmsatSetFeaturesDMA(
19929285809Sscottl           smRoot_t                  *smRoot,
19930285809Sscottl           smIORequest_t             *smIORequest,
19931285809Sscottl           smDeviceHandle_t          *smDeviceHandle,
19932285809Sscottl           smScsiInitiatorRequest_t  *smScsiRequest,
19933285809Sscottl           smSatIOContext_t          *satIOContext
19934285809Sscottl           )
19935285809Sscottl{
19936285809Sscottl  bit32                     status = SM_RC_FAILURE;
19937285809Sscottl  bit32                     agRequestType;
19938285809Sscottl  smDeviceData_t            *pSatDevData;
19939285809Sscottl  agsaFisRegHostToDevice_t  *fis;
19940285809Sscottl
19941285809Sscottl  pSatDevData   = satIOContext->pSatDevData;
19942285809Sscottl  fis           = satIOContext->pFis;
19943285809Sscottl  SM_DBG2(("smsatSetFeaturesDMA: start\n"));
19944285809Sscottl  /*
19945285809Sscottl   * Send the Set Features command.
19946285809Sscottl   * See SATA II 1.0a spec
19947285809Sscottl   */
19948285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
19949285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19950285809Sscottl  fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19951285809Sscottl  fis->h.features       = 0x03;                   /* enable ATA transfer mode */
19952285809Sscottl  fis->d.lbaLow         = 0;
19953285809Sscottl  fis->d.lbaMid         = 0;
19954285809Sscottl  fis->d.lbaHigh        = 0;
19955285809Sscottl  fis->d.device         = 0;
19956285809Sscottl  fis->d.lbaLowExp      = 0;
19957285809Sscottl  fis->d.lbaMidExp      = 0;
19958285809Sscottl  fis->d.lbaHighExp     = 0;
19959285809Sscottl  fis->d.featuresExp    = 0;
19960285809Sscottl  fis->d.sectorCount    = 0x40 |(bit8)pSatDevData->satUltraDMAMode;   /* enable Ultra DMA mode */
19961285809Sscottl  fis->d.sectorCountExp = 0;
19962285809Sscottl  fis->d.reserved4      = 0;
19963285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
19964285809Sscottl  fis->d.reserved5      = 0;
19965285809Sscottl
19966285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19967285809Sscottl
19968285809Sscottl  /* Initialize CB for SATA completion.
19969285809Sscottl   */
19970285809Sscottl  satIOContext->satCompleteCB = &smsatSetFeaturesDMACB;
19971285809Sscottl
19972285809Sscottl  /*
19973285809Sscottl   * Prepare SGL and send FIS to LL layer.
19974285809Sscottl   */
19975285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
19976285809Sscottl
19977285809Sscottl  status = smsataLLIOStart( smRoot,
19978285809Sscottl                          smIORequest,
19979285809Sscottl                          smDeviceHandle,
19980285809Sscottl                          smScsiRequest,
19981285809Sscottl                          satIOContext);
19982285809Sscottl
19983285809Sscottl  /* debugging code */
19984285809Sscottl  if (smIORequest->tdData == smIORequest->smData)
19985285809Sscottl  {
19986285809Sscottl    SM_DBG1(("smsatSetFeaturesDMA: incorrect smIORequest\n"));
19987285809Sscottl  }
19988285809Sscottl
19989285809Sscottl  SM_DBG2(("smsatSetFeaturesDMA: return\n"));
19990285809Sscottl
19991285809Sscottl  return status;
19992285809Sscottl}
19993285809Sscottl
19994285809Sscottl/* set feature for Read Look Ahead*/
19995285809SscottlosGLOBAL bit32
19996285809SscottlsmsatSetFeaturesReadLookAhead(
19997285809Sscottl           smRoot_t                  *smRoot,
19998285809Sscottl           smIORequest_t             *smIORequest,
19999285809Sscottl           smDeviceHandle_t          *smDeviceHandle,
20000285809Sscottl           smScsiInitiatorRequest_t  *smScsiRequest,
20001285809Sscottl           smSatIOContext_t          *satIOContext
20002285809Sscottl           )
20003285809Sscottl{
20004285809Sscottl  bit32                     status = SM_RC_FAILURE;
20005285809Sscottl  bit32                     agRequestType;
20006285809Sscottl  agsaFisRegHostToDevice_t  *fis;
20007285809Sscottl
20008285809Sscottl  fis           = satIOContext->pFis;
20009285809Sscottl  SM_DBG2(("smsatSetFeaturesReadLookAhead: start\n"));
20010285809Sscottl  /*
20011285809Sscottl   * Send the Set Features command.
20012285809Sscottl   * See SATA II 1.0a spec
20013285809Sscottl   */
20014285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
20015285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
20016285809Sscottl  fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
20017285809Sscottl  fis->h.features       = 0xAA;                   /* Enable read look-ahead feature */
20018285809Sscottl  fis->d.lbaLow         = 0;
20019285809Sscottl  fis->d.lbaMid         = 0;
20020285809Sscottl  fis->d.lbaHigh        = 0;
20021285809Sscottl  fis->d.device         = 0;
20022285809Sscottl  fis->d.lbaLowExp      = 0;
20023285809Sscottl  fis->d.lbaMidExp      = 0;
20024285809Sscottl  fis->d.lbaHighExp     = 0;
20025285809Sscottl  fis->d.featuresExp    = 0;
20026285809Sscottl  fis->d.sectorCount    = 0;
20027285809Sscottl  fis->d.sectorCountExp = 0;
20028285809Sscottl  fis->d.reserved4      = 0;
20029285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
20030285809Sscottl  fis->d.reserved5      = 0;
20031285809Sscottl
20032285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
20033285809Sscottl
20034285809Sscottl  /* Initialize CB for SATA completion.
20035285809Sscottl   */
20036285809Sscottl  satIOContext->satCompleteCB = &smsatSetFeaturesReadLookAheadCB;
20037285809Sscottl
20038285809Sscottl  /*
20039285809Sscottl   * Prepare SGL and send FIS to LL layer.
20040285809Sscottl   */
20041285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
20042285809Sscottl
20043285809Sscottl  status = smsataLLIOStart( smRoot,
20044285809Sscottl                          smIORequest,
20045285809Sscottl                          smDeviceHandle,
20046285809Sscottl                          smScsiRequest,
20047285809Sscottl                          satIOContext);
20048285809Sscottl
20049285809Sscottl  /* debugging code */
20050285809Sscottl  if (smIORequest->tdData == smIORequest->smData)
20051285809Sscottl  {
20052285809Sscottl    SM_DBG1(("smsatSetFeaturesReadLookAhead: incorrect smIORequest\n"));
20053285809Sscottl  }
20054285809Sscottl
20055285809Sscottl  SM_DBG2(("smsatSetFeaturesReadLookAhead: return\n"));
20056285809Sscottl
20057285809Sscottl  return status;
20058285809Sscottl}
20059285809Sscottl
20060285809Sscottl/* set feature for Volatile Write Cache*/
20061285809SscottlosGLOBAL bit32
20062285809SscottlsmsatSetFeaturesVolatileWriteCache(
20063285809Sscottl           smRoot_t                  *smRoot,
20064285809Sscottl           smIORequest_t             *smIORequest,
20065285809Sscottl           smDeviceHandle_t          *smDeviceHandle,
20066285809Sscottl           smScsiInitiatorRequest_t  *smScsiRequest,
20067285809Sscottl           smSatIOContext_t            *satIOContext
20068285809Sscottl           )
20069285809Sscottl{
20070285809Sscottl  bit32                     status = SM_RC_FAILURE;
20071285809Sscottl  bit32                     agRequestType;
20072285809Sscottl  agsaFisRegHostToDevice_t  *fis;
20073285809Sscottl
20074285809Sscottl  fis           = satIOContext->pFis;
20075285809Sscottl  SM_DBG2(("smsatSetFeaturesVolatileWriteCache: start\n"));
20076285809Sscottl  /*
20077285809Sscottl   * Send the Set Features command.
20078285809Sscottl   * See SATA II 1.0a spec
20079285809Sscottl   */
20080285809Sscottl  fis->h.fisType        = 0x27;                   /* Reg host to device */
20081285809Sscottl  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
20082285809Sscottl  fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
20083285809Sscottl  fis->h.features       = 0x02;                   /* Enable Volatile Write Cache feature */
20084285809Sscottl  fis->d.lbaLow         = 0;
20085285809Sscottl  fis->d.lbaMid         = 0;
20086285809Sscottl  fis->d.lbaHigh        = 0;
20087285809Sscottl  fis->d.device         = 0;
20088285809Sscottl  fis->d.lbaLowExp      = 0;
20089285809Sscottl  fis->d.lbaMidExp      = 0;
20090285809Sscottl  fis->d.lbaHighExp     = 0;
20091285809Sscottl  fis->d.featuresExp    = 0;
20092285809Sscottl  fis->d.sectorCount    = 0;
20093285809Sscottl  fis->d.sectorCountExp = 0;
20094285809Sscottl  fis->d.reserved4      = 0;
20095285809Sscottl  fis->d.control        = 0;                      /* FIS HOB bit clear */
20096285809Sscottl  fis->d.reserved5      = 0;
20097285809Sscottl
20098285809Sscottl  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
20099285809Sscottl
20100285809Sscottl  /* Initialize CB for SATA completion.
20101285809Sscottl   */
20102285809Sscottl  satIOContext->satCompleteCB = &smsatSetFeaturesVolatileWriteCacheCB;
20103285809Sscottl  /*
20104285809Sscottl   * Prepare SGL and send FIS to LL layer.
20105285809Sscottl   */
20106285809Sscottl  satIOContext->reqType = agRequestType;       /* Save it */
20107285809Sscottl
20108285809Sscottl  status = smsataLLIOStart( smRoot,
20109285809Sscottl                          smIORequest,
20110285809Sscottl                          smDeviceHandle,
20111285809Sscottl                          smScsiRequest,
20112285809Sscottl                          satIOContext);
20113285809Sscottl  /* debugging code */
20114285809Sscottl  if (smIORequest->tdData == smIORequest->smData)
20115285809Sscottl  {
20116285809Sscottl    SM_DBG1(("smsatSetFeaturesVolatileWriteCache: incorrect smIORequest\n"));
20117285809Sscottl  }
20118285809Sscottl  SM_DBG2(("smsatSetFeaturesVolatileWriteCache: return\n"));
20119285809Sscottl
20120285809Sscottl  return status;
20121285809Sscottl}
20122285809Sscottl
20123285809Sscottl
20124285809Sscottl
20125285809Sscottl/******************************** start of utils    ***********************************************************/
20126285809SscottlosGLOBAL FORCEINLINE void
20127285809SscottlsmsatBitSet(smRoot_t *smRoot, bit8 *data, bit32 index)
20128285809Sscottl{
20129285809Sscottl  data[index>>3] |= (1 << (index&7));
20130285809Sscottl}
20131285809Sscottl
20132285809SscottlosGLOBAL FORCEINLINE void
20133285809SscottlsmsatBitClear(smRoot_t *smRoot, bit8 *data, bit32 index)
20134285809Sscottl{
20135285809Sscottl  data[index>>3] &= ~(1 << (index&7));
20136285809Sscottl}
20137285809Sscottl
20138285809SscottlosGLOBAL FORCEINLINE BOOLEAN
20139285809SscottlsmsatBitTest(smRoot_t *smRoot, bit8 *data, bit32 index)
20140285809Sscottl{
20141285809Sscottl   return ( (BOOLEAN)((data[index>>3] & (1 << (index&7)) ) ? 1: 0));
20142285809Sscottl}
20143285809Sscottl
20144285809Sscottl
20145285809SscottlFORCEINLINE bit32
20146285809SscottlsmsatTagAlloc(
20147285809Sscottl               smRoot_t         *smRoot,
20148285809Sscottl               smDeviceData_t   *pSatDevData,
20149285809Sscottl               bit8             *pTag
20150285809Sscottl             )
20151285809Sscottl{
20152285809Sscottl  bit32             retCode = agFALSE;
20153285809Sscottl  bit32             i;
20154285809Sscottl
20155285809Sscottl  tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK);
20156285809Sscottl
20157285809Sscottl#ifdef CCFLAG_OPTIMIZE_SAT_LOCK
20158285809Sscottl
20159285809Sscottl  if (tdsmBitScanForward(smRoot, &i, ~(pSatDevData->freeSATAFDMATagBitmap)))
20160285809Sscottl  {
20161285809Sscottl    smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20162285809Sscottl    *pTag = (bit8)i;
20163285809Sscottl    retCode = agTRUE;
20164285809Sscottl  }
20165285809Sscottl
20166285809Sscottl#else
20167285809Sscottl
20168285809Sscottl  for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
20169285809Sscottl  {
20170285809Sscottl    if ( 0 == smsatBitTest(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
20171285809Sscottl    {
20172285809Sscottl      smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20173285809Sscottl      *pTag = (bit8) i;
20174285809Sscottl      retCode = agTRUE;
20175285809Sscottl      break;
20176285809Sscottl    }
20177285809Sscottl  }
20178285809Sscottl
20179285809Sscottl#endif
20180285809Sscottl
20181285809Sscottl  tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK);
20182285809Sscottl
20183285809Sscottl  return retCode;
20184285809Sscottl}
20185285809Sscottl
20186285809SscottlFORCEINLINE bit32
20187285809SscottlsmsatTagRelease(
20188285809Sscottl                smRoot_t         *smRoot,
20189285809Sscottl                smDeviceData_t   *pSatDevData,
20190285809Sscottl                bit8              tag
20191285809Sscottl               )
20192285809Sscottl{
20193285809Sscottl  bit32             retCode = agFALSE;
20194285809Sscottl
20195285809Sscottl  if ( tag < pSatDevData->satNCQMaxIO )
20196285809Sscottl  {
20197285809Sscottl    tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK);
20198285809Sscottl    smsatBitClear(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
20199285809Sscottl    tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK);
20200285809Sscottl    /*tdsmInterlockedAnd(smRoot, (volatile LONG *)(&pSatDevData->freeSATAFDMATagBitmap), ~(1 << (tag&31)));*/
20201285809Sscottl    retCode = agTRUE;
20202285809Sscottl  }
20203285809Sscottl  else
20204285809Sscottl  {
20205285809Sscottl    SM_DBG1(("smsatTagRelease: tag %d >= satNCQMaxIO %d!!!!\n", tag, pSatDevData->satNCQMaxIO));
20206285809Sscottl  }
20207285809Sscottl  return retCode;
20208285809Sscottl}
20209285809Sscottl
20210285809Sscottl
20211285809Sscottl
20212285809SscottlosGLOBAL bit32
20213285809SscottlsmsatComputeCDB10LBA(smSatIOContext_t            *satIOContext)
20214285809Sscottl{
20215285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
20216285809Sscottl  smScsiInitiatorRequest_t  *smScsiRequest;
20217285809Sscottl  bit32                     lba = 0;
20218285809Sscottl
20219285809Sscottl  SM_DBG5(("smsatComputeCDB10LBA: start\n"));
20220285809Sscottl  smScsiRequest = satIOContext->smScsiXchg;
20221285809Sscottl  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20222285809Sscottl
20223285809Sscottl  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
20224285809Sscottl    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
20225285809Sscottl
20226285809Sscottl  return lba;
20227285809Sscottl}
20228285809Sscottl
20229285809SscottlosGLOBAL bit32
20230285809SscottlsmsatComputeCDB10TL(smSatIOContext_t            *satIOContext)
20231285809Sscottl{
20232285809Sscottl
20233285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
20234285809Sscottl  smScsiInitiatorRequest_t  *smScsiRequest;
20235285809Sscottl  bit32                     tl = 0;
20236285809Sscottl
20237285809Sscottl  SM_DBG5(("smsatComputeCDB10TL: start\n"));
20238285809Sscottl  smScsiRequest = satIOContext->smScsiXchg;
20239285809Sscottl  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20240285809Sscottl
20241285809Sscottl  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
20242285809Sscottl  return tl;
20243285809Sscottl}
20244285809Sscottl
20245285809SscottlosGLOBAL bit32
20246285809SscottlsmsatComputeCDB12LBA(smSatIOContext_t            *satIOContext)
20247285809Sscottl{
20248285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
20249285809Sscottl  smScsiInitiatorRequest_t  *smScsiRequest;
20250285809Sscottl  bit32                     lba = 0;
20251285809Sscottl
20252285809Sscottl  SM_DBG5(("smsatComputeCDB12LBA: start\n"));
20253285809Sscottl  smScsiRequest = satIOContext->smScsiXchg;
20254285809Sscottl  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20255285809Sscottl
20256285809Sscottl  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
20257285809Sscottl    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
20258285809Sscottl
20259285809Sscottl  return lba;
20260285809Sscottl}
20261285809Sscottl
20262285809SscottlosGLOBAL bit32
20263285809SscottlsmsatComputeCDB12TL(smSatIOContext_t            *satIOContext)
20264285809Sscottl{
20265285809Sscottl
20266285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
20267285809Sscottl  smScsiInitiatorRequest_t  *smScsiRequest;
20268285809Sscottl  bit32                     tl = 0;
20269285809Sscottl
20270285809Sscottl  SM_DBG5(("smsatComputeCDB12TL: start\n"));
20271285809Sscottl  smScsiRequest = satIOContext->smScsiXchg;
20272285809Sscottl  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20273285809Sscottl
20274285809Sscottl  tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
20275285809Sscottl    + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
20276285809Sscottl  return tl;
20277285809Sscottl}
20278285809Sscottl
20279285809Sscottl/*
20280285809Sscottl  CBD16 has bit64 LBA
20281285809Sscottl  But it has to be less than (2^28 - 1)
20282285809Sscottl  Therefore, use last four bytes to compute LBA is OK
20283285809Sscottl*/
20284285809SscottlosGLOBAL bit32
20285285809SscottlsmsatComputeCDB16LBA(smSatIOContext_t            *satIOContext)
20286285809Sscottl{
20287285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
20288285809Sscottl  smScsiInitiatorRequest_t  *smScsiRequest;
20289285809Sscottl  bit32                     lba = 0;
20290285809Sscottl
20291285809Sscottl  SM_DBG5(("smsatComputeCDB16LBA: start\n"));
20292285809Sscottl  smScsiRequest = satIOContext->smScsiXchg;
20293285809Sscottl  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20294285809Sscottl
20295285809Sscottl  lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
20296285809Sscottl    + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
20297285809Sscottl
20298285809Sscottl  return lba;
20299285809Sscottl}
20300285809Sscottl
20301285809SscottlosGLOBAL bit32
20302285809SscottlsmsatComputeCDB16TL(smSatIOContext_t            *satIOContext)
20303285809Sscottl{
20304285809Sscottl
20305285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
20306285809Sscottl  smScsiInitiatorRequest_t  *smScsiRequest;
20307285809Sscottl  bit32                     tl = 0;
20308285809Sscottl
20309285809Sscottl  SM_DBG5(("smsatComputeCDB16TL: start\n"));
20310285809Sscottl  smScsiRequest = satIOContext->smScsiXchg;
20311285809Sscottl  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20312285809Sscottl
20313285809Sscottl  tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
20314285809Sscottl    + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
20315285809Sscottl  return tl;
20316285809Sscottl}
20317285809Sscottl
20318285809Sscottl/*
20319285809Sscottl  (tl, denom)
20320285809Sscottl  tl can be upto bit32 because CDB16 has bit32 tl
20321285809Sscottl  Therefore, fine
20322285809Sscottl  either (tl, 0xFF) or (tl, 0xFFFF)
20323285809Sscottl*/
20324285809SscottlosGLOBAL FORCEINLINE bit32
20325285809SscottlsmsatComputeLoopNum(bit32 a, bit32 b)
20326285809Sscottl{
20327285809Sscottl  bit32 LoopNum = 0;
20328285809Sscottl
20329285809Sscottl  SM_DBG5(("smsatComputeLoopNum: start\n"));
20330285809Sscottl
20331285809Sscottl  if (a < b || a == 0)
20332285809Sscottl  {
20333285809Sscottl    LoopNum = 1;
20334285809Sscottl  }
20335285809Sscottl  else
20336285809Sscottl  {
20337285809Sscottl    if (a == b || a == 0)
20338285809Sscottl    {
20339285809Sscottl      LoopNum = a/b;
20340285809Sscottl    }
20341285809Sscottl    else
20342285809Sscottl    {
20343285809Sscottl      LoopNum = a/b + 1;
20344285809Sscottl    }
20345285809Sscottl  }
20346285809Sscottl
20347285809Sscottl  return LoopNum;
20348285809Sscottl}
20349285809Sscottl
20350285809Sscottl/*
20351285809Sscottl  Generic new function for checking
20352285809Sscottl  LBA itself, LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT
20353285809Sscottl  and LBA+TL < Read Capacity Limit
20354285809Sscottl  flag: false - not 48BitSupport; true - 48BitSupport
20355285809Sscottl  returns TRUE when over the limit
20356285809Sscottl
20357285809Sscottl*/
20358285809SscottlosGLOBAL FORCEINLINE bit32
20359285809SscottlsmsatCheckLimit(bit8 *lba, bit8 *tl, int flag, smDeviceData_t *pSatDevData)
20360285809Sscottl{
20361285809Sscottl  bit32 lbaCheck = agFALSE;
20362285809Sscottl  int i;
20363285809Sscottl  bit8 limit[8];
20364285809Sscottl  bit32 rangeCheck = agFALSE;
20365285809Sscottl  bit16 ans[8];       // 0 MSB, 8 LSB
20366285809Sscottl  bit8  final_ans[9]; // 0 MSB, 9 LSB
20367285809Sscottl  bit8  Bit28max[8];
20368285809Sscottl  bit8  Bit48max[8];
20369285809Sscottl  bit32 ReadCapCheck = agFALSE;
20370285809Sscottl  bit32 ret;
20371285809Sscottl
20372285809Sscottl  bit8  final_satMaxLBA[9];
20373285809Sscottl  bit8  oneTL[8];
20374285809Sscottl  bit8  temp_satMaxLBA[8];       // 0 MSB, 8 LSB
20375285809Sscottl  /*
20376285809Sscottl    check LBA
20377285809Sscottl  */
20378285809Sscottl  if (flag == agFALSE)
20379285809Sscottl  {
20380285809Sscottl    /* limit is 0xF FF FF = 2^28 - 1 */
20381285809Sscottl    limit[0] = 0x0;   /* MSB */
20382285809Sscottl    limit[1] = 0x0;
20383285809Sscottl    limit[2] = 0x0;
20384285809Sscottl    limit[3] = 0x0;
20385285809Sscottl    limit[4] = 0xF;
20386285809Sscottl    limit[5] = 0xFF;
20387285809Sscottl    limit[6] = 0xFF;
20388285809Sscottl    limit[7] = 0xFF;  /* LSB */
20389285809Sscottl  }
20390285809Sscottl  else
20391285809Sscottl  {
20392285809Sscottl    /* limit is 0xF FF FF = 2^48 - 1 */
20393285809Sscottl    limit[0] = 0x0;   /* MSB */
20394285809Sscottl    limit[1] = 0x0;
20395285809Sscottl    limit[2] = 0xFF;
20396285809Sscottl    limit[3] = 0xFF;
20397285809Sscottl    limit[4] = 0xFF;
20398285809Sscottl    limit[5] = 0xFF;
20399285809Sscottl    limit[6] = 0xFF;
20400285809Sscottl    limit[7] = 0xFF;  /* LSB */
20401285809Sscottl  }
20402285809Sscottl  //compare lba to limit
20403285809Sscottl  for(i=0;i<8;i++)
20404285809Sscottl  {
20405285809Sscottl    if (lba[i] > limit[i])
20406285809Sscottl    {
20407285809Sscottl      SM_DBG1(("smsatCheckLimit: LBA check True at %d\n", i));
20408285809Sscottl      lbaCheck = agTRUE;
20409285809Sscottl      break;
20410285809Sscottl    }
20411285809Sscottl    else if (lba[i] < limit[i])
20412285809Sscottl    {
20413285809Sscottl      SM_DBG5(("smsatCheckLimit: LBA check False at %d\n", i));
20414285809Sscottl      lbaCheck = agFALSE;
20415285809Sscottl      break;
20416285809Sscottl    }
20417285809Sscottl    else
20418285809Sscottl    {
20419285809Sscottl      continue;
20420285809Sscottl    }
20421285809Sscottl  }
20422285809Sscottl
20423285809Sscottl  if (lbaCheck == agTRUE)
20424285809Sscottl  {
20425285809Sscottl    SM_DBG1(("smsatCheckLimit: return LBA check True\n"));
20426285809Sscottl    return agTRUE;
20427285809Sscottl  }
20428285809Sscottl
20429285809Sscottl  /*
20430285809Sscottl    check LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT
20431285809Sscottl  */
20432285809Sscottl  sm_memset(ans, 0, sizeof(ans));
20433285809Sscottl  sm_memset(final_ans, 0, sizeof(final_ans));
20434285809Sscottl
20435285809Sscottl  // adding from LSB to MSB
20436285809Sscottl  for(i=7;i>=0;i--)
20437285809Sscottl  {
20438285809Sscottl    ans[i] = (bit16)(lba[i] + tl[i]);
20439285809Sscottl    if (i != 7)
20440285809Sscottl    {
20441285809Sscottl      ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
20442285809Sscottl    }
20443285809Sscottl  }
20444285809Sscottl
20445285809Sscottl  /*
20446285809Sscottl    filling in the final answer
20447285809Sscottl   */
20448285809Sscottl  final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
20449285809Sscottl
20450285809Sscottl  for(i=1;i<=8;i++)
20451285809Sscottl  {
20452285809Sscottl    final_ans[i] = (bit8)(ans[i-1] & 0xFF);
20453285809Sscottl  }
20454285809Sscottl
20455285809Sscottl
20456285809Sscottl  if (flag == agFALSE)
20457285809Sscottl  {
20458285809Sscottl    sm_memset(Bit28max, 0, sizeof(Bit28max));
20459285809Sscottl    Bit28max[4] = 0x10; // max =0x1000 0000
20460285809Sscottl
20461285809Sscottl    //compare final_ans to max
20462285809Sscottl    if (final_ans[0] != 0 || final_ans[1] != 0 || final_ans[2] != 0
20463285809Sscottl        || final_ans[3] != 0 || final_ans[4] != 0)
20464285809Sscottl    {
20465285809Sscottl      SM_DBG1(("smsatCheckLimit: before 28Bit addressing TRUE\n"));
20466285809Sscottl      rangeCheck = agTRUE;
20467285809Sscottl    }
20468285809Sscottl    else
20469285809Sscottl    {
20470285809Sscottl      for(i=5;i<=8;i++)
20471285809Sscottl      {
20472285809Sscottl        if (final_ans[i] > Bit28max[i-1])
20473285809Sscottl        {
20474285809Sscottl          SM_DBG1(("smsatCheckLimit: 28Bit addressing TRUE at %d\n", i));
20475285809Sscottl          rangeCheck = agTRUE;
20476285809Sscottl          break;
20477285809Sscottl        }
20478285809Sscottl        else if (final_ans[i] < Bit28max[i-1])
20479285809Sscottl        {
20480285809Sscottl          SM_DBG5(("smsatCheckLimit: 28Bit addressing FALSE at %d\n", i));
20481285809Sscottl          rangeCheck = agFALSE;
20482285809Sscottl          break;
20483285809Sscottl        }
20484285809Sscottl        else
20485285809Sscottl        {
20486285809Sscottl          continue;
20487285809Sscottl        }
20488285809Sscottl      }
20489285809Sscottl    }
20490285809Sscottl  }
20491285809Sscottl  else
20492285809Sscottl  {
20493285809Sscottl    sm_memset(Bit48max, 0, sizeof(Bit48max));
20494285809Sscottl    Bit48max[1] = 0x1; //max = 0x1 0000 0000 0000
20495285809Sscottl
20496285809Sscottl    //compare final_ans to max
20497285809Sscottl    if (final_ans[0] != 0 || final_ans[1] != 0)
20498285809Sscottl    {
20499285809Sscottl      SM_DBG1(("smsatCheckLimit: before 48Bit addressing TRUE\n"));
20500285809Sscottl      rangeCheck = agTRUE;
20501285809Sscottl    }
20502285809Sscottl    else
20503285809Sscottl    {
20504285809Sscottl      for(i=2;i<=8;i++)
20505285809Sscottl      {
20506285809Sscottl        if (final_ans[i] > Bit48max[i-1])
20507285809Sscottl        {
20508285809Sscottl          SM_DBG1(("smsatCheckLimit: 48Bit addressing TRUE at %d\n", i));
20509285809Sscottl          rangeCheck = agTRUE;
20510285809Sscottl	  break;
20511285809Sscottl        }
20512285809Sscottl        else if (final_ans[i] < Bit48max[i-1])
20513285809Sscottl        {
20514285809Sscottl          SM_DBG5(("smsatCheckLimit: 48Bit addressing FALSE at %d\n", i));
20515285809Sscottl          rangeCheck = agFALSE;
20516285809Sscottl	  break;
20517285809Sscottl        }
20518285809Sscottl        else
20519285809Sscottl        {
20520285809Sscottl          continue;
20521285809Sscottl        }
20522285809Sscottl      }
20523285809Sscottl    }
20524285809Sscottl  }
20525285809Sscottl  if (rangeCheck == agTRUE)
20526285809Sscottl  {
20527285809Sscottl    SM_DBG1(("smsatCheckLimit: return rangeCheck True\n"));
20528285809Sscottl    return agTRUE;
20529285809Sscottl  }
20530285809Sscottl
20531285809Sscottl  /*
20532285809Sscottl    LBA+TL < Read Capacity Limit
20533285809Sscottl  */
20534285809Sscottl  sm_memset(temp_satMaxLBA, 0, sizeof(temp_satMaxLBA));
20535285809Sscottl  sm_memset(oneTL, 0, sizeof(oneTL));
20536285809Sscottl  sm_memset(final_satMaxLBA, 0, sizeof(final_satMaxLBA));
20537285809Sscottl  sm_memset(ans, 0, sizeof(ans));
20538285809Sscottl
20539285809Sscottl  sm_memcpy(&temp_satMaxLBA, &pSatDevData->satMaxLBA, sizeof(temp_satMaxLBA));
20540285809Sscottl  oneTL[7] = 1;
20541285809Sscottl
20542285809Sscottl  // adding temp_satMaxLBA to oneTL
20543285809Sscottl  for(i=7;i>=0;i--)
20544285809Sscottl  {
20545285809Sscottl    ans[i] = (bit16)(temp_satMaxLBA[i] + oneTL[i]);
20546285809Sscottl    if (i != 7)
20547285809Sscottl    {
20548285809Sscottl      ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
20549285809Sscottl    }
20550285809Sscottl  }
20551285809Sscottl
20552285809Sscottl  /*
20553285809Sscottl    filling in the final answer
20554285809Sscottl   */
20555285809Sscottl  final_satMaxLBA[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
20556285809Sscottl
20557285809Sscottl  for(i=1;i<=8;i++)
20558285809Sscottl  {
20559285809Sscottl    final_satMaxLBA[i] = (bit8)(ans[i-1] & 0xFF);
20560285809Sscottl  }
20561285809Sscottl  if ( pSatDevData->ReadCapacity == 10)
20562285809Sscottl  {
20563285809Sscottl    for (i=0;i<=8;i++)
20564285809Sscottl    {
20565285809Sscottl      if (final_ans[i] > final_satMaxLBA[i])
20566285809Sscottl      {
20567285809Sscottl        SM_DBG1(("smsatCheckLimit: Read Capacity 10 TRUE at %d\n", i));
20568285809Sscottl        ReadCapCheck = agTRUE;
20569285809Sscottl        break;
20570285809Sscottl      }
20571285809Sscottl      else if (final_ans[i] < final_satMaxLBA[i])
20572285809Sscottl      {
20573285809Sscottl        SM_DBG5(("smsatCheckLimit: Read Capacity 10 FALSE at %d\n", i));
20574285809Sscottl        ReadCapCheck = agFALSE;
20575285809Sscottl        break;
20576285809Sscottl      }
20577285809Sscottl      else
20578285809Sscottl      {
20579285809Sscottl        continue;
20580285809Sscottl      }
20581285809Sscottl    }
20582285809Sscottl    if ( ReadCapCheck)
20583285809Sscottl    {
20584285809Sscottl      SM_DBG1(("smsatCheckLimit: after Read Capacity 10 TRUE\n"));
20585285809Sscottl    }
20586285809Sscottl    else
20587285809Sscottl    {
20588285809Sscottl      SM_DBG5(("smsatCheckLimit: after Read Capacity 10 FALSE\n"));
20589285809Sscottl    }
20590285809Sscottl  }
20591285809Sscottl  else if ( pSatDevData->ReadCapacity == 16)
20592285809Sscottl  {
20593285809Sscottl    for (i=0;i<=8;i++)
20594285809Sscottl    {
20595285809Sscottl      if (final_ans[i] > final_satMaxLBA[i])
20596285809Sscottl      {
20597285809Sscottl        SM_DBG1(("smsatCheckLimit: Read Capacity 16 TRUE at %d\n", i));
20598285809Sscottl        ReadCapCheck = agTRUE;
20599285809Sscottl        break;
20600285809Sscottl      }
20601285809Sscottl      else if (final_ans[i] < final_satMaxLBA[i])
20602285809Sscottl      {
20603285809Sscottl        SM_DBG5(("smsatCheckLimit: Read Capacity 16 FALSE at %d\n", i));
20604285809Sscottl        ReadCapCheck = agFALSE;
20605285809Sscottl        break;
20606285809Sscottl      }
20607285809Sscottl      else
20608285809Sscottl      {
20609285809Sscottl        continue;
20610285809Sscottl      }
20611285809Sscottl    }
20612285809Sscottl    if ( ReadCapCheck)
20613285809Sscottl    {
20614285809Sscottl      SM_DBG1(("smsatCheckLimit: after Read Capacity 16 TRUE\n"));
20615285809Sscottl    }
20616285809Sscottl    else
20617285809Sscottl    {
20618285809Sscottl      SM_DBG5(("smsatCheckLimit: after Read Capacity 16 FALSE\n"));
20619285809Sscottl    }
20620285809Sscottl  }
20621285809Sscottl  else
20622285809Sscottl  {
20623285809Sscottl    SM_DBG5(("smsatCheckLimit: unknown pSatDevData->ReadCapacity %d\n", pSatDevData->ReadCapacity));
20624285809Sscottl  }
20625285809Sscottl
20626285809Sscottl  if (ReadCapCheck == agTRUE)
20627285809Sscottl  {
20628285809Sscottl    SM_DBG1(("smsatCheckLimit: return ReadCapCheck True\n"));
20629285809Sscottl    return agTRUE;
20630285809Sscottl  }
20631285809Sscottl
20632285809Sscottl
20633285809Sscottl  ret = (lbaCheck | rangeCheck | ReadCapCheck);
20634285809Sscottl  if (ret == agTRUE)
20635285809Sscottl  {
20636285809Sscottl    SM_DBG1(("smsatCheckLimit: final check TRUE\n"));
20637285809Sscottl  }
20638285809Sscottl  else
20639285809Sscottl  {
20640285809Sscottl    SM_DBG5(("smsatCheckLimit: final check FALSE\n"));
20641285809Sscottl  }
20642285809Sscottl  return   ret;
20643285809Sscottl}
20644285809Sscottl
20645285809Sscottl
20646285809Sscottl
20647285809SscottlosGLOBAL void
20648285809SscottlsmsatPrintSgl(
20649285809Sscottl            smRoot_t                  *smRoot,
20650285809Sscottl            agsaEsgl_t                *agEsgl,
20651285809Sscottl      bit32                     idx
20652285809Sscottl      )
20653285809Sscottl{
20654285809Sscottl  bit32                     i=0;
20655285809Sscottl#ifdef  TD_DEBUG_ENABLE
20656285809Sscottl  agsaSgl_t                 *agSgl;
20657285809Sscottl#endif
20658285809Sscottl
20659285809Sscottl  for (i=0;i<idx;i++)
20660285809Sscottl  {
20661285809Sscottl#ifdef  TD_DEBUG_ENABLE
20662285809Sscottl    agSgl = &(agEsgl->descriptor[i]);
20663285809Sscottl#endif
20664285809Sscottl    SM_DBG3(("smsatPrintSgl: agSgl %d upperAddr 0x%08x lowerAddr 0x%08x len 0x%08x ext 0x%08x\n",
20665285809Sscottl      i, agSgl->sgUpper, agSgl->sgLower, agSgl->len,  agSgl->extReserved));
20666285809Sscottl  }
20667285809Sscottl
20668285809Sscottl  return;
20669285809Sscottl}
20670285809Sscottl
20671285809Sscottl
20672285809SscottlosGLOBAL void
20673285809SscottlsmsatSplitSGL(
20674285809Sscottl     smRoot_t                  *smRoot,
20675285809Sscottl     smIORequest_t             *smIORequest,
20676285809Sscottl     smDeviceHandle_t          *smDeviceHandle,
20677285809Sscottl     smScsiInitiatorRequest_t  *smScsiRequest,
20678285809Sscottl     smSatIOContext_t          *satIOContext,
20679285809Sscottl     bit32                     split, /*in sector number, depeding on IO value */
20680285809Sscottl     bit32                     tl, /* in sector number */
20681285809Sscottl     bit32                     flag
20682285809Sscottl    )
20683285809Sscottl{
20684285809Sscottl  agsaSgl_t                 *agSgl;
20685285809Sscottl  agsaEsgl_t                *agEsgl;
20686285809Sscottl  bit32                     i=0;
20687285809Sscottl  smIniScsiCmnd_t           *scsiCmnd;
20688285809Sscottl  bit32                     totalLen=0; /* in bytes */
20689285809Sscottl  bit32                     splitLen=0; /* in bytes */
20690285809Sscottl  bit32                     splitDiffByte = 0; /* in bytes */
20691285809Sscottl  bit32                     splitDiffExtra = 0; /* in bytes */
20692285809Sscottl  bit32                     splitIdx = 0;
20693285809Sscottl  bit32                     UpperAddr, LowerAddr;
20694285809Sscottl  bit32                     tmpLowerAddr;
20695285809Sscottl  void                      *sglVirtualAddr;
20696285809Sscottl  void                      *sglSplitVirtualAddr;
20697285809Sscottl
20698285809Sscottl  scsiCmnd      = &smScsiRequest->scsiCmnd;
20699285809Sscottl  SM_DBG3(("smsatSplitSGL: start\n"));
20700285809Sscottl
20701285809Sscottl  if (smScsiRequest->smSgl1.type == 0x80000000) /* esgl */
20702285809Sscottl  {
20703285809Sscottl    if (flag == agFALSE)
20704285809Sscottl    {
20705285809Sscottl      SM_DBG3(("smsatSplitSGL: Not first time\n"));
20706285809Sscottl      SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x LowerAddr 0x%08x\n", satIOContext->UpperAddr, satIOContext->LowerAddr));
20707285809Sscottl      SM_DBG3(("smsatSplitSGL: SplitIdx %d AdjustBytes 0x%08x\n", satIOContext->SplitIdx, satIOContext->AdjustBytes));
20708285809Sscottl
20709285809Sscottl      sglVirtualAddr = smScsiRequest->sglVirtualAddr;
20710285809Sscottl
20711285809Sscottl      agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20712285809Sscottl
20713285809Sscottl      sglSplitVirtualAddr = &(agEsgl->descriptor[satIOContext->SplitIdx]);
20714285809Sscottl
20715285809Sscottl      agEsgl = (agsaEsgl_t *)sglSplitVirtualAddr;
20716285809Sscottl
20717285809Sscottl      if (agEsgl == agNULL)
20718285809Sscottl      {
20719285809Sscottl        SM_DBG1(("smsatSplitSGL: error!\n"));
20720285809Sscottl        return;
20721285809Sscottl      }
20722285809Sscottl      /* first sgl ajustment */
20723285809Sscottl      agSgl = &(agEsgl->descriptor[0]);
20724285809Sscottl      agSgl->sgUpper = satIOContext->UpperAddr;
20725285809Sscottl      agSgl->sgLower = satIOContext->LowerAddr;
20726285809Sscottl      agSgl->len = satIOContext->AdjustBytes;
20727285809Sscottl      sm_memcpy(sglVirtualAddr, sglSplitVirtualAddr, (satIOContext->EsglLen) * sizeof(agsaSgl_t));
20728285809Sscottl      agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20729285809Sscottl      smsatPrintSgl(smRoot, (agsaEsgl_t *)sglVirtualAddr, satIOContext->EsglLen);
20730285809Sscottl    }
20731285809Sscottl    else
20732285809Sscottl    {
20733285809Sscottl      /* first time */
20734285809Sscottl      SM_DBG3(("smsatSplitSGL: first time\n"));
20735285809Sscottl      satIOContext->EsglLen = smScsiRequest->smSgl1.len;
20736285809Sscottl      agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20737285809Sscottl      if (agEsgl == agNULL)
20738285809Sscottl      {
20739285809Sscottl        return;
20740285809Sscottl      }
20741285809Sscottl      smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20742285809Sscottl    }
20743285809Sscottl
20744285809Sscottl    if (tl > split)
20745285809Sscottl    {
20746285809Sscottl      /* split */
20747285809Sscottl      SM_DBG3(("smsatSplitSGL: split case\n"));
20748285809Sscottl      i = 0;
20749285809Sscottl      while (1)
20750285809Sscottl      {
20751285809Sscottl        agSgl = &(agEsgl->descriptor[i]);
20752285809Sscottl        splitLen = splitLen + agSgl->len;
20753285809Sscottl        if (splitLen >= split)
20754285809Sscottl        {
20755285809Sscottl          splitDiffExtra = splitLen - split;
20756285809Sscottl          splitDiffByte = agSgl->len - splitDiffExtra;
20757285809Sscottl          splitIdx = i;
20758285809Sscottl          break;
20759285809Sscottl        }
20760285809Sscottl        i++;
20761285809Sscottl      }
20762285809Sscottl      SM_DBG3(("smsatSplitSGL: splitIdx %d\n", splitIdx));
20763285809Sscottl      SM_DBG3(("smsatSplitSGL: splitDiffByte 0x%8x\n", splitDiffByte));
20764285809Sscottl      SM_DBG3(("smsatSplitSGL: splitDiffExtra 0x%8x \n", splitDiffExtra));
20765285809Sscottl
20766285809Sscottl
20767285809Sscottl      agSgl = &(agEsgl->descriptor[splitIdx]);
20768285809Sscottl      UpperAddr = agSgl->sgUpper;
20769285809Sscottl      LowerAddr = agSgl->sgLower;
20770285809Sscottl      tmpLowerAddr = LowerAddr + splitDiffByte;
20771285809Sscottl      if (tmpLowerAddr < LowerAddr)
20772285809Sscottl      {
20773285809Sscottl        UpperAddr = UpperAddr + 1;
20774285809Sscottl      }
20775285809Sscottl      SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x tmpLowerAddr 0x%08x\n", UpperAddr, tmpLowerAddr));
20776285809Sscottl      agSgl->len = splitDiffByte;
20777285809Sscottl      /* Esgl len adjustment */
20778285809Sscottl      smScsiRequest->smSgl1.len =  splitIdx;
20779285809Sscottl      /* expected data lent adjustment */
20780285809Sscottl      scsiCmnd->expDataLength = 0x20000;
20781285809Sscottl      /* remeber for the next round */
20782285809Sscottl      satIOContext->UpperAddr = UpperAddr;
20783285809Sscottl      satIOContext->LowerAddr = tmpLowerAddr;
20784285809Sscottl      satIOContext->SplitIdx = splitIdx;
20785285809Sscottl      satIOContext->AdjustBytes = splitDiffExtra;
20786285809Sscottl      satIOContext->EsglLen =  satIOContext->EsglLen - smScsiRequest->smSgl1.len;
20787285809Sscottl      satIOContext->OrgTL = satIOContext->OrgTL - 0x100;
20788285809Sscottl//    smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20789285809Sscottl
20790285809Sscottl    }
20791285809Sscottl    else
20792285809Sscottl    {
20793285809Sscottl      /* no split */
20794285809Sscottl      SM_DBG3(("smsatSplitSGL: no split case\n"));
20795285809Sscottl      /* Esgl len adjustment */
20796285809Sscottl      smScsiRequest->smSgl1.len = satIOContext->EsglLen;
20797285809Sscottl      for (i=0;i< smScsiRequest->smSgl1.len;i++)
20798285809Sscottl      {
20799285809Sscottl        agSgl = &(agEsgl->descriptor[i]);
20800285809Sscottl        totalLen = totalLen + (agSgl->len);
20801285809Sscottl      }
20802285809Sscottl      /* expected data lent adjustment */
20803285809Sscottl      scsiCmnd->expDataLength = totalLen;
20804285809Sscottl//    smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20805285809Sscottl    }
20806285809Sscottl  }
20807285809Sscottl  else
20808285809Sscottl  {
20809285809Sscottl    SM_DBG1(("not exntened esgl\n"));
20810285809Sscottl
20811285809Sscottl  }
20812285809Sscottl
20813285809Sscottl  return;
20814285809Sscottl}
20815285809Sscottl
20816285809Sscottl
20817285809Sscottl/******************************** end   of utils    ***********************************************************/
20818285809Sscottl
20819285809Sscottl
20820285809Sscottl
20821