1/*******************************************************************************
2*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3*
4*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5*that the following conditions are met:
6*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7*following disclaimer.
8*2. Redistributions in binary form must reproduce the above copyright notice,
9*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10*with the distribution.
11*
12*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20
21********************************************************************************/
22#include <sys/cdefs.h>
23__FBSDID("$FreeBSD$");
24#include <dev/pms/config.h>
25
26#include <dev/pms/freebsd/driver/common/osenv.h>
27#include <dev/pms/freebsd/driver/common/ostypes.h>
28#include <dev/pms/freebsd/driver/common/osdebug.h>
29
30#include <dev/pms/RefTisa/tisa/api/titypes.h>
31
32#include <dev/pms/RefTisa/sallsdk/api/sa.h>
33#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
34#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
35
36#include <dev/pms/RefTisa/sat/api/sm.h>
37#include <dev/pms/RefTisa/sat/api/smapi.h>
38#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
39
40#include <dev/pms/RefTisa/sat/src/smdefs.h>
41#include <dev/pms/RefTisa/sat/src/smproto.h>
42#include <dev/pms/RefTisa/sat/src/smtypes.h>
43
44/* start smapi defined APIs */
45osGLOBAL bit32
46smRegisterDevice(
47                 smRoot_t                       *smRoot,
48                 agsaDevHandle_t                *agDevHandle,
49                 smDeviceHandle_t               *smDeviceHandle,
50                 agsaDevHandle_t                *agExpDevHandle,
51                 bit32                          phyID,
52                 bit32                          DeviceType
53                )
54{
55  smDeviceData_t            *oneDeviceData = agNULL;
56
57  SM_DBG2(("smRegisterDevice: start\n"));
58
59  if (smDeviceHandle == agNULL)
60  {
61    SM_DBG1(("smRegisterDevice: smDeviceHandle is NULL!!!\n"));
62    return SM_RC_FAILURE;
63  }
64
65  if (agDevHandle == agNULL)
66  {
67    SM_DBG1(("smRegisterDevice: agDevHandle is NULL!!!\n"));
68    return SM_RC_FAILURE;
69  }
70
71  oneDeviceData = smAddToSharedcontext(smRoot, agDevHandle, smDeviceHandle, agExpDevHandle, phyID);
72  if (oneDeviceData != agNULL)
73  {
74    oneDeviceData->satDeviceType = DeviceType;
75    return SM_RC_SUCCESS;
76  }
77  else
78  {
79    return SM_RC_FAILURE;
80  }
81
82}
83
84osGLOBAL bit32
85smDeregisterDevice(
86                   smRoot_t                     *smRoot,
87                   agsaDevHandle_t              *agDevHandle,
88                   smDeviceHandle_t             *smDeviceHandle
89                  )
90{
91  bit32                     status = SM_RC_FAILURE;
92
93  SM_DBG2(("smDeregisterDevice: start\n"));
94
95  if (smDeviceHandle == agNULL)
96  {
97    SM_DBG1(("smDeregisterDevice: smDeviceHandle is NULL!!!\n"));
98    return SM_RC_FAILURE;
99  }
100
101  if (agDevHandle == agNULL)
102  {
103    SM_DBG1(("smDeregisterDevice: agDevHandle is NULL!!!\n"));
104    return SM_RC_FAILURE;
105  }
106
107  status = smRemoveFromSharedcontext(smRoot, agDevHandle, smDeviceHandle);
108
109  return status;
110}
111
112osGLOBAL bit32
113smIOAbort(
114           smRoot_t                     *smRoot,
115           smIORequest_t                *tasktag
116         )
117
118{
119  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
120  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
121  agsaRoot_t                *agRoot;
122  smIORequestBody_t         *smIORequestBody = agNULL;
123  smIORequestBody_t         *smIONewRequestBody = agNULL;
124  agsaIORequest_t           *agIORequest = agNULL; /* IO to be aborted */
125  bit32                     status = SM_RC_FAILURE;
126  agsaIORequest_t           *agAbortIORequest;  /* abort IO itself */
127  smIORequestBody_t         *smAbortIORequestBody;
128#if 1
129  bit32                     PhysUpper32;
130  bit32                     PhysLower32;
131  bit32                     memAllocStatus;
132  void                      *osMemHandle;
133#endif
134  smSatIOContext_t            *satIOContext;
135  smSatInternalIo_t           *satIntIo;
136  smSatIOContext_t            *satAbortIOContext;
137
138  SM_DBG1(("smIOAbort: start\n"));
139  SM_DBG2(("smIOAbort: tasktag %p\n", tasktag));
140  /*
141    alloc smIORequestBody for abort itself
142    call saSATAAbort()
143  */
144
145  agRoot = smAllShared->agRoot;
146  smIORequestBody =  (smIORequestBody_t *)tasktag->smData;
147
148  if (smIORequestBody == agNULL)
149  {
150    SM_DBG1(("smIOAbort: smIORequestBody is NULL!!!\n"));
151    return SM_RC_FAILURE;
152  }
153
154  /* needs to distinguish internally generated or externally generated */
155  satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
156  satIntIo     = satIOContext->satIntIoContext;
157  if (satIntIo == agNULL)
158  {
159    SM_DBG2(("smIOAbort: External, OS generated\n"));
160    agIORequest     = &(smIORequestBody->agIORequest);
161  }
162  else
163  {
164    SM_DBG2(("smIOAbort: Internal, SM generated\n"));
165    smIONewRequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
166    agIORequest     = &(smIONewRequestBody->agIORequest);
167  }
168
169  /*
170    allocate smAbortIORequestBody for abort request itself
171  */
172
173#if 1
174  /* allocating agIORequest for abort itself */
175  memAllocStatus = tdsmAllocMemory(
176                                   smRoot,
177                                   &osMemHandle,
178                                   (void **)&smAbortIORequestBody,
179                                   &PhysUpper32,
180                                   &PhysLower32,
181                                   8,
182                                   sizeof(smIORequestBody_t),
183                                   agTRUE
184                                   );
185  if (memAllocStatus != SM_RC_SUCCESS)
186  {
187    /* let os process IO */
188    SM_DBG1(("smIOAbort: tdsmAllocMemory failed...!!!\n"));
189    return SM_RC_FAILURE;
190  }
191
192  if (smAbortIORequestBody == agNULL)
193  {
194    /* let os process IO */
195    SM_DBG1(("smIOAbort: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n"));
196    return SM_RC_FAILURE;
197  }
198
199  smIOReInit(smRoot, smAbortIORequestBody);
200
201  /* setup task management structure */
202  smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
203  satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext);
204  satAbortIOContext->smRequestBody = smAbortIORequestBody;
205
206  smAbortIORequestBody->smDevHandle = smIORequestBody->smDevHandle;
207
208  /* initialize agIORequest */
209  agAbortIORequest = &(smAbortIORequestBody->agIORequest);
210  agAbortIORequest->osData = (void *) smAbortIORequestBody;
211  agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
212
213  /* remember IO to be aborted */
214  smAbortIORequestBody->smIOToBeAbortedRequest = tasktag;
215
216  status = saSATAAbort(agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, smaSATAAbortCB);
217
218  SM_DBG2(("smIOAbort: return status=0x%x\n", status));
219
220#endif /* 1 */
221
222
223  if (status == AGSA_RC_SUCCESS)
224  {
225    return SM_RC_SUCCESS;
226  }
227  else
228  {
229    SM_DBG1(("smIOAbort: failed to call saSATAAbort, status=%d!!!\n", status));
230    tdsmFreeMemory(smRoot,
231               smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle,
232               sizeof(smIORequestBody_t)
233               );
234    return SM_RC_FAILURE;
235  }
236}
237
238osGLOBAL bit32
239smIOAbortAll(
240             smRoot_t                     *smRoot,
241             smDeviceHandle_t             *smDeviceHandle
242            )
243{
244  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
245  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
246  agsaRoot_t                *agRoot;
247  bit32                     status = SM_RC_FAILURE;
248  agsaIORequest_t           *agAbortIORequest;
249  smIORequestBody_t         *smAbortIORequestBody;
250  smSatIOContext_t          *satAbortIOContext;
251  smDeviceData_t            *oneDeviceData = agNULL;
252  agsaDevHandle_t           *agDevHandle;
253
254  bit32                     PhysUpper32;
255  bit32                     PhysLower32;
256  bit32                     memAllocStatus;
257  void                      *osMemHandle;
258
259
260  SM_DBG2(("smIOAbortAll: start\n"));
261
262  agRoot = smAllShared->agRoot;
263
264  if (smDeviceHandle == agNULL)
265  {
266    SM_DBG1(("smIOAbortAll: smDeviceHandle is NULL!!!\n"));
267    return SM_RC_FAILURE;
268  }
269
270  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
271  if (oneDeviceData == agNULL)
272  {
273    SM_DBG1(("smIOAbortAll: oneDeviceData is NULL!!!\n"));
274    return SM_RC_FAILURE;
275  }
276  if (oneDeviceData->valid == agFALSE)
277  {
278    SM_DBG1(("smIOAbortAll: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
279    return SM_RC_FAILURE;
280  }
281
282  agDevHandle     = oneDeviceData->agDevHandle;
283  if (agDevHandle == agNULL)
284  {
285    SM_DBG1(("smIOAbortAll: agDevHandle is NULL!!!\n"));
286    return SM_RC_FAILURE;
287  }
288/*
289  smAbortIORequestBody = smDequeueIO(smRoot);
290  if (smAbortIORequestBody == agNULL)
291  {
292    SM_DBG1(("smIOAbortAll: empty freeIOList!!!\n"));
293    return SM_RC_FAILURE;
294  }
295*/
296  /* allocating agIORequest for abort itself */
297  memAllocStatus = tdsmAllocMemory(
298                                   smRoot,
299                                   &osMemHandle,
300                                   (void **)&smAbortIORequestBody,
301                                   &PhysUpper32,
302                                   &PhysLower32,
303                                   8,
304                                   sizeof(smIORequestBody_t),
305                                   agTRUE
306                                   );
307  if (memAllocStatus != SM_RC_SUCCESS)
308  {
309     /* let os process IO */
310     SM_DBG1(("smIOAbortAll: tdsmAllocMemory failed...!!!\n"));
311     return SM_RC_FAILURE;
312  }
313
314  if (smAbortIORequestBody == agNULL)
315  {
316    /* let os process IO */
317    SM_DBG1(("smIOAbortAll: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n"));
318    return SM_RC_FAILURE;
319  }
320
321  smIOReInit(smRoot, smAbortIORequestBody);
322
323  /* setup task management structure */
324  smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
325
326  satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext);
327  satAbortIOContext->smRequestBody = smAbortIORequestBody;
328  smAbortIORequestBody->smDevHandle = smDeviceHandle;
329
330  /* initialize agIORequest */
331  agAbortIORequest = &(smAbortIORequestBody->agIORequest);
332  agAbortIORequest->osData = (void *) smAbortIORequestBody;
333  agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
334
335  oneDeviceData->OSAbortAll = agTRUE;
336  /* abort all */
337  status = saSATAAbort(agRoot, agAbortIORequest, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, 1, agNULL, smaSATAAbortCB);
338  if (status != AGSA_RC_SUCCESS)
339  {
340    SM_DBG1(("smIOAbortAll: failed to call saSATAAbort, status=%d!!!\n", status));
341    tdsmFreeMemory(smRoot,
342                   smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle,
343                   sizeof(smIORequestBody_t)
344                   );
345  }
346
347  return status;
348}
349
350osGLOBAL bit32
351smSuperIOStart(
352               smRoot_t                         *smRoot,
353               smIORequest_t                    *smIORequest,
354               smDeviceHandle_t                 *smDeviceHandle,
355               smSuperScsiInitiatorRequest_t    *smSCSIRequest,
356               bit32                            AddrHi,
357               bit32                            AddrLo,
358               bit32                            interruptContext
359              )
360{
361  smDeviceData_t            *oneDeviceData = agNULL;
362  smIORequestBody_t         *smIORequestBody = agNULL;
363  smSatIOContext_t            *satIOContext = agNULL;
364  bit32                     status = SM_RC_FAILURE;
365
366  SM_DBG2(("smSuperIOStart: start\n"));
367
368  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
369  if (oneDeviceData == agNULL)
370  {
371    SM_DBG1(("smSuperIOStart: oneDeviceData is NULL!!!\n"));
372    return SM_RC_FAILURE;
373  }
374  if (oneDeviceData->valid == agFALSE)
375  {
376    SM_DBG1(("smSuperIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
377    return SM_RC_FAILURE;
378  }
379  smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
380
381  if (smIORequestBody == agNULL)
382  {
383    SM_DBG1(("smSuperIOStart: smIORequestBody is NULL!!!\n"));
384    return SM_RC_FAILURE;
385  }
386
387  smIOReInit(smRoot, smIORequestBody);
388
389  SM_DBG3(("smSuperIOStart: io ID %d!!!\n", smIORequestBody->id ));
390
391  oneDeviceData->sasAddressHi = AddrHi;
392  oneDeviceData->sasAddressLo = AddrLo;
393
394  smIORequestBody->smIORequest = smIORequest;
395  smIORequestBody->smDevHandle = smDeviceHandle;
396
397  satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
398
399  /*
400   * Need to initialize all the fields within satIOContext except
401   * reqType and satCompleteCB which will be set later in SM.
402   */
403  smIORequestBody->transport.SATA.smSenseData.senseData = agNULL;
404  smIORequestBody->transport.SATA.smSenseData.senseLen = 0;
405  satIOContext->pSatDevData   = oneDeviceData;
406  satIOContext->pFis          =
407    &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
408  satIOContext->pScsiCmnd     = &smSCSIRequest->scsiCmnd;
409  satIOContext->pSense        = &smIORequestBody->transport.SATA.sensePayload;
410  satIOContext->pSmSenseData  = &smIORequestBody->transport.SATA.smSenseData;
411  satIOContext->pSmSenseData->senseData = satIOContext->pSense;
412  /*    satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */
413  satIOContext->smRequestBody = smIORequestBody;
414  satIOContext->interruptContext = interruptContext;
415  satIOContext->psmDeviceHandle = smDeviceHandle;
416  satIOContext->smScsiXchg = smSCSIRequest;
417  satIOContext->superIOFlag = agTRUE;
418//  satIOContext->superIOFlag = agFALSE;
419
420  satIOContext->satIntIoContext  = agNULL;
421  satIOContext->satOrgIOContext  = agNULL;
422  /*    satIOContext->tiIORequest      = tiIORequest; */
423
424  /* save context if we need to abort later */
425  /*smIORequest->smData = smIORequestBody;*/
426
427  /* followings are used only for internal IO */
428  satIOContext->currentLBA = 0;
429  satIOContext->OrgTL = 0;
430
431  status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, (smScsiInitiatorRequest_t *)smSCSIRequest, satIOContext);
432
433  return status;
434}
435
436/*
437osGLOBAL bit32
438tiINIIOStart(
439             tiRoot_t                  *tiRoot,
440             tiIORequest_t             *tiIORequest,
441             tiDeviceHandle_t          *tiDeviceHandle,
442             tiScsiInitiatorRequest_t  *tiScsiRequest,
443             void                      *tiRequestBody,
444             bit32                     interruptContext
445             )
446
447GLOBAL bit32  satIOStart(
448                   tiRoot_t                  *tiRoot,
449                   tiIORequest_t             *tiIORequest,
450                   tiDeviceHandle_t          *tiDeviceHandle,
451                   tiScsiInitiatorRequest_t  *tiScsiRequest,
452                   smSatIOContext_t            *satIOContext
453                  )
454smIOStart(
455          smRoot_t      *smRoot,
456          smIORequest_t     *smIORequest,
457          smDeviceHandle_t    *smDeviceHandle,
458          smScsiInitiatorRequest_t  *smSCSIRequest,
459          smIORequestBody_t             *smRequestBody,
460          bit32       interruptContext
461         )
462
463
464*/
465FORCEINLINE bit32
466smIOStart(
467          smRoot_t                      *smRoot,
468          smIORequest_t                 *smIORequest,
469          smDeviceHandle_t              *smDeviceHandle,
470          smScsiInitiatorRequest_t      *smSCSIRequest,
471          bit32                         interruptContext
472         )
473{
474  smDeviceData_t            *oneDeviceData = agNULL;
475  smIORequestBody_t         *smIORequestBody = agNULL;
476  smSatIOContext_t          *satIOContext = agNULL;
477  bit32                     status = SM_RC_FAILURE;
478
479  SM_DBG2(("smIOStart: start\n"));
480
481  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
482  if (oneDeviceData == agNULL)
483  {
484    SM_DBG1(("smIOStart: oneDeviceData is NULL!!!\n"));
485    return SM_RC_FAILURE;
486  }
487  if (oneDeviceData->valid == agFALSE)
488  {
489    SM_DBG1(("smIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
490    return SM_RC_FAILURE;
491  }
492  smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
493
494  if (smIORequestBody == agNULL)
495  {
496    SM_DBG1(("smIOStart: smIORequestBody is NULL!!!\n"));
497    return SM_RC_FAILURE;
498  }
499
500  smIOReInit(smRoot, smIORequestBody);
501
502  SM_DBG3(("smIOStart: io ID %d!!!\n", smIORequestBody->id ));
503
504  smIORequestBody->smIORequest = smIORequest;
505  smIORequestBody->smDevHandle = smDeviceHandle;
506
507  satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
508
509  /*
510   * Need to initialize all the fields within satIOContext except
511   * reqType and satCompleteCB which will be set later in SM.
512   */
513  smIORequestBody->transport.SATA.smSenseData.senseData = agNULL;
514  smIORequestBody->transport.SATA.smSenseData.senseLen = 0;
515  satIOContext->pSatDevData   = oneDeviceData;
516  satIOContext->pFis          =
517    &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
518  satIOContext->pScsiCmnd     = &smSCSIRequest->scsiCmnd;
519  satIOContext->pSense        = &smIORequestBody->transport.SATA.sensePayload;
520  satIOContext->pSmSenseData  = &smIORequestBody->transport.SATA.smSenseData;
521  satIOContext->pSmSenseData->senseData = satIOContext->pSense;
522  /*    satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */
523  satIOContext->smRequestBody = smIORequestBody;
524  satIOContext->interruptContext = interruptContext;
525  satIOContext->psmDeviceHandle = smDeviceHandle;
526  satIOContext->smScsiXchg = smSCSIRequest;
527  satIOContext->superIOFlag = agFALSE;
528
529  satIOContext->satIntIoContext  = agNULL;
530  satIOContext->satOrgIOContext  = agNULL;
531  satIOContext->currentLBA = 0;
532  satIOContext->OrgTL = 0;
533
534  status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
535
536  return status;
537
538}
539
540
541
542osGLOBAL bit32
543smTaskManagement(
544                 smRoot_t                       *smRoot,
545                 smDeviceHandle_t               *smDeviceHandle,
546                 bit32                          task,
547                 smLUN_t                        *lun,
548                 smIORequest_t                  *taskTag, /* io to be aborted */
549                 smIORequest_t                  *currentTaskTag /* task management */
550                )
551{
552  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
553  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
554  agsaRoot_t                *agRoot = smAllShared->agRoot;
555  smDeviceData_t            *oneDeviceData = agNULL;
556  smIORequestBody_t         *smIORequestBody = agNULL;
557  bit32                     status;
558  agsaContext_t             *agContext = agNULL;
559  smSatIOContext_t          *satIOContext;
560
561  SM_DBG1(("smTaskManagement: start\n"));
562  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
563
564  if (task == SM_LOGICAL_UNIT_RESET || task == SM_TARGET_WARM_RESET || task == SM_ABORT_TASK)
565  {
566    if (task == AG_LOGICAL_UNIT_RESET)
567    {
568      if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
569            lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
570      {
571        SM_DBG1(("smTaskManagement: *** REJECT *** LUN not zero, did %d!!!\n",
572                oneDeviceData->id));
573        return SM_RC_FAILURE;
574      }
575    }
576
577    oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
578    oneDeviceData->satAbortAfterReset = agFALSE;
579
580    saSetDeviceState(agRoot,
581                     agNULL,
582                     tdsmRotateQnumber(smRoot, smDeviceHandle),
583                     oneDeviceData->agDevHandle,
584                     SA_DS_IN_RECOVERY
585                     );
586
587    if (oneDeviceData->directlyAttached == agFALSE)
588    {
589      /* expander attached */
590      SM_DBG1(("smTaskManagement: LUN reset or device reset expander attached!!!\n"));
591      status = smPhyControlSend(smRoot,
592                                oneDeviceData,
593                                SMP_PHY_CONTROL_HARD_RESET,
594                                currentTaskTag,
595                                tdsmRotateQnumber(smRoot, smDeviceHandle)
596                               );
597      return status;
598    }
599    else
600    {
601      SM_DBG1(("smTaskManagement: LUN reset or device reset directly attached\n"));
602
603      smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot);
604
605      if (smIORequestBody == agNULL)
606      {
607        SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n"));
608        return SM_RC_FAILURE;
609      }
610
611      smIOReInit(smRoot, smIORequestBody);
612
613      satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
614      satIOContext->smRequestBody = smIORequestBody;
615      smIORequestBody->smDevHandle = smDeviceHandle;
616
617      agContext = &(oneDeviceData->agDeviceResetContext);
618      agContext->osData = currentTaskTag;
619
620      status = saLocalPhyControl(agRoot,
621                                 agContext,
622                                 tdsmRotateQnumber(smRoot, smDeviceHandle) &0xFFFF,
623                                 oneDeviceData->phyID,
624                                 AGSA_PHY_HARD_RESET,
625                                 smLocalPhyControlCB
626                                 );
627
628      if ( status == AGSA_RC_SUCCESS)
629      {
630        return SM_RC_SUCCESS;
631      }
632      else if (status == AGSA_RC_BUSY)
633      {
634        return SM_RC_BUSY;
635      }
636      else if (status == AGSA_RC_FAILURE)
637      {
638        return SM_RC_FAILURE;
639      }
640      else
641      {
642        SM_DBG1(("smTaskManagement: unknown status %d\n",status));
643        return SM_RC_FAILURE;
644      }
645    }
646  }
647  else
648  {
649    /* smsatsmTaskManagement() which is satTM() */
650    smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot);
651
652    if (smIORequestBody == agNULL)
653    {
654      SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n"));
655      return SM_RC_FAILURE;
656    }
657
658    smIOReInit(smRoot, smIORequestBody);
659    /*currentTaskTag->smData = smIORequestBody;*/
660
661    status = smsatTaskManagement(smRoot,
662                                 smDeviceHandle,
663                                 task,
664                                 lun,
665                                 taskTag,
666                                 currentTaskTag,
667                                 smIORequestBody
668                                );
669
670    return status;
671  }
672  return SM_RC_SUCCESS;
673}
674
675
676
677/********************************************************* end smapi defined APIS */
678/* counterpart is
679   smEnqueueIO(smRoot_t       *smRoot,
680               smSatIOContext_t       *satIOContext)
681*/
682osGLOBAL smIORequestBody_t *
683smDequeueIO(smRoot_t          *smRoot)
684{
685  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
686  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
687  smIORequestBody_t         *smIORequestBody = agNULL;
688  smList_t                  *IOListList;
689
690  SM_DBG2(("smDequeueIO: start\n"));
691
692  tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
693  if (SMLIST_EMPTY(&(smAllShared->freeIOList)))
694  {
695    SM_DBG1(("smDequeueIO: empty freeIOList!!!\n"));
696    tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
697    return agNULL;
698  }
699
700  SMLIST_DEQUEUE_FROM_HEAD(&IOListList, &(smAllShared->freeIOList));
701  smIORequestBody = SMLIST_OBJECT_BASE(smIORequestBody_t, satIoBodyLink, IOListList);
702  SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink));
703  SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->mainIOList));
704  tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
705
706  if (smIORequestBody->InUse == agTRUE)
707  {
708    SM_DBG1(("smDequeueIO: wrong. already in USE ID %d!!!!\n", smIORequestBody->id));
709  }
710  smIOReInit(smRoot, smIORequestBody);
711
712
713  SM_DBG2(("smDequeueIO: io ID %d!\n", smIORequestBody->id));
714
715  /* debugging */
716  if (smIORequestBody->satIoBodyLink.flink == agNULL)
717  {
718    SM_DBG1(("smDequeueIO: io ID %d, flink is NULL!!!\n", smIORequestBody->id));
719  }
720  if (smIORequestBody->satIoBodyLink.blink == agNULL)
721  {
722    SM_DBG1(("smDequeueIO: io ID %d, blink is NULL!!!\n", smIORequestBody->id));
723  }
724
725  return smIORequestBody;
726}
727
728//start here
729//compare with ossaSATAAbortCB()
730//qqq1
731osGLOBAL void
732smsatAbort(
733           smRoot_t          *smRoot,
734           agsaRoot_t        *agRoot,
735           smSatIOContext_t  *satIOContext
736    )
737{
738  smIORequestBody_t         *smIORequestBody = agNULL; /* abort itself */
739  smIORequestBody_t         *smToBeAbortedIORequestBody; /* io to be aborted */
740  agsaIORequest_t           *agToBeAbortedIORequest; /* io to be aborted */
741  agsaIORequest_t           *agAbortIORequest;  /* abort io itself */
742  smSatIOContext_t          *satAbortIOContext;
743  bit32                      PhysUpper32;
744  bit32                      PhysLower32;
745  bit32                      memAllocStatus;
746  void                       *osMemHandle;
747
748
749  SM_DBG2(("smsatAbort: start\n"));
750
751  if (satIOContext == agNULL)
752  {
753    SM_DBG1(("smsatAbort: satIOContext is NULL, wrong!!!\n"));
754    return;
755  }
756
757  smToBeAbortedIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
758  agToBeAbortedIORequest = (agsaIORequest_t *)&(smToBeAbortedIORequestBody->agIORequest);
759  /*
760  smIORequestBody = smDequeueIO(smRoot);
761
762  if (smIORequestBody == agNULL)
763  {
764    SM_DBG1(("smsatAbort: empty freeIOList!!!\n"));
765    return;
766  }
767   */
768  /* allocating agIORequest for abort itself */
769  memAllocStatus = tdsmAllocMemory(
770                                   smRoot,
771                                   &osMemHandle,
772                                   (void **)&smIORequestBody,
773                                   &PhysUpper32,
774                                   &PhysLower32,
775                                   8,
776                                   sizeof(smIORequestBody_t),
777                                   agTRUE
778                                   );
779  if (memAllocStatus != tiSuccess)
780  {
781    /* let os process IO */
782    SM_DBG1(("smsatAbort: ostiAllocMemory failed...\n"));
783    return;
784  }
785
786  if (smIORequestBody == agNULL)
787  {
788    /* let os process IO */
789    SM_DBG1(("smsatAbort: ostiAllocMemory returned NULL smIORequestBody\n"));
790    return;
791  }
792  smIOReInit(smRoot, smIORequestBody);
793
794  smIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
795  smIORequestBody->smDevHandle = smToBeAbortedIORequestBody->smDevHandle;
796  /* initialize agIORequest */
797  satAbortIOContext = &(smIORequestBody->transport.SATA.satIOContext);
798  satAbortIOContext->smRequestBody = smIORequestBody;
799
800  agAbortIORequest = &(smIORequestBody->agIORequest);
801  agAbortIORequest->osData = (void *) smIORequestBody;
802  agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
803
804  /*
805   * Issue abort
806   */
807                                                                                                                                                                 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, smaSATAAbortCB);
808
809
810  SM_DBG1(("satAbort: end!!!\n"));
811
812  return;
813}
814
815osGLOBAL bit32
816smsatStartCheckPowerMode(
817                         smRoot_t                  *smRoot,
818                         smIORequest_t             *currentTaskTag,
819                         smDeviceHandle_t          *smDeviceHandle,
820                         smScsiInitiatorRequest_t  *smScsiRequest,
821                         smSatIOContext_t            *satIOContext
822                        )
823{
824  smSatInternalIo_t           *satIntIo = agNULL;
825  smDeviceData_t            *oneDeviceData = agNULL;
826  smSatIOContext_t            *satNewIOContext;
827  bit32                     status;
828
829  SM_DBG1(("smsatStartCheckPowerMode: start\n"));
830
831  oneDeviceData = satIOContext->pSatDevData;
832
833  SM_DBG6(("smsatStartCheckPowerMode: before alloc\n"));
834
835  /* allocate any fis for seting SRT bit in device control */
836  satIntIo = smsatAllocIntIoResource( smRoot,
837                                      currentTaskTag,
838                                      oneDeviceData,
839                                      0,
840                                      satIntIo);
841
842  SM_DBG6(("smsatStartCheckPowerMode: before after\n"));
843
844  if (satIntIo == agNULL)
845  {
846    SM_DBG1(("smsatStartCheckPowerMode: can't alloacate!!!\n"));
847    /*smEnqueueIO(smRoot, satIOContext);*/
848    return SM_RC_FAILURE;
849  }
850
851  satNewIOContext = smsatPrepareNewIO(satIntIo,
852                                      currentTaskTag,
853                                      oneDeviceData,
854                                      agNULL,
855                                      satIOContext);
856
857  SM_DBG6(("smsatStartCheckPowerMode: TD satIOContext %p \n", satIOContext));
858  SM_DBG6(("smsatStartCheckPowerMode: SM satNewIOContext %p \n", satNewIOContext));
859  SM_DBG6(("smsatStartCheckPowerMode: TD smScsiXchg %p \n", satIOContext->smScsiXchg));
860  SM_DBG6(("smsatStartCheckPowerMode: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg));
861
862
863
864  SM_DBG2(("smsatStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
865
866  status = smsatCheckPowerMode(smRoot,
867                               &satIntIo->satIntSmIORequest, /* New smIORequest */
868                               smDeviceHandle,
869                               satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *smScsiRequest, */
870                               satNewIOContext);
871
872  if (status != SM_RC_SUCCESS)
873  {
874    SM_DBG1(("smsatStartCheckPowerMode: failed in sending!!!\n"));
875
876    smsatFreeIntIoResource( smRoot,
877                            oneDeviceData,
878                            satIntIo);
879
880    /*smEnqueueIO(smRoot, satIOContext);*/
881
882    return SM_RC_FAILURE;
883  }
884
885
886  SM_DBG6(("smsatStartCheckPowerMode: end\n"));
887
888  return status;
889}
890
891osGLOBAL bit32
892smsatStartResetDevice(
893                       smRoot_t                  *smRoot,
894                       smIORequest_t             *currentTaskTag,
895                       smDeviceHandle_t          *smDeviceHandle,
896                       smScsiInitiatorRequest_t  *smScsiRequest,
897                       smSatIOContext_t            *satIOContext
898                     )
899{
900  smSatInternalIo_t           *satIntIo = agNULL;
901  smDeviceData_t            *oneDeviceData = agNULL;
902  smSatIOContext_t            *satNewIOContext;
903  bit32                     status;
904
905  SM_DBG1(("smsatStartResetDevice: start\n"));
906
907  oneDeviceData = satIOContext->pSatDevData;
908
909  SM_DBG6(("smsatStartResetDevice: before alloc\n"));
910
911  /* allocate any fis for seting SRT bit in device control */
912  satIntIo = smsatAllocIntIoResource( smRoot,
913                                      currentTaskTag,
914                                      oneDeviceData,
915                                      0,
916                                      satIntIo);
917
918  SM_DBG6(("smsatStartResetDevice: before after\n"));
919
920  if (satIntIo == agNULL)
921  {
922    SM_DBG1(("smsatStartResetDevice: can't alloacate!!!\n"));
923    /*smEnqueueIO(smRoot, satIOContext);*/
924    return SM_RC_FAILURE;
925  }
926
927  satNewIOContext = smsatPrepareNewIO(satIntIo,
928                                      currentTaskTag,
929                                      oneDeviceData,
930                                      agNULL,
931                                      satIOContext);
932
933  SM_DBG6(("smsatStartResetDevice: TD satIOContext %p \n", satIOContext));
934  SM_DBG6(("smsatStartResetDevice: SM satNewIOContext %p \n", satNewIOContext));
935  SM_DBG6(("smsatStartResetDevice: TD smScsiXchg %p \n", satIOContext->smScsiXchg));
936  SM_DBG6(("smsatStartResetDevice: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg));
937
938
939
940  SM_DBG6(("smsatStartResetDevice: satNewIOContext %p \n", satNewIOContext));
941
942  if (oneDeviceData->satDeviceType == SATA_ATAPI_DEVICE)
943  {
944      /*if ATAPI device, send DEVICE RESET command to ATAPI device*/
945      status = smsatDeviceReset(smRoot,
946                            &satIntIo->satIntSmIORequest, /* New smIORequest */
947                            smDeviceHandle,
948                            satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */
949                            satNewIOContext);
950  }
951  else
952  {
953      status = smsatResetDevice(smRoot,
954                            &satIntIo->satIntSmIORequest, /* New smIORequest */
955                            smDeviceHandle,
956                            satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */
957                            satNewIOContext);
958   }
959
960  if (status != SM_RC_SUCCESS)
961  {
962    SM_DBG1(("smsatStartResetDevice: failed in sending!!!\n"));
963
964    smsatFreeIntIoResource( smRoot,
965                            oneDeviceData,
966                            satIntIo);
967
968    /*smEnqueueIO(smRoot, satIOContext);*/
969
970    return SM_RC_FAILURE;
971  }
972
973
974  SM_DBG6(("smsatStartResetDevice: end\n"));
975
976  return status;
977}
978
979osGLOBAL bit32
980smsatTmAbortTask(
981                  smRoot_t                  *smRoot,
982                  smIORequest_t             *currentTaskTag, /* task management */
983                  smDeviceHandle_t          *smDeviceHandle,
984                  smScsiInitiatorRequest_t  *smScsiRequest, /* NULL */
985                  smSatIOContext_t            *satIOContext, /* task management */
986                  smIORequest_t             *taskTag) /* io to be aborted */
987{
988  smDeviceData_t          *oneDeviceData = agNULL;
989  smSatIOContext_t        *satTempIOContext = agNULL;
990  smList_t                *elementHdr;
991  bit32                   found = agFALSE;
992  smIORequestBody_t       *smIORequestBody = agNULL;
993  smIORequest_t           *smIOReq = agNULL;
994  bit32                   status;
995
996  SM_DBG1(("smsatTmAbortTask: start\n"));
997
998  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
999
1000  /*
1001   * Check that the only pending I/O matches taskTag. If not return tiError.
1002   */
1003  tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
1004
1005  elementHdr = oneDeviceData->satIoLinkList.flink;
1006
1007  while (elementHdr != &oneDeviceData->satIoLinkList)
1008  {
1009    satTempIOContext = SMLIST_OBJECT_BASE( smSatIOContext_t,
1010                                           satIoContextLink,
1011                                           elementHdr );
1012
1013    if ( satTempIOContext != agNULL)
1014    {
1015      smIORequestBody = (smIORequestBody_t *) satTempIOContext->smRequestBody;
1016      smIOReq = smIORequestBody->smIORequest;
1017    }
1018
1019    elementHdr = elementHdr->flink;   /* for the next while loop  */
1020
1021    /*
1022     * Check if the tag matches
1023     */
1024    if ( smIOReq == taskTag)
1025    {
1026      found = agTRUE;
1027      satIOContext->satToBeAbortedIOContext = satTempIOContext;
1028      SM_DBG1(("smsatTmAbortTask: found matching tag.\n"));
1029
1030      break;
1031
1032    } /* if matching tag */
1033
1034  } /* while loop */
1035
1036  tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
1037
1038  if (found == agFALSE )
1039  {
1040    SM_DBG1(("smsatTmAbortTask: *** REJECT *** no match!!!\n"));
1041
1042    /*smEnqueueIO(smRoot, satIOContext);*/
1043    /* clean up TD layer's smIORequestBody */
1044    if (smIORequestBody)
1045    {
1046      if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL)
1047      {
1048        tdsmFreeMemory(
1049                     smRoot,
1050                     smIORequestBody->IOType.InitiatorTMIO.osMemHandle,
1051                     sizeof(smIORequestBody_t)
1052                     );
1053      }
1054    }
1055    else
1056    {
1057      SM_DBG1(("smsatTmAbortTask: smIORequestBody is NULL!!!\n"));
1058    }
1059
1060    return SM_RC_FAILURE;
1061  }
1062
1063  if (satTempIOContext == agNULL)
1064  {
1065    SM_DBG1(("smsatTmAbortTask: satTempIOContext is NULL!!!\n"));
1066    return SM_RC_FAILURE;
1067  }
1068
1069  /*
1070   * Save smIORequest, will be returned at device reset completion to return
1071   * the TM completion.
1072   */
1073  oneDeviceData->satTmTaskTag = currentTaskTag;
1074
1075  /*
1076   * Set flag to indicate device in recovery mode.
1077   */
1078  oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
1079
1080
1081  /*
1082   * Issue SATA device reset or check power mode.. Set flag to to automatically abort
1083   * at the completion of SATA device reset.
1084   * SAT r09 p25
1085   */
1086  oneDeviceData->satAbortAfterReset = agTRUE;
1087
1088  if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
1089       (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
1090      )
1091  {
1092    SM_DBG1(("smsatTmAbortTask: calling satStartCheckPowerMode!!!\n"));
1093    /* send check power mode */
1094    status = smsatStartCheckPowerMode(
1095                                       smRoot,
1096                                       currentTaskTag, /* currentTaskTag */
1097                                       smDeviceHandle,
1098                                       smScsiRequest, /* NULL */
1099                                       satIOContext
1100                                     );
1101  }
1102  else
1103  {
1104    SM_DBG1(("smsatTmAbortTask: calling satStartResetDevice!!!\n"));
1105    /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */
1106    status = smsatStartResetDevice(
1107                                    smRoot,
1108                                    currentTaskTag, /* currentTaskTag */
1109                                    smDeviceHandle,
1110                                    smScsiRequest, /* NULL */
1111                                    satIOContext
1112                                  );
1113  }
1114  return status;
1115}
1116
1117/* satTM() */
1118osGLOBAL bit32
1119smsatTaskManagement(
1120                    smRoot_t          *smRoot,
1121                    smDeviceHandle_t  *smDeviceHandle,
1122                    bit32             task,
1123                    smLUN_t           *lun,
1124                    smIORequest_t     *taskTag, /* io to be aborted */
1125                    smIORequest_t     *currentTaskTag, /* task management */
1126                    smIORequestBody_t *smIORequestBody
1127       )
1128{
1129  smSatIOContext_t              *satIOContext = agNULL;
1130  smDeviceData_t              *oneDeviceData = agNULL;
1131  bit32                       status;
1132
1133  SM_DBG1(("smsatTaskManagement: start\n"));
1134  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
1135
1136  satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
1137
1138  satIOContext->pSatDevData   = oneDeviceData;
1139  satIOContext->pFis          =
1140    &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
1141
1142
1143  satIOContext->smRequestBody = smIORequestBody;
1144  satIOContext->psmDeviceHandle = smDeviceHandle;
1145  satIOContext->satIntIoContext  = agNULL;
1146  satIOContext->satOrgIOContext  = agNULL;
1147
1148  /* followings are used only for internal IO */
1149  satIOContext->currentLBA = 0;
1150  satIOContext->OrgTL = 0;
1151
1152  /* saving task in satIOContext */
1153  satIOContext->TMF = task;
1154
1155  satIOContext->satToBeAbortedIOContext = agNULL;
1156
1157  if (task == AG_ABORT_TASK)
1158  {
1159    status = smsatTmAbortTask( smRoot,
1160                               currentTaskTag,
1161                               smDeviceHandle,
1162                               agNULL,
1163                               satIOContext,
1164                               taskTag);
1165
1166    return status;
1167  }
1168  else
1169  {
1170    SM_DBG1(("smsatTaskManagement: UNSUPPORTED TM task=0x%x!!!\n", task ));
1171
1172    /*smEnqueueIO(smRoot, satIOContext);*/
1173
1174    return SM_RC_FAILURE;
1175  }
1176
1177  return SM_RC_SUCCESS;
1178}
1179
1180
1181osGLOBAL bit32
1182smPhyControlSend(
1183                  smRoot_t             *smRoot,
1184                  smDeviceData_t       *oneDeviceData, /* sata disk itself */
1185                  bit8                 phyOp,
1186                  smIORequest_t        *CurrentTaskTag,
1187                  bit32                queueNumber
1188                )
1189{
1190  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1191  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1192  agsaRoot_t                *agRoot = smAllShared->agRoot;
1193  agsaDevHandle_t           *agExpDevHandle;
1194  smpReqPhyControl_t        smpPhyControlReq;
1195  void                      *osMemHandle;
1196  bit32                     PhysUpper32;
1197  bit32                     PhysLower32;
1198  bit32                     memAllocStatus;
1199  bit32                     expectedRspLen = 0;
1200  smSMPRequestBody_t        *smSMPRequestBody;
1201  agsaSASRequestBody_t      *agSASRequestBody;
1202  agsaSMPFrame_t            *agSMPFrame;
1203  agsaIORequest_t           *agIORequest;
1204//  agsaDevHandle_t           *agDevHandle;
1205  smSMPFrameHeader_t        smSMPFrameHeader;
1206  bit32                     status;
1207  bit8                      *pSmpBody; /* smp payload itself w/o first 4 bytes(header) */
1208  bit32                     smpBodySize; /* smp payload size w/o first 4 bytes(header) */
1209  bit32                     agRequestType;
1210
1211  SM_DBG2(("smPhyControlSend: start\n"));
1212
1213  agExpDevHandle = oneDeviceData->agExpDevHandle;
1214
1215  if (agExpDevHandle == agNULL)
1216  {
1217    SM_DBG1(("smPhyControlSend: agExpDevHandle is NULL!!!\n"));
1218    return SM_RC_FAILURE;
1219  }
1220
1221  SM_DBG5(("smPhyControlSend: phyID %d\n", oneDeviceData->phyID));
1222
1223  sm_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t));
1224
1225  /* fill in SMP payload */
1226  smpPhyControlReq.phyIdentifier = (bit8)oneDeviceData->phyID;
1227  smpPhyControlReq.phyOperation = phyOp;
1228
1229  /* allocate smp and send it */
1230  memAllocStatus = tdsmAllocMemory(
1231                                   smRoot,
1232                                   &osMemHandle,
1233                                   (void **)&smSMPRequestBody,
1234                                   &PhysUpper32,
1235                                   &PhysLower32,
1236                                   8,
1237                                   sizeof(smSMPRequestBody_t),
1238                                   agTRUE
1239                                   );
1240
1241  if (memAllocStatus != SM_RC_SUCCESS)
1242  {
1243    SM_DBG1(("smPhyControlSend: tdsmAllocMemory failed...!!!\n"));
1244    return SM_RC_FAILURE;
1245  }
1246
1247  if (smSMPRequestBody == agNULL)
1248  {
1249    SM_DBG1(("smPhyControlSend: tdsmAllocMemory returned NULL smSMPRequestBody!!!\n"));
1250    return SM_RC_FAILURE;
1251  }
1252
1253  /* saves mem handle for freeing later */
1254  smSMPRequestBody->osMemHandle = osMemHandle;
1255
1256  /* saves oneDeviceData */
1257  smSMPRequestBody->smDeviceData = oneDeviceData; /* sata disk */
1258
1259  /* saves oneDeviceData */
1260  smSMPRequestBody->smDevHandle = oneDeviceData->smDevHandle;
1261
1262//  agDevHandle = oneDeviceData->agDevHandle;
1263
1264  /* save the callback funtion */
1265  smSMPRequestBody->SMPCompletionFunc = smSMPCompleted; /* in satcb.c */
1266
1267  /* for simulate warm target reset */
1268  smSMPRequestBody->CurrentTaskTag = CurrentTaskTag;
1269
1270  if (CurrentTaskTag != agNULL)
1271  {
1272    CurrentTaskTag->smData = smSMPRequestBody;
1273  }
1274
1275  /* initializes the number of SMP retries */
1276  smSMPRequestBody->retries = 0;
1277
1278#ifdef TD_INTERNAL_DEBUG  /* debugging */
1279  SM_DBG4(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody));
1280  SM_DBG4(("smPhyControlSend: callback fn %p\n", smSMPRequestBody->SMPCompletionFunc));
1281#endif
1282
1283  agIORequest = &(smSMPRequestBody->agIORequest);
1284  agIORequest->osData = (void *) smSMPRequestBody;
1285  agIORequest->sdkData = agNULL; /* SALL takes care of this */
1286
1287
1288  agSASRequestBody = &(smSMPRequestBody->agSASRequestBody);
1289  agSMPFrame = &(agSASRequestBody->smpFrame);
1290
1291  SM_DBG3(("smPhyControlSend: agIORequest %p\n", agIORequest));
1292  SM_DBG3(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody));
1293
1294  expectedRspLen = 4;
1295
1296  pSmpBody = (bit8 *)&smpPhyControlReq;
1297  smpBodySize = sizeof(smpReqPhyControl_t);
1298  agRequestType = AGSA_SMP_INIT_REQ;
1299
1300  if (SMIsSPC(agRoot))
1301  {
1302    if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */
1303    {
1304      SM_DBG3(("smPhyControlSend: DIRECT smp payload\n"));
1305      sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t));
1306      sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
1307
1308      /* SMP header */
1309      smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
1310      smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL;
1311      smSMPFrameHeader.smpFunctionResult = 0;
1312      smSMPFrameHeader.smpReserved = 0;
1313
1314      sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4);
1315      sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
1316
1317      /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
1318      agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload;
1319      agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
1320      /* to specify DIRECT SMP response */
1321      agSMPFrame->inFrameLen = 0;
1322
1323      /* temporary solution for T2D Combo*/
1324#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
1325      /* force smp repsonse to be direct */
1326      agSMPFrame->expectedRespLen = 0;
1327#else
1328      agSMPFrame->expectedRespLen = expectedRspLen;
1329#endif
1330  //    smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
1331  //    smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen);
1332  //    smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t));
1333    }
1334    else
1335    {
1336      SM_DBG1(("smPhyControlSend: INDIRECT smp payload, not supported!!!\n"));
1337      tdsmFreeMemory(
1338                     smRoot,
1339                     osMemHandle,
1340                     sizeof(smSMPRequestBody_t)
1341                     );
1342
1343      return SM_RC_FAILURE;
1344    }
1345  }
1346  else /* SPCv controller */
1347  {
1348    /* only direct mode for both request and response */
1349    SM_DBG3(("smPhyControlSend: DIRECT smp payload\n"));
1350    agSMPFrame->flag = 0;
1351    sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t));
1352    sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
1353
1354    /* SMP header */
1355    smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
1356    smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL;
1357    smSMPFrameHeader.smpFunctionResult = 0;
1358    smSMPFrameHeader.smpReserved = 0;
1359
1360    sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4);
1361    sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
1362
1363    /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
1364    agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload;
1365    agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
1366    /* to specify DIRECT SMP response */
1367    agSMPFrame->inFrameLen = 0;
1368
1369    /* temporary solution for T2D Combo*/
1370#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
1371    /* force smp repsonse to be direct */
1372    agSMPFrame->expectedRespLen = 0;
1373#else
1374    agSMPFrame->expectedRespLen = expectedRspLen;
1375#endif
1376//    smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
1377//    smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen);
1378//    smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t));
1379  }
1380
1381  status = saSMPStart(
1382                      agRoot,
1383                      agIORequest,
1384                      queueNumber,
1385                      agExpDevHandle,
1386                      agRequestType,
1387                      agSASRequestBody,
1388                      &smSMPCompletedCB
1389                      );
1390
1391  if (status == AGSA_RC_SUCCESS)
1392  {
1393    return SM_RC_SUCCESS;
1394  }
1395  else if (status == AGSA_RC_BUSY)
1396  {
1397    SM_DBG1(("smPhyControlSend: saSMPStart is busy!!!\n"));
1398    tdsmFreeMemory(
1399                   smRoot,
1400                   osMemHandle,
1401                   sizeof(smSMPRequestBody_t)
1402                   );
1403
1404    return SM_RC_BUSY;
1405  }
1406  else /* AGSA_RC_FAILURE */
1407  {
1408    SM_DBG1(("smPhyControlSend: saSMPStart is failed. status %d!!!\n", status));
1409    tdsmFreeMemory(
1410                   smRoot,
1411                   osMemHandle,
1412                   sizeof(smSMPRequestBody_t)
1413                   );
1414
1415    return SM_RC_FAILURE;
1416  }
1417}
1418
1419/* free IO which are internally completed within SM
1420   counterpart is
1421   osGLOBAL smIORequestBody_t *
1422   smDequeueIO(smRoot_t          *smRoot)
1423*/
1424osGLOBAL void
1425smEnqueueIO(
1426             smRoot_t               *smRoot,
1427             smSatIOContext_t         *satIOContext
1428      )
1429{
1430  smIntRoot_t          *smIntRoot = agNULL;
1431  smIntContext_t       *smAllShared = agNULL;
1432  smIORequestBody_t    *smIORequestBody;
1433
1434  SM_DBG3(("smEnqueueIO: start\n"));
1435  smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
1436  smIntRoot       = (smIntRoot_t *)smRoot->smData;
1437  smAllShared     = (smIntContext_t *)&smIntRoot->smAllShared;
1438
1439  /* enque back to smAllShared->freeIOList */
1440  if (satIOContext->satIntIoContext == agNULL)
1441  {
1442    SM_DBG2(("smEnqueueIO: external command!!!, io ID %d!!!\n", smIORequestBody->id));
1443    /* debugging only */
1444    if (smIORequestBody->satIoBodyLink.flink == agNULL)
1445    {
1446      SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id));
1447    }
1448    if (smIORequestBody->satIoBodyLink.blink == agNULL)
1449    {
1450      SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id));
1451    }
1452  }
1453  else
1454  {
1455    SM_DBG2(("smEnqueueIO: internal command!!!, io ID %d!!!\n", smIORequestBody->id));
1456    /* debugging only */
1457    if (smIORequestBody->satIoBodyLink.flink == agNULL)
1458    {
1459      SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id));
1460    }
1461    if (smIORequestBody->satIoBodyLink.blink == agNULL)
1462    {
1463      SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id));
1464    }
1465  }
1466
1467  if (smIORequestBody->smIORequest == agNULL)
1468  {
1469    SM_DBG1(("smEnqueueIO: smIORequest is NULL, io ID %d!!!\n", smIORequestBody->id));
1470  }
1471
1472  if (smIORequestBody->InUse == agTRUE)
1473  {
1474    smIORequestBody->InUse = agFALSE;
1475    tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
1476    SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink));
1477    SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->freeIOList));
1478    tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
1479  }
1480  else
1481  {
1482    SM_DBG2(("smEnqueueIO: check!!!, io ID %d!!!\n", smIORequestBody->id));
1483  }
1484
1485
1486  return;
1487}
1488
1489FORCEINLINE void
1490smsatFreeIntIoResource(
1491       smRoot_t              *smRoot,
1492       smDeviceData_t        *satDevData,
1493       smSatInternalIo_t     *satIntIo
1494       )
1495{
1496  SM_DBG3(("smsatFreeIntIoResource: start\n"));
1497
1498  if (satIntIo == agNULL)
1499  {
1500    SM_DBG2(("smsatFreeIntIoResource: allowed call\n"));
1501    return;
1502  }
1503
1504  /* sets the original smIOrequest to agNULL for internally generated ATA cmnd */
1505  satIntIo->satOrgSmIORequest = agNULL;
1506
1507  /*
1508   * Free DMA memory if previosly alocated
1509   */
1510  if (satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength != 0)
1511  {
1512    SM_DBG3(("smsatFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
1513    SM_DBG3(("smsatFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
1514
1515    tdsmFreeMemory( smRoot,
1516                    satIntIo->satIntDmaMem.osHandle,
1517                    satIntIo->satIntDmaMem.totalLength);
1518    satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0;
1519  }
1520
1521  if (satIntIo->satIntReqBodyMem.totalLength != 0)
1522  {
1523    SM_DBG3(("smsatFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
1524    /*
1525     * Free mem allocated for Req body
1526     */
1527    tdsmFreeMemory( smRoot,
1528                    satIntIo->satIntReqBodyMem.osHandle,
1529                    satIntIo->satIntReqBodyMem.totalLength);
1530
1531    satIntIo->satIntReqBodyMem.totalLength = 0;
1532  }
1533
1534  SM_DBG3(("smsatFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1535  /*
1536   * Return satIntIo to the free list
1537   */
1538  tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1539  SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
1540  SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
1541  tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1542
1543  return;
1544}
1545//start here
1546osGLOBAL smSatInternalIo_t *
1547smsatAllocIntIoResource(
1548                        smRoot_t              *smRoot,
1549                        smIORequest_t         *smIORequest,
1550                        smDeviceData_t        *satDevData,
1551                        bit32                 dmaAllocLength,
1552                        smSatInternalIo_t     *satIntIo)
1553{
1554  smList_t          *smList = agNULL;
1555  bit32             memAllocStatus;
1556
1557  SM_DBG3(("smsatAllocIntIoResource: start\n"));
1558  SM_DBG3(("smsatAllocIntIoResource: satIntIo %p\n", satIntIo));
1559  if (satDevData == agNULL)
1560  {
1561    SM_DBG1(("smsatAllocIntIoResource: ***** ASSERT satDevData is null!!!\n"));
1562    return agNULL;
1563  }
1564
1565  tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1566  if (!SMLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
1567  {
1568    SMLIST_DEQUEUE_FROM_HEAD(&smList, &(satDevData->satFreeIntIoLinkList));
1569  }
1570  else
1571  {
1572    tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1573    SM_DBG1(("smsatAllocIntIoResource() no more internal free link!!!\n"));
1574    return agNULL;
1575  }
1576
1577  if (smList == agNULL)
1578  {
1579    tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1580    SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc satIntIo!!!\n"));
1581    return agNULL;
1582  }
1583
1584  satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList);
1585  SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1586
1587  /* Put in active list */
1588  SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
1589  SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
1590  tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1591
1592#ifdef REMOVED
1593  /* Put in active list */
1594  tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1595  SMLIST_DEQUEUE_THIS (smList);
1596  SMLIST_ENQUEUE_AT_TAIL (smList, &(satDevData->satActiveIntIoLinkList));
1597  tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1598
1599  satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList);
1600  SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1601#endif
1602
1603  /*
1604    typedef struct
1605    {
1606      tdList_t                    satIntIoLink;
1607      smIORequest_t               satIntSmIORequest;
1608      void                        *satIntRequestBody;
1609      smScsiInitiatorRequest_t    satIntSmScsiXchg;
1610      smMem_t                     satIntDmaMem;
1611      smMem_t                     satIntReqBodyMem;
1612      bit32                       satIntFlag;
1613    } smSatInternalIo_t;
1614  */
1615
1616  /*
1617   * Allocate mem for Request Body
1618   */
1619  satIntIo->satIntReqBodyMem.totalLength = sizeof(smIORequestBody_t);
1620
1621  memAllocStatus = tdsmAllocMemory( smRoot,
1622                                    &satIntIo->satIntReqBodyMem.osHandle,
1623                                    (void **)&satIntIo->satIntRequestBody,
1624                                    &satIntIo->satIntReqBodyMem.physAddrUpper,
1625                                    &satIntIo->satIntReqBodyMem.physAddrLower,
1626                                    8,
1627                                    satIntIo->satIntReqBodyMem.totalLength,
1628                                    agTRUE );
1629
1630  if (memAllocStatus != SM_RC_SUCCESS)
1631  {
1632    SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for Req Body!!!\n"));
1633    /*
1634     * Return satIntIo to the free list
1635     */
1636    tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1637    SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
1638    SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
1639    tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1640
1641    return agNULL;
1642  }
1643
1644  /*
1645   *   Allocate DMA memory if required
1646   */
1647  if (dmaAllocLength != 0)
1648  {
1649    satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
1650
1651    memAllocStatus = tdsmAllocMemory( smRoot,
1652                                      &satIntIo->satIntDmaMem.osHandle,
1653                                      (void **)&satIntIo->satIntDmaMem.virtPtr,
1654                                      &satIntIo->satIntDmaMem.physAddrUpper,
1655                                      &satIntIo->satIntDmaMem.physAddrLower,
1656                                      8,
1657                                      satIntIo->satIntDmaMem.totalLength,
1658                                      agFALSE);
1659    SM_DBG3(("smsatAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
1660    SM_DBG3(("smsatAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
1661
1662    if (memAllocStatus != SM_RC_SUCCESS)
1663    {
1664      SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for DMA mem!!!\n"));
1665      /*
1666       * Return satIntIo to the free list
1667       */
1668      tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1669      SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
1670      SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
1671      tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1672
1673      /*
1674       * Free mem allocated for Req body
1675       */
1676      tdsmFreeMemory( smRoot,
1677                      satIntIo->satIntReqBodyMem.osHandle,
1678                      satIntIo->satIntReqBodyMem.totalLength);
1679
1680      return agNULL;
1681    }
1682  }
1683
1684  /*
1685    typedef struct
1686    {
1687      smList_t                    satIntIoLink;
1688      smIORequest_t               satIntSmIORequest;
1689      void                        *satIntRequestBody;
1690      smScsiInitiatorRequest_t    satIntSmScsiXchg;
1691      smMem_t                     satIntDmaMem;
1692      smMem_t                     satIntReqBodyMem;
1693      bit32                       satIntFlag;
1694    } smSatInternalIo_t;
1695  */
1696
1697  /*
1698   * Initialize satIntSmIORequest field
1699   */
1700  satIntIo->satIntSmIORequest.tdData = agNULL;  /* Not used for internal SAT I/O */
1701  satIntIo->satIntSmIORequest.smData = satIntIo->satIntRequestBody;
1702
1703  /*
1704   * saves the original smIOrequest
1705   */
1706  satIntIo->satOrgSmIORequest = smIORequest;
1707  /*
1708    typedef struct tiIniScsiCmnd
1709    {
1710      tiLUN_t     lun;
1711      bit32       expDataLength;
1712      bit32       taskAttribute;
1713      bit32       crn;
1714      bit8        cdb[16];
1715    } tiIniScsiCmnd_t;
1716
1717    typedef struct tiScsiInitiatorExchange
1718    {
1719      void                *sglVirtualAddr;
1720      tiIniScsiCmnd_t     scsiCmnd;
1721      tiSgl_t             agSgl1;
1722      tiSgl_t             agSgl2;
1723      tiDataDirection_t   dataDirection;
1724    } tiScsiInitiatorRequest_t;
1725
1726  */
1727
1728  /*
1729   * Initialize satIntSmScsiXchg. Since the internal SAT request is NOT
1730   * originated from SCSI request, only the following fields are initialized:
1731   *  - sglVirtualAddr if DMA transfer is involved
1732   *  - agSgl1 if DMA transfer is involved
1733   *  - expDataLength in scsiCmnd since this field is read by smsataLLIOStart()
1734   */
1735  if (dmaAllocLength != 0)
1736  {
1737    satIntIo->satIntSmScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
1738
1739    OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntSmScsiXchg.smSgl1.len, 0,
1740                     satIntIo->satIntDmaMem.totalLength);
1741    satIntIo->satIntSmScsiXchg.smSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
1742    satIntIo->satIntSmScsiXchg.smSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
1743    satIntIo->satIntSmScsiXchg.smSgl1.type  = tiSgl;
1744
1745    satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
1746  }
1747  else
1748  {
1749    satIntIo->satIntSmScsiXchg.sglVirtualAddr = agNULL;
1750
1751    satIntIo->satIntSmScsiXchg.smSgl1.len   = 0;
1752    satIntIo->satIntSmScsiXchg.smSgl1.lower = 0;
1753    satIntIo->satIntSmScsiXchg.smSgl1.upper = 0;
1754    satIntIo->satIntSmScsiXchg.smSgl1.type  = tiSgl;
1755
1756    satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0;
1757  }
1758
1759  SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len));
1760
1761  SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper));
1762
1763  SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower));
1764
1765  SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type));
1766  SM_DBG5(("smsatAllocIntIoResource: return satIntIo %p\n", satIntIo));
1767  return  satIntIo;
1768}
1769
1770osGLOBAL smDeviceData_t *
1771smAddToSharedcontext(
1772                     smRoot_t                   *smRoot,
1773                     agsaDevHandle_t            *agDevHandle,
1774                     smDeviceHandle_t           *smDeviceHandle,
1775                     agsaDevHandle_t            *agExpDevHandle,
1776                     bit32                      phyID
1777                    )
1778{
1779  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1780  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1781  smDeviceData_t            *oneDeviceData = agNULL;
1782  smList_t                  *DeviceListList;
1783  bit32                     new_device = agTRUE;
1784
1785  SM_DBG2(("smAddToSharedcontext: start\n"));
1786
1787  /* find a device's existence */
1788  DeviceListList = smAllShared->MainDeviceList.flink;
1789  while (DeviceListList != &(smAllShared->MainDeviceList))
1790  {
1791    oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList);
1792    if (oneDeviceData == agNULL)
1793    {
1794      SM_DBG1(("smAddToSharedcontext: oneDeviceData is NULL!!!\n"));
1795      return agNULL;
1796    }
1797    if (oneDeviceData->agDevHandle == agDevHandle)
1798    {
1799      SM_DBG2(("smAddToSharedcontext: did %d\n", oneDeviceData->id));
1800      new_device = agFALSE;
1801      break;
1802    }
1803    DeviceListList = DeviceListList->flink;
1804  }
1805
1806  /* new device */
1807  if (new_device == agTRUE)
1808  {
1809    SM_DBG2(("smAddToSharedcontext: new device\n"));
1810    tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1811    if (SMLIST_EMPTY(&(smAllShared->FreeDeviceList)))
1812    {
1813      tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1814      SM_DBG1(("smAddToSharedcontext: empty DeviceData FreeLink!!!\n"));
1815      smDeviceHandle->smData = agNULL;
1816      return agNULL;
1817    }
1818
1819    SMLIST_DEQUEUE_FROM_HEAD(&DeviceListList, &(smAllShared->FreeDeviceList));
1820    tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1821    oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, FreeLink, DeviceListList);
1822    oneDeviceData->smRoot = smRoot;
1823    oneDeviceData->agDevHandle = agDevHandle;
1824    oneDeviceData->valid = agTRUE;
1825    smDeviceHandle->smData = oneDeviceData;
1826    oneDeviceData->smDevHandle = smDeviceHandle;
1827    if (agExpDevHandle == agNULL)
1828    {
1829      oneDeviceData->directlyAttached = agTRUE;
1830    }
1831    else
1832    {
1833      oneDeviceData->directlyAttached = agFALSE;
1834    }
1835    oneDeviceData->agExpDevHandle = agExpDevHandle;
1836    oneDeviceData->phyID = phyID;
1837    oneDeviceData->satPendingIO = 0;
1838    oneDeviceData->satPendingNCQIO = 0;
1839    oneDeviceData->satPendingNONNCQIO = 0;
1840    /* add the devicedata to the portcontext */
1841    tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1842    SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->MainLink), &(smAllShared->MainDeviceList));
1843    tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1844    SM_DBG2(("smAddToSharedcontext: new case did %d\n", oneDeviceData->id));
1845  }
1846  else
1847  {
1848    SM_DBG2(("smAddToSharedcontext: old device\n"));
1849    oneDeviceData->smRoot = smRoot;
1850    oneDeviceData->agDevHandle = agDevHandle;
1851    oneDeviceData->valid = agTRUE;
1852    smDeviceHandle->smData = oneDeviceData;
1853    oneDeviceData->smDevHandle = smDeviceHandle;
1854    if (agExpDevHandle == agNULL)
1855    {
1856      oneDeviceData->directlyAttached = agTRUE;
1857    }
1858    else
1859    {
1860      oneDeviceData->directlyAttached = agFALSE;
1861    }
1862    oneDeviceData->agExpDevHandle = agExpDevHandle;
1863    oneDeviceData->phyID = phyID;
1864    oneDeviceData->satPendingIO = 0;
1865    oneDeviceData->satPendingNCQIO = 0;
1866    oneDeviceData->satPendingNONNCQIO = 0;
1867    SM_DBG2(("smAddToSharedcontext: old case did %d\n", oneDeviceData->id));
1868  }
1869
1870  return  oneDeviceData;
1871}
1872
1873osGLOBAL bit32
1874smRemoveFromSharedcontext(
1875                          smRoot_t                      *smRoot,
1876                          agsaDevHandle_t               *agDevHandle,
1877                          smDeviceHandle_t              *smDeviceHandle
1878                         )
1879{
1880  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1881  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1882  smDeviceData_t            *oneDeviceData = agNULL;
1883
1884  SM_DBG2(("smRemoveFromSharedcontext: start\n"));
1885
1886  //due to device all and completion
1887  //smDeviceHandle->smData = agNULL;
1888
1889  /* find oneDeviceData from MainLink */
1890  oneDeviceData = smFindInSharedcontext(smRoot, agDevHandle);
1891
1892  if (oneDeviceData == agNULL)
1893  {
1894    return SM_RC_FAILURE;
1895  }
1896  else
1897  {
1898    if (oneDeviceData->valid == agTRUE)
1899    {
1900      smDeviceDataReInit(smRoot, oneDeviceData);
1901      tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1902      SMLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
1903      SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(smAllShared->FreeDeviceList));
1904      tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1905      return SM_RC_SUCCESS;
1906    }
1907    else
1908    {
1909      SM_DBG1(("smRemoveFromSharedcontext: did %d bad case!!!\n", oneDeviceData->id));
1910      return SM_RC_FAILURE;
1911    }
1912  }
1913
1914}
1915
1916osGLOBAL smDeviceData_t *
1917smFindInSharedcontext(
1918                      smRoot_t                  *smRoot,
1919                      agsaDevHandle_t           *agDevHandle
1920                      )
1921{
1922  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1923  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1924  smDeviceData_t            *oneDeviceData = agNULL;
1925  smList_t                  *DeviceListList;
1926
1927  SM_DBG2(("smFindInSharedcontext: start\n"));
1928
1929  tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1930  if (SMLIST_EMPTY(&(smAllShared->MainDeviceList)))
1931  {
1932    SM_DBG1(("smFindInSharedcontext: empty MainDeviceList!!!\n"));
1933    tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1934    return agNULL;
1935  }
1936  else
1937  {
1938    tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1939  }
1940
1941  DeviceListList = smAllShared->MainDeviceList.flink;
1942  while (DeviceListList != &(smAllShared->MainDeviceList))
1943  {
1944    oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList);
1945    if (oneDeviceData == agNULL)
1946    {
1947      SM_DBG1(("smFindInSharedcontext: oneDeviceData is NULL!!!\n"));
1948      return agNULL;
1949    }
1950    if ((oneDeviceData->agDevHandle == agDevHandle) &&
1951        (oneDeviceData->valid == agTRUE)
1952       )
1953    {
1954      SM_DBG2(("smFindInSharedcontext: found, did %d\n", oneDeviceData->id));
1955      return oneDeviceData;
1956    }
1957    DeviceListList = DeviceListList->flink;
1958  }
1959  SM_DBG2(("smFindInSharedcontext: not found\n"));
1960  return agNULL;
1961}
1962
1963osGLOBAL smSatIOContext_t *
1964smsatPrepareNewIO(
1965                  smSatInternalIo_t       *satNewIntIo,
1966                  smIORequest_t           *smOrgIORequest,
1967                  smDeviceData_t          *satDevData,
1968                  smIniScsiCmnd_t         *scsiCmnd,
1969                  smSatIOContext_t        *satOrgIOContext
1970                 )
1971{
1972  smSatIOContext_t        *satNewIOContext;
1973  smIORequestBody_t       *smNewIORequestBody;
1974
1975  SM_DBG3(("smsatPrepareNewIO: start\n"));
1976
1977  /* the one to be used; good 8/2/07 */
1978  satNewIntIo->satOrgSmIORequest = smOrgIORequest; /* this is already done in
1979                                                      smsatAllocIntIoResource() */
1980
1981  smNewIORequestBody = (smIORequestBody_t *)satNewIntIo->satIntRequestBody;
1982  satNewIOContext = &(smNewIORequestBody->transport.SATA.satIOContext);
1983
1984  satNewIOContext->pSatDevData   = satDevData;
1985  satNewIOContext->pFis          = &(smNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
1986  satNewIOContext->pScsiCmnd     = &(satNewIntIo->satIntSmScsiXchg.scsiCmnd);
1987  if (scsiCmnd != agNULL)
1988  {
1989    /* saves only CBD; not scsi command for LBA and number of blocks */
1990    sm_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
1991  }
1992  satNewIOContext->pSense        = &(smNewIORequestBody->transport.SATA.sensePayload);
1993  satNewIOContext->pSmSenseData  = &(smNewIORequestBody->transport.SATA.smSenseData);
1994  satNewIOContext->pSmSenseData->senseData = satNewIOContext->pSense;
1995  satNewIOContext->smRequestBody = satNewIntIo->satIntRequestBody;
1996  satNewIOContext->interruptContext = satNewIOContext->interruptContext;
1997  satNewIOContext->satIntIoContext  = satNewIntIo;
1998  satNewIOContext->psmDeviceHandle = satOrgIOContext->psmDeviceHandle;
1999  satNewIOContext->satOrgIOContext = satOrgIOContext;
2000  /* saves tiScsiXchg; only for writesame10() */
2001  satNewIOContext->smScsiXchg = satOrgIOContext->smScsiXchg;
2002
2003  return satNewIOContext;
2004}
2005
2006
2007osGLOBAL void
2008smsatSetDevInfo(
2009                 smDeviceData_t            *oneDeviceData,
2010                 agsaSATAIdentifyData_t    *SATAIdData
2011               )
2012{
2013  SM_DBG3(("smsatSetDevInfo: start\n"));
2014
2015  oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
2016  oneDeviceData->satFormatState = agFALSE;
2017  oneDeviceData->satDeviceFaultState = agFALSE;
2018  oneDeviceData->satTmTaskTag  = agNULL;
2019  oneDeviceData->satAbortAfterReset = agFALSE;
2020  oneDeviceData->satAbortCalled = agFALSE;
2021  oneDeviceData->satSectorDone  = 0;
2022
2023  /* Qeueu depth, Word 75 */
2024  oneDeviceData->satNCQMaxIO = SATAIdData->queueDepth + 1;
2025  SM_DBG3(("smsatSetDevInfo: max queue depth %d\n",oneDeviceData->satNCQMaxIO));
2026
2027  /* Support NCQ, if Word 76 bit 8 is set */
2028  if (SATAIdData->sataCapabilities & 0x100)
2029  {
2030    SM_DBG3(("smsatSetDevInfo: device supports NCQ\n"));
2031    oneDeviceData->satNCQ   = agTRUE;
2032  }
2033  else
2034  {
2035    SM_DBG3(("smsatSetDevInfo: no NCQ\n"));
2036    oneDeviceData->satNCQ = agFALSE;
2037  }
2038
2039  /* Support 48 bit addressing, if Word 83 bit 10 and Word 86 bit 10 are set */
2040  if ((SATAIdData->commandSetSupported1 & 0x400) &&
2041      (SATAIdData->commandSetFeatureEnabled1 & 0x400) )
2042  {
2043    SM_DBG3(("smsatSetDevInfo: support 48 bit addressing\n"));
2044    oneDeviceData->sat48BitSupport = agTRUE;
2045  }
2046  else
2047  {
2048    SM_DBG3(("smsatSetDevInfo: NO 48 bit addressing\n"));
2049    oneDeviceData->sat48BitSupport = agFALSE;
2050  }
2051
2052  /* Support SMART Self Test, word84 bit 1 */
2053  if (SATAIdData->commandSetFeatureSupportedExt & 0x02)
2054  {
2055    SM_DBG3(("smsatSetDevInfo: SMART self-test supported \n"));
2056    oneDeviceData->satSMARTSelfTest   = agTRUE;
2057  }
2058  else
2059  {
2060    SM_DBG3(("smsatSetDevInfo: no SMART self-test suppored\n"));
2061    oneDeviceData->satSMARTSelfTest = agFALSE;
2062  }
2063
2064  /* Support SMART feature set, word82 bit 0 */
2065  if (SATAIdData->commandSetSupported & 0x01)
2066  {
2067    SM_DBG3(("smsatSetDevInfo: SMART feature set supported \n"));
2068    oneDeviceData->satSMARTFeatureSet   = agTRUE;
2069  }
2070  else
2071  {
2072    SM_DBG3(("smsatSetDevInfo: no SMART feature set suppored\n"));
2073    oneDeviceData->satSMARTFeatureSet = agFALSE;
2074  }
2075
2076  /* Support SMART enabled, word85 bit 0 */
2077  if (SATAIdData->commandSetFeatureEnabled & 0x01)
2078  {
2079    SM_DBG3(("smsatSetDevInfo: SMART enabled \n"));
2080    oneDeviceData->satSMARTEnabled   = agTRUE;
2081  }
2082  else
2083  {
2084    SM_DBG3(("smsatSetDevInfo: no SMART enabled\n"));
2085    oneDeviceData->satSMARTEnabled = agFALSE;
2086  }
2087
2088  oneDeviceData->satVerifyState = 0;
2089
2090  /* Removable Media feature set support, word82 bit 2 */
2091  if (SATAIdData->commandSetSupported & 0x4)
2092  {
2093    SM_DBG3(("smsatSetDevInfo: Removable Media supported \n"));
2094    oneDeviceData->satRemovableMedia   = agTRUE;
2095  }
2096  else
2097  {
2098    SM_DBG3(("smsatSetDevInfo: no Removable Media suppored\n"));
2099    oneDeviceData->satRemovableMedia = agFALSE;
2100  }
2101
2102  /* Removable Media feature set enabled, word 85, bit 2 */
2103  if (SATAIdData->commandSetFeatureEnabled & 0x4)
2104  {
2105    SM_DBG3(("smsatSetDevInfo: Removable Media enabled\n"));
2106    oneDeviceData->satRemovableMediaEnabled   = agTRUE;
2107  }
2108  else
2109  {
2110    SM_DBG3(("smsatSetDevInfo: no Removable Media enabled\n"));
2111    oneDeviceData->satRemovableMediaEnabled = agFALSE;
2112  }
2113
2114  /* DMA Support, word49 bit8 */
2115  if (SATAIdData->dma_lba_iod_ios_stimer & 0x100)
2116  {
2117    SM_DBG3(("smsatSetDevInfo: DMA supported \n"));
2118    oneDeviceData->satDMASupport   = agTRUE;
2119  }
2120  else
2121  {
2122    SM_DBG3(("smsatSetDevInfo: no DMA suppored\n"));
2123    oneDeviceData->satDMASupport = agFALSE;
2124  }
2125
2126  /* Support DMADIR, if Word 62 bit 8 is set */
2127  if (SATAIdData->word62_74[0] & 0x8000)
2128  {
2129     SM_DBG3(("satSetDevInfo: DMADIR enabled\n"));
2130     oneDeviceData->satDMADIRSupport   = agTRUE;
2131  }
2132  else
2133  {
2134     SM_DBG3(("satSetDevInfo: DMADIR disabled\n"));
2135     oneDeviceData->satDMADIRSupport   = agFALSE;
2136  }
2137
2138  /* DMA Enabled, word88 bit0-6, bit8-14*/
2139  /* 0x7F7F = 0111 1111 0111 1111*/
2140  if (SATAIdData->ultraDMAModes & 0x7F7F)
2141  {
2142    SM_DBG3(("smsatSetDevInfo: DMA enabled \n"));
2143    oneDeviceData->satDMAEnabled   = agTRUE;
2144    if (SATAIdData->ultraDMAModes & 0x40)
2145    {
2146       oneDeviceData->satUltraDMAMode = 6;
2147    }
2148    else if (SATAIdData->ultraDMAModes & 0x20)
2149    {
2150       oneDeviceData->satUltraDMAMode = 5;
2151    }
2152    else if (SATAIdData->ultraDMAModes & 0x10)
2153    {
2154       oneDeviceData->satUltraDMAMode = 4;
2155    }
2156    else if (SATAIdData->ultraDMAModes & 0x08)
2157    {
2158       oneDeviceData->satUltraDMAMode = 3;
2159    }
2160    else if (SATAIdData->ultraDMAModes & 0x04)
2161    {
2162       oneDeviceData->satUltraDMAMode = 2;
2163    }
2164    else if (SATAIdData->ultraDMAModes & 0x01)
2165    {
2166       oneDeviceData->satUltraDMAMode = 1;
2167    }
2168  }
2169  else
2170  {
2171    SM_DBG3(("smsatSetDevInfo: no DMA enabled\n"));
2172    oneDeviceData->satDMAEnabled = agFALSE;
2173    oneDeviceData->satUltraDMAMode = 0;
2174  }
2175
2176  /*
2177    setting MaxUserAddrSectors: max user addressable setctors
2178    word60 - 61, should be 0x 0F FF FF FF
2179  */
2180  oneDeviceData->satMaxUserAddrSectors
2181    = (SATAIdData->numOfUserAddressableSectorsHi << (8*2) )
2182    + SATAIdData->numOfUserAddressableSectorsLo;
2183  SM_DBG3(("smsatSetDevInfo: MaxUserAddrSectors 0x%x decimal %d\n", oneDeviceData->satMaxUserAddrSectors, oneDeviceData->satMaxUserAddrSectors));
2184
2185  /* Read Look-ahead is supported */
2186  if (SATAIdData->commandSetSupported & 0x40)
2187  {
2188    SM_DBG3(("smsatSetDevInfo: Read Look-ahead is supported\n"));
2189    oneDeviceData->satReadLookAheadSupport= agTRUE;
2190  }
2191  else
2192  {
2193    SM_DBG3(("smsatSetDevInfo: Read Look-ahead is not supported\n"));
2194    oneDeviceData->satReadLookAheadSupport= agFALSE;
2195  }
2196
2197  /* Volatile Write Cache is supported */
2198  if (SATAIdData->commandSetSupported & 0x20)
2199  {
2200    SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is supported\n"));
2201    oneDeviceData->satVolatileWriteCacheSupport = agTRUE;
2202  }
2203  else
2204  {
2205    SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is not supported\n"));
2206    oneDeviceData->satVolatileWriteCacheSupport = agFALSE;
2207  }
2208
2209  /* write cache enabled for caching mode page SAT Table 67 p69, word85 bit5 */
2210  if (SATAIdData->commandSetFeatureEnabled & 0x20)
2211  {
2212    SM_DBG3(("smsatSetDevInfo: write cache enabled\n"));
2213    oneDeviceData->satWriteCacheEnabled   = agTRUE;
2214  }
2215  else
2216  {
2217    SM_DBG3(("smsatSetDevInfo: no write cache enabled\n"));
2218    oneDeviceData->satWriteCacheEnabled = agFALSE;
2219  }
2220
2221  /* look ahead enabled for caching mode page SAT Table 67 p69, word85 bit6 */
2222  if (SATAIdData->commandSetFeatureEnabled & 0x40)
2223  {
2224    SM_DBG3(("smsatSetDevInfo: look ahead enabled\n"));
2225    oneDeviceData->satLookAheadEnabled   = agTRUE;
2226  }
2227  else
2228  {
2229    SM_DBG3(("smsatSetDevInfo: no look ahead enabled\n"));
2230    oneDeviceData->satLookAheadEnabled = agFALSE;
2231  }
2232
2233  /* Support WWN, if Word 87 bit 8 is set */
2234  if (SATAIdData->commandSetFeatureDefault & 0x100)
2235  {
2236    SM_DBG3(("smsatSetDevInfo: device supports WWN\n"));
2237    oneDeviceData->satWWNSupport   = agTRUE;
2238  }
2239  else
2240  {
2241    SM_DBG3(("smsatSetDevInfo: no WWN\n"));
2242    oneDeviceData->satWWNSupport = agFALSE;
2243  }
2244
2245  /* Support DMA Setup Auto-Activate, if Word 78 bit 2 is set */
2246  if (SATAIdData->sataFeaturesSupported & 0x4)
2247  {
2248    SM_DBG3(("smsatSetDevInfo: device supports DMA Setup Auto-Activate\n"));
2249    oneDeviceData->satDMASetupAA   = agTRUE;
2250  }
2251  else
2252  {
2253    SM_DBG3(("smsatSetDevInfo: no DMA Setup Auto-Activate\n"));
2254    oneDeviceData->satDMASetupAA = agFALSE;
2255  }
2256
2257  /* Support NCQ Queue Management Command, if Word 77 bit 5 is set */
2258  if (SATAIdData->word77 & 0x10)
2259  {
2260    SM_DBG3(("smsatSetDevInfo: device supports NCQ Queue Management Command\n"));
2261    oneDeviceData->satNCQQMgntCmd   = agTRUE;
2262  }
2263  else
2264  {
2265    SM_DBG3(("smsatSetDevInfo: no NCQ Queue Management Command\n"));
2266    oneDeviceData->satNCQQMgntCmd = agFALSE;
2267  }
2268  return;
2269}
2270
2271
2272osGLOBAL void
2273smsatInquiryStandard(
2274                     bit8                    *pInquiry,
2275                     agsaSATAIdentifyData_t  *pSATAIdData,
2276                     smIniScsiCmnd_t         *scsiCmnd
2277                    )
2278{
2279  smLUN_t       *pLun;
2280  pLun          = &scsiCmnd->lun;
2281
2282  /*
2283    Assumption: Basic Task Mangement is supported
2284    -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147
2285  */
2286 /*
2287    See SPC-4, 6.4.2, p 143
2288    and SAT revision 8, 8.1.2, p 28
2289   */
2290  SM_DBG5(("smsatInquiryStandard: start\n"));
2291
2292  if (pInquiry == agNULL)
2293  {
2294    SM_DBG1(("smsatInquiryStandard: pInquiry is NULL, wrong\n"));
2295    return;
2296  }
2297  else
2298  {
2299    SM_DBG5(("smsatInquiryStandard: pInquiry is NOT NULL\n"));
2300  }
2301  /*
2302   * Reject all other LUN other than LUN 0.
2303   */
2304  if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
2305         pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) )
2306  {
2307    /* SAT Spec Table 8, p27, footnote 'a' */
2308    pInquiry[0] = 0x7F;
2309
2310  }
2311  else
2312  {
2313    pInquiry[0] = 0x00;
2314  }
2315
2316  if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
2317  {
2318    pInquiry[1] = 0x80;
2319  }
2320  else
2321  {
2322    pInquiry[1] = 0x00;
2323  }
2324  pInquiry[2] = 0x05;   /* SPC-3 */
2325  pInquiry[3] = 0x12;   /* set HiSup 1; resp data format set to 2 */
2326  pInquiry[4] = 0x1F;   /* 35 - 4 = 31; Additional length */
2327  pInquiry[5] = 0x00;
2328  /* The following two are for task management. SAT Rev8, p20 */
2329  if (pSATAIdData->sataCapabilities & 0x100)
2330  {
2331    /* NCQ supported; multiple outstanding SCSI IO are supported */
2332    pInquiry[6] = 0x00;   /* BQUE bit is not set */
2333    pInquiry[7] = 0x02;   /* CMDQUE bit is set */
2334  }
2335  else
2336  {
2337    pInquiry[6] = 0x80;   /* BQUE bit is set */
2338    pInquiry[7] = 0x00;   /* CMDQUE bit is not set */
2339  }
2340  /*
2341   * Vendor ID.
2342   */
2343  sm_strncpy((char*)&pInquiry[8],  AG_SAT_VENDOR_ID_STRING, 8);   /* 8 bytes   */
2344
2345  /*
2346   * Product ID
2347   */
2348  /* when flipped by LL */
2349  pInquiry[16] = pSATAIdData->modelNumber[1];
2350  pInquiry[17] = pSATAIdData->modelNumber[0];
2351  pInquiry[18] = pSATAIdData->modelNumber[3];
2352  pInquiry[19] = pSATAIdData->modelNumber[2];
2353  pInquiry[20] = pSATAIdData->modelNumber[5];
2354  pInquiry[21] = pSATAIdData->modelNumber[4];
2355  pInquiry[22] = pSATAIdData->modelNumber[7];
2356  pInquiry[23] = pSATAIdData->modelNumber[6];
2357  pInquiry[24] = pSATAIdData->modelNumber[9];
2358  pInquiry[25] = pSATAIdData->modelNumber[8];
2359  pInquiry[26] = pSATAIdData->modelNumber[11];
2360  pInquiry[27] = pSATAIdData->modelNumber[10];
2361  pInquiry[28] = pSATAIdData->modelNumber[13];
2362  pInquiry[29] = pSATAIdData->modelNumber[12];
2363  pInquiry[30] = pSATAIdData->modelNumber[15];
2364  pInquiry[31] = pSATAIdData->modelNumber[14];
2365
2366  /* when flipped */
2367  /*
2368   * Product Revision level.
2369   */
2370
2371  /*
2372   * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
2373   * device are ASCII spaces (20h), do this translation.
2374   */
2375  if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
2376       (pSATAIdData->firmwareVersion[5] == 0x20 ) &&
2377       (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
2378       (pSATAIdData->firmwareVersion[7] == 0x20 )
2379       )
2380  {
2381    pInquiry[32] = pSATAIdData->firmwareVersion[1];
2382    pInquiry[33] = pSATAIdData->firmwareVersion[0];
2383    pInquiry[34] = pSATAIdData->firmwareVersion[3];
2384    pInquiry[35] = pSATAIdData->firmwareVersion[2];
2385  }
2386  else
2387  {
2388    pInquiry[32] = pSATAIdData->firmwareVersion[5];
2389    pInquiry[33] = pSATAIdData->firmwareVersion[4];
2390    pInquiry[34] = pSATAIdData->firmwareVersion[7];
2391    pInquiry[35] = pSATAIdData->firmwareVersion[6];
2392  }
2393
2394
2395#ifdef REMOVED
2396  /*
2397   * Product ID
2398   */
2399  /* when flipped by LL */
2400  pInquiry[16] = pSATAIdData->modelNumber[0];
2401  pInquiry[17] = pSATAIdData->modelNumber[1];
2402  pInquiry[18] = pSATAIdData->modelNumber[2];
2403  pInquiry[19] = pSATAIdData->modelNumber[3];
2404  pInquiry[20] = pSATAIdData->modelNumber[4];
2405  pInquiry[21] = pSATAIdData->modelNumber[5];
2406  pInquiry[22] = pSATAIdData->modelNumber[6];
2407  pInquiry[23] = pSATAIdData->modelNumber[7];
2408  pInquiry[24] = pSATAIdData->modelNumber[8];
2409  pInquiry[25] = pSATAIdData->modelNumber[9];
2410  pInquiry[26] = pSATAIdData->modelNumber[10];
2411  pInquiry[27] = pSATAIdData->modelNumber[11];
2412  pInquiry[28] = pSATAIdData->modelNumber[12];
2413  pInquiry[29] = pSATAIdData->modelNumber[13];
2414  pInquiry[30] = pSATAIdData->modelNumber[14];
2415  pInquiry[31] = pSATAIdData->modelNumber[15];
2416
2417  /* when flipped */
2418  /*
2419   * Product Revision level.
2420   */
2421
2422  /*
2423   * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
2424   * device are ASCII spaces (20h), do this translation.
2425   */
2426  if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
2427       (pSATAIdData->firmwareVersion[5] == 0x20 ) &&
2428       (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
2429       (pSATAIdData->firmwareVersion[7] == 0x20 )
2430       )
2431  {
2432    pInquiry[32] = pSATAIdData->firmwareVersion[0];
2433    pInquiry[33] = pSATAIdData->firmwareVersion[1];
2434    pInquiry[34] = pSATAIdData->firmwareVersion[2];
2435    pInquiry[35] = pSATAIdData->firmwareVersion[3];
2436  }
2437  else
2438  {
2439    pInquiry[32] = pSATAIdData->firmwareVersion[4];
2440    pInquiry[33] = pSATAIdData->firmwareVersion[5];
2441    pInquiry[34] = pSATAIdData->firmwareVersion[6];
2442    pInquiry[35] = pSATAIdData->firmwareVersion[7];
2443  }
2444#endif
2445
2446  SM_DBG5(("smsatInquiryStandard: end\n"));
2447
2448  return;
2449}
2450
2451osGLOBAL void
2452smsatInquiryPage0(
2453                   bit8                    *pInquiry,
2454                   agsaSATAIdentifyData_t  *pSATAIdData
2455     )
2456{
2457  SM_DBG5(("smsatInquiryPage0: start\n"));
2458
2459  /*
2460    See SPC-4, 7.6.9, p 345
2461    and SAT revision 8, 10.3.2, p 77
2462   */
2463  pInquiry[0] = 0x00;
2464  pInquiry[1] = 0x00; /* page code */
2465  pInquiry[2] = 0x00; /* reserved */
2466  pInquiry[3] = 8 - 3; /* last index(in this case, 6) - 3; page length */
2467
2468  /* supported vpd page list */
2469  pInquiry[4] = 0x00; /* page 0x00 supported */
2470  pInquiry[5] = 0x80; /* page 0x80 supported */
2471  pInquiry[6] = 0x83; /* page 0x83 supported */
2472  pInquiry[7] = 0x89; /* page 0x89 supported */
2473  pInquiry[8] = 0xB1; /* page 0xB1 supported */
2474
2475  return;
2476}
2477
2478osGLOBAL void
2479smsatInquiryPage83(
2480                    bit8                    *pInquiry,
2481                    agsaSATAIdentifyData_t  *pSATAIdData,
2482                    smDeviceData_t          *oneDeviceData
2483      )
2484{
2485  satSimpleSATAIdentifyData_t   *pSimpleData;
2486
2487  /*
2488   * When translating the fields, in some cases using the simple form of SATA
2489   * Identify Device Data is easier. So we define it here.
2490   * Both pSimpleData and pSATAIdData points to the same data.
2491   */
2492  pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2493
2494  SM_DBG5(("smsatInquiryPage83: start\n"));
2495
2496  pInquiry[0] = 0x00;
2497  pInquiry[1] = 0x83; /* page code */
2498  pInquiry[2] = 0;    /* Reserved */
2499  /*
2500   * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE
2501   * data indicating that it supports the WORLD WIDE NAME field
2502   * (i.e., words 108-111), the SATL shall include an identification descriptor
2503   * containing a logical unit name.
2504   */
2505  if ( oneDeviceData->satWWNSupport)
2506  {
2507#ifndef PMC_FREEBSD
2508    /* Fill in SAT Rev8 Table85 */
2509    /*
2510     * Logical unit name derived from the world wide name.
2511     */
2512    pInquiry[3] = 12;         /* 15-3; page length, no addition ID descriptor assumed*/
2513
2514    /*
2515     * Identifier descriptor
2516     */
2517    pInquiry[4]  = 0x01;                        /* Code set: binary codes */
2518    pInquiry[5]  = 0x03;                        /* Identifier type : NAA  */
2519    pInquiry[6]  = 0x00;                        /* Reserved               */
2520    pInquiry[7]  = 0x08;                        /* Identifier length      */
2521
2522    /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
2523    pInquiry[8]  = (bit8)((pSATAIdData->namingAuthority) >> 8);
2524    pInquiry[9]  = (bit8)((pSATAIdData->namingAuthority) & 0xFF);           /* IEEE Company ID */
2525    pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8);            /* IEEE Company ID */
2526    /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
2527    pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
2528    pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8);       /* Vendor Specific ID  */
2529    pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF);     /* Vendor Specific ID  */
2530    pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8);        /* Vendor Specific ID  */
2531    pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF);      /* Vendor Specific ID  */
2532
2533#else
2534
2535    /* For FreeBSD */
2536
2537    /* Fill in SAT Rev8 Table85 */
2538    /*
2539     * Logical unit name derived from the world wide name.
2540     */
2541    pInquiry[3] = 24;         /* 35-3; page length, no addition ID descriptor assumed*/
2542   /*
2543     * Identifier descriptor
2544     */
2545    pInquiry[4]  = 0x01;                        /* Code set: binary codes; this is proto_codeset in FreeBSD */
2546    pInquiry[5]  = 0x03;                        /* Identifier type : NAA ; this is  id_type in FreeBSD*/
2547    pInquiry[6]  = 0x00;                        /* Reserved               */
2548    pInquiry[7]  = 0x08;                        /* Identifier length      */
2549
2550    /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
2551    pInquiry[8]  = (bit8)((pSATAIdData->namingAuthority) >> 8);
2552    pInquiry[9]  = (bit8)((pSATAIdData->namingAuthority) & 0xFF);           /* IEEE Company ID */
2553    pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8);            /* IEEE Company ID */
2554    /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
2555    pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
2556    pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8);       /* Vendor Specific ID  */
2557    pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF);     /* Vendor Specific ID  */
2558    pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8);        /* Vendor Specific ID  */
2559    pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF);      /* Vendor Specific ID  */
2560
2561    pInquiry[16]  = 0x61;                        /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */
2562    pInquiry[17]  = 0x93;                        /* Identifier type : NAA ; this is  id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h)   */
2563    pInquiry[18]  = 0x00;                        /* Reserved               */
2564    pInquiry[19]  = 0x08;                        /* Identifier length      */
2565
2566    SM_DBG5(("smsatInquiryPage83: sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi));
2567    SM_DBG5(("smsatInquiryPage83: sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo));
2568
2569    /* SAS address of SATA */
2570    pInquiry[20]  = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24;
2571    pInquiry[21]  = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16;
2572    pInquiry[22]  = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8;
2573    pInquiry[23]  = (oneDeviceData->sasAddressHi) & 0xFF;
2574    pInquiry[24]  = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24;
2575    pInquiry[25]  = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16;
2576    pInquiry[26]  = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8;
2577    pInquiry[27]  = (oneDeviceData->sasAddressLo) & 0xFF;
2578#endif
2579  }
2580  else
2581  {
2582#ifndef PMC_FREEBSD
2583    /* Fill in SAT Rev8 Table86 */
2584    /*
2585     * Logical unit name derived from the model number and serial number.
2586     */
2587    pInquiry[3] = 72;    /* 75 - 3; page length */
2588
2589    /*
2590     * Identifier descriptor
2591     */
2592    pInquiry[4] = 0x02;             /* Code set: ASCII codes */
2593    pInquiry[5] = 0x01;             /* Identifier type : T10 vendor ID based */
2594    pInquiry[6] = 0x00;             /* Reserved */
2595    pInquiry[7] = 0x44;               /* 0x44, 68 Identifier length */
2596
2597    /* Byte 8 to 15 is the vendor id string 'ATA     '. */
2598    sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
2599
2600
2601        /*
2602     * Byte 16 to 75 is vendor specific id
2603     */
2604    pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
2605    pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
2606    pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
2607    pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
2608    pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
2609    pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
2610    pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
2611    pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
2612    pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
2613    pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
2614    pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
2615    pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
2616    pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
2617    pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
2618    pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
2619    pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
2620    pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
2621    pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
2622    pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
2623    pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
2624    pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
2625    pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
2626    pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
2627    pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
2628    pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
2629    pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
2630    pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
2631    pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
2632    pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
2633    pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
2634    pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
2635    pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
2636    pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
2637    pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
2638    pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
2639    pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
2640    pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
2641    pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
2642    pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
2643    pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
2644
2645    pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
2646    pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
2647    pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
2648    pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
2649    pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
2650    pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
2651    pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
2652    pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
2653    pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
2654    pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
2655    pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
2656    pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
2657    pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
2658    pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
2659    pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
2660    pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
2661    pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
2662    pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
2663    pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
2664    pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
2665#else
2666    /* for the FreeBSD */
2667    /* Fill in SAT Rev8 Table86 */
2668    /*
2669     * Logical unit name derived from the model number and serial number.
2670     */
2671    pInquiry[3] = 84;    /* 87 - 3; page length */
2672
2673    /*
2674     * Identifier descriptor
2675     */
2676    pInquiry[4] = 0x02;             /* Code set: ASCII codes */
2677    pInquiry[5] = 0x01;             /* Identifier type : T10 vendor ID based */
2678    pInquiry[6] = 0x00;             /* Reserved */
2679    pInquiry[7] = 0x44;               /* 0x44, 68 Identifier length */
2680
2681    /* Byte 8 to 15 is the vendor id string 'ATA     '. */
2682    sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
2683
2684
2685        /*
2686     * Byte 16 to 75 is vendor specific id
2687     */
2688    pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
2689    pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
2690    pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
2691    pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
2692    pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
2693    pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
2694    pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
2695    pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
2696    pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
2697    pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
2698    pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
2699    pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
2700    pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
2701    pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
2702    pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
2703    pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
2704    pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
2705    pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
2706    pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
2707    pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
2708    pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
2709    pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
2710    pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
2711    pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
2712    pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
2713    pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
2714    pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
2715    pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
2716    pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
2717    pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
2718    pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
2719    pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
2720    pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
2721    pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
2722    pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
2723    pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
2724    pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
2725    pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
2726    pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
2727    pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
2728
2729    pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
2730    pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
2731    pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
2732    pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
2733    pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
2734    pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
2735    pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
2736    pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
2737    pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
2738    pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
2739    pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
2740    pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
2741    pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
2742    pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
2743    pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
2744    pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
2745    pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
2746    pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
2747    pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
2748    pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
2749
2750    pInquiry[76]  = 0x61;                        /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */
2751    pInquiry[77]  = 0x93;                        /* Identifier type : NAA ; this is  id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h)   */
2752    pInquiry[78]  = 0x00;                        /* Reserved               */
2753    pInquiry[79]  = 0x08;                        /* Identifier length      */
2754
2755    SM_DBG5(("smsatInquiryPage83: NO WWN sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi));
2756    SM_DBG5(("smsatInquiryPage83: No WWN sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo));
2757
2758    /* SAS address of SATA */
2759    pInquiry[80]  = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24;
2760    pInquiry[81]  = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16;
2761    pInquiry[82]  = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8;
2762    pInquiry[83]  = (oneDeviceData->sasAddressHi) & 0xFF;
2763    pInquiry[84]  = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24;
2764    pInquiry[85]  = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16;
2765    pInquiry[86]  = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8;
2766    pInquiry[87]  = (oneDeviceData->sasAddressLo) & 0xFF;
2767
2768#endif
2769  }
2770
2771  return;
2772}
2773
2774osGLOBAL void
2775smsatInquiryPage89(
2776                    bit8                    *pInquiry,
2777                    agsaSATAIdentifyData_t  *pSATAIdData,
2778                    smDeviceData_t          *oneDeviceData,
2779                    bit32                   len
2780      )
2781{
2782  /*
2783    SAT revision 8, 10.3.5, p 83
2784   */
2785  satSimpleSATAIdentifyData_t   *pSimpleData;
2786
2787  /*
2788   * When translating the fields, in some cases using the simple form of SATA
2789   * Identify Device Data is easier. So we define it here.
2790   * Both pSimpleData and pSATAIdData points to the same data.
2791   */
2792  pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2793
2794  SM_DBG5(("smsatInquiryPage89: start\n"));
2795
2796  pInquiry[0] = 0x00;   /* Peripheral Qualifier and Peripheral Device Type */
2797  pInquiry[1] = 0x89;   /* page code */
2798
2799  /* Page length 0x238 */
2800  pInquiry[2] = 0x02;
2801  pInquiry[3] = 0x38;
2802
2803  pInquiry[4] = 0x0;    /* reserved */
2804  pInquiry[5] = 0x0;    /* reserved */
2805  pInquiry[6] = 0x0;    /* reserved */
2806  pInquiry[7] = 0x0;    /* reserved */
2807
2808  /* SAT Vendor Identification */
2809  sm_strncpy((char*)&pInquiry[8],  "PMC-SIERRA", 8);   /* 8 bytes   */
2810
2811  /* SAT Product Idetification */
2812  sm_strncpy((char*)&pInquiry[16],  "Tachyon-SPC    ", 16);   /* 16 bytes   */
2813
2814  /* SAT Product Revision Level */
2815  sm_strncpy((char*)&pInquiry[32],  "01", 4);   /* 4 bytes   */
2816
2817  /* Signature, SAT revision8, Table88, p85 */
2818
2819
2820  pInquiry[36] = 0x34;    /* FIS type */
2821  if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2822  {
2823    /* interrupt assume to be 0 */
2824    pInquiry[37] = (bit8)((oneDeviceData->satPMField) >> (4 * 7)); /* first four bits of PM field */
2825  }
2826  else
2827  {
2828    /* interrupt assume to be 1 */
2829    pInquiry[37] = (bit8)(0x40 + (bit8)(((oneDeviceData->satPMField) >> (4 * 7)))); /* first four bits of PM field */
2830  }
2831  pInquiry[38] = 0;
2832  pInquiry[39] = 0;
2833
2834  if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2835  {
2836    pInquiry[40] = 0x01; /* LBA Low          */
2837    pInquiry[41] = 0x00; /* LBA Mid          */
2838    pInquiry[42] = 0x00; /* LBA High         */
2839    pInquiry[43] = 0x00; /* Device           */
2840    pInquiry[44] = 0x00; /* LBA Low Exp      */
2841    pInquiry[45] = 0x00; /* LBA Mid Exp      */
2842    pInquiry[46] = 0x00; /* LBA High Exp     */
2843    pInquiry[47] = 0x00; /* Reserved         */
2844    pInquiry[48] = 0x01; /* Sector Count     */
2845    pInquiry[49] = 0x00; /* Sector Count Exp */
2846  }
2847  else
2848  {
2849    pInquiry[40] = 0x01; /* LBA Low          */
2850    pInquiry[41] = 0x00; /* LBA Mid          */
2851    pInquiry[42] = 0x00; /* LBA High         */
2852    pInquiry[43] = 0x00; /* Device           */
2853    pInquiry[44] = 0x00; /* LBA Low Exp      */
2854    pInquiry[45] = 0x00; /* LBA Mid Exp      */
2855    pInquiry[46] = 0x00; /* LBA High Exp     */
2856    pInquiry[47] = 0x00; /* Reserved         */
2857    pInquiry[48] = 0x01; /* Sector Count     */
2858    pInquiry[49] = 0x00; /* Sector Count Exp */
2859  }
2860
2861  /* Reserved */
2862  pInquiry[50] = 0x00;
2863  pInquiry[51] = 0x00;
2864  pInquiry[52] = 0x00;
2865  pInquiry[53] = 0x00;
2866  pInquiry[54] = 0x00;
2867  pInquiry[55] = 0x00;
2868
2869  /* Command Code */
2870  if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2871  {
2872    pInquiry[56] = 0xEC;    /* IDENTIFY DEVICE */
2873  }
2874  else
2875  {
2876    pInquiry[56] = 0xA1;    /* IDENTIFY PACKET DEVICE */
2877  }
2878  /* Reserved */
2879  pInquiry[57] = 0x0;
2880  pInquiry[58] = 0x0;
2881  pInquiry[59] = 0x0;
2882
2883  /* check the length; len is assumed to be at least 60  */
2884  if (len < SATA_PAGE89_INQUIRY_SIZE)
2885  {
2886    /* Identify Device */
2887    sm_memcpy(&pInquiry[60], pSimpleData, MIN((len - 60), sizeof(satSimpleSATAIdentifyData_t)));
2888  }
2889  else
2890  {
2891    /* Identify Device */
2892    sm_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
2893  }
2894
2895  return;
2896}
2897
2898osGLOBAL void
2899smsatInquiryPage80(
2900                    bit8                    *pInquiry,
2901                    agsaSATAIdentifyData_t  *pSATAIdData
2902       )
2903{
2904  SM_DBG5(("smsatInquiryPage89: start\n"));
2905  /*
2906    See SPC-4, 7.6.9, p 345
2907    and SAT revision 8, 10.3.3, p 77
2908   */
2909  pInquiry[0] = 0x00;
2910  pInquiry[1] = 0x80; /* page code */
2911  pInquiry[2] = 0x00; /* reserved */
2912  pInquiry[3] = 0x14; /* page length */
2913
2914  /* product serial number */
2915  pInquiry[4] = pSATAIdData->serialNumber[1];
2916  pInquiry[5] = pSATAIdData->serialNumber[0];
2917  pInquiry[6] = pSATAIdData->serialNumber[3];
2918  pInquiry[7] = pSATAIdData->serialNumber[2];
2919  pInquiry[8] = pSATAIdData->serialNumber[5];
2920  pInquiry[9] = pSATAIdData->serialNumber[4];
2921  pInquiry[10] = pSATAIdData->serialNumber[7];
2922  pInquiry[11] = pSATAIdData->serialNumber[6];
2923  pInquiry[12] = pSATAIdData->serialNumber[9];
2924  pInquiry[13] = pSATAIdData->serialNumber[8];
2925  pInquiry[14] = pSATAIdData->serialNumber[11];
2926  pInquiry[15] = pSATAIdData->serialNumber[10];
2927  pInquiry[16] = pSATAIdData->serialNumber[13];
2928  pInquiry[17] = pSATAIdData->serialNumber[12];
2929  pInquiry[18] = pSATAIdData->serialNumber[15];
2930  pInquiry[19] = pSATAIdData->serialNumber[14];
2931  pInquiry[20] = pSATAIdData->serialNumber[17];
2932  pInquiry[21] = pSATAIdData->serialNumber[16];
2933  pInquiry[22] = pSATAIdData->serialNumber[19];
2934  pInquiry[23] = pSATAIdData->serialNumber[18];
2935
2936  return;
2937}
2938
2939osGLOBAL void
2940smsatInquiryPageB1(
2941                    bit8                    *pInquiry,
2942                    agsaSATAIdentifyData_t  *pSATAIdData
2943       )
2944{
2945  bit32 i;
2946  satSimpleSATAIdentifyData_t   *pSimpleData;
2947
2948  SM_DBG5(("smsatInquiryPageB1: start\n"));
2949
2950  pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2951  /*
2952    See SBC-3, revision31, Table193, p273
2953    and SAT-3 revision 3, 10.3.6, p141
2954   */
2955  pInquiry[0] = 0x00;   /* Peripheral Qualifier and Peripheral Device Type */
2956  pInquiry[1] = 0xB1; /* page code */
2957
2958  /* page length */
2959  pInquiry[2] = 0x0;
2960  pInquiry[3] = 0x3C;
2961
2962  /* medium rotation rate */
2963  pInquiry[4] = (bit8) ((pSimpleData->word[217]) >> 8);
2964  pInquiry[5] = (bit8) ((pSimpleData->word[217]) & 0xFF);
2965
2966  /* reserved */
2967  pInquiry[6] = 0x0;
2968
2969  /* nominal form factor bits 3:0 */
2970  pInquiry[7] = (bit8) ((pSimpleData->word[168]) & 0xF);
2971
2972
2973  /* reserved */
2974  for (i=8;i<64;i++)
2975  {
2976    pInquiry[i] = 0x0;
2977  }
2978  return;
2979}
2980
2981osGLOBAL void
2982smsatDefaultTranslation(
2983                        smRoot_t                  *smRoot,
2984                        smIORequest_t             *smIORequest,
2985                        smSatIOContext_t            *satIOContext,
2986                        smScsiRspSense_t          *pSense,
2987                        bit8                      ataStatus,
2988                        bit8                      ataError,
2989                        bit32                     interruptContext
2990                       )
2991{
2992  SM_DBG5(("smsatDefaultTranslation: start\n"));
2993  /*
2994   * Check for device fault case
2995   */
2996  if ( ataStatus & DF_ATA_STATUS_MASK )
2997  {
2998    smsatSetSensePayload( pSense,
2999                          SCSI_SNSKEY_HARDWARE_ERROR,
3000                          0,
3001                          SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3002                          satIOContext);
3003
3004    tdsmIOCompletedCB( smRoot,
3005                       smIORequest,
3006                       smIOSuccess,
3007                       SCSI_STAT_CHECK_CONDITION,
3008                       satIOContext->pSmSenseData,
3009                       interruptContext );
3010    return;
3011  }
3012
3013  /*
3014   * If status error bit it set, need to check the error register
3015   */
3016  if ( ataStatus & ERR_ATA_STATUS_MASK )
3017  {
3018    if ( ataError & NM_ATA_ERROR_MASK )
3019    {
3020      SM_DBG1(("smsatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3021                 ataError, smIORequest));
3022      smsatSetSensePayload( pSense,
3023                            SCSI_SNSKEY_NOT_READY,
3024                            0,
3025                            SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
3026                            satIOContext);
3027    }
3028
3029    else if (ataError & UNC_ATA_ERROR_MASK)
3030    {
3031      SM_DBG1(("smsatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3032                 ataError, smIORequest));
3033      smsatSetSensePayload( pSense,
3034                            SCSI_SNSKEY_MEDIUM_ERROR,
3035                            0,
3036                            SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
3037                            satIOContext);
3038    }
3039
3040    else if (ataError & IDNF_ATA_ERROR_MASK)
3041    {
3042      SM_DBG1(("smsatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3043                 ataError, smIORequest));
3044      smsatSetSensePayload( pSense,
3045                            SCSI_SNSKEY_MEDIUM_ERROR,
3046                            0,
3047                            SCSI_SNSCODE_RECORD_NOT_FOUND,
3048                            satIOContext);
3049    }
3050
3051    else if (ataError & MC_ATA_ERROR_MASK)
3052    {
3053      SM_DBG1(("smsatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3054                 ataError, smIORequest));
3055      smsatSetSensePayload( pSense,
3056                            SCSI_SNSKEY_UNIT_ATTENTION,
3057                            0,
3058                            SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
3059                            satIOContext);
3060    }
3061
3062    else if (ataError & MCR_ATA_ERROR_MASK)
3063    {
3064      SM_DBG1(("smsatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3065                 ataError, smIORequest));
3066      smsatSetSensePayload( pSense,
3067                            SCSI_SNSKEY_UNIT_ATTENTION,
3068                            0,
3069                            SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
3070                            satIOContext);
3071    }
3072
3073    else if (ataError & ICRC_ATA_ERROR_MASK)
3074    {
3075      SM_DBG1(("smsatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3076                 ataError, smIORequest));
3077      smsatSetSensePayload( pSense,
3078                            SCSI_SNSKEY_ABORTED_COMMAND,
3079                            0,
3080                            SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
3081                            satIOContext);
3082    }
3083
3084    else if (ataError & ABRT_ATA_ERROR_MASK)
3085    {
3086      SM_DBG1(("smsatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3087                 ataError, smIORequest));
3088      smsatSetSensePayload( pSense,
3089                            SCSI_SNSKEY_ABORTED_COMMAND,
3090                            0,
3091                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
3092                            satIOContext);
3093    }
3094
3095    else
3096    {
3097      SM_DBG1(("smsatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, smIORequest=%p!!!\n",
3098                 ataError, smIORequest));
3099      smsatSetSensePayload( pSense,
3100                            SCSI_SNSKEY_HARDWARE_ERROR,
3101                            0,
3102                            SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3103                            satIOContext);
3104    }
3105
3106    /* Send the completion response now */
3107    tdsmIOCompletedCB( smRoot,
3108                       smIORequest,
3109                       smIOSuccess,
3110                       SCSI_STAT_CHECK_CONDITION,
3111                       satIOContext->pSmSenseData,
3112                       interruptContext );
3113    return;
3114
3115
3116  }
3117
3118  else /*  (ataStatus & ERR_ATA_STATUS_MASK ) is false */
3119  {
3120    /* This case should never happen */
3121    SM_DBG1(("smsatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** smIORequest=%p!!!\n",
3122                 ataStatus, smIORequest));
3123    smsatSetSensePayload( pSense,
3124                          SCSI_SNSKEY_HARDWARE_ERROR,
3125                          0,
3126                          SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3127                          satIOContext);
3128
3129    tdsmIOCompletedCB( smRoot,
3130                       smIORequest,
3131                       smIOSuccess,
3132                       SCSI_STAT_CHECK_CONDITION,
3133                       satIOContext->pSmSenseData,
3134                       interruptContext );
3135    return;
3136
3137  }
3138
3139  return;
3140}
3141
3142osGLOBAL bit32
3143smIDStart(
3144          smRoot_t                     *smRoot,
3145          smIORequest_t                *smIORequest,
3146          smDeviceHandle_t             *smDeviceHandle
3147         )
3148{
3149  smDeviceData_t            *oneDeviceData = agNULL;
3150  smIORequestBody_t         *smIORequestBody = agNULL;
3151  smSatIOContext_t            *satIOContext = agNULL;
3152  bit32                     status = SM_RC_FAILURE;
3153
3154  SM_DBG2(("smIDStart: start, smIORequest %p\n", smIORequest));
3155
3156  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
3157  if (oneDeviceData == agNULL)
3158  {
3159    SM_DBG1(("smIDStart: oneDeviceData is NULL!!!\n"));
3160    return SM_RC_FAILURE;
3161  }
3162  if (oneDeviceData->valid == agFALSE)
3163  {
3164    SM_DBG1(("smIDStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
3165    return SM_RC_FAILURE;
3166  }
3167
3168  smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
3169
3170  if (smIORequestBody == agNULL)
3171  {
3172    SM_DBG1(("smIDStart: smIORequestBody is NULL!!!\n"));
3173    return SM_RC_FAILURE;
3174  }
3175
3176  smIOReInit(smRoot, smIORequestBody);
3177
3178  SM_DBG3(("smIDStart: io ID %d!!!\n", smIORequestBody->id ));
3179
3180  smIORequestBody->smIORequest = smIORequest;
3181  smIORequestBody->smDevHandle = smDeviceHandle;
3182  satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
3183
3184  /* setting up satIOContext */
3185  satIOContext->pSatDevData   = oneDeviceData;
3186  satIOContext->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
3187  satIOContext->smRequestBody = smIORequestBody;
3188  satIOContext->psmDeviceHandle = smDeviceHandle;
3189  satIOContext->smScsiXchg = agNULL;
3190
3191  /*smIORequest->smData = smIORequestBody;*/
3192  SM_DBG3(("smIDStart: smIORequestBody %p smIORequestBody->smIORequest %p!!!\n", smIORequestBody, smIORequestBody->smIORequest));
3193  SM_DBG1(("smIDStart: did %d\n",  oneDeviceData->id));
3194
3195  status = smsatIDSubStart( smRoot,
3196                            smIORequest,
3197                            smDeviceHandle,
3198                            agNULL,
3199                            satIOContext);
3200
3201  if (status != SM_RC_SUCCESS)
3202  {
3203    SM_DBG1(("smIDStart: smsatIDSubStart failure %d!!!\n", status));
3204    /*smEnqueueIO(smRoot, satIOContext);*/
3205  }
3206  SM_DBG2(("smIDStart: exit\n"));
3207
3208  return status;
3209}
3210
3211/*
3212  SM generated IO, needs to call smsatAllocIntIoResource()
3213  allocating using smsatAllocIntIoResource
3214*/
3215osGLOBAL bit32
3216smsatIDSubStart(
3217                 smRoot_t                 *smRoot,
3218                 smIORequest_t            *smIORequest,
3219                 smDeviceHandle_t         *smDeviceHandle,
3220                 smScsiInitiatorRequest_t *smSCSIRequest, /* agNULL */
3221                 smSatIOContext_t         *satIOContext
3222               )
3223{
3224  smSatInternalIo_t           *satIntIo = agNULL;
3225  smDeviceData_t            *satDevData = agNULL;
3226  smIORequestBody_t         *smIORequestBody;
3227  smSatIOContext_t            *satNewIOContext;
3228  bit32                     status;
3229  SM_DBG2(("smsatIDSubStart: start\n"));
3230
3231  satDevData = satIOContext->pSatDevData;
3232
3233  /* allocate identify device command */
3234  satIntIo = smsatAllocIntIoResource( smRoot,
3235                                      smIORequest,
3236                                      satDevData,
3237                                      sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
3238                                      satIntIo);
3239
3240  if (satIntIo == agNULL)
3241  {
3242    SM_DBG1(("smsatIDSubStart: can't alloacate!!!\n"));
3243    return SM_RC_FAILURE;
3244  }
3245
3246  satIOContext->satIntIoContext = satIntIo;
3247
3248  /* fill in fields */
3249  /* real ttttttthe one worked and the same; 5/21/07/ */
3250  satIntIo->satOrgSmIORequest = smIORequest; /* changed */
3251  smIORequestBody = satIntIo->satIntRequestBody;
3252  satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext);
3253
3254  satNewIOContext->pSatDevData   = satDevData;
3255  satNewIOContext->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
3256  satNewIOContext->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
3257  satNewIOContext->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
3258  satNewIOContext->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
3259  satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */
3260  //  satNewIOContext->interruptContext = tiInterruptContext;
3261  satNewIOContext->satIntIoContext  = satIntIo;
3262
3263  satNewIOContext->psmDeviceHandle = smDeviceHandle;
3264  satNewIOContext->satOrgIOContext = satIOContext; /* changed */
3265
3266  /* this is valid only for TD layer generated (not triggered by OS at all) IO */
3267  satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg);
3268
3269
3270  SM_DBG6(("smsatIDSubStart: SM satIOContext %p \n", satIOContext));
3271  SM_DBG6(("smsatIDSubStart: SM satNewIOContext %p \n", satNewIOContext));
3272  SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satIOContext->smScsiXchg));
3273  SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satNewIOContext->smScsiXchg));
3274
3275
3276
3277  SM_DBG3(("smsatIDSubStart: satNewIOContext %p smIORequestBody %p\n", satNewIOContext, smIORequestBody));
3278
3279  status = smsatIDStart(smRoot,
3280                        &satIntIo->satIntSmIORequest, /* New smIORequest */
3281                        smDeviceHandle,
3282                        satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, */
3283                        satNewIOContext);
3284
3285  if (status != SM_RC_SUCCESS)
3286  {
3287    SM_DBG1(("smsatIDSubStart: failed in sending %d!!!\n", status));
3288
3289    smsatFreeIntIoResource( smRoot,
3290                            satDevData,
3291                            satIntIo);
3292
3293    return SM_RC_FAILURE;
3294  }
3295
3296
3297  SM_DBG2(("smsatIDSubStart: end\n"));
3298
3299  return status;
3300
3301}
3302
3303
3304osGLOBAL bit32
3305smsatIDStart(
3306              smRoot_t                  *smRoot,
3307              smIORequest_t             *smIORequest,
3308              smDeviceHandle_t          *smDeviceHandle,
3309              smScsiInitiatorRequest_t  *smSCSIRequest,
3310              smSatIOContext_t            *satIOContext
3311             )
3312{
3313  bit32                     status;
3314  bit32                     agRequestType;
3315  smDeviceData_t            *pSatDevData;
3316  agsaFisRegHostToDevice_t  *fis;
3317#ifdef SM_INTERNAL_DEBUG
3318  smIORequestBody_t         *smIORequestBody;
3319  smSatInternalIo_t         *satIntIoContext;
3320#endif
3321
3322  pSatDevData   = satIOContext->pSatDevData;
3323  fis           = satIOContext->pFis;
3324  SM_DBG2(("smsatIDStart: start\n"));
3325#ifdef SM_INTERNAL_DEBUG
3326  satIntIoContext = satIOContext->satIntIoContext;
3327  smIORequestBody = satIntIoContext->satIntRequestBody;
3328#endif
3329  fis->h.fisType        = 0x27;                   /* Reg host to device */
3330  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3331  if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
3332  {
3333    SM_DBG2(("smsatIDStart: IDENTIFY_PACKET_DEVICE\n"));
3334    fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
3335  }
3336  else
3337  {
3338    SM_DBG2(("smsatIDStart: IDENTIFY_DEVICE\n"));
3339    fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
3340  }
3341  fis->h.features       = 0;                      /* FIS reserve */
3342  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
3343  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
3344  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
3345  fis->d.device         = 0;                      /* FIS LBA mode  */
3346  fis->d.lbaLowExp      = 0;
3347  fis->d.lbaMidExp      = 0;
3348  fis->d.lbaHighExp     = 0;
3349  fis->d.featuresExp    = 0;
3350  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
3351  fis->d.sectorCountExp = 0;
3352  fis->d.reserved4      = 0;
3353  fis->d.control        = 0;                      /* FIS HOB bit clear */
3354  fis->d.reserved5      = 0;
3355
3356  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
3357
3358  /* Initialize CB for SATA completion.
3359   */
3360  satIOContext->satCompleteCB = &smsatIDStartCB;
3361
3362  /*
3363   * Prepare SGL and send FIS to LL layer.
3364   */
3365  satIOContext->reqType = agRequestType;       /* Save it */
3366
3367#ifdef SM_INTERNAL_DEBUG
3368  smhexdump("smsatIDStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
3369  smhexdump("smsatIDStart LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
3370#endif
3371  status = smsataLLIOStart( smRoot,
3372                            smIORequest,
3373                            smDeviceHandle,
3374                            smSCSIRequest,
3375                            satIOContext);
3376
3377  SM_DBG2(("smsatIDStart: end status %d\n", status));
3378
3379  return status;
3380}
3381
3382
3383osGLOBAL FORCEINLINE bit32
3384smsatIOStart(
3385              smRoot_t                  *smRoot,
3386              smIORequest_t             *smIORequest,
3387              smDeviceHandle_t          *smDeviceHandle,
3388              smScsiInitiatorRequest_t  *smSCSIRequest,
3389              smSatIOContext_t            *satIOContext
3390             )
3391{
3392  smDeviceData_t            *pSatDevData = satIOContext->pSatDevData;
3393  smScsiRspSense_t          *pSense      = satIOContext->pSense;
3394  smIniScsiCmnd_t           *scsiCmnd    = &smSCSIRequest->scsiCmnd;
3395  smLUN_t                   *pLun        = &scsiCmnd->lun;
3396  smSatInternalIo_t         *pSatIntIo   = agNULL;
3397  bit32                     status       = SM_RC_FAILURE;
3398
3399  SM_DBG2(("smsatIOStart: start\n"));
3400
3401  /*
3402   * Reject all other LUN other than LUN 0.
3403   */
3404  if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
3405         pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) &&
3406        (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)
3407     )
3408  {
3409    SM_DBG1(("smsatIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x did %d !!!\n",
3410                 scsiCmnd->cdb[0], pSatDevData->id));
3411    smsatSetSensePayload( pSense,
3412                          SCSI_SNSKEY_ILLEGAL_REQUEST,
3413                          0,
3414                          SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
3415                          satIOContext);
3416
3417    /*smEnqueueIO(smRoot, satIOContext);*/
3418
3419    tdsmIOCompletedCB( smRoot,
3420                       smIORequest,
3421                       smIOSuccess,
3422                       SCSI_STAT_CHECK_CONDITION,
3423                       satIOContext->pSmSenseData,
3424                       satIOContext->interruptContext );
3425
3426    return SM_RC_SUCCESS;
3427  }
3428
3429  SM_DBG2(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3430
3431  /* this may happen after tiCOMReset until OS sends inquiry */
3432  if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
3433  {
3434    SM_DBG1(("smsatIOStart: invalid identify device data did %d !!!\n", pSatDevData->id));
3435    SM_DBG1(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n", pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3436    SM_DBG1(("smsatIOStart: satPendingNCQIO %d satPendingNONNCQIO %d\n", pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3437
3438    /*smEnqueueIO(smRoot, satIOContext);*/
3439
3440    return SM_RC_NODEVICE;
3441  }
3442
3443  /*
3444   * Check if we need to return BUSY, i.e. recovery in progress
3445   */
3446  if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
3447  {
3448    SM_DBG1(("smsatIOStart: IN RECOVERY STATE cdb[0]=0x%x did=%d !!!\n",
3449                 scsiCmnd->cdb[0], pSatDevData->id));
3450    SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n", pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3451    SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3452
3453    /*smEnqueueIO(smRoot, satIOContext);*/
3454
3455//    return  SM_RC_FAILURE;
3456    return SM_RC_DEVICE_BUSY;
3457  }
3458
3459  if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
3460  {
3461     if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
3462     {
3463        return smsatReportLun(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
3464     }
3465     else
3466     {
3467        return smsatPacket(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
3468     }
3469  }
3470  else
3471  {
3472     /* Parse CDB */
3473     switch(scsiCmnd->cdb[0])
3474     {
3475       case SCSIOPC_READ_10:
3476         status = smsatRead10( smRoot,
3477                              smIORequest,
3478                              smDeviceHandle,
3479                              smSCSIRequest,
3480                              satIOContext);
3481         break;
3482
3483       case SCSIOPC_WRITE_10:
3484         status = smsatWrite10( smRoot,
3485                                smIORequest,
3486                                smDeviceHandle,
3487                                smSCSIRequest,
3488                                satIOContext);
3489         break;
3490
3491       case SCSIOPC_READ_6:
3492         status = smsatRead6( smRoot,
3493                              smIORequest,
3494                              smDeviceHandle,
3495                              smSCSIRequest,
3496                              satIOContext);
3497         break;
3498
3499       case SCSIOPC_READ_12:
3500         SM_DBG5(("smsatIOStart: SCSIOPC_READ_12\n"));
3501         status = smsatRead12( smRoot,
3502                               smIORequest,
3503                               smDeviceHandle,
3504                               smSCSIRequest,
3505                               satIOContext);
3506         break;
3507
3508       case SCSIOPC_READ_16:
3509         status = smsatRead16( smRoot,
3510                               smIORequest,
3511                               smDeviceHandle,
3512                               smSCSIRequest,
3513                               satIOContext);
3514         break;
3515
3516       case SCSIOPC_WRITE_6:
3517         status = smsatWrite6( smRoot,
3518                               smIORequest,
3519                               smDeviceHandle,
3520                               smSCSIRequest,
3521                               satIOContext);
3522         break;
3523
3524       case SCSIOPC_WRITE_12:
3525         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_12 \n"));
3526         status = smsatWrite12( smRoot,
3527                                smIORequest,
3528                                smDeviceHandle,
3529                                smSCSIRequest,
3530                                satIOContext);
3531         break;
3532
3533       case SCSIOPC_WRITE_16:
3534         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_16 \n"));
3535         status = smsatWrite16( smRoot,
3536                                smIORequest,
3537                                smDeviceHandle,
3538                                smSCSIRequest,
3539                                satIOContext);
3540         break;
3541
3542       case SCSIOPC_VERIFY_10:
3543         status = smsatVerify10( smRoot,
3544                                 smIORequest,
3545                                 smDeviceHandle,
3546                                 smSCSIRequest,
3547                                 satIOContext);
3548         break;
3549
3550       case SCSIOPC_VERIFY_12:
3551         SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_12\n"));
3552         status = smsatVerify12( smRoot,
3553                                 smIORequest,
3554                                 smDeviceHandle,
3555                                 smSCSIRequest,
3556                                 satIOContext);
3557         break;
3558
3559       case SCSIOPC_VERIFY_16:
3560         SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_16\n"));
3561         status = smsatVerify16( smRoot,
3562                                 smIORequest,
3563                                 smDeviceHandle,
3564                                 smSCSIRequest,
3565                                 satIOContext);
3566         break;
3567
3568       case SCSIOPC_TEST_UNIT_READY:
3569         status = smsatTestUnitReady( smRoot,
3570                                      smIORequest,
3571                                      smDeviceHandle,
3572                                      smSCSIRequest,
3573                                      satIOContext);
3574         break;
3575
3576       case SCSIOPC_INQUIRY:
3577         status = smsatInquiry( smRoot,
3578                                smIORequest,
3579                                smDeviceHandle,
3580                                smSCSIRequest,
3581                                satIOContext);
3582         break;
3583
3584       case SCSIOPC_REQUEST_SENSE:
3585         status = smsatRequestSense( smRoot,
3586                                     smIORequest,
3587                                     smDeviceHandle,
3588                                     smSCSIRequest,
3589                                     satIOContext);
3590         break;
3591
3592       case SCSIOPC_MODE_SENSE_6:
3593         status = smsatModeSense6( smRoot,
3594                                   smIORequest,
3595                                   smDeviceHandle,
3596                                   smSCSIRequest,
3597                                   satIOContext);
3598         break;
3599
3600       case SCSIOPC_MODE_SENSE_10:
3601         status = smsatModeSense10( smRoot,
3602                                    smIORequest,
3603                                    smDeviceHandle,
3604                                    smSCSIRequest,
3605                                    satIOContext);
3606         break;
3607
3608       case SCSIOPC_READ_CAPACITY_10:
3609         status = smsatReadCapacity10( smRoot,
3610                                       smIORequest,
3611                                       smDeviceHandle,
3612                                       smSCSIRequest,
3613                                       satIOContext);
3614         break;
3615
3616       case SCSIOPC_READ_CAPACITY_16:
3617         status = smsatReadCapacity16( smRoot,
3618                                       smIORequest,
3619                                       smDeviceHandle,
3620                                       smSCSIRequest,
3621                                       satIOContext);
3622         break;
3623
3624
3625       case SCSIOPC_REPORT_LUN:
3626         status = smsatReportLun( smRoot,
3627                                  smIORequest,
3628                                  smDeviceHandle,
3629                                  smSCSIRequest,
3630                                  satIOContext);
3631         break;
3632
3633       case SCSIOPC_FORMAT_UNIT:
3634         SM_DBG5(("smsatIOStart: SCSIOPC_FORMAT_UNIT\n"));
3635         status = smsatFormatUnit( smRoot,
3636                                   smIORequest,
3637                                   smDeviceHandle,
3638                                   smSCSIRequest,
3639                                   satIOContext);
3640         break;
3641
3642       case SCSIOPC_SEND_DIAGNOSTIC:
3643         SM_DBG5(("smsatIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
3644         status = smsatSendDiagnostic( smRoot,
3645                                       smIORequest,
3646                                       smDeviceHandle,
3647                                       smSCSIRequest,
3648                                       satIOContext);
3649         break;
3650
3651       case SCSIOPC_START_STOP_UNIT:
3652         SM_DBG5(("smsatIOStart: SCSIOPC_START_STOP_UNIT\n"));
3653         status = smsatStartStopUnit( smRoot,
3654                                      smIORequest,
3655                                      smDeviceHandle,
3656                                      smSCSIRequest,
3657                                      satIOContext);
3658         break;
3659
3660       case SCSIOPC_WRITE_SAME_10:
3661         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_10\n"));
3662         status = smsatWriteSame10( smRoot,
3663                                    smIORequest,
3664                                    smDeviceHandle,
3665                                    smSCSIRequest,
3666                                    satIOContext);
3667         break;
3668
3669       case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */
3670         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_16\n"));
3671         status = smsatWriteSame16( smRoot,
3672                                    smIORequest,
3673                                    smDeviceHandle,
3674                                    smSCSIRequest,
3675                                    satIOContext);
3676         break;
3677
3678       case SCSIOPC_LOG_SENSE:
3679         SM_DBG5(("smsatIOStart: SCSIOPC_LOG_SENSE\n"));
3680         status = smsatLogSense( smRoot,
3681                                 smIORequest,
3682                                 smDeviceHandle,
3683                                 smSCSIRequest,
3684                                 satIOContext);
3685         break;
3686
3687       case SCSIOPC_MODE_SELECT_6:
3688         SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_6\n"));
3689         status = smsatModeSelect6( smRoot,
3690                                    smIORequest,
3691                                    smDeviceHandle,
3692                                    smSCSIRequest,
3693                                    satIOContext);
3694         break;
3695
3696       case SCSIOPC_MODE_SELECT_10:
3697         SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_10\n"));
3698         status = smsatModeSelect10( smRoot,
3699                                     smIORequest,
3700                                     smDeviceHandle,
3701                                     smSCSIRequest,
3702                                     satIOContext);
3703         break;
3704
3705       case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with
3706                                           satSynchronizeCache16 */
3707         SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
3708         status = smsatSynchronizeCache10( smRoot,
3709                                           smIORequest,
3710                                           smDeviceHandle,
3711                                           smSCSIRequest,
3712                                           satIOContext);
3713         break;
3714
3715       case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with
3716                                            satSynchronizeCache16 */
3717
3718         SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
3719         status = smsatSynchronizeCache16( smRoot,
3720                                           smIORequest,
3721                                           smDeviceHandle,
3722                                           smSCSIRequest,
3723                                           satIOContext);
3724         break;
3725
3726       case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */
3727         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
3728         status = smsatWriteAndVerify10( smRoot,
3729                                         smIORequest,
3730                                         smDeviceHandle,
3731                                         smSCSIRequest,
3732                                         satIOContext);
3733         break;
3734
3735       case SCSIOPC_WRITE_AND_VERIFY_12:
3736         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
3737         status = smsatWriteAndVerify12( smRoot,
3738                                         smIORequest,
3739                                         smDeviceHandle,
3740                                         smSCSIRequest,
3741                                         satIOContext);
3742         break;
3743
3744       case SCSIOPC_WRITE_AND_VERIFY_16:
3745         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
3746         status = smsatWriteAndVerify16( smRoot,
3747                                         smIORequest,
3748                                         smDeviceHandle,
3749                                         smSCSIRequest,
3750                                         satIOContext);
3751
3752         break;
3753
3754       case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
3755         SM_DBG5(("smsatIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
3756         status = smsatReadMediaSerialNumber( smRoot,
3757                                              smIORequest,
3758                                              smDeviceHandle,
3759                                              smSCSIRequest,
3760                                              satIOContext);
3761
3762         break;
3763
3764       case SCSIOPC_READ_BUFFER:
3765         SM_DBG5(("smsatIOStart: SCSIOPC_READ_BUFFER\n"));
3766         status = smsatReadBuffer( smRoot,
3767                                   smIORequest,
3768                                   smDeviceHandle,
3769                                   smSCSIRequest,
3770                                   satIOContext);
3771
3772         break;
3773
3774       case SCSIOPC_WRITE_BUFFER:
3775         SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_BUFFER\n"));
3776         status = smsatWriteBuffer( smRoot,
3777                                    smIORequest,
3778                                    smDeviceHandle,
3779                                    smSCSIRequest,
3780                                    satIOContext);
3781
3782         break;
3783
3784       case SCSIOPC_REASSIGN_BLOCKS:
3785         SM_DBG5(("smsatIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
3786         status = smsatReassignBlocks( smRoot,
3787                                       smIORequest,
3788                                       smDeviceHandle,
3789                                       smSCSIRequest,
3790                                       satIOContext);
3791
3792         break;
3793
3794       case SCSIOPC_ATA_PASS_THROUGH12: /* fall through */
3795       case SCSIOPC_ATA_PASS_THROUGH16:
3796         SM_DBG5(("smsatIOStart: SCSIOPC_ATA_PASS_THROUGH\n"));
3797         status = smsatPassthrough( smRoot,
3798                                    smIORequest,
3799                                    smDeviceHandle,
3800                                    smSCSIRequest,
3801                                    satIOContext);
3802         break;
3803
3804       default:
3805         /* Not implemented SCSI cmd, set up error response */
3806         SM_DBG1(("smsatIOStart: unsupported SCSI cdb[0]=0x%x did=%d !!!\n",
3807                    scsiCmnd->cdb[0], pSatDevData->id));
3808
3809         smsatSetSensePayload( pSense,
3810                               SCSI_SNSKEY_ILLEGAL_REQUEST,
3811                               0,
3812                               SCSI_SNSCODE_INVALID_COMMAND,
3813                               satIOContext);
3814
3815         /*smEnqueueIO(smRoot, satIOContext);*/
3816
3817         tdsmIOCompletedCB( smRoot,
3818                            smIORequest,
3819                            smIOSuccess,
3820                            SCSI_STAT_CHECK_CONDITION,
3821                            satIOContext->pSmSenseData,
3822                            satIOContext->interruptContext );
3823         status = SM_RC_SUCCESS;
3824
3825         break;
3826
3827     }  /* end switch  */
3828  }
3829
3830  if (status == SM_RC_BUSY || status == SM_RC_DEVICE_BUSY)
3831  {
3832    SM_DBG1(("smsatIOStart: BUSY did %d!!!\n", pSatDevData->id));
3833    SM_DBG2(("smsatIOStart: LL is busy or target queue is full\n"));
3834    SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3835    SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3836    pSatIntIo               = satIOContext->satIntIoContext;
3837
3838    /*smEnqueueIO(smRoot, satIOContext);*/
3839
3840    /* interal structure free */
3841    smsatFreeIntIoResource( smRoot,
3842                            pSatDevData,
3843                            pSatIntIo);
3844  }
3845
3846  return status;
3847}
3848
3849osGLOBAL void
3850smsatSetSensePayload(
3851                     smScsiRspSense_t   *pSense,
3852                     bit8               SnsKey,
3853                     bit32              SnsInfo,
3854                     bit16              SnsCode,
3855                     smSatIOContext_t     *satIOContext)
3856{
3857  /* for fixed format sense data, SPC-4, p37 */
3858  bit32      i;
3859  bit32      senseLength;
3860  bit8       tmp = 0;
3861
3862  SM_DBG2(("smsatSetSensePayload: start\n"));
3863
3864  senseLength  = sizeof(smScsiRspSense_t);
3865
3866  /* zero out the data area */
3867  for (i=0;i< senseLength;i++)
3868  {
3869    ((bit8*)pSense)[i] = 0;
3870  }
3871
3872  /*
3873   * SCSI Sense Data part of response data
3874   */
3875  pSense->snsRespCode  = 0x70;    /*  0xC0 == vendor specific */
3876                                      /*  0x70 == standard current error */
3877  pSense->senseKey     = SnsKey;
3878  /*
3879   * Put sense info in scsi order format
3880   */
3881  pSense->info[0]      = (bit8)((SnsInfo >> 24) & 0xff);
3882  pSense->info[1]      = (bit8)((SnsInfo >> 16) & 0xff);
3883  pSense->info[2]      = (bit8)((SnsInfo >> 8) & 0xff);
3884  pSense->info[3]      = (bit8)((SnsInfo) & 0xff);
3885  pSense->addSenseLen  = 11;          /* fixed size of sense data = 18 */
3886  pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
3887  pSense->senseQual    = (bit8)(SnsCode & 0xFF);
3888  /*
3889   * Set pointer in scsi status
3890   */
3891  switch(SnsKey)
3892  {
3893    /*
3894     * set illegal request sense key specific error in cdb, no bit pointer
3895     */
3896    case SCSI_SNSKEY_ILLEGAL_REQUEST:
3897      pSense->skeySpecific[0] = 0xC8;
3898      break;
3899
3900    default:
3901      break;
3902  }
3903  /* setting sense data length */
3904  if (satIOContext != agNULL)
3905  {
3906    satIOContext->pSmSenseData->senseLen = 18;
3907  }
3908  else
3909  {
3910    SM_DBG1(("smsatSetSensePayload: satIOContext is NULL!!!\n"));
3911  }
3912
3913  /* Only for SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE */
3914  if (SnsCode == SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE)
3915  {
3916    /* filling in COMMAND-SPECIFIC INFORMATION */
3917    tmp = satIOContext->extend << 7 | satIOContext->Sector_Cnt_Upper_Nonzero << 6 | satIOContext->LBA_Upper_Nonzero << 5;
3918    SM_DBG3(("smsatSetSensePayload: extend 0x%x Sector_Cnt_Upper_Nonzero 0x%x LBA_Upper_Nonzero 0x%x\n",
3919    satIOContext->extend, satIOContext->Sector_Cnt_Upper_Nonzero, satIOContext->LBA_Upper_Nonzero));
3920    SM_DBG3(("smsatSetSensePayload: tmp 0x%x\n", tmp));
3921    pSense->cmdSpecific[0]      = tmp;
3922    pSense->cmdSpecific[1]      = satIOContext->LBAHigh07;
3923    pSense->cmdSpecific[2]      = satIOContext->LBAMid07;
3924    pSense->cmdSpecific[3]      = satIOContext->LBALow07;
3925//    smhexdump("smsatSetSensePayload: cmdSpecific",(bit8 *)pSense->cmdSpecific, 4);
3926//    smhexdump("smsatSetSensePayload: info",(bit8 *)pSense->info, 4);
3927
3928  }
3929  return;
3930}
3931
3932/*****************************************************************************
3933*! \brief  smsatDecodeSATADeviceType
3934*
3935*   This routine decodes ATA signature
3936*
3937*  \param   pSignature:       ATA signature
3938*
3939*
3940*  \return:
3941*          TRUE if ATA signature
3942*          FALSE otherwise
3943*
3944*****************************************************************************/
3945/*
3946  ATA p65
3947  PM p65
3948  SATAII p79, p80
3949 */
3950GLOBAL bit32
3951smsatDecodeSATADeviceType(
3952                         bit8  *pSignature
3953                         )
3954{
3955  bit32 deviceType = UNKNOWN_DEVICE;
3956
3957  if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3958       && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00
3959       && (pSignature)[4] == 0xA0 )    /* this is the signature of a Hitachi SATA HDD*/
3960  {
3961    deviceType = SATA_ATA_DEVICE;
3962  }
3963  else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3964      && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00
3965      && (pSignature)[4] == 0x00 )
3966  {
3967    deviceType = SATA_ATA_DEVICE;
3968  }
3969  else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3970          && (pSignature)[2] == 0x14 && (pSignature)[3] == 0xEB
3971          && ( (pSignature)[4] == 0x00 || (pSignature)[4] == 0x10) )
3972  {
3973    deviceType = SATA_ATAPI_DEVICE;
3974  }
3975  else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3976          && (pSignature)[2] == 0x69 && (pSignature)[3] == 0x96
3977          && (pSignature)[4] == 0x00 )
3978  {
3979    deviceType = SATA_PM_DEVICE;
3980  }
3981  else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3982          && (pSignature)[2] == 0x3C && (pSignature)[3] == 0xC3
3983          && (pSignature)[4] == 0x00 )
3984  {
3985    deviceType = SATA_SEMB_DEVICE;
3986  }
3987  else if ( (pSignature)[0] == 0xFF && (pSignature)[1] == 0xFF
3988          && (pSignature)[2] == 0xFF && (pSignature)[3] == 0xFF
3989          && (pSignature)[4] == 0xFF )
3990  {
3991    deviceType = SATA_SEMB_WO_SEP_DEVICE;
3992  }
3993
3994  return deviceType;
3995}
3996
3997
3998/*****************************************************************************/
3999/*! \brief SAT implementation for ATAPI Packet Command.
4000 *
4001 *  SAT implementation for ATAPI Packet and send FIS request to LL layer.
4002 *
4003 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4004 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4005 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4006 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4007 *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4008 *
4009 *  \return If command is started successfully
4010 *    - \e smIOSuccess:     I/O request successfully initiated.
4011 *    - \e smIOBusy:        No resources available, try again later.
4012 *    - \e smIONoDevice:  Invalid device handle.
4013 *    - \e smIOError:       Other errors.
4014 */
4015/*****************************************************************************/
4016osGLOBAL bit32
4017smsatPacket(
4018          smRoot_t                  *smRoot,
4019          smIORequest_t             *smIORequest,
4020          smDeviceHandle_t          *smDeviceHandle,
4021          smScsiInitiatorRequest_t  *smScsiRequest,
4022          smSatIOContext_t            *satIOContext
4023  )
4024{
4025  bit32                     status;
4026  bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4027  smDeviceData_t            *pSatDevData;
4028  smIniScsiCmnd_t           *scsiCmnd;
4029  agsaFisRegHostToDevice_t  *fis;
4030
4031  pSatDevData   = satIOContext->pSatDevData;
4032  scsiCmnd      = &smScsiRequest->scsiCmnd;
4033  fis           = satIOContext->pFis;
4034
4035  SM_DBG3(("smsatPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
4036           scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
4037           scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
4038           scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
4039
4040  fis->h.fisType        = 0x27;                   /* Reg host to device */
4041  fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
4042  fis->h.command        = SAT_PACKET;             /* 0xA0 */
4043  if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
4044  {
4045     fis->h.features    = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
4046  }
4047  else
4048  {
4049     fis->h.features    = 0;                      /* FIS reserve */
4050  }
4051
4052  if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4053  {
4054     /*DMA transfer mode*/
4055     fis->h.features |= 0x01;
4056  }
4057  else
4058  {
4059     /*PIO transfer mode*/
4060     fis->h.features |= 0x0;
4061  }
4062  /* Byte count low and byte count high */
4063  if ( scsiCmnd->expDataLength > 0xFFFF )
4064  {
4065     fis->d.lbaMid = 0xFF;                                 /* FIS LBA (15:8 ) */
4066     fis->d.lbaHigh = 0xFF;                                /* FIS LBA (23:16) */
4067  }
4068  else
4069  {
4070     fis->d.lbaMid = (bit8)scsiCmnd->expDataLength;        /* FIS LBA (15:8 ) */
4071     fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8);  /* FIS LBA (23:16) */
4072  }
4073
4074  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
4075  fis->d.device         = 0;                      /* FIS LBA (27:24) and FIS LBA mode  */
4076  fis->d.lbaLowExp      = 0;
4077  fis->d.lbaMidExp      = 0;
4078  fis->d.lbaHighExp     = 0;
4079  fis->d.featuresExp    = 0;
4080  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
4081  fis->d.sectorCountExp = 0;
4082  fis->d.reserved4      = 0;
4083  fis->d.control        = 0;                      /* FIS HOB bit clear */
4084  fis->d.reserved5      = 0;
4085
4086  satIOContext->ATACmd = SAT_PACKET;
4087
4088  if (smScsiRequest->dataDirection == smDirectionIn)
4089  {
4090      agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4091  }
4092  else
4093  {
4094      agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
4095  }
4096
4097  satIOContext->satCompleteCB = &smsatPacketCB;
4098
4099  /*
4100   * Prepare SGL and send FIS to LL layer.
4101   */
4102  satIOContext->reqType = agRequestType;       /* Save it */
4103
4104  status = smsataLLIOStart(smRoot,
4105                          smIORequest,
4106                          smDeviceHandle,
4107                          smScsiRequest,
4108                          satIOContext);
4109
4110  SM_DBG3(("smsatPacket: return\n"));
4111  return (status);
4112}
4113
4114/*****************************************************************************/
4115/*! \brief SAT implementation for smsatSetFeaturePIO.
4116 *
4117 *  This function creates Set Features fis and sends the request to LL layer
4118 *
4119 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4120 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4121 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4122 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4123 *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4124 *
4125 *  \return If command is started successfully
4126 *    - \e smIOSuccess:     I/O request successfully initiated.
4127 *    - \e smIOBusy:        No resources available, try again later.
4128 *    - \e smIONoDevice:  Invalid device handle.
4129 *    - \e smIOError:       Other errors.
4130 */
4131/*****************************************************************************/
4132osGLOBAL bit32
4133smsatSetFeaturesPIO(
4134  smRoot_t                  *smRoot,
4135  smIORequest_t             *smIORequest,
4136  smDeviceHandle_t          *smDeviceHandle,
4137  smScsiInitiatorRequest_t  *smScsiRequest,
4138  smSatIOContext_t          *satIOContext
4139  )
4140{
4141  bit32                     status = SM_RC_FAILURE;
4142  bit32                     agRequestType;
4143  agsaFisRegHostToDevice_t *fis;
4144
4145  fis           = satIOContext->pFis;
4146  SM_DBG2(("smsatSetFeaturesPIO: start\n"));
4147  /*
4148   * Send the Set Features command.
4149   */
4150  fis->h.fisType        = 0x27;                   /* Reg host to device */
4151  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4152  fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
4153  fis->h.features       = 0x03;                   /* set transfer mode */
4154  fis->d.lbaLow         = 0;
4155  fis->d.lbaMid         = 0;
4156  fis->d.lbaHigh        = 0;
4157  fis->d.device         = 0;
4158  fis->d.lbaLowExp      = 0;
4159  fis->d.lbaMidExp      = 0;
4160  fis->d.lbaHighExp     = 0;
4161  fis->d.featuresExp    = 0;
4162  fis->d.sectorCountExp = 0;
4163  fis->d.reserved4      = 0;
4164  fis->d.control        = 0;                      /* FIS HOB bit clear */
4165  fis->d.reserved5      = 0;
4166
4167  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
4168
4169  /* Initialize CB for SATA completion.
4170   */
4171  fis->d.sectorCount = 0x0C;                     /*enable PIO transfer mode */
4172  satIOContext->satCompleteCB = &smsatSetFeaturesPIOCB;
4173
4174  /*
4175   * Prepare SGL and send FIS to LL layer.
4176   */
4177  satIOContext->reqType = agRequestType;       /* Save it */
4178
4179  status = smsataLLIOStart( smRoot,
4180                          smIORequest,
4181                          smDeviceHandle,
4182                          smScsiRequest,
4183                          satIOContext);
4184
4185  SM_DBG2(("smsatSetFeaturesPIO: return\n"));
4186  /* debugging code */
4187  if (smIORequest->tdData == smIORequest->smData)
4188  {
4189    SM_DBG1(("smsatSetFeaturesPIO: incorrect smIORequest\n"));
4190  }
4191
4192  return status;
4193}
4194/*****************************************************************************/
4195/*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device.
4196 *
4197 *  SAT implementation for SCSI REQUEST SENSE.
4198 *
4199 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4200 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4201 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4202 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4203 *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4204 *
4205 *  \return If command is started successfully
4206 *    - \e smIOSuccess:     I/O request successfully initiated.
4207 *    - \e smIOBusy:        No resources available, try again later.
4208 *    - \e smIONoDevice:  Invalid device handle.
4209 *    - \e smIOError:       Other errors.
4210 */
4211/*****************************************************************************/
4212osGLOBAL bit32
4213smsatRequestSenseForATAPI(
4214  smRoot_t                  *smRoot,
4215  smIORequest_t             *smIORequest,
4216  smDeviceHandle_t          *smDeviceHandle,
4217  smScsiInitiatorRequest_t  *smScsiRequest,
4218  smSatIOContext_t            *satIOContext
4219  )
4220{
4221  bit32                     status;
4222  bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4223  smDeviceData_t            *pSatDevData;
4224  smIniScsiCmnd_t           *scsiCmnd;
4225  agsaFisRegHostToDevice_t  *fis;
4226
4227  pSatDevData   = satIOContext->pSatDevData;
4228  scsiCmnd      = &smScsiRequest->scsiCmnd;
4229  fis           = satIOContext->pFis;
4230
4231  scsiCmnd->cdb[0]   = SCSIOPC_REQUEST_SENSE;
4232  scsiCmnd->cdb[1]   = 0;
4233  scsiCmnd->cdb[2]   = 0;
4234  scsiCmnd->cdb[3]   = 0;
4235  scsiCmnd->cdb[4]   = (bit8)scsiCmnd->expDataLength;
4236  scsiCmnd->cdb[5]   = 0;
4237  SM_DBG3(("smsatRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
4238           scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
4239           scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
4240           scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
4241
4242  fis->h.fisType        = 0x27;                   /* Reg host to device */
4243  fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
4244  fis->h.command        = SAT_PACKET;             /* 0xA0 */
4245  if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
4246  {
4247     fis->h.features    = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
4248  }
4249  else
4250  {
4251     fis->h.features    = 0;                      /* FIS reserve */
4252  }
4253
4254  if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4255  {
4256     fis->h.features |= 0x01;
4257  }
4258  else
4259  {
4260     fis->h.features |= 0x0;
4261  }
4262
4263  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
4264  fis->d.lbaMid         = (bit8)scsiCmnd->expDataLength;        /* FIS LBA (15:8 ) */
4265  fis->d.lbaHigh        = (bit8)(scsiCmnd->expDataLength>>8);  /* FIS LBA (23:16) */
4266  fis->d.device         = 0;                      /* FIS LBA (27:24) and FIS LBA mode  */
4267  fis->d.lbaLowExp      = 0;
4268  fis->d.lbaMidExp      = 0;
4269  fis->d.lbaHighExp     = 0;
4270  fis->d.featuresExp    = 0;
4271  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
4272  fis->d.sectorCountExp = 0;
4273  fis->d.reserved4      = 0;
4274  fis->d.control        = 0;                      /* FIS HOB bit clear */
4275  fis->d.reserved5      = 0;
4276
4277  satIOContext->ATACmd = SAT_PACKET;
4278
4279  agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4280
4281
4282  satIOContext->satCompleteCB = &smsatRequestSenseForATAPICB;
4283
4284  /*
4285   * Prepare SGL and send FIS to LL layer.
4286   */
4287  satIOContext->reqType = agRequestType;       /* Save it */
4288
4289  status = smsataLLIOStart( smRoot,
4290                          smIORequest,
4291                          smDeviceHandle,
4292                          smScsiRequest,
4293                          satIOContext);
4294
4295  SM_DBG3(("smsatRequestSenseForATAPI: return\n"));
4296  return (status);
4297}
4298/*****************************************************************************/
4299/*! \brief SAT implementation for smsatDeviceReset.
4300 *
4301 *  This function creates DEVICE RESET fis and sends the request to LL layer
4302 *
4303 *  \param   smRoot:           Pointer to TISA initiator driver/port instance.
4304 *  \param   smIORequest:      Pointer to TISA I/O request context for this I/O.
4305 *  \param   smDeviceHandle:   Pointer to TISA device handle for this I/O.
4306 *  \param   smScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4307 *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4308 *
4309 *  \return If command is started successfully
4310 *    - \e smIOSuccess:     I/O request successfully initiated.
4311 *    - \e smIOBusy:        No resources available, try again later.
4312 *    - \e smIONoDevice:  Invalid device handle.
4313 *    - \e smIOError:       Other errors.
4314 */
4315/*****************************************************************************/
4316osGLOBAL bit32
4317smsatDeviceReset(
4318  smRoot_t                  *smRoot,
4319  smIORequest_t             *smIORequest,
4320  smDeviceHandle_t          *smDeviceHandle,
4321  smScsiInitiatorRequest_t  *smScsiRequest,
4322  smSatIOContext_t            *satIOContext
4323  )
4324{
4325  bit32                     status;
4326  bit32                     agRequestType;
4327  agsaFisRegHostToDevice_t *fis;
4328
4329  fis           = satIOContext->pFis;
4330  SM_DBG3(("smsatDeviceReset: start\n"));
4331  /*
4332   * Send the  Execute Device Diagnostic command.
4333   */
4334  fis->h.fisType        = 0x27;                   /* Reg host to device */
4335  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4336  fis->h.command        = SAT_DEVICE_RESET;       /* 0x08 */
4337  fis->h.features       = 0;
4338  fis->d.lbaLow         = 0;
4339  fis->d.lbaMid         = 0;
4340  fis->d.lbaHigh        = 0;
4341  fis->d.device         = 0;
4342  fis->d.lbaLowExp      = 0;
4343  fis->d.lbaMidExp      = 0;
4344  fis->d.lbaHighExp     = 0;
4345  fis->d.featuresExp    = 0;
4346  fis->d.sectorCount    = 0;
4347  fis->d.sectorCountExp = 0;
4348  fis->d.reserved4      = 0;
4349  fis->d.control        = 0;                      /* FIS HOB bit clear */
4350  fis->d.reserved5      = 0;
4351
4352  agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
4353
4354  /* Initialize CB for SATA completion.
4355   */
4356  satIOContext->satCompleteCB = &smsatDeviceResetCB;
4357
4358  /*
4359   * Prepare SGL and send FIS to LL layer.
4360   */
4361  satIOContext->reqType = agRequestType;       /* Save it */
4362
4363  status = smsataLLIOStart( smRoot,
4364                          smIORequest,
4365                          smDeviceHandle,
4366                          smScsiRequest,
4367                          satIOContext);
4368
4369  SM_DBG3(("smsatDeviceReset: return\n"));
4370
4371  return status;
4372}
4373
4374
4375/*****************************************************************************/
4376/*! \brief SAT implementation for smsatExecuteDeviceDiagnostic.
4377 *
4378 *  This function creates Execute Device Diagnostic fis and sends the request to LL layer
4379 *
4380 *  \param   smRoot:           Pointer to TISA initiator driver/port instance.
4381 *  \param   smIORequest:      Pointer to TISA I/O request context for this I/O.
4382 *  \param   smDeviceHandle:   Pointer to TISA device handle for this I/O.
4383 *  \param   smScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4384 *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4385 *
4386 *  \return If command is started successfully
4387 *    - \e smIOSuccess:     I/O request successfully initiated.
4388 *    - \e smIOBusy:        No resources available, try again later.
4389 *    - \e smIONoDevice:  Invalid device handle.
4390 *    - \e smIOError:       Other errors.
4391 */
4392/*****************************************************************************/
4393osGLOBAL bit32
4394smsatExecuteDeviceDiagnostic(
4395  smRoot_t                  *smRoot,
4396  smIORequest_t             *smIORequest,
4397  smDeviceHandle_t          *smDeviceHandle,
4398  smScsiInitiatorRequest_t  *smScsiRequest,
4399  smSatIOContext_t            *satIOContext
4400  )
4401{
4402  bit32                     status;
4403  bit32                     agRequestType;
4404  agsaFisRegHostToDevice_t *fis;
4405
4406  fis           = satIOContext->pFis;
4407  SM_DBG3(("smsatExecuteDeviceDiagnostic: start\n"));
4408  /*
4409   * Send the  Execute Device Diagnostic command.
4410   */
4411  fis->h.fisType        = 0x27;                   /* Reg host to device */
4412  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4413  fis->h.command        = SAT_EXECUTE_DEVICE_DIAGNOSTIC;   /* 0x90 */
4414  fis->h.features       = 0;
4415  fis->d.lbaLow         = 0;
4416  fis->d.lbaMid         = 0;
4417  fis->d.lbaHigh        = 0;
4418  fis->d.device         = 0;
4419  fis->d.lbaLowExp      = 0;
4420  fis->d.lbaMidExp      = 0;
4421  fis->d.lbaHighExp     = 0;
4422  fis->d.featuresExp    = 0;
4423  fis->d.sectorCount    = 0;
4424  fis->d.sectorCountExp = 0;
4425  fis->d.reserved4      = 0;
4426  fis->d.control        = 0;                      /* FIS HOB bit clear */
4427  fis->d.reserved5      = 0;
4428
4429  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
4430
4431  /* Initialize CB for SATA completion.
4432   */
4433  satIOContext->satCompleteCB = &smsatExecuteDeviceDiagnosticCB;
4434
4435  /*
4436   * Prepare SGL and send FIS to LL layer.
4437   */
4438  satIOContext->reqType = agRequestType;       /* Save it */
4439
4440  status = smsataLLIOStart( smRoot,
4441                          smIORequest,
4442                          smDeviceHandle,
4443                          smScsiRequest,
4444                          satIOContext);
4445
4446  SM_DBG3(("smsatExecuteDeviceDiagnostic: return\n"));
4447
4448  return status;
4449}
4450
4451
4452osGLOBAL void
4453smsatSetDeferredSensePayload(
4454                             smScsiRspSense_t *pSense,
4455                             bit8             SnsKey,
4456                             bit32            SnsInfo,
4457                             bit16            SnsCode,
4458                             smSatIOContext_t   *satIOContext
4459                            )
4460{
4461  SM_DBG2(("smsatSetDeferredSensePayload: start\n"));
4462  return;
4463}
4464
4465
4466GLOBAL bit32
4467smsatRead6(
4468           smRoot_t                  *smRoot,
4469           smIORequest_t             *smIORequest,
4470           smDeviceHandle_t          *smDeviceHandle,
4471           smScsiInitiatorRequest_t  *smScsiRequest,
4472           smSatIOContext_t            *satIOContext
4473    )
4474{
4475  bit32                     status;
4476  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4477  smDeviceData_t            *pSatDevData;
4478  smScsiRspSense_t          *pSense;
4479  smIniScsiCmnd_t           *scsiCmnd;
4480  agsaFisRegHostToDevice_t  *fis;
4481  bit32                     lba = 0;
4482  bit16                     tl = 0;
4483
4484  pSense        = satIOContext->pSense;
4485  pSatDevData   = satIOContext->pSatDevData;
4486  scsiCmnd      = &smScsiRequest->scsiCmnd;
4487  fis           = satIOContext->pFis;
4488
4489  SM_DBG2(("smsatRead6: start\n"));
4490
4491  /* no FUA checking since read6 */
4492
4493
4494  /* checking CONTROL */
4495  /* NACA == 1 or LINK == 1*/
4496  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
4497  {
4498    smsatSetSensePayload( pSense,
4499                          SCSI_SNSKEY_ILLEGAL_REQUEST,
4500                          0,
4501                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4502                          satIOContext);
4503
4504    /*smEnqueueIO(smRoot, satIOContext);*/
4505
4506    tdsmIOCompletedCB( smRoot,
4507                       smIORequest,
4508                       smIOSuccess,
4509                       SCSI_STAT_CHECK_CONDITION,
4510                       satIOContext->pSmSenseData,
4511                       satIOContext->interruptContext );
4512
4513    SM_DBG1(("smsatRead6: return control!!!\n"));
4514    return SM_RC_SUCCESS;
4515  }
4516
4517  /* cbd6; computing LBA and transfer length */
4518  lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
4519    + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
4520  tl = scsiCmnd->cdb[4];
4521
4522  /* Table 34, 9.1, p 46 */
4523  /*
4524    note: As of 2/10/2006, no support for DMA QUEUED
4525   */
4526
4527  /*
4528    Table 34, 9.1, p 46, b
4529    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4530    return check condition
4531  */
4532  if (pSatDevData->satNCQ != agTRUE &&
4533      pSatDevData->sat48BitSupport != agTRUE
4534      )
4535  {
4536    if (lba > SAT_TR_LBA_LIMIT - 1)
4537    {
4538      smsatSetSensePayload( pSense,
4539                            SCSI_SNSKEY_ILLEGAL_REQUEST,
4540                            0,
4541                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4542                            satIOContext);
4543
4544      /*smEnqueueIO(smRoot, satIOContext);*/
4545
4546      tdsmIOCompletedCB( smRoot,
4547                         smIORequest,
4548                         smIOSuccess,
4549                         SCSI_STAT_CHECK_CONDITION,
4550                         satIOContext->pSmSenseData,
4551                         satIOContext->interruptContext );
4552
4553    SM_DBG1(("smsatRead6: return LBA out of range!!!\n"));
4554    return SM_RC_SUCCESS;
4555    }
4556  }
4557
4558  /* case 1 and 2 */
4559  if (lba + tl <= SAT_TR_LBA_LIMIT)
4560  {
4561    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4562    {
4563      /* case 2 */
4564      /* READ DMA*/
4565      SM_DBG5(("smsatRead6: case 2\n"));
4566
4567
4568      fis->h.fisType        = 0x27;                   /* Reg host to device */
4569      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4570      fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
4571      fis->h.features       = 0;                      /* FIS reserve */
4572      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4573      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4574      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4575      fis->d.device         = 0x40;                   /* FIS LBA mode  */
4576      fis->d.lbaLowExp      = 0;
4577      fis->d.lbaMidExp      = 0;
4578      fis->d.lbaHighExp     = 0;
4579      fis->d.featuresExp    = 0;
4580      if (tl == 0)
4581      {
4582        /* temporary fix */
4583        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4584      }
4585      else
4586      {
4587        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4588      }
4589      fis->d.sectorCountExp = 0;
4590      fis->d.reserved4      = 0;
4591      fis->d.control        = 0;                      /* FIS HOB bit clear */
4592      fis->d.reserved5      = 0;
4593
4594      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4595    }
4596    else
4597    {
4598      /* case 1 */
4599      /* READ SECTORS for easier implemetation */
4600      SM_DBG5(("smsatRead6: case 1\n"));
4601
4602      fis->h.fisType        = 0x27;                   /* Reg host to device */
4603      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4604      fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
4605      fis->h.features       = 0;                      /* FIS reserve */
4606      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4607      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4608      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4609      fis->d.device         = 0x40;                   /* FIS LBA mode  */
4610      fis->d.lbaLowExp      = 0;
4611      fis->d.lbaMidExp      = 0;
4612      fis->d.lbaHighExp     = 0;
4613      fis->d.featuresExp    = 0;
4614      if (tl == 0)
4615      {
4616        /* temporary fix */
4617        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4618      }
4619      else
4620      {
4621        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4622      }
4623      fis->d.sectorCountExp = 0;
4624      fis->d.reserved4      = 0;
4625      fis->d.control        = 0;                      /* FIS HOB bit clear */
4626      fis->d.reserved5      = 0;
4627
4628      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
4629
4630    }
4631  }
4632
4633  /* case 3 and 4 */
4634  if (pSatDevData->sat48BitSupport == agTRUE)
4635  {
4636    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4637    {
4638      /* case 3 */
4639      /* READ DMA EXT only */
4640      SM_DBG5(("smsatRead6: case 3\n"));
4641      fis->h.fisType        = 0x27;                   /* Reg host to device */
4642      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4643      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
4644      fis->h.features       = 0;                      /* FIS reserve */
4645      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4646      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4647      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4648      fis->d.device         = 0x40;                   /* FIS LBA mode set */
4649      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4650      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4651      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4652      fis->d.featuresExp    = 0;                      /* FIS reserve */
4653      if (tl == 0)
4654      {
4655        /* sector count is 256, 0x100*/
4656        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4657        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4658      }
4659      else
4660      {
4661        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4662        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4663      }
4664      fis->d.reserved4      = 0;
4665      fis->d.control        = 0;                      /* FIS HOB bit clear */
4666      fis->d.reserved5      = 0;
4667
4668      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4669    }
4670    else
4671    {
4672      /* case 4 */
4673      /* READ SECTORS EXT for easier implemetation */
4674      SM_DBG5(("smsatRead6: case 4\n"));
4675
4676      fis->h.fisType        = 0x27;                   /* Reg host to device */
4677      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4678      fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
4679      fis->h.features       = 0;                      /* FIS reserve */
4680      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4681      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4682      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4683      fis->d.device         = 0x40;                   /* FIS LBA mode set */
4684      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4685      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4686      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4687      fis->d.featuresExp    = 0;                      /* FIS reserve */
4688      if (tl == 0)
4689      {
4690        /* sector count is 256, 0x100*/
4691        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4692        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4693      }
4694      else
4695      {
4696        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4697        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4698      }
4699      fis->d.reserved4      = 0;
4700      fis->d.control        = 0;                      /* FIS HOB bit clear */
4701      fis->d.reserved5      = 0;
4702
4703      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
4704    }
4705  }
4706
4707  /* case 5 */
4708  if (pSatDevData->satNCQ == agTRUE)
4709  {
4710    /* READ FPDMA QUEUED */
4711    if (pSatDevData->sat48BitSupport != agTRUE)
4712    {
4713      /* sanity check */
4714      SM_DBG1(("smsatRead6: case 5 !!! error NCQ but 28 bit address support!!!\n"));
4715      smsatSetSensePayload( pSense,
4716                            SCSI_SNSKEY_ILLEGAL_REQUEST,
4717                            0,
4718                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4719                            satIOContext);
4720
4721      /*smEnqueueIO(smRoot, satIOContext);*/
4722
4723      tdsmIOCompletedCB( smRoot,
4724                         smIORequest,
4725                         smIOSuccess,
4726                         SCSI_STAT_CHECK_CONDITION,
4727                         satIOContext->pSmSenseData,
4728                         satIOContext->interruptContext );
4729      return SM_RC_SUCCESS;
4730    }
4731    SM_DBG5(("smsatRead6: case 5\n"));
4732
4733    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
4734
4735    fis->h.fisType        = 0x27;                   /* Reg host to device */
4736    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4737    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
4738    fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4739    fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4740    fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4741    fis->d.device         = 0x40;                   /* FIS FUA clear */
4742    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4743    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4744    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4745    if (tl == 0)
4746    {
4747      /* sector count is 256, 0x100*/
4748      fis->h.features       = 0;                         /* FIS sector count (7:0) */
4749      fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
4750    }
4751    else
4752    {
4753      fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4754      fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
4755    }
4756    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4757    fis->d.sectorCountExp = 0;
4758    fis->d.reserved4      = 0;
4759    fis->d.control        = 0;                      /* FIS HOB bit clear */
4760    fis->d.reserved5      = 0;
4761
4762    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
4763  }
4764
4765   /* Initialize CB for SATA completion.
4766   */
4767  satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
4768
4769  /*
4770   * Prepare SGL and send FIS to LL layer.
4771   */
4772  satIOContext->reqType = agRequestType;       /* Save it */
4773
4774  status = smsataLLIOStart( smRoot,
4775                            smIORequest,
4776                            smDeviceHandle,
4777                            smScsiRequest,
4778                            satIOContext);
4779  return (status);
4780
4781}
4782
4783osGLOBAL FORCEINLINE bit32
4784smsatRead10(
4785            smRoot_t                  *smRoot,
4786            smIORequest_t             *smIORequest,
4787            smDeviceHandle_t          *smDeviceHandle,
4788            smScsiInitiatorRequest_t  *smScsiRequest,
4789            smSatIOContext_t            *satIOContext
4790     )
4791{
4792  smDeviceData_t            *pSatDevData = satIOContext->pSatDevData;
4793  smScsiRspSense_t          *pSense      = satIOContext->pSense;
4794  smIniScsiCmnd_t           *scsiCmnd    = &smScsiRequest->scsiCmnd;
4795  agsaFisRegHostToDevice_t  *fis         = satIOContext->pFis;
4796
4797  bit32                     status;
4798  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4799  bit32                     lba = 0;
4800  bit32                     tl = 0;
4801  bit32                     LoopNum = 1;
4802  bit8                      LBA[8];
4803  bit8                      TL[8];
4804  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
4805
4806  SM_DBG2(("smsatRead10: start\n"));
4807  SM_DBG2(("smsatRead10: pSatDevData did=%d\n", pSatDevData->id));
4808  //  smhexdump("smsatRead10", (bit8 *)scsiCmnd->cdb, 10);
4809
4810  /* checking FUA_NV */
4811  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
4812  {
4813    smsatSetSensePayload( pSense,
4814                          SCSI_SNSKEY_ILLEGAL_REQUEST,
4815                          0,
4816                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4817                          satIOContext);
4818
4819    /*smEnqueueIO(smRoot, satIOContext);*/
4820
4821    tdsmIOCompletedCB( smRoot,
4822                       smIORequest,
4823                       smIOSuccess,
4824                       SCSI_STAT_CHECK_CONDITION,
4825                       satIOContext->pSmSenseData,
4826                       satIOContext->interruptContext );
4827
4828    SM_DBG1(("smsatRead10: return FUA_NV!!!\n"));
4829    return SM_RC_SUCCESS;
4830
4831  }
4832
4833  /* checking CONTROL */
4834  /* NACA == 1 or LINK == 1*/
4835  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
4836  {
4837    smsatSetSensePayload( pSense,
4838                          SCSI_SNSKEY_ILLEGAL_REQUEST,
4839                          0,
4840                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4841                          satIOContext);
4842
4843    /*smEnqueueIO(smRoot, satIOContext);*/
4844
4845    tdsmIOCompletedCB( smRoot,
4846                       smIORequest,
4847                       smIOSuccess,
4848                       SCSI_STAT_CHECK_CONDITION,
4849                       satIOContext->pSmSenseData,
4850                       satIOContext->interruptContext );
4851
4852    SM_DBG1(("smsatRead10: return control!!!\n"));
4853    return SM_RC_SUCCESS;
4854  }
4855  /*
4856  sm_memset(LBA, 0, sizeof(LBA));
4857  sm_memset(TL, 0, sizeof(TL));
4858  */
4859  /* do not use memcpy due to indexing in LBA and TL */
4860  LBA[0] = 0;                  /* MSB */
4861  LBA[1] = 0;
4862  LBA[2] = 0;
4863  LBA[3] = 0;
4864  LBA[4] = scsiCmnd->cdb[2];
4865  LBA[5] = scsiCmnd->cdb[3];
4866  LBA[6] = scsiCmnd->cdb[4];
4867  LBA[7] = scsiCmnd->cdb[5];   /* LSB */
4868
4869  TL[0] = 0;
4870  TL[1] = 0;
4871  TL[2] = 0;
4872  TL[3] = 0;
4873  TL[4] = 0;
4874  TL[5] = 0;
4875  TL[6] = scsiCmnd->cdb[7];
4876  TL[7] = scsiCmnd->cdb[8];    /* LSB */
4877
4878
4879  /* cbd10; computing LBA and transfer length */
4880  lba = (scsiCmnd->cdb[2] << 24) + (scsiCmnd->cdb[3] << 16)
4881        + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
4882  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
4883
4884
4885  SM_DBG5(("smsatRead10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext)));
4886  SM_DBG5(("smsatRead10: lba 0x%x functioned lba 0x%x\n", lba, smsatComputeCDB10LBA(satIOContext)));
4887  SM_DBG5(("smsatRead10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext)));
4888
4889  /* Table 34, 9.1, p 46 */
4890  /*
4891    note: As of 2/10/2006, no support for DMA QUEUED
4892   */
4893
4894  /*
4895    Table 34, 9.1, p 46, b
4896    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4897    return check condition
4898  */
4899
4900  if (pSatDevData->satNCQ != agTRUE &&
4901      pSatDevData->sat48BitSupport != agTRUE
4902      )
4903  {
4904    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
4905    if (AllChk)
4906    {
4907      SM_DBG1(("smsatRead10: return LBA out of range, not EXT!!!\n"));
4908      smsatSetSensePayload( pSense,
4909                            SCSI_SNSKEY_ILLEGAL_REQUEST,
4910                            0,
4911                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4912                            satIOContext);
4913
4914      /*smEnqueueIO(smRoot, satIOContext);*/
4915
4916      tdsmIOCompletedCB( smRoot,
4917                         smIORequest,
4918                         smIOSuccess,
4919                         SCSI_STAT_CHECK_CONDITION,
4920                         satIOContext->pSmSenseData,
4921                         satIOContext->interruptContext );
4922
4923      return SM_RC_SUCCESS;
4924    }
4925  }
4926  else
4927  {
4928    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
4929    if (AllChk)
4930    {
4931      SM_DBG1(("smsatRead10: return LBA out of range, EXT!!!\n"));
4932      smsatSetSensePayload( pSense,
4933                            SCSI_SNSKEY_ILLEGAL_REQUEST,
4934                            0,
4935                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4936                            satIOContext);
4937
4938      /*smEnqueueIO(smRoot, satIOContext);*/
4939
4940      tdsmIOCompletedCB( smRoot,
4941                         smIORequest,
4942                         smIOSuccess,
4943                         SCSI_STAT_CHECK_CONDITION,
4944                         satIOContext->pSmSenseData,
4945                         satIOContext->interruptContext );
4946
4947    return SM_RC_SUCCESS;
4948    }
4949  }
4950    /* case 5 */
4951  if (pSatDevData->satNCQ == agTRUE)
4952  {
4953    /* READ FPDMA QUEUED */
4954    if (pSatDevData->sat48BitSupport != agTRUE)
4955    {
4956      SM_DBG1(("smsatRead10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
4957      smsatSetSensePayload( pSense,
4958                            SCSI_SNSKEY_ILLEGAL_REQUEST,
4959                            0,
4960                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4961                            satIOContext);
4962
4963      /*smEnqueueIO(smRoot, satIOContext);*/
4964
4965      tdsmIOCompletedCB( smRoot,
4966                         smIORequest,
4967                         smIOSuccess,
4968                         SCSI_STAT_CHECK_CONDITION,
4969                         satIOContext->pSmSenseData,
4970                         satIOContext->interruptContext );
4971      return SM_RC_SUCCESS;
4972    }
4973
4974    SM_DBG6(("smsatRead10: case 5\n"));
4975
4976    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
4977
4978    fis->h.fisType        = 0x27;                   /* Reg host to device */
4979    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4980    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
4981    fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4982    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4983    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4984    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4985
4986    /* Check FUA bit */
4987    if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
4988      fis->d.device       = 0xC0;                   /* FIS FUA set */
4989    else
4990      fis->d.device       = 0x40;                   /* FIS FUA clear */
4991
4992    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4993    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4994    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4995    fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4996    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4997    fis->d.sectorCountExp = 0;
4998    fis->d.reserved4      = 0;
4999    fis->d.control        = 0;                      /* FIS HOB bit clear */
5000    fis->d.reserved5      = 0;
5001
5002    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
5003    satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
5004  }
5005  else if (pSatDevData->sat48BitSupport == agTRUE) /* case 3 and 4 */
5006  {
5007    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5008    {
5009      /* case 3 */
5010      /* READ DMA EXT */
5011      SM_DBG5(("smsatRead10: case 3\n"));
5012      fis->h.fisType        = 0x27;                   /* Reg host to device */
5013
5014      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5015      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
5016      fis->h.features       = 0;                      /* FIS reserve */
5017      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5018      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5019      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5020      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5021      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5022      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5023      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5024      fis->d.featuresExp    = 0;                      /* FIS reserve */
5025      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5026      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
5027      fis->d.reserved4      = 0;
5028      fis->d.control        = 0;                      /* FIS HOB bit clear */
5029      fis->d.reserved5      = 0;
5030
5031      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5032      satIOContext->ATACmd = SAT_READ_DMA_EXT;
5033
5034    }
5035    else
5036    {
5037      /* case 4 */
5038      /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5039      /* READ SECTORS EXT for easier implemetation */
5040      SM_DBG5(("smsatRead10: case 4\n"));
5041      fis->h.fisType        = 0x27;                   /* Reg host to device */
5042      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5043
5044      /* Check FUA bit */
5045      if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
5046      {
5047
5048        /* for now, no support for FUA */
5049        smsatSetSensePayload( pSense,
5050                              SCSI_SNSKEY_ILLEGAL_REQUEST,
5051                              0,
5052                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5053                              satIOContext);
5054
5055        /*smEnqueueIO(smRoot, satIOContext);*/
5056
5057        tdsmIOCompletedCB( smRoot,
5058                           smIORequest,
5059                           smIOSuccess,
5060                           SCSI_STAT_CHECK_CONDITION,
5061                           satIOContext->pSmSenseData,
5062                           satIOContext->interruptContext );
5063        return SM_RC_SUCCESS;
5064      }
5065
5066      fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
5067
5068      fis->h.features       = 0;                      /* FIS reserve */
5069      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5070      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5071      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5072      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5073      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5074      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5075      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5076      fis->d.featuresExp    = 0;                      /* FIS reserve */
5077      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5078      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
5079      fis->d.reserved4      = 0;
5080      fis->d.control        = 0;                      /* FIS HOB bit clear */
5081      fis->d.reserved5      = 0;
5082
5083      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5084      satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
5085    }
5086  }
5087  else/* case 1 and 2 */
5088  {
5089      if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5090      {
5091        /* case 2 */
5092        /* READ DMA*/
5093        /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */
5094        SM_DBG5(("smsatRead10: case 2\n"));
5095
5096
5097        fis->h.fisType        = 0x27;                   /* Reg host to device */
5098        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5099        fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
5100        fis->h.features       = 0;                      /* FIS reserve */
5101        fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5102        fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5103        fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5104        fis->d.device         =
5105          (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5106        fis->d.lbaLowExp      = 0;
5107        fis->d.lbaMidExp      = 0;
5108        fis->d.lbaHighExp     = 0;
5109        fis->d.featuresExp    = 0;
5110        fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5111        fis->d.sectorCountExp = 0;
5112        fis->d.reserved4      = 0;
5113        fis->d.control        = 0;                      /* FIS HOB bit clear */
5114        fis->d.reserved5      = 0;
5115
5116
5117        agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5118        satIOContext->ATACmd = SAT_READ_DMA;
5119      }
5120      else
5121      {
5122        /* case 1 */
5123        /* READ MULTIPLE or READ SECTOR(S) */
5124        /* READ SECTORS for easier implemetation */
5125        /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */
5126        SM_DBG5(("smsatRead10: case 1\n"));
5127
5128        fis->h.fisType        = 0x27;                   /* Reg host to device */
5129        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5130        fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
5131        fis->h.features       = 0;                      /* FIS reserve */
5132        fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5133        fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5134        fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5135        fis->d.device         =
5136          (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5137        fis->d.lbaLowExp      = 0;
5138        fis->d.lbaMidExp      = 0;
5139        fis->d.lbaHighExp     = 0;
5140        fis->d.featuresExp    = 0;
5141        fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5142        fis->d.sectorCountExp = 0;
5143        fis->d.reserved4      = 0;
5144        fis->d.control        = 0;                      /* FIS HOB bit clear */
5145        fis->d.reserved5      = 0;
5146
5147
5148        agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5149        satIOContext->ATACmd = SAT_READ_SECTORS;
5150    }
5151  }
5152  //  smhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
5153
5154  /* saves the current LBA and orginal TL */
5155  satIOContext->currentLBA = lba;
5156  satIOContext->OrgTL = tl;
5157
5158 /*
5159    computing number of loop and remainder for tl
5160    0xFF in case not ext
5161    0xFFFF in case EXT
5162  */
5163  if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5164  {
5165    LoopNum = smsatComputeLoopNum(tl, 0x100);
5166  }
5167  else
5168  {
5169     /* SAT_READ_FPDMA_QUEUED */
5170     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5171     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5172  }
5173
5174  satIOContext->LoopNum = LoopNum;
5175
5176  /* Initialize CB for SATA completion.
5177   */
5178  if (LoopNum == 1)
5179  {
5180    SM_DBG5(("smsatRead10: NON CHAINED data\n"));
5181    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
5182  }
5183  else
5184  {
5185    SM_DBG2(("smsatRead10: CHAINED data!!!\n"));
5186
5187    /* re-setting tl */
5188    if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5189    {
5190      fis->d.sectorCount    = 0x0;
5191      smsatSplitSGL(smRoot,
5192                    smIORequest,
5193                    smDeviceHandle,
5194                    smScsiRequest,
5195                    satIOContext,
5196                    NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */
5197                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5198                    agTRUE);
5199    }
5200    else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5201    {
5202      /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5203      fis->d.sectorCount    = 0xFF;
5204      fis->d.sectorCountExp = 0xFF;
5205      smsatSplitSGL(smRoot,
5206                    smIORequest,
5207                    smDeviceHandle,
5208                    smScsiRequest,
5209                    satIOContext,
5210                    BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
5211                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5212                    agTRUE);
5213    }
5214    else
5215    {
5216      /* SAT_READ_FPDMA_QUEUED */
5217      fis->h.features       = 0xFF;
5218      fis->d.featuresExp    = 0xFF;
5219      smsatSplitSGL(smRoot,
5220                    smIORequest,
5221                    smDeviceHandle,
5222                    smScsiRequest,
5223                    satIOContext,
5224                    BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
5225                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5226                    agTRUE);
5227    }
5228
5229    /* chained data */
5230    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
5231
5232  }
5233
5234  /*
5235   * Prepare SGL and send FIS to LL layer.
5236   */
5237  satIOContext->reqType = agRequestType;       /* Save it */
5238
5239  status = smsataLLIOStart( smRoot,
5240                            smIORequest,
5241                            smDeviceHandle,
5242                            smScsiRequest,
5243                            satIOContext);
5244
5245  SM_DBG5(("smsatRead10: return\n"));
5246  return (status);
5247
5248}
5249
5250osGLOBAL bit32
5251smsatRead12(
5252            smRoot_t                  *smRoot,
5253            smIORequest_t             *smIORequest,
5254            smDeviceHandle_t          *smDeviceHandle,
5255            smScsiInitiatorRequest_t  *smScsiRequest,
5256            smSatIOContext_t            *satIOContext
5257     )
5258{
5259  bit32                     status;
5260  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5261  smDeviceData_t            *pSatDevData;
5262  smScsiRspSense_t          *pSense;
5263  smIniScsiCmnd_t           *scsiCmnd;
5264  agsaFisRegHostToDevice_t  *fis;
5265  bit32                     lba = 0;
5266  bit32                     tl = 0;
5267  bit32                     LoopNum = 1;
5268  bit8                      LBA[8];
5269  bit8                      TL[8];
5270  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
5271
5272  pSense        = satIOContext->pSense;
5273  pSatDevData   = satIOContext->pSatDevData;
5274  scsiCmnd      = &smScsiRequest->scsiCmnd;
5275  fis           = satIOContext->pFis;
5276
5277  SM_DBG5(("smsatRead12: start\n"));
5278
5279  /* checking FUA_NV */
5280  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
5281  {
5282    smsatSetSensePayload( pSense,
5283                          SCSI_SNSKEY_ILLEGAL_REQUEST,
5284                          0,
5285                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5286                          satIOContext);
5287
5288    /*smEnqueueIO(smRoot, satIOContext);*/
5289
5290    tdsmIOCompletedCB( smRoot,
5291                       smIORequest,
5292                       smIOSuccess,
5293                       SCSI_STAT_CHECK_CONDITION,
5294                       satIOContext->pSmSenseData,
5295                       satIOContext->interruptContext );
5296
5297    SM_DBG1(("smsatRead12: return FUA_NV!!!\n"));
5298    return SM_RC_SUCCESS;
5299
5300  }
5301
5302  /* checking CONTROL */
5303  /* NACA == 1 or LINK == 1*/
5304  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
5305  {
5306    smsatSetSensePayload( pSense,
5307                          SCSI_SNSKEY_ILLEGAL_REQUEST,
5308                          0,
5309                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5310                          satIOContext);
5311
5312    /*smEnqueueIO(smRoot, satIOContext);*/
5313
5314    tdsmIOCompletedCB( smRoot,
5315                       smIORequest,
5316                       smIOSuccess,
5317                       SCSI_STAT_CHECK_CONDITION,
5318                       satIOContext->pSmSenseData,
5319                       satIOContext->interruptContext );
5320
5321    SM_DBG1(("smsatRead12: return control!!!\n"));
5322    return SM_RC_SUCCESS;
5323  }
5324
5325  sm_memset(LBA, 0, sizeof(LBA));
5326  sm_memset(TL, 0, sizeof(TL));
5327
5328  /* do not use memcpy due to indexing in LBA and TL */
5329  LBA[0] = 0;                  /* MSB */
5330  LBA[1] = 0;
5331  LBA[2] = 0;
5332  LBA[3] = 0;
5333  LBA[4] = scsiCmnd->cdb[2];
5334  LBA[5] = scsiCmnd->cdb[3];
5335  LBA[6] = scsiCmnd->cdb[4];
5336  LBA[7] = scsiCmnd->cdb[5];   /* LSB */
5337
5338  TL[0] = 0;                   /* MSB */
5339  TL[1] = 0;
5340  TL[2] = 0;
5341  TL[3] = 0;
5342  TL[4] = scsiCmnd->cdb[6];
5343  TL[5] = scsiCmnd->cdb[7];
5344  TL[6] = scsiCmnd->cdb[8];
5345  TL[7] = scsiCmnd->cdb[9];   	/* LSB */
5346
5347
5348  lba = smsatComputeCDB12LBA(satIOContext);
5349  tl = smsatComputeCDB12TL(satIOContext);
5350
5351  /* Table 34, 9.1, p 46 */
5352  /*
5353    note: As of 2/10/2006, no support for DMA QUEUED
5354   */
5355
5356  /*
5357    Table 34, 9.1, p 46, b
5358    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
5359    return check condition
5360  */
5361  if (pSatDevData->satNCQ != agTRUE &&
5362      pSatDevData->sat48BitSupport != agTRUE
5363      )
5364  {
5365
5366    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
5367    if (AllChk)
5368    {
5369      SM_DBG1(("smsatRead12: return LBA out of range, not EXT!!!\n"));
5370      smsatSetSensePayload( pSense,
5371                            SCSI_SNSKEY_ILLEGAL_REQUEST,
5372                            0,
5373                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5374                            satIOContext);
5375
5376      /*smEnqueueIO(smRoot, satIOContext);*/
5377
5378      tdsmIOCompletedCB( smRoot,
5379                         smIORequest,
5380                         smIOSuccess,
5381                         SCSI_STAT_CHECK_CONDITION,
5382                         satIOContext->pSmSenseData,
5383                         satIOContext->interruptContext );
5384
5385    return SM_RC_SUCCESS;
5386    }
5387  }
5388  else
5389  {
5390    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
5391    if (AllChk)
5392    {
5393      SM_DBG1(("smsatRead12: return LBA out of range, EXT!!!\n"));
5394      smsatSetSensePayload( pSense,
5395                            SCSI_SNSKEY_ILLEGAL_REQUEST,
5396                            0,
5397                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5398                            satIOContext);
5399
5400      /*smEnqueueIO(smRoot, satIOContext);*/
5401
5402      tdsmIOCompletedCB( smRoot,
5403                         smIORequest,
5404                         smIOSuccess,
5405                         SCSI_STAT_CHECK_CONDITION,
5406                         satIOContext->pSmSenseData,
5407                         satIOContext->interruptContext );
5408
5409    return SM_RC_SUCCESS;
5410    }
5411  }
5412
5413  /* case 1 and 2 */
5414    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5415    {
5416      /* case 2 */
5417      /* READ DMA*/
5418      /* in case that we can't fit the transfer length,
5419         we need to make it fit by sending multiple ATA cmnds */
5420      SM_DBG5(("smsatRead12: case 2\n"));
5421
5422
5423      fis->h.fisType        = 0x27;                   /* Reg host to device */
5424      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5425      fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
5426      fis->h.features       = 0;                      /* FIS reserve */
5427      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5428      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5429      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5430      fis->d.device         =
5431        (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5432      fis->d.lbaLowExp      = 0;
5433      fis->d.lbaMidExp      = 0;
5434      fis->d.lbaHighExp     = 0;
5435      fis->d.featuresExp    = 0;
5436      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5437      fis->d.sectorCountExp = 0;
5438      fis->d.reserved4      = 0;
5439      fis->d.control        = 0;                      /* FIS HOB bit clear */
5440      fis->d.reserved5      = 0;
5441
5442
5443      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5444      satIOContext->ATACmd = SAT_READ_DMA;
5445    }
5446    else
5447    {
5448      /* case 1 */
5449      /* READ MULTIPLE or READ SECTOR(S) */
5450      /* READ SECTORS for easier implemetation */
5451      /* can't fit the transfer length but need to make it fit by sending multiple*/
5452      SM_DBG5(("smsatRead12: case 1\n"));
5453
5454      fis->h.fisType        = 0x27;                   /* Reg host to device */
5455      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5456      fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
5457      fis->h.features       = 0;                      /* FIS reserve */
5458      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5459      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5460      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5461      fis->d.device         =
5462        (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5463      fis->d.lbaLowExp      = 0;
5464      fis->d.lbaMidExp      = 0;
5465      fis->d.lbaHighExp     = 0;
5466      fis->d.featuresExp    = 0;
5467      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5468      fis->d.sectorCountExp = 0;
5469      fis->d.reserved4      = 0;
5470      fis->d.control        = 0;                      /* FIS HOB bit clear */
5471      fis->d.reserved5      = 0;
5472
5473
5474      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5475      satIOContext->ATACmd = SAT_READ_SECTORS;
5476  }
5477
5478  /* case 3 and 4 */
5479  if (pSatDevData->sat48BitSupport == agTRUE)
5480  {
5481    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5482    {
5483      /* case 3 */
5484      /* READ DMA EXT */
5485      SM_DBG5(("smsatRead12: case 3\n"));
5486      fis->h.fisType        = 0x27;                   /* Reg host to device */
5487
5488      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5489      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
5490      fis->h.features       = 0;                      /* FIS reserve */
5491      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5492      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5493      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5494      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5495      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5496      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5497      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5498      fis->d.featuresExp    = 0;                      /* FIS reserve */
5499      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5500      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
5501      fis->d.reserved4      = 0;
5502      fis->d.control        = 0;                      /* FIS HOB bit clear */
5503      fis->d.reserved5      = 0;
5504
5505      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5506      satIOContext->ATACmd = SAT_READ_DMA_EXT;
5507
5508    }
5509    else
5510    {
5511      /* case 4 */
5512      /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5513      /* READ SECTORS EXT for easier implemetation */
5514      SM_DBG5(("smsatRead12: case 4\n"));
5515      fis->h.fisType        = 0x27;                   /* Reg host to device */
5516      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5517
5518      /* Check FUA bit */
5519      if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
5520      {
5521
5522        /* for now, no support for FUA */
5523        smsatSetSensePayload( pSense,
5524                              SCSI_SNSKEY_ILLEGAL_REQUEST,
5525                              0,
5526                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5527                              satIOContext);
5528
5529        /*smEnqueueIO(smRoot, satIOContext);*/
5530
5531        tdsmIOCompletedCB( smRoot,
5532                           smIORequest,
5533                           smIOSuccess,
5534                           SCSI_STAT_CHECK_CONDITION,
5535                           satIOContext->pSmSenseData,
5536                           satIOContext->interruptContext );
5537        return SM_RC_SUCCESS;
5538      }
5539
5540      fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
5541
5542      fis->h.features       = 0;                      /* FIS reserve */
5543      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5544      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5545      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5546      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5547      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5548      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5549      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5550      fis->d.featuresExp    = 0;                      /* FIS reserve */
5551      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5552      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
5553      fis->d.reserved4      = 0;
5554      fis->d.control        = 0;                      /* FIS HOB bit clear */
5555      fis->d.reserved5      = 0;
5556
5557      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5558      satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
5559    }
5560  }
5561
5562  /* case 5 */
5563  if (pSatDevData->satNCQ == agTRUE)
5564  {
5565    /* READ FPDMA QUEUED */
5566    if (pSatDevData->sat48BitSupport != agTRUE)
5567    {
5568      SM_DBG1(("smsatRead12: case 5 !!! error NCQ but 28 bit address support!!!\n"));
5569      smsatSetSensePayload( pSense,
5570                            SCSI_SNSKEY_ILLEGAL_REQUEST,
5571                            0,
5572                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5573                            satIOContext);
5574
5575        /*smEnqueueIO(smRoot, satIOContext);*/
5576
5577        tdsmIOCompletedCB( smRoot,
5578                           smIORequest,
5579                           smIOSuccess,
5580                           SCSI_STAT_CHECK_CONDITION,
5581                           satIOContext->pSmSenseData,
5582                           satIOContext->interruptContext );
5583      return SM_RC_SUCCESS;
5584    }
5585
5586    SM_DBG6(("smsatRead12: case 5\n"));
5587
5588    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
5589
5590    fis->h.fisType        = 0x27;                   /* Reg host to device */
5591    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5592    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
5593    fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5594    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5595    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5596    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5597
5598    /* Check FUA bit */
5599    if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
5600      fis->d.device       = 0xC0;                   /* FIS FUA set */
5601    else
5602      fis->d.device       = 0x40;                   /* FIS FUA clear */
5603
5604    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5605    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5606    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5607    fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
5608    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
5609    fis->d.sectorCountExp = 0;
5610    fis->d.reserved4      = 0;
5611    fis->d.control        = 0;                      /* FIS HOB bit clear */
5612    fis->d.reserved5      = 0;
5613
5614    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
5615    satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
5616  }
5617
5618  /* saves the current LBA and orginal TL */
5619  satIOContext->currentLBA = lba;
5620  satIOContext->OrgTL = tl;
5621
5622  /*
5623    computing number of loop and remainder for tl
5624    0xFF in case not ext
5625    0xFFFF in case EXT
5626  */
5627  if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5628  {
5629    LoopNum = smsatComputeLoopNum(tl, 0xFF);
5630  }
5631  else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5632  {
5633    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5634    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5635  }
5636  else
5637  {
5638    /* SAT_READ_FPDMA_QUEUEDK */
5639    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5640  }
5641
5642  satIOContext->LoopNum = LoopNum;
5643
5644  if (LoopNum == 1)
5645  {
5646    SM_DBG5(("smsatRead12: NON CHAINED data\n"));
5647    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
5648  }
5649  else
5650  {
5651    SM_DBG1(("smsatRead12: CHAINED data\n"));
5652    /* re-setting tl */
5653    if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5654    {
5655       fis->d.sectorCount    = 0xFF;
5656    }
5657    else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5658    {
5659      /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5660      fis->d.sectorCount    = 0xFF;
5661      fis->d.sectorCountExp = 0xFF;
5662    }
5663    else
5664    {
5665      /* SAT_READ_FPDMA_QUEUED */
5666      fis->h.features       = 0xFF;
5667      fis->d.featuresExp    = 0xFF;
5668    }
5669
5670    /* chained data */
5671    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
5672  }
5673
5674  /*
5675   * Prepare SGL and send FIS to LL layer.
5676   */
5677  satIOContext->reqType = agRequestType;       /* Save it */
5678
5679  status = smsataLLIOStart( smRoot,
5680                            smIORequest,
5681                            smDeviceHandle,
5682                            smScsiRequest,
5683                            satIOContext);
5684
5685  SM_DBG5(("smsatRead12: return\n"));
5686  return (status);
5687}
5688
5689osGLOBAL bit32
5690smsatRead16(
5691            smRoot_t                  *smRoot,
5692            smIORequest_t             *smIORequest,
5693            smDeviceHandle_t          *smDeviceHandle,
5694            smScsiInitiatorRequest_t  *smScsiRequest,
5695            smSatIOContext_t            *satIOContext
5696     )
5697{
5698  bit32                     status;
5699  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5700  smDeviceData_t            *pSatDevData;
5701  smScsiRspSense_t          *pSense;
5702  smIniScsiCmnd_t           *scsiCmnd;
5703  agsaFisRegHostToDevice_t  *fis;
5704  bit32                     lba = 0;
5705  bit32                     tl = 0;
5706  bit32                     LoopNum = 1;
5707  bit8                      LBA[8];
5708  bit8                      TL[8];
5709  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
5710//  bit32                     limitExtChk = agFALSE; /* lba limit check for bit48 addressing check */
5711
5712  pSense        = satIOContext->pSense;
5713  pSatDevData   = satIOContext->pSatDevData;
5714  scsiCmnd      = &smScsiRequest->scsiCmnd;
5715  fis           = satIOContext->pFis;
5716
5717  SM_DBG5(("smsatRead16: start\n"));
5718
5719  /* checking FUA_NV */
5720  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
5721  {
5722    smsatSetSensePayload( pSense,
5723                          SCSI_SNSKEY_ILLEGAL_REQUEST,
5724                          0,
5725                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5726                          satIOContext);
5727
5728    /*smEnqueueIO(smRoot, satIOContext);*/
5729
5730    tdsmIOCompletedCB( smRoot,
5731                       smIORequest,
5732                       smIOSuccess,
5733                       SCSI_STAT_CHECK_CONDITION,
5734                       satIOContext->pSmSenseData,
5735                       satIOContext->interruptContext );
5736
5737    SM_DBG1(("smsatRead16: return FUA_NV!!!\n"));
5738    return SM_RC_SUCCESS;
5739
5740  }
5741
5742  /* checking CONTROL */
5743  /* NACA == 1 or LINK == 1*/
5744  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
5745  {
5746    smsatSetSensePayload( pSense,
5747                          SCSI_SNSKEY_ILLEGAL_REQUEST,
5748                          0,
5749                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5750                          satIOContext);
5751
5752    /*smEnqueueIO(smRoot, satIOContext);*/
5753
5754    tdsmIOCompletedCB( smRoot,
5755                       smIORequest,
5756                       smIOSuccess,
5757                       SCSI_STAT_CHECK_CONDITION,
5758                       satIOContext->pSmSenseData,
5759                       satIOContext->interruptContext );
5760
5761    SM_DBG1(("smsatRead16: return control!!!\n"));
5762    return SM_RC_SUCCESS;
5763  }
5764
5765
5766  sm_memset(LBA, 0, sizeof(LBA));
5767  sm_memset(TL, 0, sizeof(TL));
5768
5769
5770  /* do not use memcpy due to indexing in LBA and TL */
5771  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
5772  LBA[1] = scsiCmnd->cdb[3];
5773  LBA[2] = scsiCmnd->cdb[4];
5774  LBA[3] = scsiCmnd->cdb[5];
5775  LBA[4] = scsiCmnd->cdb[6];
5776  LBA[5] = scsiCmnd->cdb[7];
5777  LBA[6] = scsiCmnd->cdb[8];
5778  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
5779
5780  TL[0] = 0;
5781  TL[1] = 0;
5782  TL[2] = 0;
5783  TL[3] = 0;
5784  TL[4] = scsiCmnd->cdb[10];   /* MSB */
5785  TL[5] = scsiCmnd->cdb[11];
5786  TL[6] = scsiCmnd->cdb[12];
5787  TL[7] = scsiCmnd->cdb[13];   /* LSB */
5788
5789
5790
5791
5792 lba = smsatComputeCDB16LBA(satIOContext);
5793 tl = smsatComputeCDB16TL(satIOContext);
5794
5795
5796  /* Table 34, 9.1, p 46 */
5797  /*
5798    note: As of 2/10/2006, no support for DMA QUEUED
5799   */
5800
5801  /*
5802    Table 34, 9.1, p 46, b
5803    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
5804    return check condition
5805  */
5806  if (pSatDevData->satNCQ != agTRUE &&
5807      pSatDevData->sat48BitSupport != agTRUE
5808      )
5809  {
5810    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
5811    if (AllChk)
5812    {
5813      SM_DBG1(("smsatRead16: return LBA out of range, not EXT!!!\n"));
5814
5815      /*smEnqueueIO(smRoot, satIOContext);*/
5816
5817
5818      smsatSetSensePayload( pSense,
5819                            SCSI_SNSKEY_ILLEGAL_REQUEST,
5820                            0,
5821                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5822                            satIOContext);
5823
5824      /*smEnqueueIO(smRoot, satIOContext);*/
5825
5826      tdsmIOCompletedCB( smRoot,
5827                         smIORequest,
5828                         smIOSuccess,
5829                         SCSI_STAT_CHECK_CONDITION,
5830                         satIOContext->pSmSenseData,
5831                         satIOContext->interruptContext );
5832
5833      return SM_RC_SUCCESS;
5834    }
5835  }
5836  else
5837  {
5838//    rangeChk = smsatAddNComparebit64(LBA, TL);
5839
5840    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
5841
5842
5843    if (AllChk)
5844    {
5845      SM_DBG1(("smsatRead16: return LBA out of range, EXT!!!\n"));
5846      smsatSetSensePayload( pSense,
5847                            SCSI_SNSKEY_ILLEGAL_REQUEST,
5848                            0,
5849                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5850                            satIOContext);
5851
5852      /*smEnqueueIO(smRoot, satIOContext);*/
5853
5854      tdsmIOCompletedCB( smRoot,
5855                         smIORequest,
5856                         smIOSuccess,
5857                         SCSI_STAT_CHECK_CONDITION,
5858                         satIOContext->pSmSenseData,
5859                         satIOContext->interruptContext );
5860
5861      return SM_RC_SUCCESS;
5862    }
5863  }
5864
5865  /* case 1 and 2 */
5866    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5867    {
5868      /* case 2 */
5869      /* READ DMA*/
5870      /* in case that we can't fit the transfer length,
5871         we need to make it fit by sending multiple ATA cmnds */
5872      SM_DBG5(("smsatRead16: case 2\n"));
5873
5874
5875      fis->h.fisType        = 0x27;                   /* Reg host to device */
5876      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5877      fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
5878      fis->h.features       = 0;                      /* FIS reserve */
5879      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5880      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5881      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5882      fis->d.device         =
5883        (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5884      fis->d.lbaLowExp      = 0;
5885      fis->d.lbaMidExp      = 0;
5886      fis->d.lbaHighExp     = 0;
5887      fis->d.featuresExp    = 0;
5888      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
5889      fis->d.sectorCountExp = 0;
5890      fis->d.reserved4      = 0;
5891      fis->d.control        = 0;                      /* FIS HOB bit clear */
5892      fis->d.reserved5      = 0;
5893
5894
5895      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5896      satIOContext->ATACmd = SAT_READ_DMA;
5897    }
5898    else
5899    {
5900      /* case 1 */
5901      /* READ MULTIPLE or READ SECTOR(S) */
5902      /* READ SECTORS for easier implemetation */
5903      /* can't fit the transfer length but need to make it fit by sending multiple*/
5904      SM_DBG5(("smsatRead16: case 1\n"));
5905
5906      fis->h.fisType        = 0x27;                   /* Reg host to device */
5907      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5908      fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
5909      fis->h.features       = 0;                      /* FIS reserve */
5910      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5911      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5912      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5913      fis->d.device         =
5914        (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5915      fis->d.lbaLowExp      = 0;
5916      fis->d.lbaMidExp      = 0;
5917      fis->d.lbaHighExp     = 0;
5918      fis->d.featuresExp    = 0;
5919      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
5920      fis->d.sectorCountExp = 0;
5921      fis->d.reserved4      = 0;
5922      fis->d.control        = 0;                      /* FIS HOB bit clear */
5923      fis->d.reserved5      = 0;
5924
5925
5926      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5927      satIOContext->ATACmd = SAT_READ_SECTORS;
5928  }
5929
5930  /* case 3 and 4 */
5931  if (pSatDevData->sat48BitSupport == agTRUE)
5932  {
5933    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5934    {
5935      /* case 3 */
5936      /* READ DMA EXT */
5937      SM_DBG5(("smsatRead16: case 3\n"));
5938      fis->h.fisType        = 0x27;                   /* Reg host to device */
5939
5940      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5941      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
5942      fis->h.features       = 0;                      /* FIS reserve */
5943      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5944      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5945      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5946      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5947      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
5948      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
5949      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
5950      fis->d.featuresExp    = 0;                      /* FIS reserve */
5951      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
5952      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
5953      fis->d.reserved4      = 0;
5954      fis->d.control        = 0;                      /* FIS HOB bit clear */
5955      fis->d.reserved5      = 0;
5956
5957      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5958      satIOContext->ATACmd = SAT_READ_DMA_EXT;
5959
5960    }
5961    else
5962    {
5963      /* case 4 */
5964      /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5965      /* READ SECTORS EXT for easier implemetation */
5966      SM_DBG5(("smsatRead16: case 4\n"));
5967      fis->h.fisType        = 0x27;                   /* Reg host to device */
5968      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5969
5970      /* Check FUA bit */
5971      if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
5972      {
5973        /* for now, no support for FUA */
5974        smsatSetSensePayload( pSense,
5975                              SCSI_SNSKEY_ILLEGAL_REQUEST,
5976                              0,
5977                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5978                              satIOContext);
5979
5980        /*smEnqueueIO(smRoot, satIOContext);*/
5981
5982        tdsmIOCompletedCB( smRoot,
5983                           smIORequest,
5984                           smIOSuccess,
5985                           SCSI_STAT_CHECK_CONDITION,
5986                           satIOContext->pSmSenseData,
5987                           satIOContext->interruptContext );
5988        return SM_RC_SUCCESS;
5989      }
5990
5991      fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
5992
5993      fis->h.features       = 0;                      /* FIS reserve */
5994      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5995      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5996      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5997      fis->d.device         = 0x40;                   /* FIS LBA mode set */
5998      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
5999      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
6000      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
6001      fis->d.featuresExp    = 0;                      /* FIS reserve */
6002      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
6003      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
6004      fis->d.reserved4      = 0;
6005      fis->d.control        = 0;                      /* FIS HOB bit clear */
6006      fis->d.reserved5      = 0;
6007
6008      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
6009      satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
6010    }
6011  }
6012
6013
6014  /* case 5 */
6015  if (pSatDevData->satNCQ == agTRUE)
6016  {
6017    /* READ FPDMA QUEUED */
6018    if (pSatDevData->sat48BitSupport != agTRUE)
6019    {
6020      SM_DBG1(("smsatRead16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6021      smsatSetSensePayload( pSense,
6022                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6023                            0,
6024                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6025                            satIOContext);
6026
6027      /*smEnqueueIO(smRoot, satIOContext);*/
6028
6029      tdsmIOCompletedCB( smRoot,
6030                         smIORequest,
6031                         smIOSuccess,
6032                         SCSI_STAT_CHECK_CONDITION,
6033                         satIOContext->pSmSenseData,
6034                         satIOContext->interruptContext );
6035      return SM_RC_SUCCESS;
6036    }
6037
6038    SM_DBG6(("smsatRead16: case 5\n"));
6039
6040    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
6041
6042    fis->h.fisType        = 0x27;                   /* Reg host to device */
6043    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6044    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
6045    fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
6046    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
6047    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
6048    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
6049
6050    /* Check FUA bit */
6051    if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
6052      fis->d.device       = 0xC0;                   /* FIS FUA set */
6053    else
6054      fis->d.device       = 0x40;                   /* FIS FUA clear */
6055
6056    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
6057    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
6058    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
6059    fis->d.featuresExp    = scsiCmnd->cdb[12];      /* FIS sector count (15:8) */
6060    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
6061    fis->d.sectorCountExp = 0;
6062    fis->d.reserved4      = 0;
6063    fis->d.control        = 0;                      /* FIS HOB bit clear */
6064    fis->d.reserved5      = 0;
6065
6066    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
6067    satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
6068  }
6069
6070  /* saves the current LBA and orginal TL */
6071  satIOContext->currentLBA = lba;
6072  satIOContext->OrgTL = tl;
6073
6074  /*
6075    computing number of loop and remainder for tl
6076    0xFF in case not ext
6077    0xFFFF in case EXT
6078  */
6079  if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
6080  {
6081    LoopNum = smsatComputeLoopNum(tl, 0xFF);
6082  }
6083  else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
6084  {
6085    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6086    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6087  }
6088  else
6089  {
6090    /* SAT_READ_FPDMA_QUEUEDK */
6091    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6092  }
6093  satIOContext->LoopNum = LoopNum;
6094
6095  if (LoopNum == 1)
6096  {
6097    SM_DBG5(("smsatRead16: NON CHAINED data\n"));
6098    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6099  }
6100  else
6101  {
6102    SM_DBG1(("smsatRead16: CHAINED data!!!\n"));
6103    /* re-setting tl */
6104    if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
6105    {
6106       fis->d.sectorCount    = 0xFF;
6107    }
6108    else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
6109    {
6110      /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6111      fis->d.sectorCount    = 0xFF;
6112      fis->d.sectorCountExp = 0xFF;
6113    }
6114    else
6115    {
6116      /* SAT_READ_FPDMA_QUEUED */
6117      fis->h.features       = 0xFF;
6118      fis->d.featuresExp    = 0xFF;
6119    }
6120
6121    /* chained data */
6122    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
6123  }
6124
6125  /*
6126   * Prepare SGL and send FIS to LL layer.
6127   */
6128  satIOContext->reqType = agRequestType;       /* Save it */
6129
6130  status = smsataLLIOStart( smRoot,
6131                            smIORequest,
6132                            smDeviceHandle,
6133                            smScsiRequest,
6134                            satIOContext);
6135
6136  SM_DBG5(("smsatRead16: return\n"));
6137  return (status);
6138
6139}
6140
6141osGLOBAL bit32
6142smsatWrite6(
6143            smRoot_t                  *smRoot,
6144            smIORequest_t             *smIORequest,
6145            smDeviceHandle_t          *smDeviceHandle,
6146            smScsiInitiatorRequest_t  *smScsiRequest,
6147            smSatIOContext_t            *satIOContext
6148     )
6149{
6150
6151  bit32                     status;
6152  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6153  smDeviceData_t            *pSatDevData;
6154  smScsiRspSense_t          *pSense;
6155  smIniScsiCmnd_t           *scsiCmnd;
6156  agsaFisRegHostToDevice_t  *fis;
6157  bit32                     lba = 0;
6158  bit16                     tl = 0;
6159
6160  pSense        = satIOContext->pSense;
6161  pSatDevData   = satIOContext->pSatDevData;
6162  scsiCmnd      = &smScsiRequest->scsiCmnd;
6163  fis           = satIOContext->pFis;
6164
6165  SM_DBG5(("smsatWrite6: start\n"));
6166
6167  /* checking CONTROL */
6168  /* NACA == 1 or LINK == 1*/
6169  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
6170  {
6171    smsatSetSensePayload( pSense,
6172                          SCSI_SNSKEY_ILLEGAL_REQUEST,
6173                          0,
6174                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6175                          satIOContext);
6176
6177    /*smEnqueueIO(smRoot, satIOContext);*/
6178
6179    tdsmIOCompletedCB( smRoot,
6180                       smIORequest,
6181                       smIOSuccess,
6182                       SCSI_STAT_CHECK_CONDITION,
6183                       satIOContext->pSmSenseData,
6184                       satIOContext->interruptContext );
6185
6186    SM_DBG1(("smsatWrite6: return control!!!\n"));
6187    return SM_RC_SUCCESS;
6188  }
6189
6190
6191  /* cbd6; computing LBA and transfer length */
6192  lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
6193    + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
6194  tl = scsiCmnd->cdb[4];
6195
6196
6197  /* Table 34, 9.1, p 46 */
6198  /*
6199    note: As of 2/10/2006, no support for DMA QUEUED
6200   */
6201
6202  /*
6203    Table 34, 9.1, p 46, b
6204    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
6205    return check condition
6206  */
6207  if (pSatDevData->satNCQ != agTRUE &&
6208      pSatDevData->sat48BitSupport != agTRUE
6209      )
6210  {
6211    if (lba > SAT_TR_LBA_LIMIT - 1)
6212    {
6213      smsatSetSensePayload( pSense,
6214                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6215                            0,
6216                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6217                            satIOContext);
6218
6219      /*smEnqueueIO(smRoot, satIOContext);*/
6220
6221      tdsmIOCompletedCB( smRoot,
6222                         smIORequest,
6223                         smIOSuccess,
6224                         SCSI_STAT_CHECK_CONDITION,
6225                         satIOContext->pSmSenseData,
6226                         satIOContext->interruptContext );
6227
6228    SM_DBG1(("smsatWrite6: return LBA out of range!!!\n"));
6229    return SM_RC_SUCCESS;
6230    }
6231  }
6232
6233  /* case 1 and 2 */
6234  if (lba + tl <= SAT_TR_LBA_LIMIT)
6235  {
6236    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6237    {
6238      /* case 2 */
6239      /* WRITE DMA*/
6240      SM_DBG5(("smsatWrite6: case 2\n"));
6241
6242
6243      fis->h.fisType        = 0x27;                   /* Reg host to device */
6244      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6245      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
6246      fis->h.features       = 0;                      /* FIS reserve */
6247      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6248      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6249      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6250      fis->d.device         = 0x40;                   /* FIS LBA mode  */
6251      fis->d.lbaLowExp      = 0;
6252      fis->d.lbaMidExp      = 0;
6253      fis->d.lbaHighExp     = 0;
6254      fis->d.featuresExp    = 0;
6255      if (tl == 0)
6256      {
6257        /* temporary fix */
6258        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
6259      }
6260      else
6261      {
6262        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6263      }
6264      fis->d.sectorCountExp = 0;
6265      fis->d.reserved4      = 0;
6266      fis->d.control        = 0;                      /* FIS HOB bit clear */
6267      fis->d.reserved5      = 0;
6268
6269      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6270    }
6271    else
6272    {
6273      /* case 1 */
6274      /* WRITE SECTORS for easier implemetation */
6275      SM_DBG5(("smsatWrite6: case 1\n"));
6276
6277      fis->h.fisType        = 0x27;                   /* Reg host to device */
6278      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6279      fis->h.command        = SAT_WRITE_SECTORS;          /* 0xCA */
6280      fis->h.features       = 0;                      /* FIS reserve */
6281      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6282      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6283      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6284      fis->d.device         = 0x40;                   /* FIS LBA mode  */
6285      fis->d.lbaLowExp      = 0;
6286      fis->d.lbaMidExp      = 0;
6287      fis->d.lbaHighExp     = 0;
6288      fis->d.featuresExp    = 0;
6289      if (tl == 0)
6290      {
6291        /* temporary fix */
6292        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
6293      }
6294      else
6295      {
6296        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6297      }
6298      fis->d.sectorCountExp = 0;
6299      fis->d.reserved4      = 0;
6300      fis->d.control        = 0;                      /* FIS HOB bit clear */
6301      fis->d.reserved5      = 0;
6302
6303      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6304
6305    }
6306  }
6307
6308  /* case 3 and 4 */
6309  if (pSatDevData->sat48BitSupport == agTRUE)
6310  {
6311    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6312    {
6313      /* case 3 */
6314      /* WRITE DMA EXT only */
6315      SM_DBG5(("smsatWrite6: case 3\n"));
6316      fis->h.fisType        = 0x27;                   /* Reg host to device */
6317      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6318      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
6319      fis->h.features       = 0;                      /* FIS reserve */
6320      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6321      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6322      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6323      fis->d.device         = 0x40;                   /* FIS LBA mode set */
6324      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
6325      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6326      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6327      fis->d.featuresExp    = 0;                      /* FIS reserve */
6328      if (tl == 0)
6329      {
6330        /* sector count is 256, 0x100*/
6331        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
6332        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
6333      }
6334      else
6335      {
6336        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6337        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
6338      }
6339      fis->d.reserved4      = 0;
6340      fis->d.control        = 0;                      /* FIS HOB bit clear */
6341      fis->d.reserved5      = 0;
6342
6343      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6344    }
6345    else
6346    {
6347      /* case 4 */
6348      /* WRITE SECTORS EXT for easier implemetation */
6349      SM_DBG5(("smsatWrite6: case 4\n"));
6350
6351      fis->h.fisType        = 0x27;                   /* Reg host to device */
6352      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6353      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
6354      fis->h.features       = 0;                      /* FIS reserve */
6355      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6356      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6357      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6358      fis->d.device         = 0x40;                   /* FIS LBA mode set */
6359      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
6360      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6361      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6362      fis->d.featuresExp    = 0;                      /* FIS reserve */
6363      if (tl == 0)
6364      {
6365        /* sector count is 256, 0x100*/
6366        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
6367        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
6368      }
6369      else
6370      {
6371        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6372        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
6373      }
6374      fis->d.reserved4      = 0;
6375      fis->d.control        = 0;                      /* FIS HOB bit clear */
6376      fis->d.reserved5      = 0;
6377
6378      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6379    }
6380  }
6381
6382   /* case 5 */
6383  if (pSatDevData->satNCQ == agTRUE)
6384  {
6385    /* WRITE FPDMA QUEUED */
6386    if (pSatDevData->sat48BitSupport != agTRUE)
6387    {
6388      /* sanity check */
6389      SM_DBG5(("smsatWrite6: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6390      smsatSetSensePayload( pSense,
6391                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6392                            0,
6393                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6394                            satIOContext);
6395
6396      /*smEnqueueIO(smRoot, satIOContext);*/
6397
6398      tdsmIOCompletedCB( smRoot,
6399                         smIORequest,
6400                         smIOSuccess,
6401                         SCSI_STAT_CHECK_CONDITION,
6402                         satIOContext->pSmSenseData,
6403                         satIOContext->interruptContext );
6404      return SM_RC_SUCCESS;
6405    }
6406    SM_DBG5(("smsatWrite6: case 5\n"));
6407
6408    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
6409
6410    fis->h.fisType        = 0x27;                   /* Reg host to device */
6411    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6412    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
6413    fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6414    fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6415    fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6416    fis->d.device         = 0x40;                   /* FIS FUA clear */
6417    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
6418    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6419    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6420    if (tl == 0)
6421    {
6422      /* sector count is 256, 0x100*/
6423      fis->h.features       = 0;                         /* FIS sector count (7:0) */
6424      fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
6425    }
6426    else
6427    {
6428      fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6429      fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
6430    }
6431    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
6432    fis->d.sectorCountExp = 0;
6433    fis->d.reserved4      = 0;
6434    fis->d.control        = 0;                      /* FIS HOB bit clear */
6435    fis->d.reserved5      = 0;
6436
6437    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
6438  }
6439
6440  /* Initialize CB for SATA completion.
6441   */
6442  satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6443
6444  /*
6445   * Prepare SGL and send FIS to LL layer.
6446   */
6447  satIOContext->reqType = agRequestType;       /* Save it */
6448
6449  status = smsataLLIOStart( smRoot,
6450                            smIORequest,
6451                            smDeviceHandle,
6452                            smScsiRequest,
6453                            satIOContext);
6454  return (status);
6455}
6456
6457osGLOBAL FORCEINLINE bit32
6458smsatWrite10(
6459             smRoot_t                  *smRoot,
6460             smIORequest_t             *smIORequest,
6461             smDeviceHandle_t          *smDeviceHandle,
6462             smScsiInitiatorRequest_t  *smScsiRequest,
6463             smSatIOContext_t            *satIOContext
6464            )
6465{
6466  smDeviceData_t           *pSatDevData = satIOContext->pSatDevData;
6467  smScsiRspSense_t         *pSense      = satIOContext->pSense;
6468  smIniScsiCmnd_t          *scsiCmnd    = &smScsiRequest->scsiCmnd;
6469  agsaFisRegHostToDevice_t *fis         =  satIOContext->pFis;
6470  bit32                     status      = SM_RC_FAILURE;
6471  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6472  bit32                     lba = 0;
6473  bit32                     tl = 0;
6474  bit32                     LoopNum = 1;
6475  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
6476  bit8                      LBA[8];
6477  bit8                      TL[8];
6478
6479  SM_DBG2(("smsatWrite10: start\n"));
6480
6481  /* checking FUA_NV */
6482  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
6483  {
6484    smsatSetSensePayload( pSense,
6485                          SCSI_SNSKEY_ILLEGAL_REQUEST,
6486                          0,
6487                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6488                          satIOContext);
6489
6490    /*smEnqueueIO(smRoot, satIOContext);*/
6491
6492    tdsmIOCompletedCB( smRoot,
6493                       smIORequest,
6494                       smIOSuccess,
6495                       SCSI_STAT_CHECK_CONDITION,
6496                       satIOContext->pSmSenseData,
6497                       satIOContext->interruptContext );
6498
6499    SM_DBG1(("smsatWrite10: return FUA_NV!!!\n"));
6500    return SM_RC_SUCCESS;
6501
6502  }
6503
6504  /* checking CONTROL */
6505  /* NACA == 1 or LINK == 1*/
6506  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
6507  {
6508    smsatSetSensePayload( pSense,
6509                          SCSI_SNSKEY_ILLEGAL_REQUEST,
6510                          0,
6511                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6512                          satIOContext);
6513
6514    /*smEnqueueIO(smRoot, satIOContext);*/
6515
6516    tdsmIOCompletedCB( smRoot,
6517                       smIORequest,
6518                       smIOSuccess,
6519                       SCSI_STAT_CHECK_CONDITION,
6520                       satIOContext->pSmSenseData,
6521                       satIOContext->interruptContext );
6522
6523    SM_DBG1(("smsatWrite10: return control!!!\n"));
6524    return SM_RC_SUCCESS;
6525  }
6526/*
6527  sm_memset(LBA, 0, sizeof(LBA));
6528  sm_memset(TL, 0, sizeof(TL));
6529*/
6530  /* do not use memcpy due to indexing in LBA and TL */
6531  LBA[0] = 0;                  /* MSB */
6532  LBA[1] = 0;
6533  LBA[2] = 0;
6534  LBA[3] = 0;
6535  LBA[4] = scsiCmnd->cdb[2];
6536  LBA[5] = scsiCmnd->cdb[3];
6537  LBA[6] = scsiCmnd->cdb[4];
6538  LBA[7] = scsiCmnd->cdb[5];   /* LSB */
6539
6540  TL[0] = 0;
6541  TL[1] = 0;
6542  TL[2] = 0;
6543  TL[3] = 0;
6544  TL[4] = 0;
6545  TL[5] = 0;
6546  TL[6] = scsiCmnd->cdb[7];
6547  TL[7] = scsiCmnd->cdb[8];  	/* LSB */
6548
6549
6550
6551  /* cbd10; computing LBA and transfer length */
6552  lba = (scsiCmnd->cdb[2] << (24)) + (scsiCmnd->cdb[3] << (16))
6553    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
6554  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
6555
6556  SM_DBG5(("smsatWrite10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext)));
6557  SM_DBG5(("smsatWrite10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext)));
6558
6559  /* Table 34, 9.1, p 46 */
6560  /*
6561    note: As of 2/10/2006, no support for DMA QUEUED
6562   */
6563
6564  /*
6565    Table 34, 9.1, p 46, b
6566    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
6567    return check condition
6568  */
6569  if (pSatDevData->satNCQ != agTRUE &&
6570      pSatDevData->sat48BitSupport != agTRUE
6571      )
6572  {
6573    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
6574    if (AllChk)
6575    {
6576     SM_DBG1(("smsatWrite10: return LBA out of range, not EXT!!!\n"));
6577     SM_DBG1(("smsatWrite10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
6578             scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
6579     SM_DBG1(("smsatWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
6580      smsatSetSensePayload( pSense,
6581                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6582                            0,
6583                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6584                            satIOContext);
6585
6586      /*smEnqueueIO(smRoot, satIOContext);*/
6587
6588      tdsmIOCompletedCB( smRoot,
6589                         smIORequest,
6590                         smIOSuccess,
6591                         SCSI_STAT_CHECK_CONDITION,
6592                         satIOContext->pSmSenseData,
6593                         satIOContext->interruptContext );
6594
6595    return SM_RC_SUCCESS;
6596    }
6597  }
6598  else
6599  {
6600    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
6601    if (AllChk)
6602    {
6603      SM_DBG1(("smsatWrite10: return LBA out of range, EXT!!!\n"));
6604      smsatSetSensePayload( pSense,
6605                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6606                            0,
6607                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6608                            satIOContext);
6609
6610    /*smEnqueueIO(smRoot, satIOContext);*/
6611
6612    tdsmIOCompletedCB( smRoot,
6613                       smIORequest,
6614                       smIOSuccess,
6615                       SCSI_STAT_CHECK_CONDITION,
6616                       satIOContext->pSmSenseData,
6617                       satIOContext->interruptContext );
6618
6619    return SM_RC_SUCCESS;
6620    }
6621
6622  }
6623
6624  /* case 5 */
6625  if (pSatDevData->satNCQ == agTRUE)
6626  {
6627    /* WRITE FPDMA QUEUED */
6628    if (pSatDevData->sat48BitSupport != agTRUE)
6629    {
6630      SM_DBG1(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6631      smsatSetSensePayload( pSense,
6632                            SCSI_SNSKEY_ILLEGAL_REQUEST,
6633                            0,
6634                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6635                            satIOContext);
6636
6637      /*smEnqueueIO(smRoot, satIOContext);*/
6638
6639      tdsmIOCompletedCB( smRoot,
6640                         smIORequest,
6641                         smIOSuccess,
6642                         SCSI_STAT_CHECK_CONDITION,
6643                         satIOContext->pSmSenseData,
6644                         satIOContext->interruptContext );
6645      return SM_RC_SUCCESS;
6646    }
6647    SM_DBG6(("smsatWrite10: case 5\n"));
6648
6649    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
6650
6651    fis->h.fisType        = 0x27;                   /* Reg host to device */
6652    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6653    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
6654    fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6655    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6656    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6657    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6658
6659    /* Check FUA bit */
6660    if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
6661      fis->d.device       = 0xC0;                   /* FIS FUA set */
6662    else
6663      fis->d.device       = 0x40;                   /* FIS FUA clear */
6664
6665    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
6666    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6667    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6668    fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
6669    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
6670    fis->d.sectorCountExp = 0;
6671    fis->d.reserved4      = 0;
6672    fis->d.control        = 0;                      /* FIS HOB bit clear */
6673    fis->d.reserved5      = 0;
6674
6675    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
6676    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
6677  }
6678  /* case 3 and 4 */
6679  else if (pSatDevData->sat48BitSupport == agTRUE)
6680  {
6681    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6682    {
6683      /* case 3 */
6684      /* WRITE DMA EXT or WRITE DMA FUA EXT */
6685      SM_DBG5(("smsatWrite10: case 3\n"));
6686      fis->h.fisType        = 0x27;                   /* Reg host to device */
6687      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6688
6689      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
6690      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
6691      satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
6692
6693      fis->h.features       = 0;                      /* FIS reserve */
6694      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6695      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6696      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6697      fis->d.device         = 0x40;                   /* FIS LBA mode set */
6698      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
6699      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6700      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6701      fis->d.featuresExp    = 0;                      /* FIS reserve */
6702      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6703      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
6704      fis->d.reserved4      = 0;
6705      fis->d.control        = 0;                      /* FIS HOB bit clear */
6706      fis->d.reserved5      = 0;
6707
6708      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6709    }
6710    else
6711    {
6712      /* case 4 */
6713      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
6714      /* WRITE SECTORS EXT for easier implemetation */
6715      SM_DBG5(("smsatWrite10: case 4\n"));
6716      fis->h.fisType        = 0x27;                   /* Reg host to device */
6717      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6718      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
6719
6720      fis->h.features       = 0;                      /* FIS reserve */
6721      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6722      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6723      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6724      fis->d.device         = 0x40;                   /* FIS LBA mode set */
6725      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
6726      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6727      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6728      fis->d.featuresExp    = 0;                      /* FIS reserve */
6729      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6730      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
6731      fis->d.reserved4      = 0;
6732      fis->d.control        = 0;                      /* FIS HOB bit clear */
6733      fis->d.reserved5      = 0;
6734
6735      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6736      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
6737    }
6738  }
6739  else /* case 1 and 2 */
6740  {
6741    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6742    {
6743      /* case 2 */
6744      /* WRITE DMA*/
6745      /* can't fit the transfer length */
6746      SM_DBG5(("smsatWrite10: case 2\n"));
6747      fis->h.fisType        = 0x27;                   /* Reg host to device */
6748      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
6749      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
6750      fis->h.features       = 0;                      /* FIS reserve */
6751      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6752      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6753      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6754
6755      /* FIS LBA mode set LBA (27:24) */
6756      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
6757
6758      fis->d.lbaLowExp      = 0;
6759      fis->d.lbaMidExp      = 0;
6760      fis->d.lbaHighExp     = 0;
6761      fis->d.featuresExp    = 0;
6762      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6763      fis->d.sectorCountExp = 0;
6764      fis->d.reserved4      = 0;
6765      fis->d.control        = 0;                      /* FIS HOB bit clear */
6766      fis->d.reserved5      = 0;
6767
6768      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6769      satIOContext->ATACmd = SAT_WRITE_DMA;
6770    }
6771    else
6772    {
6773      /* case 1 */
6774      /* WRITE MULTIPLE or WRITE SECTOR(S) */
6775      /* WRITE SECTORS for easier implemetation */
6776      /* can't fit the transfer length */
6777      SM_DBG5(("smsatWrite10: case 1\n"));
6778      fis->h.fisType        = 0x27;                   /* Reg host to device */
6779      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
6780      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
6781      fis->h.features       = 0;                      /* FIS reserve */
6782      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6783      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6784      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6785
6786      /* FIS LBA mode set LBA (27:24) */
6787      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
6788
6789      fis->d.lbaLowExp      = 0;
6790      fis->d.lbaMidExp      = 0;
6791      fis->d.lbaHighExp     = 0;
6792      fis->d.featuresExp    = 0;
6793      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6794      fis->d.sectorCountExp = 0;
6795      fis->d.reserved4      = 0;
6796      fis->d.control        = 0;                      /* FIS HOB bit clear */
6797      fis->d.reserved5      = 0;
6798
6799      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6800      satIOContext->ATACmd = SAT_WRITE_SECTORS;
6801    }
6802  }
6803
6804  //  smhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
6805
6806  satIOContext->currentLBA = lba;
6807  satIOContext->OrgTL = tl;
6808
6809  /*
6810    computing number of loop and remainder for tl
6811    0xFF in case not ext
6812    0xFFFF in case EXT
6813  */
6814  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
6815  {
6816    LoopNum = smsatComputeLoopNum(tl, 0x100);
6817  }
6818  else
6819  {
6820    /* SAT_WRITE_FPDMA_QUEUEDK */
6821    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6822    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6823  }
6824
6825  satIOContext->LoopNum = LoopNum;
6826
6827
6828  if (LoopNum == 1)
6829  {
6830    SM_DBG5(("smsatWrite10: NON CHAINED data\n"));
6831    /* Initialize CB for SATA completion.
6832     */
6833    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6834  }
6835  else
6836  {
6837    SM_DBG2(("smsatWrite10: CHAINED data!!!\n"));
6838    /* re-setting tl */
6839    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
6840    {
6841      fis->d.sectorCount    = 0x0;
6842      smsatSplitSGL(smRoot,
6843                    smIORequest,
6844                    smDeviceHandle,
6845                    smScsiRequest,
6846                    satIOContext,
6847                    NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */
6848                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6849                    agTRUE);
6850    }
6851    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
6852             fis->h.command == SAT_WRITE_DMA_EXT ||
6853             fis->h.command == SAT_WRITE_DMA_FUA_EXT
6854             )
6855    {
6856      fis->d.sectorCount    = 0xFF;
6857      fis->d.sectorCountExp = 0xFF;
6858      smsatSplitSGL(smRoot,
6859                    smIORequest,
6860                    smDeviceHandle,
6861                    smScsiRequest,
6862                    satIOContext,
6863                    BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
6864                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6865                    agTRUE);
6866    }
6867    else
6868    {
6869      /* SAT_WRITE_FPDMA_QUEUED */
6870      fis->h.features       = 0xFF;
6871      fis->d.featuresExp    = 0xFF;
6872      smsatSplitSGL(smRoot,
6873                    smIORequest,
6874                    smDeviceHandle,
6875                    smScsiRequest,
6876                    satIOContext,
6877                    BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
6878                    (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6879                    agTRUE);
6880    }
6881
6882    /* Initialize CB for SATA completion.
6883     */
6884    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
6885  }
6886
6887
6888  /*
6889   * Prepare SGL and send FIS to LL layer.
6890   */
6891  satIOContext->reqType = agRequestType;       /* Save it */
6892
6893  status = smsataLLIOStart( smRoot,
6894                            smIORequest,
6895                            smDeviceHandle,
6896                            smScsiRequest,
6897                            satIOContext);
6898  return (status);
6899}
6900
6901osGLOBAL bit32
6902smsatWrite12(
6903             smRoot_t                  *smRoot,
6904             smIORequest_t             *smIORequest,
6905             smDeviceHandle_t          *smDeviceHandle,
6906             smScsiInitiatorRequest_t  *smScsiRequest,
6907             smSatIOContext_t            *satIOContext
6908            )
6909{
6910  bit32                     status;
6911  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6912  smDeviceData_t            *pSatDevData;
6913  smScsiRspSense_t          *pSense;
6914  smIniScsiCmnd_t           *scsiCmnd;
6915  agsaFisRegHostToDevice_t  *fis;
6916  bit32                     lba = 0;
6917  bit32                     tl = 0;
6918  bit32                     LoopNum = 1;
6919  bit8                      LBA[8];
6920  bit8                      TL[8];
6921  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
6922
6923  pSense        = satIOContext->pSense;
6924  pSatDevData   = satIOContext->pSatDevData;
6925  scsiCmnd      = &smScsiRequest->scsiCmnd;
6926  fis           = satIOContext->pFis;
6927
6928  SM_DBG5(("smsatWrite12: start\n"));
6929
6930  /* checking FUA_NV */
6931  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
6932  {
6933    smsatSetSensePayload( pSense,
6934                          SCSI_SNSKEY_ILLEGAL_REQUEST,
6935                          0,
6936                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6937                          satIOContext);
6938
6939    /*smEnqueueIO(smRoot, satIOContext);*/
6940
6941    tdsmIOCompletedCB( smRoot,
6942                       smIORequest,
6943                       smIOSuccess,
6944                       SCSI_STAT_CHECK_CONDITION,
6945                       satIOContext->pSmSenseData,
6946                       satIOContext->interruptContext );
6947
6948    SM_DBG1(("smsatWrite12: return FUA_NV!!!\n"));
6949    return SM_RC_SUCCESS;
6950
6951  }
6952
6953
6954  /* checking CONTROL */
6955  /* NACA == 1 or LINK == 1*/
6956  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
6957  {
6958    smsatSetSensePayload( pSense,
6959                          SCSI_SNSKEY_ILLEGAL_REQUEST,
6960                          0,
6961                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6962                          satIOContext);
6963
6964    /*smEnqueueIO(smRoot, satIOContext);*/
6965
6966    tdsmIOCompletedCB( smRoot,
6967                       smIORequest,
6968                       smIOSuccess,
6969                       SCSI_STAT_CHECK_CONDITION,
6970                       satIOContext->pSmSenseData,
6971                       satIOContext->interruptContext );
6972
6973    SM_DBG1(("smsatWrite10: return control!!!\n"));
6974    return SM_RC_SUCCESS;
6975  }
6976
6977
6978  sm_memset(LBA, 0, sizeof(LBA));
6979  sm_memset(TL, 0, sizeof(TL));
6980
6981  /* do not use memcpy due to indexing in LBA and TL */
6982  LBA[0] = 0;                  /* MSB */
6983  LBA[1] = 0;
6984  LBA[2] = 0;
6985  LBA[3] = 0;
6986  LBA[4] = scsiCmnd->cdb[2];
6987  LBA[5] = scsiCmnd->cdb[3];
6988  LBA[6] = scsiCmnd->cdb[4];
6989  LBA[7] = scsiCmnd->cdb[5];  	/* LSB */
6990
6991  TL[0] = 0;                    /* MSB */
6992  TL[1] = 0;
6993  TL[2] = 0;
6994  TL[3] = 0;
6995  TL[4] = scsiCmnd->cdb[6];
6996  TL[5] = scsiCmnd->cdb[7];
6997  TL[6] = scsiCmnd->cdb[8];
6998  TL[7] = scsiCmnd->cdb[9];   	/* LSB */
6999
7000
7001  lba = smsatComputeCDB12LBA(satIOContext);
7002  tl = smsatComputeCDB12TL(satIOContext);
7003
7004
7005  /* Table 34, 9.1, p 46 */
7006  /*
7007    note: As of 2/10/2006, no support for DMA QUEUED
7008   */
7009
7010  /*
7011    Table 34, 9.1, p 46, b
7012    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
7013    return check condition
7014  */
7015  if (pSatDevData->satNCQ != agTRUE &&
7016      pSatDevData->sat48BitSupport != agTRUE
7017      )
7018  {
7019    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7020
7021      /*smEnqueueIO(smRoot, satIOContext);*/
7022
7023
7024
7025    if (AllChk)
7026    {
7027      SM_DBG1(("smsatWrite12: return LBA out of range, not EXT!!!\n"));
7028      smsatSetSensePayload( pSense,
7029                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7030                            0,
7031                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7032                            satIOContext);
7033
7034      /*smEnqueueIO(smRoot, satIOContext);*/
7035
7036      tdsmIOCompletedCB( smRoot,
7037                         smIORequest,
7038                         smIOSuccess,
7039                         SCSI_STAT_CHECK_CONDITION,
7040                         satIOContext->pSmSenseData,
7041                         satIOContext->interruptContext );
7042
7043      return SM_RC_SUCCESS;
7044    }
7045  }
7046  else
7047  {
7048    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7049    if (AllChk)
7050    {
7051      SM_DBG1(("smsatWrite12: return LBA out of range, EXT!!!\n"));
7052      smsatSetSensePayload( pSense,
7053                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7054                            0,
7055                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7056                            satIOContext);
7057      tdsmIOCompletedCB( smRoot,
7058                         smIORequest,
7059                         smIOSuccess,
7060                         SCSI_STAT_CHECK_CONDITION,
7061                         satIOContext->pSmSenseData,
7062                         satIOContext->interruptContext );
7063      return SM_RC_SUCCESS;
7064    }
7065  }
7066    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7067    {
7068      /* case 2 */
7069      /* WRITE DMA*/
7070      /* In case that we can't fit the transfer length, we loop */
7071      SM_DBG5(("smsatWrite10: case 2\n"));
7072      fis->h.fisType        = 0x27;                   /* Reg host to device */
7073      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7074      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
7075      fis->h.features       = 0;                      /* FIS reserve */
7076      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7077      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7078      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7079
7080      /* FIS LBA mode set LBA (27:24) */
7081      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7082
7083      fis->d.lbaLowExp      = 0;
7084      fis->d.lbaMidExp      = 0;
7085      fis->d.lbaHighExp     = 0;
7086      fis->d.featuresExp    = 0;
7087      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7088      fis->d.sectorCountExp = 0;
7089      fis->d.reserved4      = 0;
7090      fis->d.control        = 0;                      /* FIS HOB bit clear */
7091      fis->d.reserved5      = 0;
7092
7093      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7094      satIOContext->ATACmd = SAT_WRITE_DMA;
7095    }
7096    else
7097    {
7098      /* case 1 */
7099      /* WRITE MULTIPLE or WRITE SECTOR(S) */
7100      /* WRITE SECTORS for easier implemetation */
7101      /* In case that we can't fit the transfer length, we loop */
7102      SM_DBG5(("smsatWrite10: case 1\n"));
7103      fis->h.fisType        = 0x27;                   /* Reg host to device */
7104      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7105      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
7106      fis->h.features       = 0;                      /* FIS reserve */
7107      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7108      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7109      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7110
7111      /* FIS LBA mode set LBA (27:24) */
7112      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7113
7114      fis->d.lbaLowExp      = 0;
7115      fis->d.lbaMidExp      = 0;
7116      fis->d.lbaHighExp     = 0;
7117      fis->d.featuresExp    = 0;
7118      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7119      fis->d.sectorCountExp = 0;
7120      fis->d.reserved4      = 0;
7121      fis->d.control        = 0;                      /* FIS HOB bit clear */
7122      fis->d.reserved5      = 0;
7123
7124      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7125      satIOContext->ATACmd = SAT_WRITE_SECTORS;
7126  }
7127
7128  /* case 3 and 4 */
7129  if (pSatDevData->sat48BitSupport == agTRUE)
7130  {
7131    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7132    {
7133      /* case 3 */
7134      /* WRITE DMA EXT or WRITE DMA FUA EXT */
7135      SM_DBG5(("smsatWrite10: case 3\n"));
7136      fis->h.fisType        = 0x27;                   /* Reg host to device */
7137      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7138
7139      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
7140      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
7141
7142      fis->h.features       = 0;                      /* FIS reserve */
7143      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7144      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7145      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7146      fis->d.device         = 0x40;                   /* FIS LBA mode set */
7147      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7148      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7149      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7150      fis->d.featuresExp    = 0;                      /* FIS reserve */
7151      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7152      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
7153      fis->d.reserved4      = 0;
7154      fis->d.control        = 0;                      /* FIS HOB bit clear */
7155      fis->d.reserved5      = 0;
7156
7157      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7158      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
7159    }
7160    else
7161    {
7162      /* case 4 */
7163      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
7164      /* WRITE SECTORS EXT for easier implemetation */
7165      SM_DBG5(("smsatWrite10: case 4\n"));
7166      fis->h.fisType        = 0x27;                   /* Reg host to device */
7167      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7168      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
7169
7170      fis->h.features       = 0;                      /* FIS reserve */
7171      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7172      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7173      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7174      fis->d.device         = 0x40;                   /* FIS LBA mode set */
7175      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7176      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7177      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7178      fis->d.featuresExp    = 0;                      /* FIS reserve */
7179      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7180      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
7181      fis->d.reserved4      = 0;
7182      fis->d.control        = 0;                      /* FIS HOB bit clear */
7183      fis->d.reserved5      = 0;
7184
7185      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7186      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
7187    }
7188  }
7189
7190  /* case 5 */
7191  if (pSatDevData->satNCQ == agTRUE)
7192  {
7193    /* WRITE FPDMA QUEUED */
7194    if (pSatDevData->sat48BitSupport != agTRUE)
7195    {
7196       SM_DBG5(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
7197       smsatSetSensePayload( pSense,
7198                             SCSI_SNSKEY_ILLEGAL_REQUEST,
7199                             0,
7200                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7201                             satIOContext);
7202
7203       /*smEnqueueIO(smRoot, satIOContext);*/
7204
7205       tdsmIOCompletedCB( smRoot,
7206                          smIORequest,
7207                          smIOSuccess,
7208                          SCSI_STAT_CHECK_CONDITION,
7209                          satIOContext->pSmSenseData,
7210                          satIOContext->interruptContext );
7211      return SM_RC_SUCCESS;
7212    }
7213    SM_DBG6(("smsatWrite10: case 5\n"));
7214
7215    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
7216
7217    fis->h.fisType        = 0x27;                   /* Reg host to device */
7218    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7219    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
7220    fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7221    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7222    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7223    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7224
7225    /* Check FUA bit */
7226    if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
7227      fis->d.device       = 0xC0;                   /* FIS FUA set */
7228    else
7229      fis->d.device       = 0x40;                   /* FIS FUA clear */
7230
7231    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7232    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7233    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7234    fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
7235    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
7236    fis->d.sectorCountExp = 0;
7237    fis->d.reserved4      = 0;
7238    fis->d.control        = 0;                      /* FIS HOB bit clear */
7239    fis->d.reserved5      = 0;
7240
7241    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
7242    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
7243  }
7244
7245  satIOContext->currentLBA = lba;
7246  satIOContext->OrgTL = tl;
7247
7248  /*
7249    computing number of loop and remainder for tl
7250    0xFF in case not ext
7251    0xFFFF in case EXT
7252  */
7253  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7254  {
7255    LoopNum = smsatComputeLoopNum(tl, 0xFF);
7256  }
7257  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7258           fis->h.command == SAT_WRITE_DMA_EXT     ||
7259           fis->h.command == SAT_WRITE_DMA_FUA_EXT
7260           )
7261  {
7262    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7263    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7264  }
7265  else
7266  {
7267    /* SAT_WRITE_FPDMA_QUEUEDK */
7268    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7269  }
7270
7271  satIOContext->LoopNum = LoopNum;
7272
7273
7274  if (LoopNum == 1)
7275  {
7276    SM_DBG5(("smsatWrite10: NON CHAINED data\n"));
7277    /* Initialize CB for SATA completion.
7278     */
7279    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
7280  }
7281  else
7282  {
7283    SM_DBG1(("smsatWrite10: CHAINED data\n"));
7284    /* re-setting tl */
7285    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7286    {
7287       fis->d.sectorCount    = 0xFF;
7288    }
7289    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7290             fis->h.command == SAT_WRITE_DMA_EXT ||
7291             fis->h.command == SAT_WRITE_DMA_FUA_EXT
7292             )
7293    {
7294      fis->d.sectorCount    = 0xFF;
7295      fis->d.sectorCountExp = 0xFF;
7296    }
7297    else
7298    {
7299      /* SAT_WRITE_FPDMA_QUEUED */
7300      fis->h.features       = 0xFF;
7301      fis->d.featuresExp    = 0xFF;
7302    }
7303
7304    /* Initialize CB for SATA completion.
7305     */
7306    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
7307  }
7308
7309
7310  /*
7311   * Prepare SGL and send FIS to LL layer.
7312   */
7313  satIOContext->reqType = agRequestType;       /* Save it */
7314
7315  status = smsataLLIOStart( smRoot,
7316                            smIORequest,
7317                            smDeviceHandle,
7318                            smScsiRequest,
7319                            satIOContext);
7320  return (status);
7321}
7322
7323osGLOBAL bit32
7324smsatWrite16(
7325             smRoot_t                  *smRoot,
7326             smIORequest_t             *smIORequest,
7327             smDeviceHandle_t          *smDeviceHandle,
7328             smScsiInitiatorRequest_t  *smScsiRequest,
7329             smSatIOContext_t            *satIOContext
7330            )
7331{
7332  bit32                     status;
7333  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7334  smDeviceData_t            *pSatDevData;
7335  smScsiRspSense_t          *pSense;
7336  smIniScsiCmnd_t           *scsiCmnd;
7337  agsaFisRegHostToDevice_t  *fis;
7338  bit32                     lba = 0;
7339  bit32                     tl = 0;
7340  bit32                     LoopNum = 1;
7341  bit8                      LBA[8];
7342  bit8                      TL[8];
7343  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
7344
7345  pSense        = satIOContext->pSense;
7346  pSatDevData   = satIOContext->pSatDevData;
7347  scsiCmnd      = &smScsiRequest->scsiCmnd;
7348  fis           = satIOContext->pFis;
7349
7350  SM_DBG5(("smsatWrite16: start\n"));
7351
7352  /* checking FUA_NV */
7353  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
7354  {
7355    smsatSetSensePayload( pSense,
7356                          SCSI_SNSKEY_ILLEGAL_REQUEST,
7357                          0,
7358                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7359                          satIOContext);
7360
7361    /*smEnqueueIO(smRoot, satIOContext);*/
7362
7363    tdsmIOCompletedCB( smRoot,
7364                       smIORequest,
7365                       smIOSuccess,
7366                       SCSI_STAT_CHECK_CONDITION,
7367                       satIOContext->pSmSenseData,
7368                       satIOContext->interruptContext );
7369
7370    SM_DBG1(("smsatWrite16: return FUA_NV!!!\n"));
7371    return SM_RC_SUCCESS;
7372
7373  }
7374
7375  /* checking CONTROL */
7376  /* NACA == 1 or LINK == 1*/
7377  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
7378  {
7379    smsatSetSensePayload( pSense,
7380                          SCSI_SNSKEY_ILLEGAL_REQUEST,
7381                          0,
7382                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7383                          satIOContext);
7384
7385    /*smEnqueueIO(smRoot, satIOContext);*/
7386
7387    tdsmIOCompletedCB( smRoot,
7388                       smIORequest,
7389                       smIOSuccess,
7390                       SCSI_STAT_CHECK_CONDITION,
7391                       satIOContext->pSmSenseData,
7392                       satIOContext->interruptContext );
7393
7394    SM_DBG1(("smsatWrite16: return control!!!\n"));
7395    return SM_RC_SUCCESS;
7396  }
7397
7398
7399  sm_memset(LBA, 0, sizeof(LBA));
7400  sm_memset(TL, 0, sizeof(TL));
7401
7402
7403  /* do not use memcpy due to indexing in LBA and TL */
7404  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
7405  LBA[1] = scsiCmnd->cdb[3];
7406  LBA[2] = scsiCmnd->cdb[4];
7407  LBA[3] = scsiCmnd->cdb[5];
7408  LBA[4] = scsiCmnd->cdb[6];
7409  LBA[5] = scsiCmnd->cdb[7];
7410  LBA[6] = scsiCmnd->cdb[8];
7411  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
7412
7413  TL[0] = 0;
7414  TL[1] = 0;
7415  TL[2] = 0;
7416  TL[3] = 0;
7417  TL[4] = scsiCmnd->cdb[10];   /* MSB */
7418  TL[5] = scsiCmnd->cdb[11];
7419  TL[6] = scsiCmnd->cdb[12];
7420  TL[7] = scsiCmnd->cdb[13];   /* LSB */
7421
7422
7423
7424  lba = smsatComputeCDB16LBA(satIOContext);
7425  tl = smsatComputeCDB16TL(satIOContext);
7426
7427
7428
7429  /* Table 34, 9.1, p 46 */
7430  /*
7431    note: As of 2/10/2006, no support for DMA QUEUED
7432  */
7433
7434  /*
7435    Table 34, 9.1, p 46, b
7436    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
7437    return check condition
7438  */
7439  if (pSatDevData->satNCQ != agTRUE &&
7440      pSatDevData->sat48BitSupport != agTRUE
7441     )
7442  {
7443    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7444    if (AllChk)
7445    {
7446      SM_DBG1(("smsatWrite16: return LBA out of range, not EXT!!!\n"));
7447      smsatSetSensePayload( pSense,
7448                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7449                            0,
7450                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7451                            satIOContext);
7452
7453      /*smEnqueueIO(smRoot, satIOContext);*/
7454
7455      tdsmIOCompletedCB( smRoot,
7456                         smIORequest,
7457                         smIOSuccess,
7458                         SCSI_STAT_CHECK_CONDITION,
7459                         satIOContext->pSmSenseData,
7460                         satIOContext->interruptContext );
7461
7462    return SM_RC_SUCCESS;
7463    }
7464  }
7465  else
7466  {
7467    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7468    if (AllChk)
7469    {
7470      SM_DBG1(("smsatWrite16: return LBA out of range, EXT!!!\n"));
7471      smsatSetSensePayload( pSense,
7472                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7473                            0,
7474                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7475                            satIOContext);
7476
7477      /*smEnqueueIO(smRoot, satIOContext);*/
7478
7479      tdsmIOCompletedCB( smRoot,
7480                         smIORequest,
7481                         smIOSuccess,
7482                         SCSI_STAT_CHECK_CONDITION,
7483                         satIOContext->pSmSenseData,
7484                         satIOContext->interruptContext );
7485
7486    return SM_RC_SUCCESS;
7487    }
7488  }
7489
7490  /* case 1 and 2 */
7491    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7492    {
7493      /* case 2 */
7494      /* WRITE DMA*/
7495      /* In case that we can't fit the transfer length, we loop */
7496      SM_DBG5(("smsatWrite16: case 2\n"));
7497      fis->h.fisType        = 0x27;                   /* Reg host to device */
7498      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7499      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
7500      fis->h.features       = 0;                      /* FIS reserve */
7501      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7502      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7503      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7504
7505      /* FIS LBA mode set LBA (27:24) */
7506      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
7507
7508      fis->d.lbaLowExp      = 0;
7509      fis->d.lbaMidExp      = 0;
7510      fis->d.lbaHighExp     = 0;
7511      fis->d.featuresExp    = 0;
7512      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7513      fis->d.sectorCountExp = 0;
7514      fis->d.reserved4      = 0;
7515      fis->d.control        = 0;                      /* FIS HOB bit clear */
7516      fis->d.reserved5      = 0;
7517
7518      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7519      satIOContext->ATACmd = SAT_WRITE_DMA;
7520    }
7521    else
7522    {
7523      /* case 1 */
7524      /* WRITE MULTIPLE or WRITE SECTOR(S) */
7525      /* WRITE SECTORS for easier implemetation */
7526      /* In case that we can't fit the transfer length, we loop */
7527      SM_DBG5(("smsatWrite16: case 1\n"));
7528      fis->h.fisType        = 0x27;                   /* Reg host to device */
7529      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7530      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
7531      fis->h.features       = 0;                      /* FIS reserve */
7532      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7533      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7534      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7535
7536      /* FIS LBA mode set LBA (27:24) */
7537      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
7538
7539      fis->d.lbaLowExp      = 0;
7540      fis->d.lbaMidExp      = 0;
7541      fis->d.lbaHighExp     = 0;
7542      fis->d.featuresExp    = 0;
7543      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7544      fis->d.sectorCountExp = 0;
7545      fis->d.reserved4      = 0;
7546      fis->d.control        = 0;                      /* FIS HOB bit clear */
7547      fis->d.reserved5      = 0;
7548
7549      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7550      satIOContext->ATACmd = SAT_WRITE_SECTORS;
7551  }
7552
7553  /* case 3 and 4 */
7554  if (pSatDevData->sat48BitSupport == agTRUE)
7555  {
7556    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7557    {
7558      /* case 3 */
7559      /* WRITE DMA EXT or WRITE DMA FUA EXT */
7560      SM_DBG5(("smsatWrite16: case 3\n"));
7561      fis->h.fisType        = 0x27;                   /* Reg host to device */
7562      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7563
7564      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
7565      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
7566
7567      fis->h.features       = 0;                      /* FIS reserve */
7568      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7569      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7570      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7571      fis->d.device         = 0x40;                   /* FIS LBA mode set */
7572      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
7573      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
7574      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
7575      fis->d.featuresExp    = 0;                      /* FIS reserve */
7576      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7577      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
7578      fis->d.reserved4      = 0;
7579      fis->d.control        = 0;                      /* FIS HOB bit clear */
7580      fis->d.reserved5      = 0;
7581
7582      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7583      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
7584    }
7585    else
7586    {
7587      /* case 4 */
7588      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
7589      /* WRITE SECTORS EXT for easier implemetation */
7590      SM_DBG5(("smsatWrite16: case 4\n"));
7591      fis->h.fisType        = 0x27;                   /* Reg host to device */
7592      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7593      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
7594
7595      fis->h.features       = 0;                      /* FIS reserve */
7596      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7597      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7598      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7599      fis->d.device         = 0x40;                   /* FIS LBA mode set */
7600      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
7601      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
7602      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
7603      fis->d.featuresExp    = 0;                      /* FIS reserve */
7604      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7605      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
7606      fis->d.reserved4      = 0;
7607      fis->d.control        = 0;                      /* FIS HOB bit clear */
7608      fis->d.reserved5      = 0;
7609
7610      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7611      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
7612    }
7613  }
7614
7615  /* case 5 */
7616  if (pSatDevData->satNCQ == agTRUE)
7617  {
7618    /* WRITE FPDMA QUEUED */
7619    if (pSatDevData->sat48BitSupport != agTRUE)
7620    {
7621      SM_DBG5(("smsatWrite16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
7622      smsatSetSensePayload( pSense,
7623                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7624                            0,
7625                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7626                            satIOContext);
7627
7628      /*smEnqueueIO(smRoot, satIOContext);*/
7629
7630      tdsmIOCompletedCB( smRoot,
7631                         smIORequest,
7632                         smIOSuccess,
7633                         SCSI_STAT_CHECK_CONDITION,
7634                         satIOContext->pSmSenseData,
7635                         satIOContext->interruptContext );
7636      return SM_RC_SUCCESS;
7637    }
7638    SM_DBG6(("smsatWrite16: case 5\n"));
7639
7640    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
7641
7642    fis->h.fisType        = 0x27;                   /* Reg host to device */
7643    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7644    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
7645    fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7646    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7647    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7648    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7649
7650    /* Check FUA bit */
7651    if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
7652      fis->d.device       = 0xC0;                   /* FIS FUA set */
7653    else
7654      fis->d.device       = 0x40;                   /* FIS FUA clear */
7655
7656    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
7657    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
7658    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
7659    fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
7660    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
7661    fis->d.sectorCountExp = 0;
7662    fis->d.reserved4      = 0;
7663    fis->d.control        = 0;                      /* FIS HOB bit clear */
7664    fis->d.reserved5      = 0;
7665
7666    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
7667    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
7668  }
7669
7670  satIOContext->currentLBA = lba;
7671  satIOContext->OrgTL = tl;
7672
7673  /*
7674    computing number of loop and remainder for tl
7675    0xFF in case not ext
7676    0xFFFF in case EXT
7677  */
7678  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7679  {
7680    LoopNum = smsatComputeLoopNum(tl, 0xFF);
7681  }
7682  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7683           fis->h.command == SAT_WRITE_DMA_EXT     ||
7684           fis->h.command == SAT_WRITE_DMA_FUA_EXT
7685           )
7686  {
7687    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7688    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7689  }
7690  else
7691  {
7692    /* SAT_WRITE_FPDMA_QUEUEDK */
7693    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7694  }
7695
7696  satIOContext->LoopNum = LoopNum;
7697
7698
7699  if (LoopNum == 1)
7700  {
7701    SM_DBG5(("smsatWrite16: NON CHAINED data\n"));
7702    /* Initialize CB for SATA completion.
7703     */
7704    satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
7705  }
7706  else
7707  {
7708    SM_DBG1(("smsatWrite16: CHAINED data!!!\n"));
7709    /* re-setting tl */
7710    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7711    {
7712       fis->d.sectorCount    = 0xFF;
7713    }
7714    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7715             fis->h.command == SAT_WRITE_DMA_EXT ||
7716             fis->h.command == SAT_WRITE_DMA_FUA_EXT
7717             )
7718    {
7719      fis->d.sectorCount    = 0xFF;
7720      fis->d.sectorCountExp = 0xFF;
7721    }
7722    else
7723    {
7724      /* SAT_WRITE_FPDMA_QUEUED */
7725      fis->h.features       = 0xFF;
7726      fis->d.featuresExp    = 0xFF;
7727    }
7728
7729    /* Initialize CB for SATA completion.
7730     */
7731    satIOContext->satCompleteCB = &smsatChainedDataIOCB;
7732  }
7733
7734
7735  /*
7736   * Prepare SGL and send FIS to LL layer.
7737   */
7738  satIOContext->reqType = agRequestType;       /* Save it */
7739
7740  status = smsataLLIOStart( smRoot,
7741                            smIORequest,
7742                            smDeviceHandle,
7743                            smScsiRequest,
7744                            satIOContext);
7745  return (status);
7746}
7747
7748
7749osGLOBAL bit32
7750smsatVerify10(
7751              smRoot_t                  *smRoot,
7752              smIORequest_t             *smIORequest,
7753              smDeviceHandle_t          *smDeviceHandle,
7754              smScsiInitiatorRequest_t  *smScsiRequest,
7755              smSatIOContext_t            *satIOContext
7756             )
7757{
7758  /*
7759    For simple implementation,
7760    no byte comparison supported as of 4/5/06
7761  */
7762  smScsiRspSense_t          *pSense;
7763  smIniScsiCmnd_t           *scsiCmnd;
7764  smDeviceData_t            *pSatDevData;
7765  agsaFisRegHostToDevice_t  *fis;
7766  bit32                     status;
7767  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7768  bit32                     lba = 0;
7769  bit32                     tl = 0;
7770  bit32                     LoopNum = 1;
7771  bit8                      LBA[8];
7772  bit8                      TL[8];
7773  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
7774
7775  pSense            = satIOContext->pSense;
7776  scsiCmnd          = &smScsiRequest->scsiCmnd;
7777  pSatDevData       = satIOContext->pSatDevData;
7778  fis               = satIOContext->pFis;
7779  SM_DBG5(("smsatVerify10: start\n"));
7780  /* checking BYTCHK */
7781  if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
7782  {
7783    /*
7784      should do the byte check
7785      but not supported in this version
7786     */
7787    smsatSetSensePayload( pSense,
7788                          SCSI_SNSKEY_ILLEGAL_REQUEST,
7789                          0,
7790                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7791                          satIOContext);
7792    /*smEnqueueIO(smRoot, satIOContext);*/
7793    tdsmIOCompletedCB( smRoot,
7794                       smIORequest,
7795                       smIOSuccess,
7796                       SCSI_STAT_CHECK_CONDITION,
7797                       satIOContext->pSmSenseData,
7798                       satIOContext->interruptContext );
7799
7800    SM_DBG1(("smsatVerify10: no byte checking!!!\n"));
7801    return SM_RC_SUCCESS;
7802  }
7803
7804  /* checking CONTROL */
7805  /* NACA == 1 or LINK == 1*/
7806  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
7807  {
7808    smsatSetSensePayload( pSense,
7809                          SCSI_SNSKEY_ILLEGAL_REQUEST,
7810                          0,
7811                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7812                          satIOContext);
7813
7814    /*smEnqueueIO(smRoot, satIOContext);*/
7815
7816    tdsmIOCompletedCB( smRoot,
7817                       smIORequest,
7818                       smIOSuccess,
7819                       SCSI_STAT_CHECK_CONDITION,
7820                       satIOContext->pSmSenseData,
7821                       satIOContext->interruptContext );
7822
7823    SM_DBG1(("smsatVerify10: return control!!!\n"));
7824    return SM_RC_SUCCESS;
7825  }
7826
7827
7828  sm_memset(LBA, 0, sizeof(LBA));
7829  sm_memset(TL, 0, sizeof(TL));
7830
7831  /* do not use memcpy due to indexing in LBA and TL */
7832  LBA[0] = 0;                  /* MSB */
7833  LBA[1] = 0;
7834  LBA[2] = 0;
7835  LBA[3] = 0;
7836  LBA[4] = scsiCmnd->cdb[2];
7837  LBA[5] = scsiCmnd->cdb[3];
7838  LBA[6] = scsiCmnd->cdb[4];
7839  LBA[7] = scsiCmnd->cdb[5];  	/* LSB */
7840
7841  TL[0] = 0;
7842  TL[1] = 0;
7843  TL[2] = 0;
7844  TL[3] = 0;
7845  TL[4] = 0;
7846  TL[5] = 0;
7847  TL[6] = scsiCmnd->cdb[7];
7848  TL[7] = scsiCmnd->cdb[8];  	/* LSB */
7849
7850
7851  /* cbd10; computing LBA and transfer length */
7852  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
7853    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
7854  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7855
7856  if (pSatDevData->satNCQ != agTRUE &&
7857      pSatDevData->sat48BitSupport != agTRUE
7858      )
7859  {
7860    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7861    if (AllChk)
7862    {
7863      SM_DBG1(("smsatVerify10: return LBA out of range, not EXT!!!\n"));
7864      SM_DBG1(("smsatVerify10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
7865             scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
7866      SM_DBG1(("smsatVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
7867      smsatSetSensePayload( pSense,
7868                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7869                            0,
7870                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7871                            satIOContext);
7872
7873      /*smEnqueueIO(smRoot, satIOContext);*/
7874
7875      tdsmIOCompletedCB( smRoot,
7876                         smIORequest,
7877                         smIOSuccess,
7878                         SCSI_STAT_CHECK_CONDITION,
7879                         satIOContext->pSmSenseData,
7880                         satIOContext->interruptContext );
7881
7882    return SM_RC_SUCCESS;
7883    }
7884  }
7885  else
7886  {
7887    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7888    if (AllChk)
7889    {
7890      SM_DBG1(("smsatVerify10: return LBA out of range, EXT!!!\n"));
7891      smsatSetSensePayload( pSense,
7892                            SCSI_SNSKEY_ILLEGAL_REQUEST,
7893                            0,
7894                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7895                            satIOContext);
7896
7897      /*smEnqueueIO(smRoot, satIOContext);*/
7898
7899      tdsmIOCompletedCB( smRoot,
7900                         smIORequest,
7901                         smIOSuccess,
7902                         SCSI_STAT_CHECK_CONDITION,
7903                         satIOContext->pSmSenseData,
7904                         satIOContext->interruptContext );
7905
7906    return SM_RC_SUCCESS;
7907    }
7908  }
7909
7910  if (pSatDevData->sat48BitSupport == agTRUE)
7911  {
7912    SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS_EXT\n"));
7913    fis->h.fisType        = 0x27;                   /* Reg host to device */
7914    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7915
7916    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
7917    fis->h.features       = 0;                      /* FIS reserve */
7918    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7919    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7920    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7921    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
7922    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7923    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7924    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7925    fis->d.featuresExp    = 0;                      /* FIS reserve */
7926    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7927    fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
7928
7929    fis->d.reserved4      = 0;
7930    fis->d.control        = 0;                      /* FIS HOB bit clear */
7931    fis->d.reserved5      = 0;
7932
7933    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7934    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
7935  }
7936  else
7937  {
7938    SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS\n"));
7939    fis->h.fisType        = 0x27;                   /* Reg host to device */
7940    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7941    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
7942    fis->h.features       = 0;                      /* FIS reserve */
7943    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7944    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7945    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7946      /* FIS LBA mode set LBA (27:24) */
7947    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7948    fis->d.lbaLowExp      = 0;
7949    fis->d.lbaMidExp      = 0;
7950    fis->d.lbaHighExp     = 0;
7951    fis->d.featuresExp    = 0;
7952    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7953    fis->d.sectorCountExp = 0;
7954    fis->d.reserved4      = 0;
7955    fis->d.control        = 0;                      /* FIS HOB bit clear */
7956    fis->d.reserved5      = 0;
7957
7958    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7959    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
7960
7961 }
7962
7963  satIOContext->currentLBA = lba;
7964  satIOContext->OrgTL = tl;
7965
7966  /*
7967    computing number of loop and remainder for tl
7968    0xFF in case not ext
7969    0xFFFF in case EXT
7970  */
7971  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7972  {
7973    LoopNum = smsatComputeLoopNum(tl, 0xFF);
7974  }
7975  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
7976  {
7977    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7978    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7979  }
7980  else
7981  {
7982    SM_DBG1(("smsatVerify10: error case 1!!!\n"));
7983    LoopNum = 1;
7984  }
7985
7986  satIOContext->LoopNum = LoopNum;
7987
7988  if (LoopNum == 1)
7989  {
7990    SM_DBG5(("smsatVerify10: NON CHAINED data\n"));
7991    /* Initialize CB for SATA completion.
7992     */
7993    satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
7994  }
7995  else
7996  {
7997    SM_DBG1(("smsatVerify10: CHAINED data!!!\n"));
7998    /* re-setting tl */
7999    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8000    {
8001       fis->d.sectorCount    = 0xFF;
8002    }
8003    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8004    {
8005      fis->d.sectorCount    = 0xFF;
8006      fis->d.sectorCountExp = 0xFF;
8007    }
8008    else
8009    {
8010      SM_DBG1(("smsatVerify10: error case 2!!!\n"));
8011    }
8012
8013    /* Initialize CB for SATA completion.
8014     */
8015    satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8016  }
8017
8018
8019  /*
8020   * Prepare SGL and send FIS to LL layer.
8021   */
8022  satIOContext->reqType = agRequestType;       /* Save it */
8023
8024  status = smsataLLIOStart( smRoot,
8025                            smIORequest,
8026                            smDeviceHandle,
8027                            smScsiRequest,
8028                            satIOContext);
8029  return (status);
8030}
8031
8032osGLOBAL bit32
8033smsatVerify12(
8034              smRoot_t                  *smRoot,
8035              smIORequest_t             *smIORequest,
8036              smDeviceHandle_t          *smDeviceHandle,
8037              smScsiInitiatorRequest_t  *smScsiRequest,
8038              smSatIOContext_t            *satIOContext
8039             )
8040{
8041  /*
8042    For simple implementation,
8043    no byte comparison supported as of 4/5/06
8044  */
8045  smScsiRspSense_t          *pSense;
8046  smIniScsiCmnd_t           *scsiCmnd;
8047  smDeviceData_t            *pSatDevData;
8048  agsaFisRegHostToDevice_t  *fis;
8049  bit32                     status;
8050  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8051  bit32                     lba = 0;
8052  bit32                     tl = 0;
8053  bit32                     LoopNum = 1;
8054  bit8                      LBA[8];
8055  bit8                      TL[8];
8056  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
8057
8058  pSense            = satIOContext->pSense;
8059  scsiCmnd          = &smScsiRequest->scsiCmnd;
8060  pSatDevData       = satIOContext->pSatDevData;
8061  fis               = satIOContext->pFis;
8062  SM_DBG5(("smsatVerify12: start\n"));
8063  /* checking BYTCHK */
8064  if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8065  {
8066    /*
8067      should do the byte check
8068      but not supported in this version
8069     */
8070    smsatSetSensePayload( pSense,
8071                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8072                          0,
8073                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8074                          satIOContext);
8075
8076    /*smEnqueueIO(smRoot, satIOContext);*/
8077
8078    tdsmIOCompletedCB( smRoot,
8079                       smIORequest,
8080                       smIOSuccess,
8081                       SCSI_STAT_CHECK_CONDITION,
8082                       satIOContext->pSmSenseData,
8083                       satIOContext->interruptContext );
8084
8085    SM_DBG1(("smsatVerify12: no byte checking!!!\n"));
8086    return SM_RC_SUCCESS;
8087  }
8088
8089  /* checking CONTROL */
8090  /* NACA == 1 or LINK == 1*/
8091  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
8092  {
8093    smsatSetSensePayload( pSense,
8094                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8095                          0,
8096                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8097                          satIOContext);
8098
8099    /*smEnqueueIO(smRoot, satIOContext);*/
8100
8101    tdsmIOCompletedCB( smRoot,
8102                       smIORequest,
8103                       smIOSuccess,
8104                       SCSI_STAT_CHECK_CONDITION,
8105                       satIOContext->pSmSenseData,
8106                       satIOContext->interruptContext );
8107
8108    SM_DBG1(("smsatVerify12: return control!!!\n"));
8109    return SM_RC_SUCCESS;
8110  }
8111
8112  sm_memset(LBA, 0, sizeof(LBA));
8113  sm_memset(TL, 0, sizeof(TL));
8114
8115  /* do not use memcpy due to indexing in LBA and TL */
8116  LBA[0] = 0;                  /* MSB */
8117  LBA[1] = 0;
8118  LBA[2] = 0;
8119  LBA[3] = 0;
8120  LBA[4] = scsiCmnd->cdb[2];
8121  LBA[5] = scsiCmnd->cdb[3];
8122  LBA[6] = scsiCmnd->cdb[4];
8123  LBA[7] = scsiCmnd->cdb[5];  	/* LSB */
8124
8125  TL[0] = 0;                    /* MSB */
8126  TL[1] = 0;
8127  TL[2] = 0;
8128  TL[3] = 0;
8129  TL[4] = scsiCmnd->cdb[6];
8130  TL[5] = scsiCmnd->cdb[7];
8131  TL[6] = scsiCmnd->cdb[8];
8132  TL[7] = scsiCmnd->cdb[9];   	/* LSB */
8133
8134
8135  lba = smsatComputeCDB12LBA(satIOContext);
8136  tl = smsatComputeCDB12TL(satIOContext);
8137
8138  if (pSatDevData->satNCQ != agTRUE &&
8139      pSatDevData->sat48BitSupport != agTRUE
8140      )
8141  {
8142    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
8143    if (AllChk)
8144    {
8145      SM_DBG1(("smsatVerify12: return LBA out of range, not EXT!!!\n"));
8146      SM_DBG1(("smsatVerify12: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
8147             scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
8148      SM_DBG1(("smsatVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
8149      smsatSetSensePayload( pSense,
8150                            SCSI_SNSKEY_ILLEGAL_REQUEST,
8151                            0,
8152                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8153                            satIOContext);
8154
8155      /*smEnqueueIO(smRoot, satIOContext);*/
8156
8157      tdsmIOCompletedCB( smRoot,
8158                         smIORequest,
8159                         smIOSuccess,
8160                         SCSI_STAT_CHECK_CONDITION,
8161                         satIOContext->pSmSenseData,
8162                         satIOContext->interruptContext );
8163
8164    return SM_RC_SUCCESS;
8165    }
8166  }
8167  else
8168  {
8169    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
8170    if (AllChk)
8171    {
8172      SM_DBG1(("smsatVerify12: return LBA out of range, EXT!!!\n"));
8173      smsatSetSensePayload( pSense,
8174                            SCSI_SNSKEY_ILLEGAL_REQUEST,
8175                            0,
8176                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8177                            satIOContext);
8178
8179      /*smEnqueueIO(smRoot, satIOContext);*/
8180
8181      tdsmIOCompletedCB( smRoot,
8182                         smIORequest,
8183                         smIOSuccess,
8184                         SCSI_STAT_CHECK_CONDITION,
8185                         satIOContext->pSmSenseData,
8186                         satIOContext->interruptContext );
8187
8188    return SM_RC_SUCCESS;
8189    }
8190  }
8191
8192  if (pSatDevData->sat48BitSupport == agTRUE)
8193  {
8194    SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS_EXT\n"));
8195    fis->h.fisType        = 0x27;                   /* Reg host to device */
8196    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8197
8198    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8199    fis->h.features       = 0;                      /* FIS reserve */
8200    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8201    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8202    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8203    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8204    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
8205    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
8206    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
8207    fis->d.featuresExp    = 0;                      /* FIS reserve */
8208    fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8209    fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
8210
8211    fis->d.reserved4      = 0;
8212    fis->d.control        = 0;                      /* FIS HOB bit clear */
8213    fis->d.reserved5      = 0;
8214
8215    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8216    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8217  }
8218  else
8219  {
8220    SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS\n"));
8221    fis->h.fisType        = 0x27;                   /* Reg host to device */
8222    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8223    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8224    fis->h.features       = 0;                      /* FIS reserve */
8225    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8226    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8227    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8228      /* FIS LBA mode set LBA (27:24) */
8229    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
8230    fis->d.lbaLowExp      = 0;
8231    fis->d.lbaMidExp      = 0;
8232    fis->d.lbaHighExp     = 0;
8233    fis->d.featuresExp    = 0;
8234    fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8235    fis->d.sectorCountExp = 0;
8236    fis->d.reserved4      = 0;
8237    fis->d.control        = 0;                      /* FIS HOB bit clear */
8238    fis->d.reserved5      = 0;
8239
8240    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8241    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8242
8243 }
8244
8245  satIOContext->currentLBA = lba;
8246  satIOContext->OrgTL = tl;
8247
8248  /*
8249    computing number of loop and remainder for tl
8250    0xFF in case not ext
8251    0xFFFF in case EXT
8252  */
8253  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8254  {
8255    LoopNum = smsatComputeLoopNum(tl, 0xFF);
8256  }
8257  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8258  {
8259    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8260    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
8261  }
8262  else
8263  {
8264    SM_DBG1(("smsatVerify12: error case 1!!!\n"));
8265    LoopNum = 1;
8266  }
8267
8268  satIOContext->LoopNum = LoopNum;
8269
8270  if (LoopNum == 1)
8271  {
8272    SM_DBG5(("smsatVerify12: NON CHAINED data\n"));
8273    /* Initialize CB for SATA completion.
8274     */
8275    satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
8276  }
8277  else
8278  {
8279    SM_DBG1(("smsatVerify12: CHAINED data!!!\n"));
8280    /* re-setting tl */
8281    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8282    {
8283       fis->d.sectorCount    = 0xFF;
8284    }
8285    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8286    {
8287      fis->d.sectorCount    = 0xFF;
8288      fis->d.sectorCountExp = 0xFF;
8289    }
8290    else
8291    {
8292      SM_DBG1(("smsatVerify12: error case 2!!!\n"));
8293    }
8294
8295    /* Initialize CB for SATA completion.
8296     */
8297    satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8298  }
8299
8300
8301  /*
8302   * Prepare SGL and send FIS to LL layer.
8303   */
8304  satIOContext->reqType = agRequestType;       /* Save it */
8305
8306  status = smsataLLIOStart( smRoot,
8307                            smIORequest,
8308                            smDeviceHandle,
8309                            smScsiRequest,
8310                            satIOContext);
8311  return (status);
8312}
8313
8314osGLOBAL bit32
8315smsatVerify16(
8316              smRoot_t                  *smRoot,
8317              smIORequest_t             *smIORequest,
8318              smDeviceHandle_t          *smDeviceHandle,
8319              smScsiInitiatorRequest_t  *smScsiRequest,
8320              smSatIOContext_t            *satIOContext
8321             )
8322{
8323  /*
8324    For simple implementation,
8325    no byte comparison supported as of 4/5/06
8326  */
8327  smScsiRspSense_t          *pSense;
8328  smIniScsiCmnd_t           *scsiCmnd;
8329  smDeviceData_t            *pSatDevData;
8330  agsaFisRegHostToDevice_t  *fis;
8331  bit32                     status;
8332  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8333  bit32                     lba = 0;
8334  bit32                     tl = 0;
8335  bit32                     LoopNum = 1;
8336  bit8                      LBA[8];
8337  bit8                      TL[8];
8338  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
8339
8340  pSense            = satIOContext->pSense;
8341  scsiCmnd          = &smScsiRequest->scsiCmnd;
8342  pSatDevData       = satIOContext->pSatDevData;
8343  fis               = satIOContext->pFis;
8344  SM_DBG5(("smsatVerify16: start\n"));
8345  /* checking BYTCHK */
8346  if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8347  {
8348    /*
8349      should do the byte check
8350      but not supported in this version
8351     */
8352    smsatSetSensePayload( pSense,
8353                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8354                          0,
8355                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8356                          satIOContext);
8357    /*smEnqueueIO(smRoot, satIOContext);*/
8358    tdsmIOCompletedCB( smRoot,
8359                       smIORequest,
8360                       smIOSuccess,
8361                       SCSI_STAT_CHECK_CONDITION,
8362                       satIOContext->pSmSenseData,
8363                       satIOContext->interruptContext );
8364    SM_DBG1(("smsatVerify16: no byte checking!!!\n"));
8365    return SM_RC_SUCCESS;
8366  }
8367  /* checking CONTROL */
8368  /* NACA == 1 or LINK == 1*/
8369  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
8370  {
8371    smsatSetSensePayload( pSense,
8372                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8373                          0,
8374                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8375                          satIOContext);
8376    /*smEnqueueIO(smRoot, satIOContext);*/
8377    tdsmIOCompletedCB( smRoot,
8378                       smIORequest,
8379                       smIOSuccess,
8380                       SCSI_STAT_CHECK_CONDITION,
8381                       satIOContext->pSmSenseData,
8382                       satIOContext->interruptContext );
8383    SM_DBG1(("smsatVerify16: return control!!!\n"));
8384    return SM_RC_SUCCESS;
8385  }
8386  sm_memset(LBA, 0, sizeof(LBA));
8387  sm_memset(TL, 0, sizeof(TL));
8388
8389  /* do not use memcpy due to indexing in LBA and TL */
8390  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
8391  LBA[1] = scsiCmnd->cdb[3];
8392  LBA[2] = scsiCmnd->cdb[4];
8393  LBA[3] = scsiCmnd->cdb[5];
8394  LBA[4] = scsiCmnd->cdb[6];
8395  LBA[5] = scsiCmnd->cdb[7];
8396  LBA[6] = scsiCmnd->cdb[8];
8397  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
8398
8399  TL[0] = 0;
8400  TL[1] = 0;
8401  TL[2] = 0;
8402  TL[3] = 0;
8403  TL[4] = scsiCmnd->cdb[10];   /* MSB */
8404  TL[5] = scsiCmnd->cdb[11];
8405  TL[6] = scsiCmnd->cdb[12];
8406  TL[7] = scsiCmnd->cdb[13];   /* LSB */
8407  lba = smsatComputeCDB16LBA(satIOContext);
8408  tl = smsatComputeCDB16TL(satIOContext);
8409
8410  if (pSatDevData->satNCQ != agTRUE &&
8411     pSatDevData->sat48BitSupport != agTRUE
8412     )
8413  {
8414    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
8415    if (AllChk)
8416    {
8417      SM_DBG1(("smsatVerify16: return LBA out of range, not EXT!!!\n"));
8418      smsatSetSensePayload( pSense,
8419                            SCSI_SNSKEY_ILLEGAL_REQUEST,
8420                            0,
8421                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8422                            satIOContext);
8423     /*smEnqueueIO(smRoot, satIOContext);*/
8424     tdsmIOCompletedCB( smRoot,
8425                         smIORequest,
8426                         smIOSuccess,
8427                         SCSI_STAT_CHECK_CONDITION,
8428                         satIOContext->pSmSenseData,
8429                         satIOContext->interruptContext );
8430    return SM_RC_SUCCESS;
8431    }
8432  }
8433  else
8434  {
8435    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
8436    if (AllChk)
8437    {
8438      SM_DBG1(("smsatVerify16: return LBA out of range, EXT!!!\n"));
8439      smsatSetSensePayload( pSense,
8440                            SCSI_SNSKEY_ILLEGAL_REQUEST,
8441                            0,
8442                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8443                            satIOContext);
8444      /*smEnqueueIO(smRoot, satIOContext);*/
8445      tdsmIOCompletedCB( smRoot,
8446                         smIORequest,
8447                         smIOSuccess,
8448                         SCSI_STAT_CHECK_CONDITION,
8449                         satIOContext->pSmSenseData,
8450                         satIOContext->interruptContext );
8451    return SM_RC_SUCCESS;
8452    }
8453  }
8454
8455  if (pSatDevData->sat48BitSupport == agTRUE)
8456  {
8457    SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS_EXT\n"));
8458    fis->h.fisType        = 0x27;                   /* Reg host to device */
8459    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8460    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8461    fis->h.features       = 0;                      /* FIS reserve */
8462    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8463    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8464    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8465    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8466    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
8467    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
8468    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
8469    fis->d.featuresExp    = 0;                      /* FIS reserve */
8470    fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8471    fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
8472
8473    fis->d.reserved4      = 0;
8474    fis->d.control        = 0;                      /* FIS HOB bit clear */
8475    fis->d.reserved5      = 0;
8476
8477    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8478    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8479  }
8480  else
8481  {
8482    SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS\n"));
8483    fis->h.fisType        = 0x27;                   /* Reg host to device */
8484    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8485    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8486    fis->h.features       = 0;                      /* FIS reserve */
8487    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8488    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8489    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8490      /* FIS LBA mode set LBA (27:24) */
8491    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
8492    fis->d.lbaLowExp      = 0;
8493    fis->d.lbaMidExp      = 0;
8494    fis->d.lbaHighExp     = 0;
8495    fis->d.featuresExp    = 0;
8496    fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8497    fis->d.sectorCountExp = 0;
8498    fis->d.reserved4      = 0;
8499    fis->d.control        = 0;                      /* FIS HOB bit clear */
8500    fis->d.reserved5      = 0;
8501
8502    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8503    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8504
8505 }
8506
8507  satIOContext->currentLBA = lba;
8508  satIOContext->OrgTL = tl;
8509
8510  /*
8511    computing number of loop and remainder for tl
8512    0xFF in case not ext
8513    0xFFFF in case EXT
8514  */
8515  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8516  {
8517    LoopNum = smsatComputeLoopNum(tl, 0xFF);
8518  }
8519  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8520  {
8521    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8522    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
8523  }
8524  else
8525  {
8526    SM_DBG1(("smsatVerify16: error case 1!!!\n"));
8527    LoopNum = 1;
8528  }
8529
8530  satIOContext->LoopNum = LoopNum;
8531
8532  if (LoopNum == 1)
8533  {
8534    SM_DBG5(("smsatVerify16: NON CHAINED data\n"));
8535    /* Initialize CB for SATA completion.
8536     */
8537    satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
8538  }
8539  else
8540  {
8541    SM_DBG1(("smsatVerify16: CHAINED data!!!\n"));
8542    /* re-setting tl */
8543    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8544    {
8545       fis->d.sectorCount    = 0xFF;
8546    }
8547    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8548    {
8549      fis->d.sectorCount    = 0xFF;
8550      fis->d.sectorCountExp = 0xFF;
8551    }
8552    else
8553    {
8554      SM_DBG1(("smsatVerify16: error case 2!!!\n"));
8555    }
8556
8557    /* Initialize CB for SATA completion.
8558     */
8559    satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8560  }
8561
8562
8563  /*
8564   * Prepare SGL and send FIS to LL layer.
8565   */
8566  satIOContext->reqType = agRequestType;       /* Save it */
8567
8568  status = smsataLLIOStart( smRoot,
8569                            smIORequest,
8570                            smDeviceHandle,
8571                            smScsiRequest,
8572                            satIOContext);
8573  return (status);
8574}
8575
8576osGLOBAL bit32
8577smsatTestUnitReady(
8578                   smRoot_t                  *smRoot,
8579                   smIORequest_t             *smIORequest,
8580                   smDeviceHandle_t          *smDeviceHandle,
8581                   smScsiInitiatorRequest_t  *smScsiRequest,
8582                   smSatIOContext_t            *satIOContext
8583                  )
8584{
8585  bit32                     status;
8586  bit32                     agRequestType;
8587  smDeviceData_t            *pSatDevData;
8588  smScsiRspSense_t          *pSense;
8589  smIniScsiCmnd_t           *scsiCmnd;
8590  agsaFisRegHostToDevice_t  *fis;
8591
8592  pSense        = satIOContext->pSense;
8593  pSatDevData   = satIOContext->pSatDevData;
8594  scsiCmnd      = &smScsiRequest->scsiCmnd;
8595  fis           = satIOContext->pFis;
8596
8597  SM_DBG5(("smsatTestUnitReady: start\n"));
8598
8599  /* checking CONTROL */
8600  /* NACA == 1 or LINK == 1*/
8601  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8602  {
8603    smsatSetSensePayload( pSense,
8604                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8605                          0,
8606                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8607                          satIOContext);
8608
8609    /*smEnqueueIO(smRoot, satIOContext);*/
8610
8611    tdsmIOCompletedCB( smRoot,
8612                       smIORequest,
8613                       smIOSuccess,
8614                       SCSI_STAT_CHECK_CONDITION,
8615                       satIOContext->pSmSenseData,
8616                       satIOContext->interruptContext );
8617
8618    SM_DBG1(("smsatTestUnitReady: return control!!!\n"));
8619    return SM_RC_SUCCESS;
8620  }
8621
8622  /* SAT revision 8, 8.11.2, p42*/
8623  if (pSatDevData->satStopState == agTRUE)
8624  {
8625    smsatSetSensePayload( pSense,
8626                          SCSI_SNSKEY_NOT_READY,
8627                          0,
8628                          SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
8629                          satIOContext);
8630
8631    /*smEnqueueIO(smRoot, satIOContext);*/
8632
8633    tdsmIOCompletedCB( smRoot,
8634                       smIORequest,
8635                       smIOSuccess,
8636                       SCSI_STAT_CHECK_CONDITION,
8637                       satIOContext->pSmSenseData,
8638                       satIOContext->interruptContext );
8639    SM_DBG1(("smsatTestUnitReady: stop state!!!\n"));
8640    return SM_RC_SUCCESS;
8641  }
8642
8643  /*
8644   * Check if format is in progress
8645   */
8646  if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
8647  {
8648    SM_DBG1(("smsatTestUnitReady: FORMAT_IN_PROGRESS!!!\n"));
8649
8650    smsatSetSensePayload( pSense,
8651                          SCSI_SNSKEY_NOT_READY,
8652                          0,
8653                          SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
8654                          satIOContext);
8655
8656    /*smEnqueueIO(smRoot, satIOContext);*/
8657
8658    tdsmIOCompletedCB( smRoot,
8659                       smIORequest,
8660                       smIOSuccess,
8661                       SCSI_STAT_CHECK_CONDITION,
8662                       satIOContext->pSmSenseData,
8663                       satIOContext->interruptContext );
8664    SM_DBG1(("smsatTestUnitReady: format in progress!!!\n"));
8665    return SM_RC_SUCCESS;
8666  }
8667
8668  /*
8669    check previously issued ATA command
8670  */
8671  if (pSatDevData->satPendingIO != 0)
8672  {
8673    if (pSatDevData->satDeviceFaultState == agTRUE)
8674    {
8675      smsatSetSensePayload( pSense,
8676                            SCSI_SNSKEY_HARDWARE_ERROR,
8677                            0,
8678                            SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
8679                            satIOContext);
8680
8681      /*smEnqueueIO(smRoot, satIOContext);*/
8682
8683      tdsmIOCompletedCB( smRoot,
8684                         smIORequest,
8685                         smIOSuccess,
8686                         SCSI_STAT_CHECK_CONDITION,
8687                         satIOContext->pSmSenseData,
8688                         satIOContext->interruptContext );
8689      SM_DBG1(("smsatTestUnitReady: previous command ended in error!!!\n"));
8690      return SM_RC_SUCCESS;
8691    }
8692  }
8693
8694  /*
8695    check removalbe media feature set
8696   */
8697  if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
8698  {
8699    SM_DBG5(("smsatTestUnitReady: sending get media status cmnd\n"));
8700    /* send GET MEDIA STATUS command */
8701    fis->h.fisType        = 0x27;                   /* Reg host to device */
8702    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8703    fis->h.command        = SAT_GET_MEDIA_STATUS;   /* 0xDA */
8704    fis->h.features       = 0;                      /* FIS features NA       */
8705    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
8706    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
8707    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
8708    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
8709    fis->d.lbaLowExp      = 0;
8710    fis->d.lbaMidExp      = 0;
8711    fis->d.lbaHighExp     = 0;
8712    fis->d.featuresExp    = 0;
8713    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
8714    fis->d.sectorCountExp = 0;
8715    fis->d.reserved4      = 0;
8716    fis->d.control        = 0;                      /* FIS HOB bit clear */
8717    fis->d.reserved5      = 0;
8718    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8719
8720    /* Initialize CB for SATA completion.
8721     */
8722    satIOContext->satCompleteCB = &smsatTestUnitReadyCB;
8723
8724    /*
8725     * Prepare SGL and send FIS to LL layer.
8726     */
8727    satIOContext->reqType = agRequestType;       /* Save it */
8728
8729    status = smsataLLIOStart( smRoot,
8730                              smIORequest,
8731                              smDeviceHandle,
8732                              smScsiRequest,
8733                              satIOContext);
8734
8735    return (status);
8736  }
8737  /*
8738    number 6) in SAT p42
8739    send ATA CHECK POWER MODE
8740  */
8741   SM_DBG5(("smsatTestUnitReady: sending check power mode cmnd\n"));
8742   status = smsatTestUnitReady_1( smRoot,
8743                                  smIORequest,
8744                                  smDeviceHandle,
8745                                  smScsiRequest,
8746                                  satIOContext);
8747   return (status);
8748}
8749
8750osGLOBAL bit32
8751smsatTestUnitReady_1(
8752                     smRoot_t                  *smRoot,
8753                     smIORequest_t             *smIORequest,
8754                     smDeviceHandle_t          *smDeviceHandle,
8755                     smScsiInitiatorRequest_t  *smScsiRequest,
8756                     smSatIOContext_t            *satIOContext
8757                    )
8758{
8759  /*
8760    sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY
8761    internally generated - no directly corresponding scsi
8762    called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42
8763  */
8764  bit32                     status;
8765  bit32                     agRequestType;
8766  agsaFisRegHostToDevice_t  *fis;
8767
8768  fis           = satIOContext->pFis;
8769  SM_DBG5(("smsatTestUnitReady_1: start\n"));
8770  /*
8771   * Send the ATA CHECK POWER MODE command.
8772   */
8773  fis->h.fisType        = 0x27;                   /* Reg host to device */
8774  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8775  fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
8776  fis->h.features       = 0;
8777  fis->d.lbaLow         = 0;
8778  fis->d.lbaMid         = 0;
8779  fis->d.lbaHigh        = 0;
8780  fis->d.device         = 0;
8781  fis->d.lbaLowExp      = 0;
8782  fis->d.lbaMidExp      = 0;
8783  fis->d.lbaHighExp     = 0;
8784  fis->d.featuresExp    = 0;
8785  fis->d.sectorCount    = 0;
8786  fis->d.sectorCountExp = 0;
8787  fis->d.reserved4      = 0;
8788  fis->d.control        = 0;                      /* FIS HOB bit clear */
8789  fis->d.reserved5      = 0;
8790
8791  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8792
8793  /* Initialize CB for SATA completion.
8794   */
8795  satIOContext->satCompleteCB = &smsatTestUnitReadyCB;
8796
8797  /*
8798   * Prepare SGL and send FIS to LL layer.
8799   */
8800  satIOContext->reqType = agRequestType;       /* Save it */
8801
8802  status = smsataLLIOStart( smRoot,
8803                            smIORequest,
8804                            smDeviceHandle,
8805                            smScsiRequest,
8806                            satIOContext);
8807
8808  SM_DBG5(("smsatTestUnitReady_1: return\n"));
8809
8810  return status;
8811}
8812
8813osGLOBAL bit32
8814smsatInquiry(
8815             smRoot_t                  *smRoot,
8816             smIORequest_t             *smIORequest,
8817             smDeviceHandle_t          *smDeviceHandle,
8818             smScsiInitiatorRequest_t  *smScsiRequest,
8819             smSatIOContext_t            *satIOContext
8820            )
8821{
8822  /*
8823    CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8
8824  */
8825  smScsiRspSense_t          *pSense;
8826  smIniScsiCmnd_t           *scsiCmnd;
8827  smDeviceData_t            *pSatDevData;
8828  bit32                      status;
8829
8830  pSense      = satIOContext->pSense;
8831  scsiCmnd    = &smScsiRequest->scsiCmnd;
8832  pSatDevData = satIOContext->pSatDevData;
8833  SM_DBG5(("smsatInquiry: start\n"));
8834  SM_DBG5(("smsatInquiry: pSatDevData did %d\n", pSatDevData->id));
8835  //smhexdump("smsatInquiry", (bit8 *)scsiCmnd->cdb, 6);
8836  /* checking CONTROL */
8837  /* NACA == 1 or LINK == 1*/
8838  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8839  {
8840    smsatSetSensePayload( pSense,
8841                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8842                          0,
8843                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8844                          satIOContext);
8845    /*smEnqueueIO(smRoot, satIOContext);*/
8846    tdsmIOCompletedCB( smRoot,
8847                       smIORequest,
8848                       smIOSuccess,
8849                       SCSI_STAT_CHECK_CONDITION,
8850                       satIOContext->pSmSenseData,
8851                       satIOContext->interruptContext );
8852    SM_DBG1(("smsatInquiry: return control!!!\n"));
8853    return SM_RC_SUCCESS;
8854  }
8855
8856  /* checking EVPD and Allocation Length */
8857  /* SPC-4 spec 6.4 p141 */
8858  /* EVPD bit == 0 && PAGE CODE != 0 */
8859  if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
8860       (scsiCmnd->cdb[2] != 0)
8861       )
8862  {
8863    smsatSetSensePayload( pSense,
8864                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8865                          0,
8866                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8867                          satIOContext);
8868    /*smEnqueueIO(smRoot, satIOContext);*/
8869    tdsmIOCompletedCB( smRoot,
8870                       smIORequest,
8871                       smIOSuccess,
8872                       SCSI_STAT_CHECK_CONDITION,
8873                       satIOContext->pSmSenseData,
8874                       satIOContext->interruptContext );
8875    SM_DBG1(("smsatInquiry: return EVPD and PAGE CODE!!!\n"));
8876    return SM_RC_SUCCESS;
8877  }
8878  SM_DBG6(("smsatInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4]));
8879  /* convert OS IO to TD internal IO */
8880  if ( pSatDevData->IDDeviceValid == agFALSE)
8881  {
8882    status = smsatStartIDDev(
8883                             smRoot,
8884                             smIORequest,
8885                             smDeviceHandle,
8886                             smScsiRequest,
8887                             satIOContext
8888                            );
8889    SM_DBG6(("smsatInquiry: end status %d\n", status));
8890    return status;
8891  }
8892  else
8893  {
8894    SM_DBG6(("smsatInquiry: calling satInquiryIntCB\n"));
8895    smsatInquiryIntCB(
8896                      smRoot,
8897                      smIORequest,
8898                      smDeviceHandle,
8899                      smScsiRequest,
8900                      satIOContext
8901                     );
8902    /*smEnqueueIO(smRoot, satIOContext);*/
8903    return SM_RC_SUCCESS;
8904  }
8905}
8906
8907
8908osGLOBAL bit32
8909smsatStartIDDev(
8910                smRoot_t                  *smRoot,
8911                smIORequest_t             *smIORequest,
8912                smDeviceHandle_t          *smDeviceHandle,
8913                smScsiInitiatorRequest_t  *smScsiRequest,
8914                smSatIOContext_t            *satIOContext
8915               )
8916{
8917  smSatInternalIo_t        *satIntIo = agNULL;
8918  smDeviceData_t           *satDevData = agNULL;
8919  smIORequestBody_t        *smIORequestBody;
8920  smSatIOContext_t         *satNewIOContext;
8921  bit32                     status;
8922
8923  SM_DBG5(("smsatStartIDDev: start\n"));
8924
8925  satDevData = satIOContext->pSatDevData;
8926
8927  SM_DBG6(("smsatStartIDDev: before alloc\n"));
8928
8929  /* allocate identify device command */
8930  satIntIo = smsatAllocIntIoResource( smRoot,
8931                                      smIORequest,
8932                                      satDevData,
8933                                      sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
8934                                      satIntIo);
8935
8936  SM_DBG6(("smsatStartIDDev: before after\n"));
8937
8938  if (satIntIo == agNULL)
8939  {
8940    SM_DBG1(("smsatStartIDDev: can't alloacate!!!\n"));
8941
8942    /*smEnqueueIO(smRoot, satIOContext);*/
8943
8944    return SM_RC_FAILURE;
8945  }
8946
8947  satIntIo->satOrgSmIORequest = smIORequest; /* changed */
8948  smIORequestBody = satIntIo->satIntRequestBody;
8949  satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext);
8950
8951  satNewIOContext->pSatDevData   = satDevData;
8952  satNewIOContext->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
8953  satNewIOContext->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
8954  satNewIOContext->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
8955  satNewIOContext->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
8956  satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */
8957  satNewIOContext->interruptContext = tiInterruptContext;
8958  satNewIOContext->satIntIoContext  = satIntIo;
8959
8960  satNewIOContext->psmDeviceHandle = agNULL;
8961  satNewIOContext->satOrgIOContext = satIOContext; /* changed */
8962
8963  /* this is valid only for TD layer generated (not triggered by OS at all) IO */
8964  satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg);
8965
8966
8967  SM_DBG6(("smsatStartIDDev: OS satIOContext %p \n", satIOContext));
8968  SM_DBG6(("smsatStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
8969  SM_DBG6(("smsatStartIDDev: OS tiScsiXchg %p \n", satIOContext->smScsiXchg));
8970  SM_DBG6(("smsatStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->smScsiXchg));
8971
8972
8973
8974  SM_DBG1(("smsatStartIDDev: satNewIOContext %p smIORequestBody %p!!!\n", satNewIOContext, smIORequestBody));
8975
8976  status = smsatSendIDDev( smRoot,
8977                           &satIntIo->satIntSmIORequest, /* New smIORequest */
8978                           smDeviceHandle,
8979                           satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
8980                           satNewIOContext);
8981
8982  if (status != SM_RC_SUCCESS)
8983  {
8984    SM_DBG1(("smsatStartIDDev: failed in sending!!!\n"));
8985
8986    smsatFreeIntIoResource( smRoot,
8987                            satDevData,
8988                            satIntIo);
8989    /*smEnqueueIO(smRoot, satIOContext);*/
8990
8991    return SM_RC_FAILURE;
8992  }
8993
8994
8995  SM_DBG6(("smsatStartIDDev: end\n"));
8996
8997  return status;
8998}
8999
9000osGLOBAL bit32
9001smsatSendIDDev(
9002                smRoot_t                  *smRoot,
9003                smIORequest_t             *smIORequest,
9004                smDeviceHandle_t          *smDeviceHandle,
9005                smScsiInitiatorRequest_t  *smScsiRequest,
9006                smSatIOContext_t            *satIOContext
9007               )
9008{
9009  bit32                     status;
9010  bit32                     agRequestType;
9011  smDeviceData_t           *pSatDevData;
9012  agsaFisRegHostToDevice_t *fis;
9013#ifdef SM_INTERNAL_DEBUG
9014  smIORequestBody_t        *smIORequestBody;
9015  smSatInternalIo_t        *satIntIoContext;
9016#endif
9017
9018  pSatDevData   = satIOContext->pSatDevData;
9019  fis           = satIOContext->pFis;
9020  SM_DBG6(("smsatSendIDDev: start\n"));
9021  SM_DBG6(("smsatSendIDDev: did %d\n", pSatDevData->id));
9022#ifdef SM_INTERNAL_DEBUG
9023  satIntIoContext = satIOContext->satIntIoContext;
9024  smIORequestBody = satIntIoContext->satIntRequestBody;
9025#endif
9026  fis->h.fisType        = 0x27;                   /* Reg host to device */
9027  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9028  if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
9029      fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
9030  else
9031      fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
9032  fis->h.features       = 0;                      /* FIS reserve */
9033  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9034  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9035  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9036  fis->d.device         = 0;                      /* FIS LBA mode  */
9037  fis->d.lbaLowExp      = 0;
9038  fis->d.lbaMidExp      = 0;
9039  fis->d.lbaHighExp     = 0;
9040  fis->d.featuresExp    = 0;
9041  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9042  fis->d.sectorCountExp = 0;
9043  fis->d.reserved4      = 0;
9044  fis->d.control        = 0;                      /* FIS HOB bit clear */
9045  fis->d.reserved5      = 0;
9046
9047  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
9048
9049  /* Initialize CB for SATA completion.
9050   */
9051  satIOContext->satCompleteCB = &smsatInquiryCB;
9052
9053  /*
9054   * Prepare SGL and send FIS to LL layer.
9055   */
9056  satIOContext->reqType = agRequestType;       /* Save it */
9057
9058#ifdef SM_INTERNAL_DEBUG
9059  smhexdump("smsatSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
9060  smhexdump("smsatSendIDDev LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
9061#endif
9062  status = smsataLLIOStart( smRoot,
9063                            smIORequest,
9064                            smDeviceHandle,
9065                            smScsiRequest,
9066                            satIOContext);
9067
9068  SM_DBG6(("smsatSendIDDev: end status %d\n", status));
9069  return status;
9070}
9071
9072osGLOBAL bit32
9073smsatRequestSense(
9074                  smRoot_t                  *smRoot,
9075                  smIORequest_t             *smIORequest,
9076                  smDeviceHandle_t          *smDeviceHandle,
9077                  smScsiInitiatorRequest_t  *smScsiRequest,
9078                  smSatIOContext_t            *satIOContext
9079                 )
9080{
9081  /*
9082    SAT Rev 8 p38, Table25
9083    sending SMART RETURN STATUS
9084    Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB()
9085    Only fixed format sense data is support. In other words, we don't support DESC bit is set
9086    in Request Sense
9087   */
9088  bit32                     status;
9089  bit32                     agRequestType;
9090  smScsiRspSense_t          *pSense;
9091  smDeviceData_t            *pSatDevData;
9092  smIniScsiCmnd_t           *scsiCmnd;
9093  agsaFisRegHostToDevice_t  *fis;
9094  smIORequestBody_t         *smIORequestBody;
9095  smSatInternalIo_t           *satIntIo = agNULL;
9096  smSatIOContext_t            *satIOContext2;
9097  bit8                      *pDataBuffer = agNULL;
9098  bit32                     allocationLen = 0;
9099
9100  pSense            = satIOContext->pSense;
9101  pSatDevData       = satIOContext->pSatDevData;
9102  scsiCmnd          = &smScsiRequest->scsiCmnd;
9103  fis               = satIOContext->pFis;
9104  pDataBuffer       = (bit8 *) smScsiRequest->sglVirtualAddr;
9105  allocationLen     = scsiCmnd->cdb[4];
9106  allocationLen     = MIN(allocationLen, scsiCmnd->expDataLength);
9107  SM_DBG5(("smsatRequestSense: start\n"));
9108
9109  /* checking CONTROL */
9110  /* NACA == 1 or LINK == 1*/
9111  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9112  {
9113    smsatSetSensePayload( pSense,
9114                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9115                          0,
9116                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9117                          satIOContext);
9118    sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9119
9120    /*smEnqueueIO(smRoot, satIOContext);*/
9121
9122    tdsmIOCompletedCB( smRoot,
9123                       smIORequest,
9124                       smIOSuccess,
9125                       SCSI_STAT_CHECK_CONDITION,
9126                       satIOContext->pSmSenseData,
9127                       satIOContext->interruptContext );
9128
9129    SM_DBG1(("smsatRequestSense: return control!!!\n"));
9130    return SM_RC_SUCCESS;
9131  }
9132
9133  /*
9134    Only fixed format sense data is support. In other words, we don't support DESC bit is set
9135    in Request Sense
9136   */
9137  if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
9138  {
9139    smsatSetSensePayload( pSense,
9140                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9141                          0,
9142                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9143                          satIOContext);
9144    sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9145
9146    /*smEnqueueIO(smRoot, satIOContext);*/
9147
9148    tdsmIOCompletedCB( smRoot,
9149                       smIORequest,
9150                       smIOSuccess,
9151                       SCSI_STAT_CHECK_CONDITION,
9152                       satIOContext->pSmSenseData,
9153                       satIOContext->interruptContext );
9154
9155    SM_DBG1(("smsatRequestSense: DESC bit is set, which we don't support!!!\n"));
9156    return SM_RC_SUCCESS;
9157  }
9158
9159
9160  if (pSatDevData->satSMARTEnabled == agTRUE)
9161  {
9162    /* sends SMART RETURN STATUS */
9163    fis->h.fisType        = 0x27;                   /* Reg host to device */
9164    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9165
9166    fis->h.command        = SAT_SMART;               /* 0xB0 */
9167    fis->h.features       = SAT_SMART_RETURN_STATUS; /* FIS features */
9168    fis->d.featuresExp    = 0;                      /* FIS reserve */
9169    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9170    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9171    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9172    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9173    fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
9174    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9175    fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
9176    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9177    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
9178    fis->d.control        = 0;                      /* FIS HOB bit clear */
9179    fis->d.reserved4      = 0;
9180    fis->d.reserved5      = 0;
9181
9182    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9183    /* Initialize CB for SATA completion.
9184     */
9185    satIOContext->satCompleteCB = &smsatRequestSenseCB;
9186
9187    /*
9188     * Prepare SGL and send FIS to LL layer.
9189     */
9190    satIOContext->reqType = agRequestType;       /* Save it */
9191
9192    status = smsataLLIOStart( smRoot,
9193                              smIORequest,
9194                              smDeviceHandle,
9195                              smScsiRequest,
9196                              satIOContext);
9197
9198    SM_DBG4(("smsatRequestSense: if return, status %d\n", status));
9199    return (status);
9200  }
9201  else
9202  {
9203    /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE
9204      then call satRequestSense2 */
9205
9206    SM_DBG4(("smsatRequestSense: before satIntIo %p\n", satIntIo));
9207    /* allocate iocontext */
9208    satIntIo = smsatAllocIntIoResource( smRoot,
9209                                        smIORequest, /* original request */
9210                                        pSatDevData,
9211                                        smScsiRequest->scsiCmnd.expDataLength,
9212                                        satIntIo);
9213
9214    SM_DBG4(("smsatRequestSense: after satIntIo %p\n", satIntIo));
9215
9216    if (satIntIo == agNULL)
9217    {
9218      /* failed during sending SMART RETURN STATUS */
9219      smsatSetSensePayload( pSense,
9220                            SCSI_SNSKEY_NO_SENSE,
9221                            0,
9222                            SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
9223                            satIOContext);
9224      sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9225
9226      /*smEnqueueIO(smRoot, satIOContext);*/
9227
9228      tdsmIOCompletedCB( smRoot,
9229                         smIORequest,
9230                         smIOSuccess,
9231                         SCSI_STAT_GOOD,
9232                         agNULL,
9233                         satIOContext->interruptContext );
9234
9235      SM_DBG1(("smsatRequestSense: else fail 1!!!\n"));
9236      return SM_RC_SUCCESS;
9237    } /* end of memory allocation failure */
9238
9239
9240    /*
9241     * Need to initialize all the fields within satIOContext except
9242     * reqType and satCompleteCB which will be set depending on cmd.
9243     */
9244
9245    if (satIntIo == agNULL)
9246    {
9247      SM_DBG4(("smsatRequestSense: satIntIo is NULL\n"));
9248    }
9249    else
9250    {
9251      SM_DBG4(("smsatRequestSense: satIntIo is NOT NULL\n"));
9252    }
9253    /* use this --- tttttthe one the same */
9254
9255
9256    satIntIo->satOrgSmIORequest = smIORequest;
9257    smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
9258    satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);
9259
9260    satIOContext2->pSatDevData   = pSatDevData;
9261    satIOContext2->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
9262    satIOContext2->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
9263    satIOContext2->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
9264    satIOContext2->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
9265    satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;
9266    satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
9267    satIOContext2->interruptContext = satIOContext->interruptContext;
9268    satIOContext2->satIntIoContext  = satIntIo;
9269    satIOContext2->psmDeviceHandle = smDeviceHandle;
9270    satIOContext2->satOrgIOContext = satIOContext;
9271
9272    SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len));
9273
9274    SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper));
9275
9276    SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower));
9277
9278    SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type));
9279
9280    status = smsatRequestSense_1( smRoot,
9281                                  &(satIntIo->satIntSmIORequest),
9282                                  smDeviceHandle,
9283                                  &(satIntIo->satIntSmScsiXchg),
9284                                  satIOContext2);
9285
9286    if (status != SM_RC_SUCCESS)
9287    {
9288      smsatFreeIntIoResource( smRoot,
9289                              pSatDevData,
9290                              satIntIo);
9291
9292      /* failed during sending SMART RETURN STATUS */
9293      smsatSetSensePayload( pSense,
9294                            SCSI_SNSKEY_NO_SENSE,
9295                            0,
9296                            SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
9297                            satIOContext);
9298      sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9299
9300      /*smEnqueueIO(smRoot, satIOContext);*/
9301
9302      tdsmIOCompletedCB( smRoot,
9303                         smIORequest,
9304                         smIOSuccess,
9305                         SCSI_STAT_CHECK_CONDITION,
9306                         agNULL,
9307                         satIOContext->interruptContext );
9308
9309      SM_DBG1(("smsatRequestSense: else fail 2!!!\n"));
9310      return SM_RC_SUCCESS;
9311    }
9312    SM_DBG4(("smsatRequestSense: else return success\n"));
9313    return SM_RC_SUCCESS;
9314  }
9315}
9316
9317osGLOBAL bit32
9318smsatRequestSense_1(
9319                    smRoot_t                  *smRoot,
9320                    smIORequest_t             *smIORequest,
9321                    smDeviceHandle_t          *smDeviceHandle,
9322                    smScsiInitiatorRequest_t  *smScsiRequest,
9323                    smSatIOContext_t            *satIOContext
9324                   )
9325{
9326  /*
9327    sends SAT_CHECK_POWER_MODE
9328  */
9329  bit32                     status;
9330  bit32                     agRequestType;
9331  agsaFisRegHostToDevice_t  *fis;
9332
9333  fis               = satIOContext->pFis;
9334  SM_DBG5(("smsatRequestSense_1: start\n"));
9335  /*
9336   * Send the ATA CHECK POWER MODE command.
9337   */
9338  fis->h.fisType        = 0x27;                   /* Reg host to device */
9339  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9340  fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
9341  fis->h.features       = 0;
9342  fis->d.lbaLow         = 0;
9343  fis->d.lbaMid         = 0;
9344  fis->d.lbaHigh        = 0;
9345  fis->d.device         = 0;
9346  fis->d.lbaLowExp      = 0;
9347  fis->d.lbaMidExp      = 0;
9348  fis->d.lbaHighExp     = 0;
9349  fis->d.featuresExp    = 0;
9350  fis->d.sectorCount    = 0;
9351  fis->d.sectorCountExp = 0;
9352  fis->d.reserved4      = 0;
9353  fis->d.control        = 0;                      /* FIS HOB bit clear */
9354  fis->d.reserved5      = 0;
9355
9356  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9357
9358  /* Initialize CB for SATA completion.
9359   */
9360  satIOContext->satCompleteCB = &smsatRequestSenseCB;
9361
9362  /*
9363   * Prepare SGL and send FIS to LL layer.
9364   */
9365  satIOContext->reqType = agRequestType;       /* Save it */
9366
9367
9368  SM_DBG4(("smsatRequestSense_1: smSgl1.len %d\n", smScsiRequest->smSgl1.len));
9369
9370  SM_DBG4(("smsatRequestSense_1: smSgl1.upper %d\n", smScsiRequest->smSgl1.upper));
9371
9372  SM_DBG4(("smsatRequestSense_1: smSgl1.lower %d\n", smScsiRequest->smSgl1.lower));
9373
9374  SM_DBG4(("smsatRequestSense_1: smSgl1.type %d\n", smScsiRequest->smSgl1.type));
9375
9376  //  smhexdump("smsatRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
9377
9378  status = smsataLLIOStart( smRoot,
9379                            smIORequest,
9380                            smDeviceHandle,
9381                            smScsiRequest,
9382                            satIOContext);
9383
9384
9385
9386  return status;
9387}
9388
9389osGLOBAL bit32
9390smsatModeSense6(
9391                smRoot_t                  *smRoot,
9392                smIORequest_t             *smIORequest,
9393                smDeviceHandle_t          *smDeviceHandle,
9394                smScsiInitiatorRequest_t  *smScsiRequest,
9395                smSatIOContext_t            *satIOContext
9396               )
9397{
9398  smScsiRspSense_t        *pSense;
9399  bit32                   allocationLen;
9400  smIniScsiCmnd_t         *scsiCmnd;
9401  bit32                   pageSupported;
9402  bit8                    page;
9403  bit8                    *pModeSense;    /* Mode Sense data buffer */
9404  smDeviceData_t          *pSatDevData;
9405  bit8                    PC;
9406  bit8                    AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN];
9407  bit8                    Control[MODE_SENSE6_CONTROL_PAGE_LEN];
9408  bit8                    RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN];
9409  bit8                    Caching[MODE_SENSE6_CACHING_LEN];
9410  bit8                    InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN];
9411  bit8                    lenRead = 0;
9412
9413
9414  pSense      = satIOContext->pSense;
9415  scsiCmnd    = &smScsiRequest->scsiCmnd;
9416  pModeSense  = (bit8 *) smScsiRequest->sglVirtualAddr;
9417  pSatDevData = satIOContext->pSatDevData;
9418
9419  //smhexdump("smsatModeSense6", (bit8 *)scsiCmnd->cdb, 6);
9420  SM_DBG5(("smsatModeSense6: start\n"));
9421  /* checking CONTROL */
9422  /* NACA == 1 or LINK == 1*/
9423  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9424  {
9425    smsatSetSensePayload( pSense,
9426                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9427                          0,
9428                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9429                          satIOContext);
9430   /*smEnqueueIO(smRoot, satIOContext);*/
9431   tdsmIOCompletedCB( smRoot,
9432                       smIORequest,
9433                       smIOSuccess,
9434                       SCSI_STAT_CHECK_CONDITION,
9435                       satIOContext->pSmSenseData,
9436                       satIOContext->interruptContext );
9437    SM_DBG1(("smsatModeSense6: return control!!!\n"));
9438    return SM_RC_SUCCESS;
9439  }
9440  /* checking PC(Page Control)
9441     SAT revion 8, 8.5.3 p33 and 10.1.2, p66
9442  */
9443  PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
9444  if (PC != 0)
9445  {
9446    smsatSetSensePayload( pSense,
9447                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9448                          0,
9449                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9450                          satIOContext);
9451    /*smEnqueueIO(smRoot, satIOContext);*/
9452    tdsmIOCompletedCB( smRoot,
9453                       smIORequest,
9454                       smIOSuccess,
9455                       SCSI_STAT_CHECK_CONDITION,
9456                       satIOContext->pSmSenseData,
9457                       satIOContext->interruptContext );
9458    SM_DBG1(("smsatModeSense6: return due to PC value pc 0x%x!!!\n", PC >> 6));
9459    return SM_RC_SUCCESS;
9460  }
9461  /* reading PAGE CODE */
9462  page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
9463
9464
9465  SM_DBG5(("smsatModeSense6: page=0x%x\n", page));
9466
9467  allocationLen = scsiCmnd->cdb[4];
9468  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
9469    /*
9470    Based on page code value, returns a corresponding mode page
9471    note: no support for subpage
9472  */
9473  switch(page)
9474  {
9475    case MODESENSE_RETURN_ALL_PAGES:
9476    case MODESENSE_CONTROL_PAGE: /* control */
9477    case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
9478    case MODESENSE_CACHING: /* caching */
9479    case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
9480      pageSupported = agTRUE;
9481      break;
9482    case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
9483    default:
9484      pageSupported = agFALSE;
9485      break;
9486  }
9487
9488  if (pageSupported == agFALSE)
9489  {
9490
9491    SM_DBG1(("smsatModeSense6 *** ERROR *** not supported page 0x%x did %d!!!\n",
9492        page, pSatDevData->id));
9493
9494    smsatSetSensePayload( pSense,
9495                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9496                          0,
9497                          SCSI_SNSCODE_INVALID_COMMAND,
9498                          satIOContext);
9499
9500    /*smEnqueueIO(smRoot, satIOContext);*/
9501
9502    tdsmIOCompletedCB( smRoot,
9503                       smIORequest,
9504                       smIOSuccess,
9505                       SCSI_STAT_CHECK_CONDITION,
9506                       satIOContext->pSmSenseData,
9507                       satIOContext->interruptContext );
9508    return SM_RC_SUCCESS;
9509  }
9510
9511  switch(page)
9512  {
9513  case MODESENSE_RETURN_ALL_PAGES:
9514    lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
9515    break;
9516  case MODESENSE_CONTROL_PAGE: /* control */
9517    lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CONTROL_PAGE_LEN);
9518    break;
9519  case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
9520    lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
9521    break;
9522  case MODESENSE_CACHING: /* caching */
9523    lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CACHING_LEN);
9524    break;
9525  case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
9526    lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
9527    break;
9528  default:
9529    SM_DBG1(("smsatModeSense6: default error page %d!!!\n", page));
9530    break;
9531  }
9532
9533  if (page == MODESENSE_RETURN_ALL_PAGES)
9534  {
9535    SM_DBG5(("smsatModeSense6: MODESENSE_RETURN_ALL_PAGES\n"));
9536    AllPages[0] = (bit8)(lenRead - 1);
9537    AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */
9538    AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9539    AllPages[3] = 0x08; /* block descriptor length */
9540
9541    /*
9542     * Fill-up direct-access device block-descriptor, SAT, Table 19
9543     */
9544
9545    /* density code */
9546    AllPages[4]  = 0x04; /* density-code : reserved for direct-access */
9547    /* number of blocks */
9548    AllPages[5]  = 0x00; /* unspecified */
9549    AllPages[6]  = 0x00; /* unspecified */
9550    AllPages[7]  = 0x00; /* unspecified */
9551    /* reserved */
9552    AllPages[8]  = 0x00; /* reserved */
9553    /* Block size */
9554    AllPages[9]  = 0x00;
9555    AllPages[10] = 0x02;   /* Block size is always 512 bytes */
9556    AllPages[11] = 0x00;
9557
9558    /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
9559    AllPages[12] = 0x01; /* page code */
9560    AllPages[13] = 0x0A; /* page length */
9561    AllPages[14] = 0x40; /* ARRE is set */
9562    AllPages[15] = 0x00;
9563    AllPages[16] = 0x00;
9564    AllPages[17] = 0x00;
9565    AllPages[18] = 0x00;
9566    AllPages[19] = 0x00;
9567    AllPages[20] = 0x00;
9568    AllPages[21] = 0x00;
9569    AllPages[22] = 0x00;
9570    AllPages[23] = 0x00;
9571    /* MODESENSE_CACHING */
9572    AllPages[24] = 0x08; /* page code */
9573    AllPages[25] = 0x12; /* page length */
9574    if (pSatDevData->satWriteCacheEnabled == agTRUE)
9575    {
9576      AllPages[26] = 0x04;/* WCE bit is set */
9577    }
9578    else
9579    {
9580      AllPages[26] = 0x00;/* WCE bit is NOT set */
9581    }
9582
9583    AllPages[27] = 0x00;
9584    AllPages[28] = 0x00;
9585    AllPages[29] = 0x00;
9586    AllPages[30] = 0x00;
9587    AllPages[31] = 0x00;
9588    AllPages[32] = 0x00;
9589    AllPages[33] = 0x00;
9590    AllPages[34] = 0x00;
9591    AllPages[35] = 0x00;
9592    if (pSatDevData->satLookAheadEnabled == agTRUE)
9593    {
9594      AllPages[36] = 0x00;/* DRA bit is NOT set */
9595    }
9596    else
9597    {
9598      AllPages[36] = 0x20;/* DRA bit is set */
9599    }
9600    AllPages[37] = 0x00;
9601    AllPages[38] = 0x00;
9602    AllPages[39] = 0x00;
9603    AllPages[40] = 0x00;
9604    AllPages[41] = 0x00;
9605    AllPages[42] = 0x00;
9606    AllPages[43] = 0x00;
9607    /* MODESENSE_CONTROL_PAGE */
9608    AllPages[44] = 0x0A; /* page code */
9609    AllPages[45] = 0x0A; /* page length */
9610    AllPages[46] = 0x02; /* only GLTSD bit is set */
9611    if (pSatDevData->satNCQ == agTRUE)
9612    {
9613      AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
9614    }
9615    else
9616    {
9617      AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
9618    }
9619    AllPages[48] = 0x00;
9620    AllPages[49] = 0x00;
9621    AllPages[50] = 0x00; /* obsolete */
9622    AllPages[51] = 0x00; /* obsolete */
9623    AllPages[52] = 0xFF; /* Busy Timeout Period */
9624    AllPages[53] = 0xFF; /* Busy Timeout Period */
9625    AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */
9626    AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */
9627    /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
9628    AllPages[56] = 0x1C; /* page code */
9629    AllPages[57] = 0x0A; /* page length */
9630    if (pSatDevData->satSMARTEnabled == agTRUE)
9631    {
9632      AllPages[58] = 0x00;/* DEXCPT bit is NOT set */
9633    }
9634    else
9635    {
9636      AllPages[58] = 0x08;/* DEXCPT bit is set */
9637    }
9638    AllPages[59] = 0x00; /* We don't support MRIE */
9639    AllPages[60] = 0x00; /* Interval timer vendor-specific */
9640    AllPages[61] = 0x00;
9641    AllPages[62] = 0x00;
9642    AllPages[63] = 0x00;
9643    AllPages[64] = 0x00; /* REPORT-COUNT */
9644    AllPages[65] = 0x00;
9645    AllPages[66] = 0x00;
9646    AllPages[67] = 0x00;
9647
9648    sm_memcpy(pModeSense, &AllPages, lenRead);
9649  }
9650  else if (page == MODESENSE_CONTROL_PAGE)
9651  {
9652    SM_DBG5(("smsatModeSense6: MODESENSE_CONTROL_PAGE\n"));
9653    Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1;
9654    Control[1] = 0x00; /* default medium type (currently mounted medium type) */
9655    Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9656    Control[3] = 0x08; /* block descriptor length */
9657    /*
9658     * Fill-up direct-access device block-descriptor, SAT, Table 19
9659     */
9660
9661    /* density code */
9662    Control[4]  = 0x04; /* density-code : reserved for direct-access */
9663    /* number of blocks */
9664    Control[5]  = 0x00; /* unspecified */
9665    Control[6]  = 0x00; /* unspecified */
9666    Control[7]  = 0x00; /* unspecified */
9667    /* reserved */
9668    Control[8]  = 0x00; /* reserved */
9669    /* Block size */
9670    Control[9]  = 0x00;
9671    Control[10] = 0x02;   /* Block size is always 512 bytes */
9672    Control[11] = 0x00;
9673    /*
9674     * Fill-up control mode page, SAT, Table 65
9675     */
9676    Control[12] = 0x0A; /* page code */
9677    Control[13] = 0x0A; /* page length */
9678    Control[14] = 0x02; /* only GLTSD bit is set */
9679    if (pSatDevData->satNCQ == agTRUE)
9680    {
9681      Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
9682    }
9683    else
9684    {
9685      Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
9686    }
9687    Control[16] = 0x00;
9688    Control[17] = 0x00;
9689    Control[18] = 0x00; /* obsolete */
9690    Control[19] = 0x00; /* obsolete */
9691    Control[20] = 0xFF; /* Busy Timeout Period */
9692    Control[21] = 0xFF; /* Busy Timeout Period */
9693    Control[22] = 0x00; /* we don't support non-000b value for the self-test code */
9694    Control[23] = 0x00; /* we don't support non-000b value for the self-test code */
9695
9696    sm_memcpy(pModeSense, &Control, lenRead);
9697
9698  }
9699  else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
9700  {
9701    SM_DBG5(("smsatModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
9702    RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1;
9703    RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */
9704    RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9705    RWErrorRecovery[3] = 0x08; /* block descriptor length */
9706    /*
9707     * Fill-up direct-access device block-descriptor, SAT, Table 19
9708     */
9709
9710    /* density code */
9711    RWErrorRecovery[4]  = 0x04; /* density-code : reserved for direct-access */
9712    /* number of blocks */
9713    RWErrorRecovery[5]  = 0x00; /* unspecified */
9714    RWErrorRecovery[6]  = 0x00; /* unspecified */
9715    RWErrorRecovery[7]  = 0x00; /* unspecified */
9716    /* reserved */
9717    RWErrorRecovery[8]  = 0x00; /* reserved */
9718    /* Block size */
9719    RWErrorRecovery[9]  = 0x00;
9720    RWErrorRecovery[10] = 0x02;   /* Block size is always 512 bytes */
9721    RWErrorRecovery[11] = 0x00;
9722    /*
9723     * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
9724     */
9725    RWErrorRecovery[12] = 0x01; /* page code */
9726    RWErrorRecovery[13] = 0x0A; /* page length */
9727    RWErrorRecovery[14] = 0x40; /* ARRE is set */
9728    RWErrorRecovery[15] = 0x00;
9729    RWErrorRecovery[16] = 0x00;
9730    RWErrorRecovery[17] = 0x00;
9731    RWErrorRecovery[18] = 0x00;
9732    RWErrorRecovery[19] = 0x00;
9733    RWErrorRecovery[20] = 0x00;
9734    RWErrorRecovery[21] = 0x00;
9735    RWErrorRecovery[22] = 0x00;
9736    RWErrorRecovery[23] = 0x00;
9737
9738    sm_memcpy(pModeSense, &RWErrorRecovery, lenRead);
9739
9740  }
9741  else if (page == MODESENSE_CACHING)
9742  {
9743    SM_DBG5(("smsatModeSense6: MODESENSE_CACHING\n"));
9744    /* special case */
9745    if (allocationLen == 4 && page == MODESENSE_CACHING)
9746    {
9747      SM_DBG5(("smsatModeSense6: linux 2.6.8.24 support\n"));
9748
9749      Caching[0] = 0x20 - 1; /* 32 - 1 */
9750      Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
9751      Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9752      Caching[3] = 0x08; /* block descriptor length */
9753
9754      sm_memcpy(pModeSense, &Caching, 4);
9755      /*smEnqueueIO(smRoot, satIOContext);*/
9756
9757      tdsmIOCompletedCB( smRoot,
9758                         smIORequest,
9759                         smIOSuccess,
9760                         SCSI_STAT_GOOD,
9761                         agNULL,
9762                         satIOContext->interruptContext);
9763      return SM_RC_SUCCESS;
9764    }
9765    Caching[0] = MODE_SENSE6_CACHING_LEN - 1;
9766    Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
9767    Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9768    Caching[3] = 0x08; /* block descriptor length */
9769    /*
9770     * Fill-up direct-access device block-descriptor, SAT, Table 19
9771     */
9772
9773    /* density code */
9774    Caching[4]  = 0x04; /* density-code : reserved for direct-access */
9775    /* number of blocks */
9776    Caching[5]  = 0x00; /* unspecified */
9777    Caching[6]  = 0x00; /* unspecified */
9778    Caching[7]  = 0x00; /* unspecified */
9779    /* reserved */
9780    Caching[8]  = 0x00; /* reserved */
9781    /* Block size */
9782    Caching[9]  = 0x00;
9783    Caching[10] = 0x02;   /* Block size is always 512 bytes */
9784    Caching[11] = 0x00;
9785    /*
9786     * Fill-up Caching mode page, SAT, Table 67
9787     */
9788    /* length 20 */
9789    Caching[12] = 0x08; /* page code */
9790    Caching[13] = 0x12; /* page length */
9791    if (pSatDevData->satWriteCacheEnabled == agTRUE)
9792    {
9793      Caching[14] = 0x04;/* WCE bit is set */
9794    }
9795    else
9796    {
9797      Caching[14] = 0x00;/* WCE bit is NOT set */
9798    }
9799
9800    Caching[15] = 0x00;
9801    Caching[16] = 0x00;
9802    Caching[17] = 0x00;
9803    Caching[18] = 0x00;
9804    Caching[19] = 0x00;
9805    Caching[20] = 0x00;
9806    Caching[21] = 0x00;
9807    Caching[22] = 0x00;
9808    Caching[23] = 0x00;
9809    if (pSatDevData->satLookAheadEnabled == agTRUE)
9810    {
9811      Caching[24] = 0x00;/* DRA bit is NOT set */
9812    }
9813    else
9814    {
9815      Caching[24] = 0x20;/* DRA bit is set */
9816    }
9817    Caching[25] = 0x00;
9818    Caching[26] = 0x00;
9819    Caching[27] = 0x00;
9820    Caching[28] = 0x00;
9821    Caching[29] = 0x00;
9822    Caching[30] = 0x00;
9823    Caching[31] = 0x00;
9824
9825    sm_memcpy(pModeSense, &Caching, lenRead);
9826
9827  }
9828  else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
9829  {
9830    SM_DBG5(("smsatModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
9831    InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1;
9832    InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */
9833    InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9834    InfoExceptionCtrl[3] = 0x08; /* block descriptor length */
9835    /*
9836     * Fill-up direct-access device block-descriptor, SAT, Table 19
9837     */
9838
9839    /* density code */
9840    InfoExceptionCtrl[4]  = 0x04; /* density-code : reserved for direct-access */
9841    /* number of blocks */
9842    InfoExceptionCtrl[5]  = 0x00; /* unspecified */
9843    InfoExceptionCtrl[6]  = 0x00; /* unspecified */
9844    InfoExceptionCtrl[7]  = 0x00; /* unspecified */
9845    /* reserved */
9846    InfoExceptionCtrl[8]  = 0x00; /* reserved */
9847    /* Block size */
9848    InfoExceptionCtrl[9]  = 0x00;
9849    InfoExceptionCtrl[10] = 0x02;   /* Block size is always 512 bytes */
9850    InfoExceptionCtrl[11] = 0x00;
9851    /*
9852     * Fill-up informational-exceptions control mode page, SAT, Table 68
9853     */
9854    InfoExceptionCtrl[12] = 0x1C; /* page code */
9855    InfoExceptionCtrl[13] = 0x0A; /* page length */
9856     if (pSatDevData->satSMARTEnabled == agTRUE)
9857    {
9858      InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */
9859    }
9860    else
9861    {
9862      InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */
9863    }
9864    InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */
9865    InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */
9866    InfoExceptionCtrl[17] = 0x00;
9867    InfoExceptionCtrl[18] = 0x00;
9868    InfoExceptionCtrl[19] = 0x00;
9869    InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */
9870    InfoExceptionCtrl[21] = 0x00;
9871    InfoExceptionCtrl[22] = 0x00;
9872    InfoExceptionCtrl[23] = 0x00;
9873    sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
9874
9875  }
9876  else
9877  {
9878    /* Error */
9879    SM_DBG1(("smsatModeSense6: Error page %d!!!\n", page));
9880    smsatSetSensePayload( pSense,
9881                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9882                          0,
9883                          SCSI_SNSCODE_INVALID_COMMAND,
9884                          satIOContext);
9885
9886    /*smEnqueueIO(smRoot, satIOContext);*/
9887
9888    tdsmIOCompletedCB( smRoot,
9889                       smIORequest,
9890                       smIOSuccess,
9891                       SCSI_STAT_CHECK_CONDITION,
9892                       satIOContext->pSmSenseData,
9893                       satIOContext->interruptContext );
9894    return SM_RC_SUCCESS;
9895  }
9896
9897  /* there can be only underrun not overrun in error case */
9898  if (allocationLen > lenRead)
9899  {
9900    SM_DBG6(("smsatModeSense6 reporting underrun lenRead=0x%x allocationLen=0x%x\n", lenRead, allocationLen));
9901
9902    /*smEnqueueIO(smRoot, satIOContext);*/
9903
9904    tdsmIOCompletedCB( smRoot,
9905                       smIORequest,
9906                       smIOUnderRun,
9907                       allocationLen - lenRead,
9908                       agNULL,
9909                       satIOContext->interruptContext );
9910
9911
9912  }
9913  else
9914  {
9915    /*smEnqueueIO(smRoot, satIOContext);*/
9916
9917    tdsmIOCompletedCB( smRoot,
9918                       smIORequest,
9919                       smIOSuccess,
9920                       SCSI_STAT_GOOD,
9921                       agNULL,
9922                       satIOContext->interruptContext);
9923  }
9924
9925  return SM_RC_SUCCESS;
9926
9927}
9928
9929osGLOBAL bit32
9930smsatModeSense10(
9931                  smRoot_t                  *smRoot,
9932                  smIORequest_t             *smIORequest,
9933                  smDeviceHandle_t          *smDeviceHandle,
9934                  smScsiInitiatorRequest_t  *smScsiRequest,
9935                  smSatIOContext_t            *satIOContext
9936                 )
9937{
9938  smScsiRspSense_t        *pSense;
9939  bit32                   allocationLen;
9940  smIniScsiCmnd_t         *scsiCmnd;
9941  bit32                   pageSupported;
9942  bit8                    page;
9943  bit8                    *pModeSense;    /* Mode Sense data buffer */
9944  smDeviceData_t          *pSatDevData;
9945  bit8                    PC; /* page control */
9946  bit8                    LLBAA; /* Long LBA Accepted */
9947  bit32                   index;
9948  bit8                    AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN];
9949  bit8                    Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN];
9950  bit8                    RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN];
9951  bit8                    Caching[MODE_SENSE10_CACHING_LLBAA_LEN];
9952  bit8                    InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN];
9953  bit8                    lenRead = 0;
9954
9955  pSense      = satIOContext->pSense;
9956  scsiCmnd    = &smScsiRequest->scsiCmnd;
9957  pModeSense  = (bit8 *) smScsiRequest->sglVirtualAddr;
9958  pSatDevData = satIOContext->pSatDevData;
9959  SM_DBG5(("smsatModeSense10: start\n"));
9960  /* checking CONTROL */
9961  /* NACA == 1 or LINK == 1*/
9962  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
9963  {
9964    smsatSetSensePayload( pSense,
9965                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9966                          0,
9967                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9968                          satIOContext);
9969
9970    /*smEnqueueIO(smRoot, satIOContext);*/
9971
9972    tdsmIOCompletedCB( smRoot,
9973                       smIORequest,
9974                       smIOSuccess,
9975                       SCSI_STAT_CHECK_CONDITION,
9976                       satIOContext->pSmSenseData,
9977                       satIOContext->interruptContext );
9978
9979    SM_DBG1(("smsatModeSense10: return control!!!\n"));
9980    return SM_RC_SUCCESS;
9981  }
9982
9983  /* checking PC(Page Control)
9984     SAT revion 8, 8.5.3 p33 and 10.1.2, p66
9985  */
9986  PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
9987  if (PC != 0)
9988  {
9989    smsatSetSensePayload( pSense,
9990                          SCSI_SNSKEY_ILLEGAL_REQUEST,
9991                          0,
9992                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9993                          satIOContext);
9994
9995    /*smEnqueueIO(smRoot, satIOContext);*/
9996
9997    tdsmIOCompletedCB( smRoot,
9998                       smIORequest,
9999                       smIOSuccess,
10000                       SCSI_STAT_CHECK_CONDITION,
10001                       satIOContext->pSmSenseData,
10002                       satIOContext->interruptContext );
10003
10004    SM_DBG1(("smsatModeSense10: return due to PC value pc 0x%x!!!\n", PC));
10005    return SM_RC_SUCCESS;
10006  }
10007
10008  /* finding LLBAA bit */
10009  LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
10010
10011  /* reading PAGE CODE */
10012  page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
10013  SM_DBG5(("smsatModeSense10: page=0x%x, did %d\n", page, pSatDevData->id));
10014  allocationLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
10015  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
10016
10017  /*
10018    Based on page code value, returns a corresponding mode page
10019    note: no support for subpage
10020  */
10021  switch(page)
10022  {
10023    case MODESENSE_RETURN_ALL_PAGES: /* return all pages */
10024    case MODESENSE_CONTROL_PAGE: /* control */
10025    case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
10026    case MODESENSE_CACHING: /* caching */
10027    case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
10028      pageSupported = agTRUE;
10029      break;
10030    case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
10031    default:
10032      pageSupported = agFALSE;
10033      break;
10034  }
10035  if (pageSupported == agFALSE)
10036  {
10037    SM_DBG1(("smsatModeSense10 *** ERROR *** not supported page 0x%x did %d!!!\n", page, pSatDevData->id));
10038
10039    smsatSetSensePayload( pSense,
10040                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10041                          0,
10042                          SCSI_SNSCODE_INVALID_COMMAND,
10043                          satIOContext);
10044    /*smEnqueueIO(smRoot, satIOContext);*/
10045    tdsmIOCompletedCB( smRoot,
10046                       smIORequest,
10047                       smIOSuccess,
10048                       SCSI_STAT_CHECK_CONDITION,
10049                       satIOContext->pSmSenseData,
10050                       satIOContext->interruptContext );
10051    return SM_RC_SUCCESS;
10052  }
10053  switch(page)
10054  {
10055  case MODESENSE_RETURN_ALL_PAGES:
10056    if (LLBAA)
10057    {
10058      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
10059    }
10060    else
10061    {
10062      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
10063    }
10064    break;
10065  case MODESENSE_CONTROL_PAGE: /* control */
10066    if (LLBAA)
10067    {
10068      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
10069    }
10070    else
10071    {
10072      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LEN);
10073    }
10074    break;
10075  case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
10076    if (LLBAA)
10077    {
10078      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
10079    }
10080    else
10081    {
10082      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
10083    }
10084    break;
10085  case MODESENSE_CACHING: /* caching */
10086    if (LLBAA)
10087    {
10088      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LLBAA_LEN);
10089    }
10090    else
10091    {
10092      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LEN);
10093    }
10094    break;
10095  case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
10096    if (LLBAA)
10097    {
10098      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
10099    }
10100    else
10101    {
10102      lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
10103    }
10104    break;
10105  default:
10106    SM_DBG1(("smsatModeSense10: default error page %d!!!\n", page));
10107    break;
10108  }
10109
10110  if (page == MODESENSE_RETURN_ALL_PAGES)
10111  {
10112    SM_DBG5(("smsatModeSense10: MODESENSE_RETURN_ALL_PAGES\n"));
10113    AllPages[0] = 0;
10114    AllPages[1] = (bit8)(lenRead - 2);
10115    AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10116    AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10117    if (LLBAA)
10118    {
10119      AllPages[4] = 0x00; /* reserved and LONGLBA */
10120      AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */
10121    }
10122    else
10123    {
10124      AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10125    }
10126    AllPages[5] = 0x00; /* reserved */
10127    AllPages[6] = 0x00; /* block descriptot length */
10128    if (LLBAA)
10129    {
10130      AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10131    }
10132    else
10133    {
10134      AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10135    }
10136
10137    /*
10138     * Fill-up direct-access device block-descriptor, SAT, Table 19
10139     */
10140
10141    if (LLBAA)
10142    {
10143      /* density code */
10144      AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
10145      /* number of blocks */
10146      AllPages[9]   = 0x00; /* unspecified */
10147      AllPages[10]  = 0x00; /* unspecified */
10148      AllPages[11]  = 0x00; /* unspecified */
10149      AllPages[12]  = 0x00; /* unspecified */
10150      AllPages[13]  = 0x00; /* unspecified */
10151      AllPages[14]  = 0x00; /* unspecified */
10152      AllPages[15]  = 0x00; /* unspecified */
10153      /* reserved */
10154      AllPages[16]  = 0x00; /* reserved */
10155      AllPages[17]  = 0x00; /* reserved */
10156      AllPages[18]  = 0x00; /* reserved */
10157      AllPages[19]  = 0x00; /* reserved */
10158      /* Block size */
10159      AllPages[20]  = 0x00;
10160      AllPages[21]  = 0x00;
10161      AllPages[22]  = 0x02;   /* Block size is always 512 bytes */
10162      AllPages[23]  = 0x00;
10163    }
10164    else
10165    {
10166      /* density code */
10167      AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
10168      /* number of blocks */
10169      AllPages[9]   = 0x00; /* unspecified */
10170      AllPages[10]  = 0x00; /* unspecified */
10171      AllPages[11]  = 0x00; /* unspecified */
10172      /* reserved */
10173      AllPages[12]  = 0x00; /* reserved */
10174      /* Block size */
10175      AllPages[13]  = 0x00;
10176      AllPages[14]  = 0x02;   /* Block size is always 512 bytes */
10177      AllPages[15]  = 0x00;
10178    }
10179
10180    if (LLBAA)
10181    {
10182      index = 24;
10183    }
10184    else
10185    {
10186      index = 16;
10187    }
10188    /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
10189    AllPages[index+0] = 0x01; /* page code */
10190    AllPages[index+1] = 0x0A; /* page length */
10191    AllPages[index+2] = 0x40; /* ARRE is set */
10192    AllPages[index+3] = 0x00;
10193    AllPages[index+4] = 0x00;
10194    AllPages[index+5] = 0x00;
10195    AllPages[index+6] = 0x00;
10196    AllPages[index+7] = 0x00;
10197    AllPages[index+8] = 0x00;
10198    AllPages[index+9] = 0x00;
10199    AllPages[index+10] = 0x00;
10200    AllPages[index+11] = 0x00;
10201
10202    /* MODESENSE_CACHING */
10203    /*
10204     * Fill-up Caching mode page, SAT, Table 67
10205     */
10206    /* length 20 */
10207    AllPages[index+12] = 0x08; /* page code */
10208    AllPages[index+13] = 0x12; /* page length */
10209    if (pSatDevData->satWriteCacheEnabled == agTRUE)
10210    {
10211      AllPages[index+14] = 0x04;/* WCE bit is set */
10212    }
10213    else
10214    {
10215      AllPages[index+14] = 0x00;/* WCE bit is NOT set */
10216    }
10217
10218    AllPages[index+15] = 0x00;
10219    AllPages[index+16] = 0x00;
10220    AllPages[index+17] = 0x00;
10221    AllPages[index+18] = 0x00;
10222    AllPages[index+19] = 0x00;
10223    AllPages[index+20] = 0x00;
10224    AllPages[index+21] = 0x00;
10225    AllPages[index+22] = 0x00;
10226    AllPages[index+23] = 0x00;
10227    if (pSatDevData->satLookAheadEnabled == agTRUE)
10228    {
10229      AllPages[index+24] = 0x00;/* DRA bit is NOT set */
10230    }
10231    else
10232    {
10233      AllPages[index+24] = 0x20;/* DRA bit is set */
10234    }
10235    AllPages[index+25] = 0x00;
10236    AllPages[index+26] = 0x00;
10237    AllPages[index+27] = 0x00;
10238    AllPages[index+28] = 0x00;
10239    AllPages[index+29] = 0x00;
10240    AllPages[index+30] = 0x00;
10241    AllPages[index+31] = 0x00;
10242
10243    /* MODESENSE_CONTROL_PAGE */
10244    /*
10245     * Fill-up control mode page, SAT, Table 65
10246     */
10247    AllPages[index+32] = 0x0A; /* page code */
10248    AllPages[index+33] = 0x0A; /* page length */
10249    AllPages[index+34] = 0x02; /* only GLTSD bit is set */
10250    if (pSatDevData->satNCQ == agTRUE)
10251    {
10252      AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
10253    }
10254    else
10255    {
10256      AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
10257    }
10258    AllPages[index+36] = 0x00;
10259    AllPages[index+37] = 0x00;
10260    AllPages[index+38] = 0x00; /* obsolete */
10261    AllPages[index+39] = 0x00; /* obsolete */
10262    AllPages[index+40] = 0xFF; /* Busy Timeout Period */
10263    AllPages[index+41] = 0xFF; /* Busy Timeout Period */
10264    AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */
10265    AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */
10266
10267    /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
10268    /*
10269     * Fill-up informational-exceptions control mode page, SAT, Table 68
10270     */
10271    AllPages[index+44] = 0x1C; /* page code */
10272    AllPages[index+45] = 0x0A; /* page length */
10273     if (pSatDevData->satSMARTEnabled == agTRUE)
10274    {
10275      AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */
10276    }
10277    else
10278    {
10279      AllPages[index+46] = 0x08;/* DEXCPT bit is set */
10280    }
10281    AllPages[index+47] = 0x00; /* We don't support MRIE */
10282    AllPages[index+48] = 0x00; /* Interval timer vendor-specific */
10283    AllPages[index+49] = 0x00;
10284    AllPages[index+50] = 0x00;
10285    AllPages[index+51] = 0x00;
10286    AllPages[index+52] = 0x00; /* REPORT-COUNT */
10287    AllPages[index+53] = 0x00;
10288    AllPages[index+54] = 0x00;
10289    AllPages[index+55] = 0x00;
10290
10291    sm_memcpy(pModeSense, &AllPages, lenRead);
10292  }
10293  else if (page == MODESENSE_CONTROL_PAGE)
10294  {
10295    SM_DBG5(("smsatModeSense10: MODESENSE_CONTROL_PAGE\n"));
10296    Control[0] = 0;
10297    Control[1] = (bit8)(lenRead - 2);
10298    Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10299    Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10300    if (LLBAA)
10301    {
10302      Control[4] = 0x00; /* reserved and LONGLBA */
10303      Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */
10304    }
10305    else
10306    {
10307      Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10308    }
10309    Control[5] = 0x00; /* reserved */
10310    Control[6] = 0x00; /* block descriptot length */
10311    if (LLBAA)
10312    {
10313      Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10314    }
10315    else
10316    {
10317      Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10318    }
10319
10320    /*
10321     * Fill-up direct-access device block-descriptor, SAT, Table 19
10322     */
10323
10324    if (LLBAA)
10325    {
10326      /* density code */
10327      Control[8]   = 0x04; /* density-code : reserved for direct-access */
10328      /* number of blocks */
10329      Control[9]   = 0x00; /* unspecified */
10330      Control[10]  = 0x00; /* unspecified */
10331      Control[11]  = 0x00; /* unspecified */
10332      Control[12]  = 0x00; /* unspecified */
10333      Control[13]  = 0x00; /* unspecified */
10334      Control[14]  = 0x00; /* unspecified */
10335      Control[15]  = 0x00; /* unspecified */
10336      /* reserved */
10337      Control[16]  = 0x00; /* reserved */
10338      Control[17]  = 0x00; /* reserved */
10339      Control[18]  = 0x00; /* reserved */
10340      Control[19]  = 0x00; /* reserved */
10341      /* Block size */
10342      Control[20]  = 0x00;
10343      Control[21]  = 0x00;
10344      Control[22]  = 0x02;   /* Block size is always 512 bytes */
10345      Control[23]  = 0x00;
10346    }
10347    else
10348    {
10349      /* density code */
10350      Control[8]   = 0x04; /* density-code : reserved for direct-access */
10351      /* number of blocks */
10352      Control[9]   = 0x00; /* unspecified */
10353      Control[10]  = 0x00; /* unspecified */
10354      Control[11]  = 0x00; /* unspecified */
10355      /* reserved */
10356      Control[12]  = 0x00; /* reserved */
10357      /* Block size */
10358      Control[13]  = 0x00;
10359      Control[14]  = 0x02;   /* Block size is always 512 bytes */
10360      Control[15]  = 0x00;
10361    }
10362
10363    if (LLBAA)
10364    {
10365      index = 24;
10366    }
10367    else
10368    {
10369      index = 16;
10370    }
10371    /*
10372     * Fill-up control mode page, SAT, Table 65
10373     */
10374    Control[index+0] = 0x0A; /* page code */
10375    Control[index+1] = 0x0A; /* page length */
10376    Control[index+2] = 0x02; /* only GLTSD bit is set */
10377    if (pSatDevData->satNCQ == agTRUE)
10378    {
10379      Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
10380    }
10381    else
10382    {
10383      Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
10384    }
10385    Control[index+4] = 0x00;
10386    Control[index+5] = 0x00;
10387    Control[index+6] = 0x00; /* obsolete */
10388    Control[index+7] = 0x00; /* obsolete */
10389    Control[index+8] = 0xFF; /* Busy Timeout Period */
10390    Control[index+9] = 0xFF; /* Busy Timeout Period */
10391    Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */
10392    Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */
10393
10394    sm_memcpy(pModeSense, &Control, lenRead);
10395  }
10396  else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
10397  {
10398    SM_DBG5(("smsatModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
10399    RWErrorRecovery[0] = 0;
10400    RWErrorRecovery[1] = (bit8)(lenRead - 2);
10401    RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10402    RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10403    if (LLBAA)
10404    {
10405      RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */
10406      RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */
10407    }
10408    else
10409    {
10410      RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10411    }
10412    RWErrorRecovery[5] = 0x00; /* reserved */
10413    RWErrorRecovery[6] = 0x00; /* block descriptot length */
10414    if (LLBAA)
10415    {
10416      RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10417    }
10418    else
10419    {
10420      RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10421    }
10422
10423    /*
10424     * Fill-up direct-access device block-descriptor, SAT, Table 19
10425     */
10426
10427    if (LLBAA)
10428    {
10429      /* density code */
10430      RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
10431      /* number of blocks */
10432      RWErrorRecovery[9]   = 0x00; /* unspecified */
10433      RWErrorRecovery[10]  = 0x00; /* unspecified */
10434      RWErrorRecovery[11]  = 0x00; /* unspecified */
10435      RWErrorRecovery[12]  = 0x00; /* unspecified */
10436      RWErrorRecovery[13]  = 0x00; /* unspecified */
10437      RWErrorRecovery[14]  = 0x00; /* unspecified */
10438      RWErrorRecovery[15]  = 0x00; /* unspecified */
10439      /* reserved */
10440      RWErrorRecovery[16]  = 0x00; /* reserved */
10441      RWErrorRecovery[17]  = 0x00; /* reserved */
10442      RWErrorRecovery[18]  = 0x00; /* reserved */
10443      RWErrorRecovery[19]  = 0x00; /* reserved */
10444      /* Block size */
10445      RWErrorRecovery[20]  = 0x00;
10446      RWErrorRecovery[21]  = 0x00;
10447      RWErrorRecovery[22]  = 0x02;   /* Block size is always 512 bytes */
10448      RWErrorRecovery[23]  = 0x00;
10449    }
10450    else
10451    {
10452      /* density code */
10453      RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
10454      /* number of blocks */
10455      RWErrorRecovery[9]   = 0x00; /* unspecified */
10456      RWErrorRecovery[10]  = 0x00; /* unspecified */
10457      RWErrorRecovery[11]  = 0x00; /* unspecified */
10458      /* reserved */
10459      RWErrorRecovery[12]  = 0x00; /* reserved */
10460      /* Block size */
10461      RWErrorRecovery[13]  = 0x00;
10462      RWErrorRecovery[14]  = 0x02;   /* Block size is always 512 bytes */
10463      RWErrorRecovery[15]  = 0x00;
10464    }
10465
10466    if (LLBAA)
10467    {
10468      index = 24;
10469    }
10470    else
10471    {
10472      index = 16;
10473    }
10474    /*
10475     * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
10476     */
10477    RWErrorRecovery[index+0] = 0x01; /* page code */
10478    RWErrorRecovery[index+1] = 0x0A; /* page length */
10479    RWErrorRecovery[index+2] = 0x40; /* ARRE is set */
10480    RWErrorRecovery[index+3] = 0x00;
10481    RWErrorRecovery[index+4] = 0x00;
10482    RWErrorRecovery[index+5] = 0x00;
10483    RWErrorRecovery[index+6] = 0x00;
10484    RWErrorRecovery[index+7] = 0x00;
10485    RWErrorRecovery[index+8] = 0x00;
10486    RWErrorRecovery[index+9] = 0x00;
10487    RWErrorRecovery[index+10] = 0x00;
10488    RWErrorRecovery[index+11] = 0x00;
10489
10490    sm_memcpy(pModeSense, &RWErrorRecovery, lenRead);
10491  }
10492  else if (page == MODESENSE_CACHING)
10493  {
10494    SM_DBG5(("smsatModeSense10: MODESENSE_CACHING\n"));
10495    Caching[0] = 0;
10496    Caching[1] = (bit8)(lenRead - 2);
10497    Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10498    Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10499    if (LLBAA)
10500    {
10501      Caching[4] = 0x00; /* reserved and LONGLBA */
10502      Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */
10503    }
10504    else
10505    {
10506      Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10507    }
10508    Caching[5] = 0x00; /* reserved */
10509    Caching[6] = 0x00; /* block descriptot length */
10510    if (LLBAA)
10511    {
10512      Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10513    }
10514    else
10515    {
10516      Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10517    }
10518
10519    /*
10520     * Fill-up direct-access device block-descriptor, SAT, Table 19
10521     */
10522
10523    if (LLBAA)
10524    {
10525      /* density code */
10526      Caching[8]   = 0x04; /* density-code : reserved for direct-access */
10527      /* number of blocks */
10528      Caching[9]   = 0x00; /* unspecified */
10529      Caching[10]  = 0x00; /* unspecified */
10530      Caching[11]  = 0x00; /* unspecified */
10531      Caching[12]  = 0x00; /* unspecified */
10532      Caching[13]  = 0x00; /* unspecified */
10533      Caching[14]  = 0x00; /* unspecified */
10534      Caching[15]  = 0x00; /* unspecified */
10535      /* reserved */
10536      Caching[16]  = 0x00; /* reserved */
10537      Caching[17]  = 0x00; /* reserved */
10538      Caching[18]  = 0x00; /* reserved */
10539      Caching[19]  = 0x00; /* reserved */
10540      /* Block size */
10541      Caching[20]  = 0x00;
10542      Caching[21]  = 0x00;
10543      Caching[22]  = 0x02;   /* Block size is always 512 bytes */
10544      Caching[23]  = 0x00;
10545    }
10546    else
10547    {
10548      /* density code */
10549      Caching[8]   = 0x04; /* density-code : reserved for direct-access */
10550      /* number of blocks */
10551      Caching[9]   = 0x00; /* unspecified */
10552      Caching[10]  = 0x00; /* unspecified */
10553      Caching[11]  = 0x00; /* unspecified */
10554      /* reserved */
10555      Caching[12]  = 0x00; /* reserved */
10556      /* Block size */
10557      Caching[13]  = 0x00;
10558      Caching[14]  = 0x02;   /* Block size is always 512 bytes */
10559      Caching[15]  = 0x00;
10560    }
10561
10562    if (LLBAA)
10563    {
10564      index = 24;
10565    }
10566    else
10567    {
10568      index = 16;
10569    }
10570    /*
10571     * Fill-up Caching mode page, SAT, Table 67
10572     */
10573    /* length 20 */
10574    Caching[index+0] = 0x08; /* page code */
10575    Caching[index+1] = 0x12; /* page length */
10576    if (pSatDevData->satWriteCacheEnabled == agTRUE)
10577    {
10578      Caching[index+2] = 0x04;/* WCE bit is set */
10579    }
10580    else
10581    {
10582      Caching[index+2] = 0x00;/* WCE bit is NOT set */
10583    }
10584
10585    Caching[index+3] = 0x00;
10586    Caching[index+4] = 0x00;
10587    Caching[index+5] = 0x00;
10588    Caching[index+6] = 0x00;
10589    Caching[index+7] = 0x00;
10590    Caching[index+8] = 0x00;
10591    Caching[index+9] = 0x00;
10592    Caching[index+10] = 0x00;
10593    Caching[index+11] = 0x00;
10594    if (pSatDevData->satLookAheadEnabled == agTRUE)
10595    {
10596      Caching[index+12] = 0x00;/* DRA bit is NOT set */
10597    }
10598    else
10599    {
10600      Caching[index+12] = 0x20;/* DRA bit is set */
10601    }
10602    Caching[index+13] = 0x00;
10603    Caching[index+14] = 0x00;
10604    Caching[index+15] = 0x00;
10605    Caching[index+16] = 0x00;
10606    Caching[index+17] = 0x00;
10607    Caching[index+18] = 0x00;
10608    Caching[index+19] = 0x00;
10609    sm_memcpy(pModeSense, &Caching, lenRead);
10610
10611  }
10612  else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
10613  {
10614    SM_DBG5(("smsatModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
10615    InfoExceptionCtrl[0] = 0;
10616    InfoExceptionCtrl[1] = (bit8)(lenRead - 2);
10617    InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10618    InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10619    if (LLBAA)
10620    {
10621      InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */
10622      InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */
10623    }
10624    else
10625    {
10626      InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10627    }
10628    InfoExceptionCtrl[5] = 0x00; /* reserved */
10629    InfoExceptionCtrl[6] = 0x00; /* block descriptot length */
10630    if (LLBAA)
10631    {
10632      InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10633    }
10634    else
10635    {
10636      InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10637    }
10638
10639    /*
10640     * Fill-up direct-access device block-descriptor, SAT, Table 19
10641     */
10642
10643    if (LLBAA)
10644    {
10645      /* density code */
10646      InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
10647      /* number of blocks */
10648      InfoExceptionCtrl[9]   = 0x00; /* unspecified */
10649      InfoExceptionCtrl[10]  = 0x00; /* unspecified */
10650      InfoExceptionCtrl[11]  = 0x00; /* unspecified */
10651      InfoExceptionCtrl[12]  = 0x00; /* unspecified */
10652      InfoExceptionCtrl[13]  = 0x00; /* unspecified */
10653      InfoExceptionCtrl[14]  = 0x00; /* unspecified */
10654      InfoExceptionCtrl[15]  = 0x00; /* unspecified */
10655      /* reserved */
10656      InfoExceptionCtrl[16]  = 0x00; /* reserved */
10657      InfoExceptionCtrl[17]  = 0x00; /* reserved */
10658      InfoExceptionCtrl[18]  = 0x00; /* reserved */
10659      InfoExceptionCtrl[19]  = 0x00; /* reserved */
10660      /* Block size */
10661      InfoExceptionCtrl[20]  = 0x00;
10662      InfoExceptionCtrl[21]  = 0x00;
10663      InfoExceptionCtrl[22]  = 0x02;   /* Block size is always 512 bytes */
10664      InfoExceptionCtrl[23]  = 0x00;
10665    }
10666    else
10667    {
10668      /* density code */
10669      InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
10670      /* number of blocks */
10671      InfoExceptionCtrl[9]   = 0x00; /* unspecified */
10672      InfoExceptionCtrl[10]  = 0x00; /* unspecified */
10673      InfoExceptionCtrl[11]  = 0x00; /* unspecified */
10674      /* reserved */
10675      InfoExceptionCtrl[12]  = 0x00; /* reserved */
10676      /* Block size */
10677      InfoExceptionCtrl[13]  = 0x00;
10678      InfoExceptionCtrl[14]  = 0x02;   /* Block size is always 512 bytes */
10679      InfoExceptionCtrl[15]  = 0x00;
10680    }
10681
10682    if (LLBAA)
10683    {
10684      index = 24;
10685    }
10686    else
10687    {
10688      index = 16;
10689    }
10690    /*
10691     * Fill-up informational-exceptions control mode page, SAT, Table 68
10692     */
10693    InfoExceptionCtrl[index+0] = 0x1C; /* page code */
10694    InfoExceptionCtrl[index+1] = 0x0A; /* page length */
10695     if (pSatDevData->satSMARTEnabled == agTRUE)
10696    {
10697      InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */
10698    }
10699    else
10700    {
10701      InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */
10702    }
10703    InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */
10704    InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */
10705    InfoExceptionCtrl[index+5] = 0x00;
10706    InfoExceptionCtrl[index+6] = 0x00;
10707    InfoExceptionCtrl[index+7] = 0x00;
10708    InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */
10709    InfoExceptionCtrl[index+9] = 0x00;
10710    InfoExceptionCtrl[index+10] = 0x00;
10711    InfoExceptionCtrl[index+11] = 0x00;
10712    sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
10713
10714  }
10715  else
10716  {
10717    /* Error */
10718    SM_DBG1(("smsatModeSense10: Error page %d!!!\n", page));
10719    smsatSetSensePayload( pSense,
10720                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10721                          0,
10722                          SCSI_SNSCODE_INVALID_COMMAND,
10723                          satIOContext);
10724
10725    /*smEnqueueIO(smRoot, satIOContext);*/
10726
10727    tdsmIOCompletedCB( smRoot,
10728                       smIORequest,
10729                       smIOSuccess,
10730                       SCSI_STAT_CHECK_CONDITION,
10731                       satIOContext->pSmSenseData,
10732                       satIOContext->interruptContext );
10733    return SM_RC_SUCCESS;
10734  }
10735
10736  if (allocationLen > lenRead)
10737  {
10738    SM_DBG1(("smsatModeSense10: reporting underrun lenRead=0x%x allocationLen=0x%x smIORequest=%p\n", lenRead, allocationLen, smIORequest));
10739
10740    /*smEnqueueIO(smRoot, satIOContext);*/
10741
10742    tdsmIOCompletedCB( smRoot,
10743                       smIORequest,
10744                       smIOUnderRun,
10745                       allocationLen - lenRead,
10746                       agNULL,
10747                       satIOContext->interruptContext );
10748
10749
10750  }
10751  else
10752  {
10753    /*smEnqueueIO(smRoot, satIOContext);*/
10754
10755    tdsmIOCompletedCB( smRoot,
10756                       smIORequest,
10757                       smIOSuccess,
10758                       SCSI_STAT_GOOD,
10759                       agNULL,
10760                       satIOContext->interruptContext);
10761  }
10762
10763  return SM_RC_SUCCESS;
10764}
10765
10766osGLOBAL bit32
10767smsatReadCapacity10(
10768                    smRoot_t                  *smRoot,
10769                    smIORequest_t             *smIORequest,
10770                    smDeviceHandle_t          *smDeviceHandle,
10771                    smScsiInitiatorRequest_t  *smScsiRequest,
10772                    smSatIOContext_t            *satIOContext
10773                   )
10774{
10775  smScsiRspSense_t        *pSense;
10776  smIniScsiCmnd_t         *scsiCmnd;
10777  bit8                    dataBuffer[8] = {0};
10778  bit32                   allocationLen;
10779  bit8  	              *pVirtAddr = agNULL;
10780  smDeviceData_t          *pSatDevData;
10781  agsaSATAIdentifyData_t  *pSATAIdData;
10782  bit32                   lastLba;
10783  bit32                   word117_118;
10784  bit32                   word117;
10785  bit32                   word118;
10786
10787  pSense      = satIOContext->pSense;
10788  pVirtAddr   = (bit8 *) smScsiRequest->sglVirtualAddr;
10789  scsiCmnd    = &smScsiRequest->scsiCmnd;
10790  pSatDevData = satIOContext->pSatDevData;
10791  pSATAIdData = &pSatDevData->satIdentifyData;
10792  allocationLen = scsiCmnd->expDataLength;
10793
10794  SM_DBG5(("smsatReadCapacity10: start\n"));
10795
10796  /* checking CONTROL */
10797  /* NACA == 1 or LINK == 1*/
10798  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
10799  {
10800    smsatSetSensePayload( pSense,
10801                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10802                          0,
10803                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10804                          satIOContext);
10805
10806    /*smEnqueueIO(smRoot, satIOContext);*/
10807
10808    tdsmIOCompletedCB( smRoot,
10809                       smIORequest,
10810                       smIOSuccess,
10811                       SCSI_STAT_CHECK_CONDITION,
10812                       satIOContext->pSmSenseData,
10813                       satIOContext->interruptContext );
10814
10815    SM_DBG1(("smsatReadCapacity10: return control!!!\n"));
10816    return SM_RC_SUCCESS;
10817  }
10818
10819
10820  /*
10821   * If Logical block address is not set to zero, return error
10822   */
10823  if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
10824  {
10825    SM_DBG1(("smsatReadCapacity10: *** ERROR *** logical address non zero, did %d!!!\n",
10826        pSatDevData->id));
10827
10828    smsatSetSensePayload( pSense,
10829                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10830                          0,
10831                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10832                          satIOContext);
10833
10834    /*smEnqueueIO(smRoot, satIOContext);*/
10835
10836    tdsmIOCompletedCB( smRoot,
10837                       smIORequest,
10838                       smIOSuccess,
10839                       SCSI_STAT_CHECK_CONDITION,
10840                       satIOContext->pSmSenseData,
10841                       satIOContext->interruptContext );
10842    return SM_RC_SUCCESS;
10843
10844  }
10845
10846  /*
10847   * If PMI bit is not zero, return error
10848   */
10849  if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
10850  {
10851    SM_DBG1(("smsatReadCapacity10: *** ERROR *** PMI is not zero, did %d\n",
10852        pSatDevData->id));
10853
10854    smsatSetSensePayload( pSense,
10855                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10856                          0,
10857                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10858                          satIOContext);
10859
10860    /*smEnqueueIO(smRoot, satIOContext);*/
10861
10862    tdsmIOCompletedCB( smRoot,
10863                       smIORequest,
10864                       smIOSuccess,
10865                       SCSI_STAT_CHECK_CONDITION,
10866                       satIOContext->pSmSenseData,
10867                       satIOContext->interruptContext );
10868    return SM_RC_SUCCESS;
10869
10870  }
10871
10872  /*
10873    filling in Read Capacity parameter data
10874    saved identify device has been already flipped
10875    See ATA spec p125 and p136 and SBC spec p54
10876  */
10877  /*
10878   * If 48-bit addressing is supported, set capacity information from Identify
10879   * Device Word 100-103.
10880   */
10881  if (pSatDevData->sat48BitSupport == agTRUE)
10882  {
10883    /*
10884     * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data:
10885     * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL
10886     * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL
10887     * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would
10888     * then issue a READ CAPACITY(16) command.
10889     */
10890    /* ATA Identify Device information word 100 - 103 */
10891    if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
10892    {
10893      dataBuffer[0] = 0xFF;        /* MSB number of block */
10894      dataBuffer[1] = 0xFF;
10895      dataBuffer[2] = 0xFF;
10896      dataBuffer[3] = 0xFF;        /* LSB number of block */
10897      SM_DBG1(("smsatReadCapacity10: returns 0xFFFFFFFF!!!\n"));
10898    }
10899    else  /* Fit the Readcapacity10 4-bytes response length */
10900    {
10901      lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
10902                  (pSATAIdData->maxLBA0_15);
10903      lastLba = lastLba - 1;      /* LBA starts from zero */
10904
10905      /*
10906        for testing
10907      lastLba = lastLba - (512*10) - 1;
10908      */
10909
10910
10911      dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
10912      dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF);
10913      dataBuffer[2] = (bit8)((lastLba >> 8)  & 0xFF);
10914      dataBuffer[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
10915
10916      SM_DBG3(("smsatReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
10917      SM_DBG3(("smsatReadCapacity10: LBA 0 is 0x%x %d\n", dataBuffer[0], dataBuffer[0]));
10918      SM_DBG3(("smsatReadCapacity10: LBA 1 is 0x%x %d\n", dataBuffer[1], dataBuffer[1]));
10919      SM_DBG3(("smsatReadCapacity10: LBA 2 is 0x%x %d\n", dataBuffer[2], dataBuffer[2]));
10920      SM_DBG3(("smsatReadCapacity10: LBA 3 is 0x%x %d\n", dataBuffer[3], dataBuffer[3]));
10921
10922    }
10923  }
10924
10925  /*
10926   * For 28-bit addressing, set capacity information from Identify
10927   * Device Word 60-61.
10928   */
10929  else
10930  {
10931    /* ATA Identify Device information word 60 - 61 */
10932    lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
10933                (pSATAIdData->numOfUserAddressableSectorsLo);
10934    lastLba = lastLba - 1;      /* LBA starts from zero */
10935
10936    dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
10937    dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF);
10938    dataBuffer[2] = (bit8)((lastLba >> 8)  & 0xFF);
10939    dataBuffer[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
10940  }
10941  /* SAT Rev 8d */
10942  if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
10943  {
10944    SM_DBG5(("smsatReadCapacity10: Default Block Length is 512\n"));
10945    /*
10946     * Set the block size, fixed at 512 bytes.
10947     */
10948    dataBuffer[4] = 0x00;        /* MSB block size in bytes */
10949    dataBuffer[5] = 0x00;
10950    dataBuffer[6] = 0x02;
10951    dataBuffer[7] = 0x00;        /* LSB block size in bytes */
10952  }
10953  else
10954  {
10955    word118 = pSATAIdData->word112_126[6];
10956    word117 = pSATAIdData->word112_126[5];
10957
10958    word117_118 = (word118 << 16) + word117;
10959    word117_118 = word117_118 * 2;
10960    dataBuffer[4] = (bit8)((word117_118 >> 24) & 0xFF);        /* MSB block size in bytes */
10961    dataBuffer[5] = (bit8)((word117_118 >> 16) & 0xFF);
10962    dataBuffer[6] = (bit8)((word117_118 >> 8) & 0xFF);
10963    dataBuffer[7] = (bit8)(word117_118 & 0xFF);                /* LSB block size in bytes */
10964
10965    SM_DBG1(("smsatReadCapacity10: Nondefault word118 %d 0x%x !!!\n", word118, word118));
10966    SM_DBG1(("smsatReadCapacity10: Nondefault word117 %d 0x%x !!!\n", word117, word117));
10967    SM_DBG1(("smsatReadCapacity10: Nondefault Block Length is %d 0x%x !!!\n",word117_118, word117_118));
10968
10969  }
10970
10971  /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
10972  pSatDevData->satMaxLBA[0] = 0;            /* MSB */
10973  pSatDevData->satMaxLBA[1] = 0;
10974  pSatDevData->satMaxLBA[2] = 0;
10975  pSatDevData->satMaxLBA[3] = 0;
10976  pSatDevData->satMaxLBA[4] = dataBuffer[0];
10977  pSatDevData->satMaxLBA[5] = dataBuffer[1];
10978  pSatDevData->satMaxLBA[6] = dataBuffer[2];
10979  pSatDevData->satMaxLBA[7] = dataBuffer[3]; /* LSB */
10980
10981
10982  SM_DBG4(("smsatReadCapacity10: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , did %d\n",
10983        dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3],
10984        dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7],
10985        pSatDevData->id));
10986
10987  sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, 8));
10988
10989  /*
10990   * Send the completion response now.
10991   */
10992  /*smEnqueueIO(smRoot, satIOContext);*/
10993
10994  tdsmIOCompletedCB( smRoot,
10995                     smIORequest,
10996                     smIOSuccess,
10997                     SCSI_STAT_GOOD,
10998                     agNULL,
10999                     satIOContext->interruptContext);
11000  return SM_RC_SUCCESS;
11001}
11002
11003osGLOBAL bit32
11004smsatReadCapacity16(
11005                    smRoot_t                  *smRoot,
11006                    smIORequest_t             *smIORequest,
11007                    smDeviceHandle_t          *smDeviceHandle,
11008                    smScsiInitiatorRequest_t  *smScsiRequest,
11009                    smSatIOContext_t            *satIOContext
11010                   )
11011{
11012  smScsiRspSense_t        *pSense;
11013  smIniScsiCmnd_t         *scsiCmnd;
11014  bit8                    dataBuffer[32] = {0};
11015  bit8  	              *pVirtAddr = agNULL;
11016  smDeviceData_t          *pSatDevData;
11017  agsaSATAIdentifyData_t  *pSATAIdData;
11018  bit32                   lastLbaLo;
11019  bit32                   allocationLen;
11020  bit32                   readCapacityLen  = 32;
11021  bit32                   i = 0;
11022
11023  pSense      = satIOContext->pSense;
11024  pVirtAddr   = (bit8 *) smScsiRequest->sglVirtualAddr;
11025  scsiCmnd    = &smScsiRequest->scsiCmnd;
11026  pSatDevData = satIOContext->pSatDevData;
11027  pSATAIdData = &pSatDevData->satIdentifyData;
11028
11029  SM_DBG5(("smsatReadCapacity16: start\n"));
11030
11031  /* Find the buffer size allocated by Initiator */
11032  allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
11033                  (((bit32)scsiCmnd->cdb[11]) << 16) |
11034                  (((bit32)scsiCmnd->cdb[12]) << 8 ) |
11035                  (((bit32)scsiCmnd->cdb[13])      );
11036  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
11037
11038#ifdef REMOVED
11039  if (allocationLen < readCapacityLen)
11040  {
11041    SM_DBG1(("smsatReadCapacity16: *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x!!!\n", allocationLen, readCapacityLen));
11042
11043    smsatSetSensePayload( pSense,
11044                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11045                          0,
11046                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11047                          satIOContext);
11048
11049    /*smEnqueueIO(smRoot, satIOContext);*/
11050
11051    tdsmIOCompletedCB( smRoot,
11052                       smIORequest,
11053                       smIOSuccess,
11054                       SCSI_STAT_CHECK_CONDITION,
11055                       satIOContext->pSmSenseData,
11056                       satIOContext->interruptContext );
11057    return SM_RC_SUCCESS;
11058
11059  }
11060#endif
11061
11062  /* checking CONTROL */
11063  /* NACA == 1 or LINK == 1*/
11064  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
11065  {
11066    smsatSetSensePayload( pSense,
11067                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11068                          0,
11069                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11070                          satIOContext);
11071
11072    /*smEnqueueIO(smRoot, satIOContext);*/
11073
11074    tdsmIOCompletedCB( smRoot,
11075                       smIORequest,
11076                       smIOSuccess,
11077                       SCSI_STAT_CHECK_CONDITION,
11078                       satIOContext->pSmSenseData,
11079                       satIOContext->interruptContext );
11080
11081    SM_DBG1(("smsatReadCapacity16: return control!!!\n"));
11082    return SM_RC_SUCCESS;
11083  }
11084
11085  /*
11086   * If Logical blcok address is not set to zero, return error
11087   */
11088  if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) ||
11089      (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9])  )
11090  {
11091    SM_DBG1(("smsatReadCapacity16: *** ERROR *** logical address non zero, did %d\n",
11092        pSatDevData->id));
11093
11094    smsatSetSensePayload( pSense,
11095                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11096                          0,
11097                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11098                          satIOContext);
11099
11100    /*smEnqueueIO(smRoot, satIOContext);*/
11101
11102    tdsmIOCompletedCB( smRoot,
11103                       smIORequest,
11104                       smIOSuccess,
11105                       SCSI_STAT_CHECK_CONDITION,
11106                       satIOContext->pSmSenseData,
11107                       satIOContext->interruptContext );
11108    return SM_RC_SUCCESS;
11109
11110  }
11111
11112  /*
11113   * If PMI bit is not zero, return error
11114   */
11115  if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
11116  {
11117    SM_DBG1(("smsatReadCapacity16: *** ERROR *** PMI is not zero, did %d\n",
11118        pSatDevData->id));
11119
11120    smsatSetSensePayload( pSense,
11121                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11122                          0,
11123                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11124                          satIOContext);
11125
11126    /*smEnqueueIO(smRoot, satIOContext);*/
11127
11128    tdsmIOCompletedCB( smRoot,
11129                       smIORequest,
11130                       smIOSuccess,
11131                       SCSI_STAT_CHECK_CONDITION,
11132                       satIOContext->pSmSenseData,
11133                       satIOContext->interruptContext );
11134    return SM_RC_SUCCESS;
11135
11136  }
11137
11138  /*
11139    filling in Read Capacity parameter data
11140  */
11141
11142  /*
11143   * If 48-bit addressing is supported, set capacity information from Identify
11144   * Device Word 100-103.
11145   */
11146  if (pSatDevData->sat48BitSupport == agTRUE)
11147  {
11148    dataBuffer[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff);  /* MSB */
11149    dataBuffer[1] = (bit8)((pSATAIdData->maxLBA48_63)        & 0xff);
11150    dataBuffer[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
11151    dataBuffer[3] = (bit8)((pSATAIdData->maxLBA32_47)        & 0xff);
11152
11153    lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
11154    lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
11155
11156    dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
11157    dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
11158    dataBuffer[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
11159    dataBuffer[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
11160
11161  }
11162
11163  /*
11164   * For 28-bit addressing, set capacity information from Identify
11165   * Device Word 60-61.
11166   */
11167  else
11168  {
11169    dataBuffer[0] = 0;       /* MSB */
11170    dataBuffer[1] = 0;
11171    dataBuffer[2] = 0;
11172    dataBuffer[3] = 0;
11173
11174    lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
11175                  (pSATAIdData->numOfUserAddressableSectorsLo);
11176    lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
11177
11178    dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
11179    dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
11180    dataBuffer[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
11181    dataBuffer[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
11182
11183  }
11184
11185  /*
11186   * Set the block size, fixed at 512 bytes.
11187   */
11188  dataBuffer[8]  = 0x00;        /* MSB block size in bytes */
11189  dataBuffer[9]  = 0x00;
11190  dataBuffer[10] = 0x02;
11191  dataBuffer[11] = 0x00;        /* LSB block size in bytes */
11192
11193
11194  /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
11195  pSatDevData->satMaxLBA[0] = dataBuffer[0];            /* MSB */
11196  pSatDevData->satMaxLBA[1] = dataBuffer[1];
11197  pSatDevData->satMaxLBA[2] = dataBuffer[2];
11198  pSatDevData->satMaxLBA[3] = dataBuffer[3];
11199  pSatDevData->satMaxLBA[4] = dataBuffer[4];
11200  pSatDevData->satMaxLBA[5] = dataBuffer[5];
11201  pSatDevData->satMaxLBA[6] = dataBuffer[6];
11202  pSatDevData->satMaxLBA[7] = dataBuffer[7];             /* LSB */
11203
11204  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",
11205        dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3],
11206        dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7],
11207        dataBuffer[8], dataBuffer[9], dataBuffer[10], dataBuffer[11],
11208        pSatDevData->id));
11209
11210  if (allocationLen > 0xC) /* 0xc = 12 */
11211  {
11212    for(i=12;i<=31;i++)
11213    {
11214      dataBuffer[i] = 0x00;
11215    }
11216  }
11217
11218  sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, readCapacityLen));
11219  /*
11220   * Send the completion response now.
11221   */
11222  if (allocationLen > readCapacityLen)
11223  {
11224    /* underrun */
11225    SM_DBG1(("smsatReadCapacity16: reporting underrun readCapacityLen=0x%x allocationLen=0x%x !!!\n", readCapacityLen, allocationLen));
11226
11227    /*smEnqueueIO(smRoot, satIOContext);*/
11228
11229    tdsmIOCompletedCB( smRoot,
11230                       smIORequest,
11231                       smIOUnderRun,
11232                       allocationLen - readCapacityLen,
11233                       agNULL,
11234                       satIOContext->interruptContext );
11235
11236
11237  }
11238  else
11239  {
11240    /*smEnqueueIO(smRoot, satIOContext);*/
11241
11242    tdsmIOCompletedCB( smRoot,
11243                       smIORequest,
11244                       smIOSuccess,
11245                       SCSI_STAT_GOOD,
11246                       agNULL,
11247                       satIOContext->interruptContext);
11248  }
11249  return SM_RC_SUCCESS;
11250}
11251
11252osGLOBAL bit32
11253smsatReportLun(
11254               smRoot_t                  *smRoot,
11255               smIORequest_t             *smIORequest,
11256               smDeviceHandle_t          *smDeviceHandle,
11257               smScsiInitiatorRequest_t  *smScsiRequest,
11258               smSatIOContext_t            *satIOContext
11259              )
11260{
11261  smScsiRspSense_t      *pSense;
11262  bit8                  dataBuffer[16] = {0};
11263  bit32                 allocationLen;
11264  bit32                 reportLunLen;
11265  smScsiReportLun_t     *pReportLun;
11266  smIniScsiCmnd_t       *scsiCmnd;
11267#ifdef  TD_DEBUG_ENABLE
11268  smDeviceData_t        *pSatDevData;
11269#endif
11270
11271  pSense     = satIOContext->pSense;
11272  pReportLun = (smScsiReportLun_t *) dataBuffer;
11273  scsiCmnd   = &smScsiRequest->scsiCmnd;
11274#ifdef  TD_DEBUG_ENABLE
11275  pSatDevData = satIOContext->pSatDevData;
11276#endif
11277  SM_DBG5(("smsatReportLun: start\n"));
11278//  smhexdump("smsatReportLun: cdb", (bit8 *)scsiCmnd, 16);
11279  /* Find the buffer size allocated by Initiator */
11280  allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
11281                  (((bit32)scsiCmnd->cdb[7]) << 16) |
11282                  (((bit32)scsiCmnd->cdb[8]) << 8 ) |
11283                  (((bit32)scsiCmnd->cdb[9])      );
11284  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
11285  reportLunLen  = 16;     /* 8 byte header and 8 bytes of LUN0 */
11286  if (allocationLen < reportLunLen)
11287  {
11288    SM_DBG1(("smsatReportLun: *** ERROR *** insufficient len=0x%x did %d\n",
11289        reportLunLen, pSatDevData->id));
11290    smsatSetSensePayload( pSense,
11291                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11292                          0,
11293                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11294                          satIOContext);
11295    /*smEnqueueIO(smRoot, satIOContext);*/
11296    tdsmIOCompletedCB( smRoot,
11297                       smIORequest,
11298                       smIOSuccess,
11299                       SCSI_STAT_CHECK_CONDITION,
11300                       satIOContext->pSmSenseData,
11301                       satIOContext->interruptContext );
11302    return SM_RC_SUCCESS;
11303  }
11304  /* Set length to one entry */
11305  pReportLun->len[0] = 0;
11306  pReportLun->len[1] = 0;
11307  pReportLun->len[2] = 0;
11308  pReportLun->len[3] = sizeof (tiLUN_t);
11309  pReportLun->reserved = 0;
11310  /* Set to LUN 0:
11311   * - address method to 0x00: Peripheral device addressing method,
11312   * - bus identifier to 0
11313   */
11314  pReportLun->lunList[0].lun[0] = 0;
11315  pReportLun->lunList[0].lun[1] = 0;
11316  pReportLun->lunList[0].lun[2] = 0;
11317  pReportLun->lunList[0].lun[3] = 0;
11318  pReportLun->lunList[0].lun[4] = 0;
11319  pReportLun->lunList[0].lun[5] = 0;
11320  pReportLun->lunList[0].lun[6] = 0;
11321  pReportLun->lunList[0].lun[7] = 0;
11322
11323  sm_memcpy(smScsiRequest->sglVirtualAddr, dataBuffer, MIN(allocationLen, reportLunLen));
11324  if (allocationLen > reportLunLen)
11325  {
11326    /* underrun */
11327    SM_DBG1(("smsatReportLun: reporting underrun reportLunLen=0x%x allocationLen=0x%x !!!\n", reportLunLen, allocationLen));
11328
11329    /*smEnqueueIO(smRoot, satIOContext);*/
11330
11331    tdsmIOCompletedCB( smRoot,
11332                       smIORequest,
11333                       smIOUnderRun,
11334                       allocationLen - reportLunLen,
11335                       agNULL,
11336                       satIOContext->interruptContext );
11337
11338
11339  }
11340  else
11341  {
11342    /*smEnqueueIO(smRoot, satIOContext);*/
11343
11344    tdsmIOCompletedCB( smRoot,
11345                       smIORequest,
11346                       smIOSuccess,
11347                       SCSI_STAT_GOOD,
11348                       agNULL,
11349                       satIOContext->interruptContext);
11350  }
11351  return SM_RC_SUCCESS;
11352}
11353
11354osGLOBAL bit32
11355smsatFormatUnit(
11356                smRoot_t                  *smRoot,
11357                smIORequest_t             *smIORequest,
11358                smDeviceHandle_t          *smDeviceHandle,
11359                smScsiInitiatorRequest_t  *smScsiRequest,
11360                smSatIOContext_t            *satIOContext
11361               )
11362{
11363  /*
11364    note: we don't support media certification in this version and IP bit
11365    satDevData->satFormatState will be agFalse since SAT does not actually sends
11366    any ATA command
11367   */
11368
11369  smScsiRspSense_t        *pSense;
11370  smIniScsiCmnd_t         *scsiCmnd;
11371  bit32                    index = 0;
11372
11373  pSense        = satIOContext->pSense;
11374  scsiCmnd      = &smScsiRequest->scsiCmnd;
11375  SM_DBG5(("smsatFormatUnit: start\n"));
11376  /*
11377    checking opcode
11378    1. FMTDATA bit == 0(no defect list header)
11379    2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided
11380    with DCRT bit set)
11381  */
11382  if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) ||
11383       ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
11384        (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK))
11385       )
11386  {
11387    /*smEnqueueIO(smRoot, satIOContext);*/
11388
11389    tdsmIOCompletedCB( smRoot,
11390                       smIORequest,
11391                       smIOSuccess,
11392                       SCSI_STAT_GOOD,
11393                       agNULL,
11394                       satIOContext->interruptContext);
11395
11396    SM_DBG1(("smsatFormatUnit: return opcode!!!\n"));
11397    return SM_RC_SUCCESS;
11398  }
11399
11400  /*
11401    checking DEFECT LIST FORMAT and defect list length
11402  */
11403  if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) ||
11404        ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) )
11405  {
11406    /* short parameter header */
11407    if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00)
11408    {
11409      index = 8;
11410    }
11411    /* long parameter header */
11412    if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01)
11413    {
11414      index = 10;
11415    }
11416    /* defect list length */
11417    if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0))
11418    {
11419      smsatSetSensePayload( pSense,
11420                            SCSI_SNSKEY_ILLEGAL_REQUEST,
11421                            0,
11422                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11423                            satIOContext);
11424
11425      /*smEnqueueIO(smRoot, satIOContext);*/
11426
11427      tdsmIOCompletedCB( smRoot,
11428                         smIORequest,
11429                         smIOSuccess,
11430                         SCSI_STAT_CHECK_CONDITION,
11431                         satIOContext->pSmSenseData,
11432                         satIOContext->interruptContext );
11433
11434      SM_DBG1(("smsatFormatUnit: return defect list format!!!\n"));
11435      return SM_RC_SUCCESS;
11436    }
11437  }
11438
11439  if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
11440       (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
11441  {
11442    smsatSetSensePayload( pSense,
11443                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11444                          0,
11445                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11446                          satIOContext);
11447
11448    /*smEnqueueIO(smRoot, satIOContext);*/
11449
11450    tdsmIOCompletedCB( smRoot,
11451                       smIORequest,
11452                       smIOSuccess,
11453                       SCSI_STAT_CHECK_CONDITION,
11454                       satIOContext->pSmSenseData,
11455                       satIOContext->interruptContext );
11456
11457    SM_DBG1(("smsatFormatUnit: return cmplist!!!\n"));
11458    return SM_RC_SUCCESS;
11459
11460  }
11461
11462  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
11463  {
11464    smsatSetSensePayload( pSense,
11465                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11466                          0,
11467                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11468                          satIOContext);
11469
11470    /*smEnqueueIO(smRoot, satIOContext);*/
11471
11472    tdsmIOCompletedCB( smRoot,
11473                       smIORequest,
11474                       smIOSuccess,
11475                       SCSI_STAT_CHECK_CONDITION,
11476                       satIOContext->pSmSenseData,
11477                       satIOContext->interruptContext );
11478
11479    SM_DBG1(("smsatFormatUnit: return control!!!\n"));
11480    return SM_RC_SUCCESS;
11481  }
11482
11483  /* defect list header filed, if exists, SAT rev8, Table 37, p48 */
11484  if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK)
11485  {
11486    /* case 1,2,3 */
11487    /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */
11488    if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) ||
11489         ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) ||
11490         ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11491           (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11492           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK))
11493         )
11494    {
11495      /*smEnqueueIO(smRoot, satIOContext);*/
11496
11497      tdsmIOCompletedCB( smRoot,
11498                         smIORequest,
11499                         smIOSuccess,
11500                         SCSI_STAT_GOOD,
11501                         agNULL,
11502                         satIOContext->interruptContext);
11503
11504      SM_DBG5(("smsatFormatUnit: return defect list case 1\n"));
11505      return SM_RC_SUCCESS;
11506    }
11507    /* case 4,5,6 */
11508    /*
11509        1. IMMED 0, FOV 1, DCRT 0, IP 0
11510        2. IMMED 0, FOV 1, DCRT 0, IP 1
11511        3. IMMED 0, FOV 1, DCRT 1, IP 1
11512      */
11513
11514    if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11515            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11516           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11517           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11518         ||
11519         ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11520            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11521           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11522            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11523         ||
11524         ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11525            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11526            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11527            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11528         )
11529    {
11530
11531      smsatSetSensePayload( pSense,
11532                            SCSI_SNSKEY_ILLEGAL_REQUEST,
11533                            0,
11534                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
11535                            satIOContext);
11536
11537      /*smEnqueueIO(smRoot, satIOContext);*/
11538
11539      tdsmIOCompletedCB( smRoot,
11540                         smIORequest,
11541                         smIOSuccess,
11542                         SCSI_STAT_CHECK_CONDITION,
11543                         satIOContext->pSmSenseData,
11544                         satIOContext->interruptContext );
11545
11546      SM_DBG5(("smsatFormatUnit: return defect list case 2\n"));
11547      return SM_RC_SUCCESS;
11548
11549    }
11550  }
11551
11552
11553  /*
11554   * Send the completion response now.
11555   */
11556  /*smEnqueueIO(smRoot, satIOContext);*/
11557
11558  tdsmIOCompletedCB( smRoot,
11559                     smIORequest,
11560                     smIOSuccess,
11561                     SCSI_STAT_GOOD,
11562                     agNULL,
11563                     satIOContext->interruptContext);
11564
11565  SM_DBG5(("smsatFormatUnit: return last\n"));
11566  return SM_RC_SUCCESS;
11567}
11568
11569osGLOBAL bit32
11570smsatSendDiagnostic(
11571                    smRoot_t                  *smRoot,
11572                    smIORequest_t             *smIORequest,
11573                    smDeviceHandle_t          *smDeviceHandle,
11574                    smScsiInitiatorRequest_t  *smScsiRequest,
11575                    smSatIOContext_t            *satIOContext
11576                   )
11577{
11578  bit32                     status;
11579  bit32                     agRequestType;
11580  smDeviceData_t            *pSatDevData;
11581  smScsiRspSense_t          *pSense;
11582  smIniScsiCmnd_t           *scsiCmnd;
11583  agsaFisRegHostToDevice_t  *fis;
11584  bit32                     parmLen;
11585
11586  pSense        = satIOContext->pSense;
11587  pSatDevData   = satIOContext->pSatDevData;
11588  scsiCmnd      = &smScsiRequest->scsiCmnd;
11589  fis           = satIOContext->pFis;
11590
11591  SM_DBG5(("smsatSendDiagnostic: start\n"));
11592
11593  /* reset satVerifyState */
11594  pSatDevData->satVerifyState = 0;
11595  /* no pending diagnostic in background */
11596  pSatDevData->satBGPendingDiag = agFALSE;
11597
11598  /* table 27, 8.10 p39 SAT Rev8 */
11599  /*
11600    1. checking PF == 1
11601    2. checking DEVOFFL == 1
11602    3. checking UNITOFFL == 1
11603    4. checking PARAMETER LIST LENGTH != 0
11604
11605  */
11606  if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) ||
11607       (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) ||
11608       (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) ||
11609       ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) )
11610       )
11611  {
11612    smsatSetSensePayload( pSense,
11613                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11614                          0,
11615                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11616                          satIOContext);
11617
11618    /*smEnqueueIO(smRoot, satIOContext);*/
11619
11620    tdsmIOCompletedCB( smRoot,
11621                       smIORequest,
11622                       smIOSuccess,
11623                       SCSI_STAT_CHECK_CONDITION,
11624                       satIOContext->pSmSenseData,
11625                       satIOContext->interruptContext );
11626
11627    SM_DBG1(("smsatSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST!!!\n"));
11628    return SM_RC_SUCCESS;
11629  }
11630
11631  /* checking CONTROL */
11632  /* NACA == 1 or LINK == 1*/
11633  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
11634  {
11635    smsatSetSensePayload( pSense,
11636                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11637                          0,
11638                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11639                          satIOContext);
11640
11641    /*smEnqueueIO(smRoot, satIOContext);*/
11642
11643    tdsmIOCompletedCB( smRoot,
11644                       smIORequest,
11645                       smIOSuccess,
11646                       SCSI_STAT_CHECK_CONDITION,
11647                       satIOContext->pSmSenseData,
11648                       satIOContext->interruptContext );
11649
11650    SM_DBG1(("smsatSendDiagnostic: return control!!!\n"));
11651    return SM_RC_SUCCESS;
11652  }
11653
11654  parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
11655
11656  /* checking SELFTEST bit*/
11657  /* table 29, 8.10.3, p41 SAT Rev8 */
11658  /* case 1 */
11659  if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11660       (pSatDevData->satSMARTSelfTest == agFALSE)
11661       )
11662  {
11663    smsatSetSensePayload( pSense,
11664                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11665                          0,
11666                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11667                          satIOContext);
11668
11669    /*smEnqueueIO(smRoot, satIOContext);*/
11670
11671    tdsmIOCompletedCB( smRoot,
11672                       smIORequest,
11673                       smIOSuccess,
11674                       SCSI_STAT_CHECK_CONDITION,
11675                       satIOContext->pSmSenseData,
11676                       satIOContext->interruptContext );
11677
11678    SM_DBG1(("smsatSendDiagnostic: return Table 29 case 1!!!\n"));
11679    return SM_RC_SUCCESS;
11680  }
11681
11682  /* case 2 */
11683  if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11684       (pSatDevData->satSMARTSelfTest == agTRUE) &&
11685       (pSatDevData->satSMARTEnabled == agFALSE)
11686       )
11687  {
11688    smsatSetSensePayload( pSense,
11689                          SCSI_SNSKEY_ABORTED_COMMAND,
11690                          0,
11691                          SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
11692                          satIOContext);
11693
11694    /*smEnqueueIO(smRoot, satIOContext);*/
11695
11696    tdsmIOCompletedCB( smRoot,
11697                       smIORequest,
11698                       smIOSuccess,
11699                       SCSI_STAT_CHECK_CONDITION,
11700                       satIOContext->pSmSenseData,
11701                       satIOContext->interruptContext );
11702
11703    SM_DBG5(("smsatSendDiagnostic: return Table 29 case 2\n"));
11704    return SM_RC_SUCCESS;
11705  }
11706  /*
11707    case 3
11708     see SELF TEST CODE later
11709  */
11710
11711
11712
11713  /* case 4 */
11714
11715  /*
11716    sends three ATA verify commands
11717
11718  */
11719  if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11720        (pSatDevData->satSMARTSelfTest == agFALSE))
11721       ||
11722       ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11723        (pSatDevData->satSMARTSelfTest == agTRUE) &&
11724        (pSatDevData->satSMARTEnabled == agFALSE))
11725       )
11726  {
11727    /*
11728      sector count 1, LBA 0
11729      sector count 1, LBA MAX
11730      sector count 1, LBA random
11731    */
11732    if (pSatDevData->sat48BitSupport == agTRUE)
11733    {
11734      /* sends READ VERIFY SECTOR(S) EXT*/
11735      fis->h.fisType        = 0x27;                   /* Reg host to device */
11736      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11737      fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
11738      fis->h.features       = 0;                      /* FIS reserve */
11739      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
11740      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
11741      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
11742      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
11743      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
11744      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
11745      fis->d.featuresExp    = 0;                      /* FIS reserve */
11746      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
11747      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
11748      fis->d.reserved4      = 0;
11749      fis->d.device         = 0x40;                   /* 01000000 */
11750      fis->d.control        = 0;                      /* FIS HOB bit clear */
11751      fis->d.reserved5      = 0;
11752
11753      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11754    }
11755    else
11756    {
11757      /* READ VERIFY SECTOR(S)*/
11758      fis->h.fisType        = 0x27;                   /* Reg host to device */
11759      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11760      fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
11761      fis->h.features       = 0;                      /* FIS features NA       */
11762      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
11763      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
11764      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
11765      fis->d.lbaLowExp      = 0;
11766      fis->d.lbaMidExp      = 0;
11767      fis->d.lbaHighExp     = 0;
11768      fis->d.featuresExp    = 0;
11769      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
11770      fis->d.sectorCountExp = 0;
11771      fis->d.reserved4      = 0;
11772      fis->d.device         = 0x40;                   /* 01000000 */
11773      fis->d.control        = 0;                      /* FIS HOB bit clear */
11774      fis->d.reserved5      = 0;
11775
11776      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11777    }
11778
11779    /* Initialize CB for SATA completion.
11780     */
11781    satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11782
11783    /*
11784     * Prepare SGL and send FIS to LL layer.
11785     */
11786    satIOContext->reqType = agRequestType;       /* Save it */
11787
11788    status = smsataLLIOStart( smRoot,
11789                              smIORequest,
11790                              smDeviceHandle,
11791                              smScsiRequest,
11792                              satIOContext);
11793
11794
11795    SM_DBG5(("smsatSendDiagnostic: return Table 29 case 4\n"));
11796    return (status);
11797  }
11798  /* case 5 */
11799  if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11800       (pSatDevData->satSMARTSelfTest == agTRUE) &&
11801       (pSatDevData->satSMARTEnabled == agTRUE)
11802       )
11803  {
11804    /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
11805    fis->h.fisType        = 0x27;                   /* Reg host to device */
11806    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11807    fis->h.command        = SAT_SMART;               /* 0xB0 */
11808    fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
11809    fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
11810    fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11811    fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11812    fis->d.lbaLowExp      = 0;
11813    fis->d.lbaMidExp      = 0;
11814    fis->d.lbaHighExp     = 0;
11815    fis->d.featuresExp    = 0;
11816    fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11817    fis->d.sectorCountExp = 0;
11818    fis->d.reserved4      = 0;
11819    fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
11820    fis->d.control        = 0;                         /* FIS HOB bit clear */
11821    fis->d.reserved5      = 0;
11822
11823    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11824
11825    /* Initialize CB for SATA completion.
11826     */
11827    satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11828
11829    /*
11830     * Prepare SGL and send FIS to LL layer.
11831     */
11832    satIOContext->reqType = agRequestType;       /* Save it */
11833
11834    status = smsataLLIOStart( smRoot,
11835                              smIORequest,
11836                              smDeviceHandle,
11837                              smScsiRequest,
11838                              satIOContext);
11839
11840
11841    SM_DBG5(("smsatSendDiagnostic: return Table 29 case 5\n"));
11842    return (status);
11843  }
11844
11845
11846
11847
11848  /* SAT rev8 Table29 p41 case 3*/
11849  /* checking SELF TEST CODE*/
11850  if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11851       (pSatDevData->satSMARTSelfTest == agTRUE) &&
11852       (pSatDevData->satSMARTEnabled == agTRUE)
11853       )
11854  {
11855    /* SAT rev8 Table28 p40 */
11856    /* finding self-test code */
11857    switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5)
11858    {
11859    case 1:
11860      pSatDevData->satBGPendingDiag = agTRUE;
11861
11862      tdsmIOCompletedCB( smRoot,
11863                         smIORequest,
11864                         smIOSuccess,
11865                         SCSI_STAT_GOOD,
11866                         agNULL,
11867                         satIOContext->interruptContext );
11868      /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
11869      fis->h.fisType        = 0x27;                   /* Reg host to device */
11870      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11871      fis->h.command        = SAT_SMART;              /* 0x40 */
11872      fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;  /* FIS features NA       */
11873      fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
11874      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11875      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11876
11877      fis->d.lbaLowExp      = 0;
11878      fis->d.lbaMidExp      = 0;
11879      fis->d.lbaHighExp     = 0;
11880      fis->d.featuresExp    = 0;
11881      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11882      fis->d.sectorCountExp = 0;
11883      fis->d.reserved4      = 0;
11884      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
11885      fis->d.control        = 0;                         /* FIS HOB bit clear */
11886      fis->d.reserved5      = 0;
11887
11888      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11889
11890      /* Initialize CB for SATA completion.
11891       */
11892      satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11893
11894      /*
11895       * Prepare SGL and send FIS to LL layer.
11896       */
11897      satIOContext->reqType = agRequestType;       /* Save it */
11898
11899      status = smsataLLIOStart( smRoot,
11900                                smIORequest,
11901                                smDeviceHandle,
11902                                smScsiRequest,
11903                                satIOContext);
11904
11905
11906      SM_DBG5(("smsatSendDiagnostic: return Table 28 case 1\n"));
11907      return (status);
11908    case 2:
11909      pSatDevData->satBGPendingDiag = agTRUE;
11910
11911      tdsmIOCompletedCB( smRoot,
11912                         smIORequest,
11913                         smIOSuccess,
11914                         SCSI_STAT_GOOD,
11915                         agNULL,
11916                         satIOContext->interruptContext );
11917
11918
11919      /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
11920      fis->h.fisType        = 0x27;                   /* Reg host to device */
11921      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11922      fis->h.command        = SAT_SMART;              /* 0x40 */
11923      fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
11924      fis->d.lbaLow         = 0x02;                      /* FIS LBA (7 :0 ) */
11925      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11926      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11927      fis->d.lbaLowExp      = 0;
11928      fis->d.lbaMidExp      = 0;
11929      fis->d.lbaHighExp     = 0;
11930      fis->d.featuresExp    = 0;
11931      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11932      fis->d.sectorCountExp = 0;
11933      fis->d.reserved4      = 0;
11934      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
11935      fis->d.control        = 0;                         /* FIS HOB bit clear */
11936      fis->d.reserved5      = 0;
11937
11938      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11939
11940      /* Initialize CB for SATA completion.
11941       */
11942      satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11943
11944      /*
11945       * Prepare SGL and send FIS to LL layer.
11946       */
11947      satIOContext->reqType = agRequestType;       /* Save it */
11948
11949      status = smsataLLIOStart( smRoot,
11950                                smIORequest,
11951                                smDeviceHandle,
11952                                smScsiRequest,
11953                                satIOContext);
11954
11955
11956      SM_DBG5(("smsatSendDiagnostic: return Table 28 case 2\n"));
11957      return (status);
11958    case 4:
11959
11960      if (parmLen != 0)
11961      {
11962        /* check condition */
11963        smsatSetSensePayload( pSense,
11964                              SCSI_SNSKEY_ILLEGAL_REQUEST,
11965                              0,
11966                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11967                              satIOContext);
11968
11969        /*smEnqueueIO(smRoot, satIOContext);*/
11970
11971        tdsmIOCompletedCB( smRoot,
11972                           smIORequest,
11973                           smIOSuccess,
11974                           SCSI_STAT_CHECK_CONDITION,
11975                           satIOContext->pSmSenseData,
11976                           satIOContext->interruptContext );
11977
11978        SM_DBG1(("smsatSendDiagnostic: case 4, non zero ParmLen %d!!!\n", parmLen));
11979        return SM_RC_SUCCESS;
11980      }
11981      if (pSatDevData->satBGPendingDiag == agTRUE)
11982      {
11983        /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */
11984        fis->h.fisType        = 0x27;                   /* Reg host to device */
11985        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11986        fis->h.command        = SAT_SMART;              /* 0x40 */
11987        fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
11988        fis->d.lbaLow         = 0x7F;                      /* FIS LBA (7 :0 ) */
11989        fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11990        fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11991
11992        fis->d.lbaLowExp      = 0;
11993        fis->d.lbaMidExp      = 0;
11994        fis->d.lbaHighExp     = 0;
11995        fis->d.featuresExp    = 0;
11996        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11997        fis->d.sectorCountExp = 0;
11998        fis->d.reserved4      = 0;
11999        fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
12000        fis->d.control        = 0;                         /* FIS HOB bit clear */
12001        fis->d.reserved5      = 0;
12002
12003        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12004
12005        /* Initialize CB for SATA completion.
12006         */
12007        satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12008
12009        /*
12010         * Prepare SGL and send FIS to LL layer.
12011         */
12012        satIOContext->reqType = agRequestType;       /* Save it */
12013
12014        status = smsataLLIOStart( smRoot,
12015                                  smIORequest,
12016                                  smDeviceHandle,
12017                                  smScsiRequest,
12018                                  satIOContext);
12019
12020
12021        SM_DBG5(("smsatSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
12022        SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n"));
12023        return (status);
12024      }
12025      else
12026      {
12027        /* check condition */
12028        smsatSetSensePayload( pSense,
12029                              SCSI_SNSKEY_ILLEGAL_REQUEST,
12030                              0,
12031                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12032                              satIOContext);
12033
12034        /*smEnqueueIO(smRoot, satIOContext);*/
12035
12036        tdsmIOCompletedCB( smRoot,
12037                           smIORequest,
12038                           smIOSuccess,
12039                           SCSI_STAT_CHECK_CONDITION,
12040                           satIOContext->pSmSenseData,
12041                           satIOContext->interruptContext );
12042
12043        SM_DBG1(("smsatSendDiagnostic: case 4, no pending diagnostic in background!!!\n"));
12044        SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n"));
12045        return SM_RC_SUCCESS;
12046      }
12047      break;
12048    case 5:
12049      /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
12050      fis->h.fisType        = 0x27;                   /* Reg host to device */
12051      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12052      fis->h.command        = SAT_SMART;              /* 0x40 */
12053      fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
12054      fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
12055      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
12056      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
12057      fis->d.lbaLowExp      = 0;
12058      fis->d.lbaMidExp      = 0;
12059      fis->d.lbaHighExp     = 0;
12060      fis->d.featuresExp    = 0;
12061      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
12062      fis->d.sectorCountExp = 0;
12063      fis->d.reserved4      = 0;
12064      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
12065      fis->d.control        = 0;                         /* FIS HOB bit clear */
12066      fis->d.reserved5      = 0;
12067
12068      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12069
12070      /* Initialize CB for SATA completion.
12071       */
12072      satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12073
12074      /*
12075       * Prepare SGL and send FIS to LL layer.
12076       */
12077      satIOContext->reqType = agRequestType;       /* Save it */
12078
12079      status = smsataLLIOStart( smRoot,
12080                                smIORequest,
12081                                smDeviceHandle,
12082                                smScsiRequest,
12083                                satIOContext);
12084
12085
12086      SM_DBG5(("smsatSendDiagnostic: return Table 28 case 5\n"));
12087      return (status);
12088    case 6:
12089      /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
12090      fis->h.fisType        = 0x27;                   /* Reg host to device */
12091      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12092      fis->h.command        = SAT_SMART;              /* 0x40 */
12093      fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
12094      fis->d.lbaLow         = 0x82;                      /* FIS LBA (7 :0 ) */
12095      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
12096      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
12097      fis->d.lbaLowExp      = 0;
12098      fis->d.lbaMidExp      = 0;
12099      fis->d.lbaHighExp     = 0;
12100      fis->d.featuresExp    = 0;
12101      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
12102      fis->d.sectorCountExp = 0;
12103      fis->d.reserved4      = 0;
12104      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
12105      fis->d.control        = 0;                         /* FIS HOB bit clear */
12106      fis->d.reserved5      = 0;
12107
12108      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12109
12110      /* Initialize CB for SATA completion.
12111       */
12112      satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12113
12114      /*
12115       * Prepare SGL and send FIS to LL layer.
12116       */
12117      satIOContext->reqType = agRequestType;       /* Save it */
12118
12119      status = smsataLLIOStart( smRoot,
12120                                smIORequest,
12121                                smDeviceHandle,
12122                                smScsiRequest,
12123                                satIOContext);
12124
12125
12126      SM_DBG5(("smsatSendDiagnostic: return Table 28 case 6\n"));
12127      return (status);
12128    case 0:
12129    case 3: /* fall through */
12130    case 7: /* fall through */
12131    default:
12132      break;
12133    }/* switch */
12134
12135    /* returns the results of default self-testing, which is good */
12136    /*smEnqueueIO(smRoot, satIOContext);*/
12137
12138    tdsmIOCompletedCB( smRoot,
12139                       smIORequest,
12140                       smIOSuccess,
12141                       SCSI_STAT_GOOD,
12142                       agNULL,
12143                       satIOContext->interruptContext );
12144
12145    SM_DBG5(("smsatSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
12146    return SM_RC_SUCCESS;
12147  }
12148
12149
12150  /*smEnqueueIO(smRoot, satIOContext);*/
12151
12152  tdsmIOCompletedCB( smRoot,
12153                     smIORequest,
12154                     smIOSuccess,
12155                     SCSI_STAT_GOOD,
12156                     agNULL,
12157                     satIOContext->interruptContext );
12158
12159
12160  SM_DBG5(("smsatSendDiagnostic: return last\n"));
12161  return SM_RC_SUCCESS;
12162
12163}
12164
12165osGLOBAL bit32
12166smsatStartStopUnit(
12167                   smRoot_t                  *smRoot,
12168                   smIORequest_t             *smIORequest,
12169                   smDeviceHandle_t          *smDeviceHandle,
12170                   smScsiInitiatorRequest_t  *smScsiRequest,
12171                   smSatIOContext_t            *satIOContext
12172                  )
12173{
12174  bit32                     status;
12175  bit32                     agRequestType;
12176  smDeviceData_t            *pSatDevData;
12177  smScsiRspSense_t          *pSense;
12178  smIniScsiCmnd_t           *scsiCmnd;
12179  agsaFisRegHostToDevice_t  *fis;
12180
12181  pSense        = satIOContext->pSense;
12182  pSatDevData   = satIOContext->pSatDevData;
12183  scsiCmnd      = &smScsiRequest->scsiCmnd;
12184  fis           = satIOContext->pFis;
12185
12186  SM_DBG5(("smsatStartStopUnit: start\n"));
12187
12188  /* checking CONTROL */
12189  /* NACA == 1 or LINK == 1*/
12190  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
12191  {
12192    smsatSetSensePayload( pSense,
12193                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12194                          0,
12195                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12196                          satIOContext);
12197
12198    /*smEnqueueIO(smRoot, satIOContext);*/
12199
12200    tdsmIOCompletedCB( smRoot,
12201                       smIORequest,
12202                       smIOSuccess,
12203                       SCSI_STAT_CHECK_CONDITION,
12204                       satIOContext->pSmSenseData,
12205                       satIOContext->interruptContext );
12206
12207    SM_DBG1(("smsatStartStopUnit: return control!!!\n"));
12208    return SM_RC_SUCCESS;
12209  }
12210
12211  /* Spec p55, Table 48 checking START and LOEJ bit */
12212  /* case 1 */
12213  if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12214  {
12215    if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12216    {
12217      /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12218      /*smEnqueueIO(smRoot, satIOContext);*/
12219
12220      tdsmIOCompletedCB( smRoot,
12221                         smIORequest,
12222                         smIOSuccess,
12223                         SCSI_STAT_GOOD,
12224                         agNULL,
12225                         satIOContext->interruptContext );
12226      SM_DBG5(("smsatStartStopUnit: return table48 case 1-1\n"));
12227      return SM_RC_SUCCESS;
12228    }
12229    /* sends FLUSH CACHE or FLUSH CACHE EXT */
12230    if (pSatDevData->sat48BitSupport == agTRUE)
12231    {
12232      /* FLUSH CACHE EXT */
12233      fis->h.fisType        = 0x27;                   /* Reg host to device */
12234      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12235
12236      fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
12237      fis->h.features       = 0;                      /* FIS reserve */
12238      fis->d.featuresExp    = 0;                      /* FIS reserve */
12239      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
12240      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12241      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
12242      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
12243      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
12244      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12245      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
12246      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12247      fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
12248      fis->d.control        = 0;                      /* FIS HOB bit clear */
12249      fis->d.reserved4      = 0;
12250      fis->d.reserved5      = 0;
12251
12252      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12253    }
12254    else
12255    {
12256      /* FLUSH CACHE */
12257      fis->h.fisType        = 0x27;                   /* Reg host to device */
12258      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12259
12260      fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
12261      fis->h.features       = 0;                      /* FIS features NA       */
12262      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
12263      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
12264      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
12265      fis->d.lbaLowExp      = 0;
12266      fis->d.lbaMidExp      = 0;
12267      fis->d.lbaHighExp     = 0;
12268      fis->d.featuresExp    = 0;
12269      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
12270      fis->d.sectorCountExp = 0;
12271      fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
12272      fis->d.control        = 0;                      /* FIS HOB bit clear */
12273      fis->d.reserved4      = 0;
12274      fis->d.reserved5      = 0;
12275
12276      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12277    }
12278
12279    /* Initialize CB for SATA completion.
12280     */
12281    satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12282
12283    /*
12284     * Prepare SGL and send FIS to LL layer.
12285     */
12286    satIOContext->reqType = agRequestType;       /* Save it */
12287
12288    status = smsataLLIOStart( smRoot,
12289                              smIORequest,
12290                              smDeviceHandle,
12291                              smScsiRequest,
12292                              satIOContext);
12293
12294
12295    SM_DBG5(("smsatStartStopUnit: return table48 case 1\n"));
12296    return (status);
12297  }
12298  /* case 2 */
12299  else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12300  {
12301    /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12302    if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12303    {
12304      /*smEnqueueIO(smRoot, satIOContext);*/
12305
12306      tdsmIOCompletedCB( smRoot,
12307                         smIORequest,
12308                         smIOSuccess,
12309                         SCSI_STAT_GOOD,
12310                         agNULL,
12311                         satIOContext->interruptContext );
12312
12313      SM_DBG5(("smsatStartStopUnit: return table48 case 2 1\n"));
12314      return SM_RC_SUCCESS;
12315    }
12316    /*
12317      sends READ_VERIFY_SECTORS(_EXT)
12318      sector count 1, any LBA between zero to Maximum
12319    */
12320    if (pSatDevData->sat48BitSupport == agTRUE)
12321    {
12322      /* READ VERIFY SECTOR(S) EXT*/
12323      fis->h.fisType        = 0x27;                   /* Reg host to device */
12324      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12325
12326      fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
12327      fis->h.features       = 0;                      /* FIS reserve */
12328      fis->d.lbaLow         = 0x01;                   /* FIS LBA (7 :0 ) */
12329      fis->d.lbaMid         = 0x00;                   /* FIS LBA (15:8 ) */
12330      fis->d.lbaHigh        = 0x00;                   /* FIS LBA (23:16) */
12331      fis->d.lbaLowExp      = 0x00;                   /* FIS LBA (31:24) */
12332      fis->d.lbaMidExp      = 0x00;                   /* FIS LBA (39:32) */
12333      fis->d.lbaHighExp     = 0x00;                   /* FIS LBA (47:40) */
12334      fis->d.featuresExp    = 0;                      /* FIS reserve */
12335      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12336      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12337      fis->d.reserved4      = 0;
12338      fis->d.device         = 0x40;                   /* 01000000 */
12339      fis->d.control        = 0;                      /* FIS HOB bit clear */
12340      fis->d.reserved5      = 0;
12341
12342    }
12343    else
12344    {
12345      /* READ VERIFY SECTOR(S)*/
12346      fis->h.fisType        = 0x27;                   /* Reg host to device */
12347      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12348
12349      fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
12350      fis->h.features       = 0;                      /* FIS features NA       */
12351      fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
12352      fis->d.lbaMid         = 0x00;                      /* FIS LBA (15:8 ) */
12353      fis->d.lbaHigh        = 0x00;                      /* FIS LBA (23:16) */
12354      fis->d.lbaLowExp      = 0;
12355      fis->d.lbaMidExp      = 0;
12356      fis->d.lbaHighExp     = 0;
12357      fis->d.featuresExp    = 0;
12358      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12359      fis->d.sectorCountExp = 0;
12360      fis->d.reserved4      = 0;
12361      fis->d.device         = 0x40;                   /* 01000000 */
12362      fis->d.control        = 0;                      /* FIS HOB bit clear */
12363      fis->d.reserved5      = 0;
12364
12365    }
12366
12367    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12368
12369    /* Initialize CB for SATA completion.
12370     */
12371    satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12372
12373    /*
12374     * Prepare SGL and send FIS to LL layer.
12375     */
12376    satIOContext->reqType = agRequestType;       /* Save it */
12377
12378    status = smsataLLIOStart( smRoot,
12379                              smIORequest,
12380                              smDeviceHandle,
12381                              smScsiRequest,
12382                              satIOContext);
12383
12384    SM_DBG5(("smsatStartStopUnit: return table48 case 2 2\n"));
12385    return status;
12386  }
12387  /* case 3 */
12388  else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12389  {
12390    if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
12391    {
12392      /* support for removal media */
12393      /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12394      if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12395      {
12396        /*smEnqueueIO(smRoot, satIOContext);*/
12397
12398        tdsmIOCompletedCB( smRoot,
12399                           smIORequest,
12400                           smIOSuccess,
12401                           SCSI_STAT_GOOD,
12402                           agNULL,
12403                           satIOContext->interruptContext );
12404
12405        SM_DBG5(("smsatStartStopUnit: return table48 case 3 1\n"));
12406        return SM_RC_SUCCESS;
12407      }
12408      /*
12409        sends MEDIA EJECT
12410      */
12411      /* Media Eject fis */
12412      fis->h.fisType        = 0x27;                   /* Reg host to device */
12413      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12414
12415      fis->h.command        = SAT_MEDIA_EJECT;        /* 0xED */
12416      fis->h.features       = 0;                      /* FIS features NA       */
12417      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
12418      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
12419      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
12420      fis->d.lbaLowExp      = 0;
12421      fis->d.lbaMidExp      = 0;
12422      fis->d.lbaHighExp     = 0;
12423      fis->d.featuresExp    = 0;
12424      /* sector count zero */
12425      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
12426      fis->d.sectorCountExp = 0;
12427      fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
12428      fis->d.control        = 0;                      /* FIS HOB bit clear */
12429      fis->d.reserved4      = 0;
12430      fis->d.reserved5      = 0;
12431
12432      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12433
12434      /* Initialize CB for SATA completion.
12435       */
12436      satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12437
12438      /*
12439       * Prepare SGL and send FIS to LL layer.
12440       */
12441      satIOContext->reqType = agRequestType;       /* Save it */
12442
12443      status = smsataLLIOStart( smRoot,
12444                                smIORequest,
12445                                smDeviceHandle,
12446                                smScsiRequest,
12447                                satIOContext);
12448
12449      return status;
12450    }
12451    else
12452    {
12453      /* no support for removal media */
12454      smsatSetSensePayload( pSense,
12455                            SCSI_SNSKEY_ILLEGAL_REQUEST,
12456                            0,
12457                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12458                            satIOContext);
12459
12460      /*smEnqueueIO(smRoot, satIOContext);*/
12461
12462      tdsmIOCompletedCB( smRoot,
12463                         smIORequest,
12464                         smIOSuccess,
12465                         SCSI_STAT_CHECK_CONDITION,
12466                         satIOContext->pSmSenseData,
12467                         satIOContext->interruptContext );
12468
12469      SM_DBG5(("smsatStartStopUnit: return Table 29 case 3 2\n"));
12470      return SM_RC_SUCCESS;
12471    }
12472
12473  }
12474  /* case 4 */
12475  else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */
12476  {
12477    smsatSetSensePayload( pSense,
12478                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12479                          0,
12480                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12481                          satIOContext);
12482
12483    /*smEnqueueIO(smRoot, satIOContext);*/
12484
12485    tdsmIOCompletedCB( smRoot,
12486                       smIORequest,
12487                       smIOSuccess,
12488                       SCSI_STAT_CHECK_CONDITION,
12489                       satIOContext->pSmSenseData,
12490                       satIOContext->interruptContext );
12491
12492    SM_DBG5(("smsatStartStopUnit: return Table 29 case 4\n"));
12493    return SM_RC_SUCCESS;
12494  }
12495}
12496
12497osGLOBAL bit32
12498smsatWriteSame10(
12499                  smRoot_t                  *smRoot,
12500                  smIORequest_t             *smIORequest,
12501                  smDeviceHandle_t          *smDeviceHandle,
12502                  smScsiInitiatorRequest_t  *smScsiRequest,
12503                  smSatIOContext_t            *satIOContext
12504                 )
12505{
12506
12507  bit32                     status;
12508  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
12509  smDeviceData_t            *pSatDevData;
12510  smScsiRspSense_t          *pSense;
12511  smIniScsiCmnd_t           *scsiCmnd;
12512  agsaFisRegHostToDevice_t  *fis;
12513  bit32                     lba = 0;
12514  bit32                     tl = 0;
12515
12516  pSense        = satIOContext->pSense;
12517  pSatDevData   = satIOContext->pSatDevData;
12518  scsiCmnd      = &smScsiRequest->scsiCmnd;
12519  fis           = satIOContext->pFis;
12520
12521  SM_DBG5(("smsatWriteSame10: start\n"));
12522
12523  /* checking CONTROL */
12524    /* NACA == 1 or LINK == 1*/
12525  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
12526  {
12527    smsatSetSensePayload( pSense,
12528                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12529                          0,
12530                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12531                          satIOContext);
12532
12533    /*smEnqueueIO(smRoot, satIOContext);*/
12534
12535    tdsmIOCompletedCB( smRoot,
12536                       smIORequest,
12537                       smIOSuccess,
12538                       SCSI_STAT_CHECK_CONDITION,
12539                       satIOContext->pSmSenseData,
12540                       satIOContext->interruptContext );
12541
12542    SM_DBG1(("smsatWriteSame10: return control!!!\n"));
12543    return SM_RC_SUCCESS;
12544  }
12545
12546
12547  /* checking LBDATA and PBDATA */
12548  /* case 1 */
12549  if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12550       !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12551  {
12552    SM_DBG5(("smsatWriteSame10: case 1\n"));
12553    /* spec 9.26.2, Table 62, p64, case 1*/
12554    /*
12555      normal case
12556      just like write in 9.17.1
12557    */
12558
12559    if ( pSatDevData->sat48BitSupport != agTRUE )
12560    {
12561      /*
12562        writeSame10 but no support for 48 bit addressing
12563        -> problem in transfer length. Therefore, return check condition
12564      */
12565      smsatSetSensePayload( pSense,
12566                            SCSI_SNSKEY_ILLEGAL_REQUEST,
12567                            0,
12568                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12569                            satIOContext);
12570
12571      /*smEnqueueIO(smRoot, satIOContext);*/
12572
12573      tdsmIOCompletedCB( smRoot,
12574                         smIORequest,
12575                         smIOSuccess,
12576                         SCSI_STAT_CHECK_CONDITION,
12577                         satIOContext->pSmSenseData,
12578                         satIOContext->interruptContext );
12579
12580      SM_DBG1(("smsatWriteSame10: return internal checking!!!\n"));
12581      return SM_RC_SUCCESS;
12582    }
12583
12584    /* cdb10; computing LBA and transfer length */
12585    lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
12586      + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
12587    tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
12588
12589
12590    /* Table 34, 9.1, p 46 */
12591    /*
12592      note: As of 2/10/2006, no support for DMA QUEUED
12593    */
12594
12595    /*
12596      Table 34, 9.1, p 46, b (footnote)
12597      When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
12598      return check condition
12599    */
12600    if (pSatDevData->satNCQ != agTRUE &&
12601        pSatDevData->sat48BitSupport != agTRUE
12602          )
12603    {
12604      if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */
12605      {
12606        smsatSetSensePayload( pSense,
12607                              SCSI_SNSKEY_ILLEGAL_REQUEST,
12608                              0,
12609                              SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
12610                              satIOContext);
12611
12612        /*smEnqueueIO(smRoot, satIOContext);*/
12613
12614        tdsmIOCompletedCB( smRoot,
12615                           smIORequest,
12616                           smIOSuccess,
12617                           SCSI_STAT_CHECK_CONDITION,
12618                           satIOContext->pSmSenseData,
12619                           satIOContext->interruptContext );
12620
12621        SM_DBG1(("smsatWriteSame10: return LBA out of range!!!\n"));
12622        return SM_RC_SUCCESS;
12623      }
12624    }
12625
12626
12627    if (lba + tl <= SAT_TR_LBA_LIMIT)
12628    {
12629      if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
12630      {
12631        /* case 2 */
12632        /* WRITE DMA */
12633        /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
12634        SM_DBG1(("smsatWriteSame10: case 1-2 !!! error due to writesame10!!!\n"));
12635        smsatSetSensePayload( pSense,
12636                              SCSI_SNSKEY_ILLEGAL_REQUEST,
12637                              0,
12638                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12639                              satIOContext);
12640
12641        /*smEnqueueIO(smRoot, satIOContext);*/
12642
12643        tdsmIOCompletedCB( smRoot,
12644                           smIORequest,
12645                           smIOSuccess,
12646                           SCSI_STAT_CHECK_CONDITION,
12647                           satIOContext->pSmSenseData,
12648                           satIOContext->interruptContext );
12649        return SM_RC_SUCCESS;
12650      }
12651      else
12652      {
12653        /* case 1 */
12654        /* WRITE MULTIPLE or WRITE SECTOR(S) */
12655        /* WRITE SECTORS is chosen for easier implemetation */
12656        /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
12657        SM_DBG1(("smsatWriteSame10: case 1-1 !!! error due to writesame10!!!\n"));
12658        smsatSetSensePayload( pSense,
12659                              SCSI_SNSKEY_ILLEGAL_REQUEST,
12660                              0,
12661                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12662                              satIOContext);
12663
12664        /*smEnqueueIO(smRoot, satIOContext);*/
12665
12666        tdsmIOCompletedCB( smRoot,
12667                           smIORequest,
12668                           smIOSuccess,
12669                           SCSI_STAT_CHECK_CONDITION,
12670                           satIOContext->pSmSenseData,
12671                           satIOContext->interruptContext );
12672        return SM_RC_SUCCESS;
12673      }
12674    } /* end of case 1 and 2 */
12675
12676    /* case 3 and 4 */
12677    if (pSatDevData->sat48BitSupport == agTRUE)
12678    {
12679      if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
12680      {
12681        /* case 3 */
12682        /* WRITE DMA EXT or WRITE DMA FUA EXT */
12683        /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */
12684        SM_DBG5(("smsatWriteSame10: case 1-3\n"));
12685        fis->h.fisType        = 0x27;                   /* Reg host to device */
12686        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12687
12688        fis->h.command        = SAT_WRITE_DMA_EXT;          /* 0x35 */
12689
12690        fis->h.features       = 0;                      /* FIS reserve */
12691        fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
12692        fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
12693        fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
12694        fis->d.device         = 0x40;                   /* FIS LBA mode set */
12695        fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
12696        fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12697        fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12698        fis->d.featuresExp    = 0;                      /* FIS reserve */
12699        if (tl == 0)
12700        {
12701          /* error check
12702             ATA spec, p125, 6.17.29
12703             pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12704             and allowed value is 0x0FFFFFFF - 1
12705          */
12706          if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12707          {
12708            SM_DBG1(("smsatWriteSame10: case 3 !!! warning can't fit sectors!!!\n"));
12709            smsatSetSensePayload( pSense,
12710                                  SCSI_SNSKEY_ILLEGAL_REQUEST,
12711                                  0,
12712                                  SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12713                                  satIOContext);
12714
12715            /*smEnqueueIO(smRoot, satIOContext);*/
12716
12717            tdsmIOCompletedCB( smRoot,
12718                               smIORequest,
12719                               smIOSuccess,
12720                               SCSI_STAT_CHECK_CONDITION,
12721                               satIOContext->pSmSenseData,
12722                               satIOContext->interruptContext );
12723            return SM_RC_SUCCESS;
12724          }
12725        }
12726        /* one sector at a time */
12727        fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12728        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12729        fis->d.reserved4      = 0;
12730        fis->d.control        = 0;                      /* FIS HOB bit clear */
12731        fis->d.reserved5      = 0;
12732
12733        agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
12734      }
12735      else
12736      {
12737        /* case 4 */
12738        /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
12739        /* WRITE SECTORS EXT is chosen for easier implemetation */
12740        SM_DBG5(("smsatWriteSame10: case 1-4\n"));
12741        fis->h.fisType        = 0x27;                   /* Reg host to device */
12742        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12743
12744        fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
12745        fis->h.features       = 0;                      /* FIS reserve */
12746        fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
12747        fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
12748        fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
12749        fis->d.device         = 0x40;                   /* FIS LBA mode set */
12750        fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
12751        fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12752        fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12753        fis->d.featuresExp    = 0;                      /* FIS reserve */
12754        if (tl == 0)
12755        {
12756          /* error check
12757             ATA spec, p125, 6.17.29
12758             pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12759             and allowed value is 0x0FFFFFFF - 1
12760          */
12761          if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12762          {
12763            SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n"));
12764            smsatSetSensePayload( pSense,
12765                                  SCSI_SNSKEY_ILLEGAL_REQUEST,
12766                                  0,
12767                                  SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12768                                  satIOContext);
12769
12770            /*smEnqueueIO(smRoot, satIOContext);*/
12771
12772            tdsmIOCompletedCB( smRoot,
12773                               smIORequest,
12774                               smIOSuccess,
12775                               SCSI_STAT_CHECK_CONDITION,
12776                               satIOContext->pSmSenseData,
12777                               satIOContext->interruptContext );
12778            return SM_RC_SUCCESS;
12779          }
12780        }
12781        /* one sector at a time */
12782        fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12783        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12784        fis->d.reserved4      = 0;
12785        fis->d.control        = 0;                      /* FIS HOB bit clear */
12786        fis->d.reserved5      = 0;
12787
12788        agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
12789      }
12790    }
12791
12792    /* case 5 */
12793    if (pSatDevData->satNCQ == agTRUE)
12794    {
12795      /* WRITE FPDMA QUEUED */
12796      if (pSatDevData->sat48BitSupport != agTRUE)
12797      {
12798        SM_DBG1(("smsatWriteSame10: case 1-5 !!! error NCQ but 28 bit address support!!!\n"));
12799        smsatSetSensePayload( pSense,
12800                              SCSI_SNSKEY_ILLEGAL_REQUEST,
12801                              0,
12802                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12803                              satIOContext);
12804
12805        /*smEnqueueIO(smRoot, satIOContext);*/
12806
12807        tdsmIOCompletedCB( smRoot,
12808                           smIORequest,
12809                           smIOSuccess,
12810                           SCSI_STAT_CHECK_CONDITION,
12811                           satIOContext->pSmSenseData,
12812                           satIOContext->interruptContext );
12813        return SM_RC_SUCCESS;
12814      }
12815      SM_DBG5(("smsatWriteSame10: case 1-5\n"));
12816
12817      /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
12818
12819      fis->h.fisType        = 0x27;                   /* Reg host to device */
12820      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12821      fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
12822
12823      if (tl == 0)
12824      {
12825        /* error check
12826           ATA spec, p125, 6.17.29
12827           pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12828           and allowed value is 0x0FFFFFFF - 1
12829        */
12830        if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12831        {
12832          SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n"));
12833          smsatSetSensePayload( pSense,
12834                                SCSI_SNSKEY_ILLEGAL_REQUEST,
12835                                0,
12836                                SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12837                                satIOContext);
12838
12839          /*smEnqueueIO(smRoot, satIOContext);*/
12840
12841          tdsmIOCompletedCB( smRoot,
12842                             smIORequest,
12843                             smIOSuccess,
12844                             SCSI_STAT_CHECK_CONDITION,
12845                             satIOContext->pSmSenseData,
12846                             satIOContext->interruptContext );
12847          return SM_RC_SUCCESS;
12848        }
12849      }
12850      /* one sector at a time */
12851      fis->h.features       = 1;            /* FIS sector count (7:0) */
12852      fis->d.featuresExp    = 0;            /* FIS sector count (15:8) */
12853
12854
12855      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
12856      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
12857      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
12858
12859      /* NO FUA bit in the WRITE SAME 10 */
12860      fis->d.device       = 0x40;                     /* FIS FUA clear */
12861
12862      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
12863      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12864      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12865      fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
12866      fis->d.sectorCountExp = 0;
12867      fis->d.reserved4      = 0;
12868      fis->d.control        = 0;                      /* FIS HOB bit clear */
12869      fis->d.reserved5      = 0;
12870
12871      agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
12872    }
12873    /* Initialize CB for SATA completion.
12874     */
12875    satIOContext->satCompleteCB = &smsatWriteSame10CB;
12876
12877    /*
12878     * Prepare SGL and send FIS to LL layer.
12879     */
12880    satIOContext->reqType = agRequestType;       /* Save it */
12881
12882    status = smsataLLIOStart( smRoot,
12883                              smIORequest,
12884                              smDeviceHandle,
12885                              smScsiRequest,
12886                              satIOContext);
12887    return (status);
12888
12889
12890  } /* end of case 1 */
12891  else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12892             (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12893  {
12894    /* spec 9.26.2, Table 62, p64, case 2*/
12895    smsatSetSensePayload( pSense,
12896                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12897                          0,
12898                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12899                          satIOContext);
12900
12901    /*smEnqueueIO(smRoot, satIOContext);*/
12902
12903    tdsmIOCompletedCB( smRoot,
12904                       smIORequest,
12905                       smIOSuccess,
12906                       SCSI_STAT_CHECK_CONDITION,
12907                       satIOContext->pSmSenseData,
12908                       satIOContext->interruptContext );
12909
12910    SM_DBG5(("smsatWriteSame10: return Table 62 case 2\n"));
12911    return SM_RC_SUCCESS;
12912  }
12913  else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12914           !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12915  {
12916    SM_DBG5(("smsatWriteSame10: Table 62 case 3\n"));
12917
12918  }
12919  else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12920            (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */
12921  {
12922
12923    /* spec 9.26.2, Table 62, p64, case 4*/
12924    smsatSetSensePayload( pSense,
12925                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12926                          0,
12927                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12928                          satIOContext);
12929
12930    /*smEnqueueIO(smRoot, satIOContext);*/
12931
12932    tdsmIOCompletedCB( smRoot,
12933                       smIORequest,
12934                       smIOSuccess,
12935                       SCSI_STAT_CHECK_CONDITION,
12936                       satIOContext->pSmSenseData,
12937                       satIOContext->interruptContext );
12938
12939    SM_DBG5(("smsatWriteSame10: return Table 62 case 4\n"));
12940    return SM_RC_SUCCESS;
12941  }
12942
12943
12944  return SM_RC_SUCCESS;
12945}
12946
12947osGLOBAL bit32
12948smsatWriteSame16(
12949                  smRoot_t                  *smRoot,
12950                  smIORequest_t             *smIORequest,
12951                  smDeviceHandle_t          *smDeviceHandle,
12952                  smScsiInitiatorRequest_t  *smScsiRequest,
12953                  smSatIOContext_t            *satIOContext
12954                 )
12955{
12956  smScsiRspSense_t          *pSense;
12957
12958  pSense        = satIOContext->pSense;
12959
12960  SM_DBG5(("smsatWriteSame16: start\n"));
12961
12962
12963  smsatSetSensePayload( pSense,
12964                        SCSI_SNSKEY_NO_SENSE,
12965                        0,
12966                        SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12967                        satIOContext);
12968
12969  /*smEnqueueIO(smRoot, satIOContext);*/
12970
12971  tdsmIOCompletedCB( smRoot,
12972                     smIORequest, /* == &satIntIo->satOrgSmIORequest */
12973                     smIOSuccess,
12974                     SCSI_STAT_CHECK_CONDITION,
12975                     satIOContext->pSmSenseData,
12976                     satIOContext->interruptContext );
12977  SM_DBG1(("smsatWriteSame16: return internal checking!!!\n"));
12978  return SM_RC_SUCCESS;
12979}
12980
12981osGLOBAL bit32
12982smsatLogSense(
12983              smRoot_t                  *smRoot,
12984              smIORequest_t             *smIORequest,
12985              smDeviceHandle_t          *smDeviceHandle,
12986              smScsiInitiatorRequest_t  *smScsiRequest,
12987              smSatIOContext_t            *satIOContext
12988             )
12989{
12990  bit32                     status;
12991  bit32                     agRequestType;
12992  smDeviceData_t            *pSatDevData;
12993  smScsiRspSense_t          *pSense;
12994  smIniScsiCmnd_t           *scsiCmnd;
12995  agsaFisRegHostToDevice_t  *fis;
12996  bit8                      *pLogPage;    /* Log Page data buffer */
12997  bit32                     flag = 0;
12998  bit16                     AllocLen = 0;       /* allocation length */
12999  bit8                      AllLogPages[8];
13000  bit16                     lenRead = 0;
13001
13002  pSense        = satIOContext->pSense;
13003  pSatDevData   = satIOContext->pSatDevData;
13004  scsiCmnd      = &smScsiRequest->scsiCmnd;
13005  fis           = satIOContext->pFis;
13006  pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
13007
13008  SM_DBG5(("smsatLogSense: start\n"));
13009
13010  sm_memset(&AllLogPages, 0, 8);
13011  /* checking CONTROL */
13012  /* NACA == 1 or LINK == 1*/
13013  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13014  {
13015    smsatSetSensePayload( pSense,
13016                          SCSI_SNSKEY_ILLEGAL_REQUEST,
13017                          0,
13018                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13019                          satIOContext);
13020
13021    /*smEnqueueIO(smRoot, satIOContext);*/
13022
13023    tdsmIOCompletedCB( smRoot,
13024                       smIORequest,
13025                       smIOSuccess,
13026                       SCSI_STAT_CHECK_CONDITION,
13027                       satIOContext->pSmSenseData,
13028                       satIOContext->interruptContext );
13029
13030    SM_DBG1(("smsatLogSense: return control!!!\n"));
13031    return SM_RC_SUCCESS;
13032  }
13033
13034
13035  AllocLen = ((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
13036  AllocLen = MIN(AllocLen, scsiCmnd->expDataLength);
13037
13038  /* checking PC (Page Control) */
13039  /* nothing */
13040
13041  /* special cases */
13042  if (AllocLen == 4)
13043  {
13044    SM_DBG1(("smsatLogSense: AllocLen is 4!!!\n"));
13045    switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
13046    {
13047      case LOGSENSE_SUPPORTED_LOG_PAGES:
13048        SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13049
13050        if (pSatDevData->satSMARTFeatureSet == agTRUE)
13051        {
13052          /* add informational exception log */
13053          flag = 1;
13054          if (pSatDevData->satSMARTSelfTest == agTRUE)
13055          {
13056            /* add Self-Test results log page */
13057            flag = 2;
13058          }
13059        }
13060        else
13061        {
13062          /* only supported, no informational exception log, no  Self-Test results log page */
13063          flag = 0;
13064        }
13065        lenRead = 4;
13066        AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES;          /* page code */
13067        AllLogPages[1] = 0;          /* reserved  */
13068        switch (flag)
13069        {
13070          case 0:
13071            /* only supported */
13072            AllLogPages[2] = 0;          /* page length */
13073            AllLogPages[3] = 1;          /* page length */
13074            break;
13075          case 1:
13076            /* supported and informational exception log */
13077            AllLogPages[2] = 0;          /* page length */
13078            AllLogPages[3] = 2;          /* page length */
13079            break;
13080          case 2:
13081            /* supported and informational exception log */
13082            AllLogPages[2] = 0;          /* page length */
13083            AllLogPages[3] = 3;          /* page length */
13084            break;
13085          default:
13086            SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag));
13087            break;
13088        }
13089        sm_memcpy(pLogPage, &AllLogPages, lenRead);
13090        break;
13091      case LOGSENSE_SELFTEST_RESULTS_PAGE:
13092        SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13093        lenRead = 4;
13094        AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE;          /* page code */
13095        AllLogPages[1] = 0;          /* reserved  */
13096        /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */
13097        AllLogPages[2] = 0x01;
13098        AllLogPages[3] = 0x90;       /* page length */
13099        sm_memcpy(pLogPage, &AllLogPages, lenRead);
13100
13101        break;
13102      case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
13103        SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13104        lenRead = 4;
13105        AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE;          /* page code */
13106        AllLogPages[1] = 0;          /* reserved  */
13107        AllLogPages[2] = 0;          /* page length */
13108        AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3;       /* page length */
13109        sm_memcpy(pLogPage, &AllLogPages, lenRead);
13110        break;
13111      default:
13112        SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
13113        smsatSetSensePayload( pSense,
13114                              SCSI_SNSKEY_ILLEGAL_REQUEST,
13115                              0,
13116                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13117                              satIOContext);
13118
13119        /*smEnqueueIO(smRoot, satIOContext);*/
13120
13121        tdsmIOCompletedCB( smRoot,
13122                           smIORequest,
13123                           smIOSuccess,
13124                           SCSI_STAT_CHECK_CONDITION,
13125                           satIOContext->pSmSenseData,
13126                           satIOContext->interruptContext );
13127        return SM_RC_SUCCESS;
13128    }
13129    /*smEnqueueIO(smRoot, satIOContext);*/
13130
13131    tdsmIOCompletedCB( smRoot,
13132                       smIORequest,
13133                       smIOSuccess,
13134                       SCSI_STAT_GOOD,
13135                       agNULL,
13136                       satIOContext->interruptContext);
13137    return SM_RC_SUCCESS;
13138
13139  } /* if */
13140
13141  /* SAT rev8 Table 11  p30*/
13142  /* checking Page Code */
13143  switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
13144  {
13145    case LOGSENSE_SUPPORTED_LOG_PAGES:
13146      SM_DBG5(("smsatLogSense: case 1\n"));
13147
13148      if (pSatDevData->satSMARTFeatureSet == agTRUE)
13149      {
13150        /* add informational exception log */
13151        flag = 1;
13152        if (pSatDevData->satSMARTSelfTest == agTRUE)
13153        {
13154          /* add Self-Test results log page */
13155          flag = 2;
13156        }
13157      }
13158      else
13159      {
13160        /* only supported, no informational exception log, no  Self-Test results log page */
13161        flag = 0;
13162      }
13163      AllLogPages[0] = 0;          /* page code */
13164      AllLogPages[1] = 0;          /* reserved  */
13165      switch (flag)
13166      {
13167      case 0:
13168        /* only supported */
13169        AllLogPages[2] = 0;          /* page length */
13170        AllLogPages[3] = 1;          /* page length */
13171        AllLogPages[4] = 0x00;       /* supported page list */
13172        lenRead = (bit8)(MIN(AllocLen, 5));
13173        break;
13174      case 1:
13175        /* supported and informational exception log */
13176        AllLogPages[2] = 0;          /* page length */
13177        AllLogPages[3] = 2;          /* page length */
13178        AllLogPages[4] = 0x00;       /* supported page list */
13179        AllLogPages[5] = 0x10;       /* supported page list */
13180        lenRead = (bit8)(MIN(AllocLen, 6));
13181        break;
13182      case 2:
13183        /* supported and informational exception log */
13184        AllLogPages[2] = 0;          /* page length */
13185        AllLogPages[3] = 3;          /* page length */
13186        AllLogPages[4] = 0x00;       /* supported page list */
13187        AllLogPages[5] = 0x10;       /* supported page list */
13188        AllLogPages[6] = 0x2F;       /* supported page list */
13189       lenRead = (bit8)(MIN(AllocLen, 7));
13190       break;
13191      default:
13192        SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag));
13193        break;
13194      }
13195
13196      sm_memcpy(pLogPage, &AllLogPages, lenRead);
13197      /* comparing allocation length to Log Page byte size */
13198      /* SPC-4, 4.3.4.6, p28 */
13199      if (AllocLen > lenRead )
13200      {
13201        SM_DBG1(("smsatLogSense: reporting underrun lenRead=0x%x AllocLen=0x%x!!!\n", lenRead, AllocLen));
13202        /*smEnqueueIO(smRoot, satIOContext);*/
13203
13204        tdsmIOCompletedCB( smRoot,
13205                           smIORequest,
13206                           smIOUnderRun,
13207                           AllocLen - lenRead,
13208                           agNULL,
13209                           satIOContext->interruptContext );
13210      }
13211      else
13212      {
13213        /*smEnqueueIO(smRoot, satIOContext);*/
13214        tdsmIOCompletedCB( smRoot,
13215                           smIORequest,
13216                           smIOSuccess,
13217                           SCSI_STAT_GOOD,
13218                           agNULL,
13219                           satIOContext->interruptContext);
13220      }
13221      break;
13222    case LOGSENSE_SELFTEST_RESULTS_PAGE:
13223      SM_DBG5(("smsatLogSense: case 2\n"));
13224      /* checking SMART self-test */
13225      if (pSatDevData->satSMARTSelfTest == agFALSE)
13226      {
13227        SM_DBG5(("smsatLogSense: case 2 no SMART Self Test\n"));
13228        smsatSetSensePayload( pSense,
13229                              SCSI_SNSKEY_ILLEGAL_REQUEST,
13230                              0,
13231                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13232                              satIOContext);
13233
13234        /*smEnqueueIO(smRoot, satIOContext);*/
13235
13236        tdsmIOCompletedCB( smRoot,
13237                           smIORequest,
13238                           smIOSuccess,
13239                           SCSI_STAT_CHECK_CONDITION,
13240                           satIOContext->pSmSenseData,
13241                           satIOContext->interruptContext );
13242      }
13243      else
13244      {
13245        /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */
13246        if (pSatDevData->satSMARTEnabled == agFALSE)
13247        {
13248          SM_DBG5(("smsatLogSense: case 2 calling satSMARTEnable\n"));
13249          status = smsatLogSenseAllocate(smRoot,
13250                                         smIORequest,
13251                                         smDeviceHandle,
13252                                         smScsiRequest,
13253                                         satIOContext,
13254                                         0,
13255                                         LOG_SENSE_0
13256                                         );
13257
13258          return status;
13259
13260        }
13261        else
13262        {
13263        /* SAT Rev 8, 10.2.4 p74 */
13264        if ( pSatDevData->sat48BitSupport == agTRUE )
13265        {
13266          SM_DBG5(("smsatLogSense: case 2-1 sends READ LOG EXT\n"));
13267          status = smsatLogSenseAllocate(smRoot,
13268                                         smIORequest,
13269                                         smDeviceHandle,
13270                                         smScsiRequest,
13271                                         satIOContext,
13272                                         512,
13273                                         LOG_SENSE_1
13274                                         );
13275
13276          return status;
13277        }
13278        else
13279        {
13280          SM_DBG5(("smsatLogSense: case 2-2 sends SMART READ LOG\n"));
13281          status = smsatLogSenseAllocate(smRoot,
13282                                         smIORequest,
13283                                         smDeviceHandle,
13284                                         smScsiRequest,
13285                                         satIOContext,
13286                                         512,
13287                                         LOG_SENSE_2
13288                                         );
13289
13290          return status;
13291        }
13292      }
13293      }
13294      break;
13295    case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
13296      SM_DBG5(("smsatLogSense: case 3\n"));
13297      /* checking SMART feature set */
13298      if (pSatDevData->satSMARTFeatureSet == agFALSE)
13299      {
13300        smsatSetSensePayload( pSense,
13301                              SCSI_SNSKEY_ILLEGAL_REQUEST,
13302                              0,
13303                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13304                              satIOContext);
13305
13306        /*smEnqueueIO(smRoot, satIOContext);*/
13307
13308        tdsmIOCompletedCB( smRoot,
13309                           smIORequest,
13310                           smIOSuccess,
13311                           SCSI_STAT_CHECK_CONDITION,
13312                           satIOContext->pSmSenseData,
13313                           satIOContext->interruptContext );
13314      }
13315      else
13316      {
13317        /* checking SMART feature enabled */
13318        if (pSatDevData->satSMARTEnabled == agFALSE)
13319        {
13320          smsatSetSensePayload( pSense,
13321                                SCSI_SNSKEY_ABORTED_COMMAND,
13322                                0,
13323                                SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
13324                                satIOContext);
13325
13326          /*smEnqueueIO(smRoot, satIOContext);*/
13327
13328          tdsmIOCompletedCB( smRoot,
13329                             smIORequest,
13330                             smIOSuccess,
13331                             SCSI_STAT_CHECK_CONDITION,
13332                             satIOContext->pSmSenseData,
13333                             satIOContext->interruptContext );
13334        }
13335        else
13336        {
13337          /* SAT Rev 8, 10.2.3 p72 */
13338          SM_DBG5(("smsatLogSense: case 3 sends SMART RETURN STATUS\n"));
13339
13340          /* sends SMART RETURN STATUS */
13341          fis->h.fisType        = 0x27;                   /* Reg host to device */
13342          fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13343
13344          fis->h.command        = SAT_SMART;              /* 0xB0 */
13345          fis->h.features       = SAT_SMART_RETURN_STATUS;/* FIS features */
13346          fis->d.featuresExp    = 0;                      /* FIS reserve */
13347          fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13348          fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
13349          fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13350          fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
13351          fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
13352          fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13353          fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
13354          fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13355          fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13356          fis->d.control        = 0;                      /* FIS HOB bit clear */
13357          fis->d.reserved4      = 0;
13358          fis->d.reserved5      = 0;
13359
13360          agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13361          /* Initialize CB for SATA completion.
13362           */
13363          satIOContext->satCompleteCB = &smsatLogSenseCB;
13364
13365          /*
13366           * Prepare SGL and send FIS to LL layer.
13367           */
13368          satIOContext->reqType = agRequestType;       /* Save it */
13369
13370          status = smsataLLIOStart( smRoot,
13371                                    smIORequest,
13372                                    smDeviceHandle,
13373                                    smScsiRequest,
13374                                    satIOContext);
13375
13376
13377          return status;
13378        }
13379      }
13380      break;
13381    default:
13382      SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
13383      smsatSetSensePayload( pSense,
13384                            SCSI_SNSKEY_ILLEGAL_REQUEST,
13385                            0,
13386                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13387                            satIOContext);
13388
13389      /*smEnqueueIO(smRoot, satIOContext);*/
13390
13391      tdsmIOCompletedCB( smRoot,
13392                         smIORequest,
13393                         smIOSuccess,
13394                         SCSI_STAT_CHECK_CONDITION,
13395                         satIOContext->pSmSenseData,
13396                         satIOContext->interruptContext );
13397
13398      break;
13399  } /* end switch */
13400
13401  return SM_RC_SUCCESS;
13402}
13403
13404osGLOBAL bit32
13405smsatLogSenseAllocate(
13406                      smRoot_t                  *smRoot,
13407                      smIORequest_t             *smIORequest,
13408                      smDeviceHandle_t          *smDeviceHandle,
13409                      smScsiInitiatorRequest_t  *smSCSIRequest,
13410                      smSatIOContext_t            *satIOContext,
13411                      bit32                     payloadSize,
13412                      bit32                     flag
13413                     )
13414{
13415  smDeviceData_t            *pSatDevData;
13416  smIORequestBody_t         *smIORequestBody;
13417  smSatInternalIo_t           *satIntIo = agNULL;
13418  smSatIOContext_t            *satIOContext2;
13419  bit32                     status;
13420
13421  SM_DBG5(("smsatLogSenseAllocate: start\n"));
13422
13423  pSatDevData       = satIOContext->pSatDevData;
13424
13425  /* create internal satIOContext */
13426  satIntIo = smsatAllocIntIoResource( smRoot,
13427                                      smIORequest, /* original request */
13428                                      pSatDevData,
13429                                      payloadSize,
13430                                      satIntIo);
13431
13432  if (satIntIo == agNULL)
13433  {
13434    /*smEnqueueIO(smRoot, satIOContext);*/
13435
13436    tdsmIOCompletedCB( smRoot,
13437                       smIORequest,
13438                       smIOFailed,
13439                       smDetailOtherError,
13440                       agNULL,
13441                       satIOContext->interruptContext );
13442
13443    SM_DBG1(("smsatLogSenseAllocate: fail in allocation!!!\n"));
13444    return SM_RC_SUCCESS;
13445  } /* end of memory allocation failure */
13446
13447  satIntIo->satOrgSmIORequest = smIORequest;
13448  smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
13449  satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);
13450
13451  satIOContext2->pSatDevData   = pSatDevData;
13452  satIOContext2->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
13453  satIOContext2->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
13454  satIOContext2->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
13455  satIOContext2->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
13456  satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;
13457  satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
13458  satIOContext2->interruptContext = satIOContext->interruptContext;
13459  satIOContext2->satIntIoContext  = satIntIo;
13460  satIOContext2->psmDeviceHandle = smDeviceHandle;
13461  satIOContext2->satOrgIOContext = satIOContext;
13462
13463  if (flag == LOG_SENSE_0)
13464  {
13465    /* SAT_SMART_ENABLE_OPERATIONS */
13466    status = smsatSMARTEnable( smRoot,
13467                               &(satIntIo->satIntSmIORequest),
13468                               smDeviceHandle,
13469                               &(satIntIo->satIntSmScsiXchg),
13470                               satIOContext2);
13471  }
13472  else if (flag == LOG_SENSE_1)
13473  {
13474    /* SAT_READ_LOG_EXT */
13475    status = smsatLogSense_2( smRoot,
13476                              &(satIntIo->satIntSmIORequest),
13477                              smDeviceHandle,
13478                              &(satIntIo->satIntSmScsiXchg),
13479                              satIOContext2);
13480  }
13481  else
13482  {
13483    /* SAT_SMART_READ_LOG */
13484    /* SAT_READ_LOG_EXT */
13485    status = smsatLogSense_3( smRoot,
13486                              &(satIntIo->satIntSmIORequest),
13487                              smDeviceHandle,
13488                              &(satIntIo->satIntSmScsiXchg),
13489                              satIOContext2);
13490
13491  }
13492  if (status != SM_RC_SUCCESS)
13493  {
13494    smsatFreeIntIoResource( smRoot,
13495                            pSatDevData,
13496                            satIntIo);
13497
13498    /*smEnqueueIO(smRoot, satIOContext);*/
13499
13500    tdsmIOCompletedCB( smRoot,
13501                       smIORequest,
13502                       smIOFailed,
13503                       smDetailOtherError,
13504                       agNULL,
13505                       satIOContext->interruptContext );
13506    return SM_RC_SUCCESS;
13507  }
13508
13509
13510  return SM_RC_SUCCESS;
13511}
13512
13513osGLOBAL bit32
13514smsatSMARTEnable(
13515                 smRoot_t                  *smRoot,
13516                 smIORequest_t             *smIORequest,
13517                 smDeviceHandle_t          *smDeviceHandle,
13518                 smScsiInitiatorRequest_t  *smScsiRequest,
13519                 smSatIOContext_t            *satIOContext
13520               )
13521{
13522  bit32                     status;
13523  bit32                     agRequestType;
13524  agsaFisRegHostToDevice_t  *fis;
13525
13526  fis               = satIOContext->pFis;
13527  SM_DBG5(("smsatSMARTEnable: start\n"));
13528  /*
13529   * Send the SAT_SMART_ENABLE_OPERATIONS command.
13530   */
13531  fis->h.fisType        = 0x27;                   /* Reg host to device */
13532  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13533  fis->h.command        = SAT_SMART;              /* 0xB0 */
13534  fis->h.features       = SAT_SMART_ENABLE_OPERATIONS;
13535  fis->d.lbaLow         = 0;
13536  fis->d.lbaMid         = 0x4F;
13537  fis->d.lbaHigh        = 0xC2;
13538  fis->d.device         = 0;
13539  fis->d.lbaLowExp      = 0;
13540  fis->d.lbaMidExp      = 0;
13541  fis->d.lbaHighExp     = 0;
13542  fis->d.featuresExp    = 0;
13543  fis->d.sectorCount    = 0;
13544  fis->d.sectorCountExp = 0;
13545  fis->d.reserved4      = 0;
13546  fis->d.control        = 0;                      /* FIS HOB bit clear */
13547  fis->d.reserved5      = 0;
13548
13549  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13550
13551  /* Initialize CB for SATA completion.
13552   */
13553  satIOContext->satCompleteCB = &smsatSMARTEnableCB;
13554
13555  /*
13556   * Prepare SGL and send FIS to LL layer.
13557   */
13558  satIOContext->reqType = agRequestType;       /* Save it */
13559
13560  status = smsataLLIOStart( smRoot,
13561                            smIORequest,
13562                            smDeviceHandle,
13563                            smScsiRequest,
13564                            satIOContext);
13565
13566
13567  return status;
13568}
13569
13570osGLOBAL bit32
13571smsatLogSense_2(
13572                smRoot_t                  *smRoot,
13573                smIORequest_t             *smIORequest,
13574                smDeviceHandle_t          *smDeviceHandle,
13575                smScsiInitiatorRequest_t  *smScsiRequest,
13576                smSatIOContext_t            *satIOContext
13577               )
13578{
13579  bit32                     status;
13580  bit32                     agRequestType;
13581  agsaFisRegHostToDevice_t  *fis;
13582
13583  fis               = satIOContext->pFis;
13584  SM_DBG5(("smsatLogSense_2: start\n"));
13585
13586  /* sends READ LOG EXT */
13587  fis->h.fisType        = 0x27;                   /* Reg host to device */
13588  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13589
13590  fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
13591  fis->h.features       = 0;                      /* FIS reserve */
13592  fis->d.lbaLow         = 0x07;                   /* 0x07 */
13593  fis->d.lbaMid         = 0;                      /*  */
13594  fis->d.lbaHigh        = 0;                      /*  */
13595  fis->d.device         = 0;                      /*  */
13596  fis->d.lbaLowExp      = 0;                      /*  */
13597  fis->d.lbaMidExp      = 0;                      /*  */
13598  fis->d.lbaHighExp     = 0;                      /*  */
13599  fis->d.featuresExp    = 0;                      /* FIS reserve */
13600  fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
13601  fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
13602  fis->d.reserved4      = 0;
13603  fis->d.control        = 0;                      /* FIS HOB bit clear */
13604  fis->d.reserved5      = 0;
13605
13606  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
13607
13608  /* Initialize CB for SATA completion.
13609   */
13610  satIOContext->satCompleteCB = &smsatLogSenseCB;
13611
13612  /*
13613   * Prepare SGL and send FIS to LL layer.
13614   */
13615  satIOContext->reqType = agRequestType;       /* Save it */
13616
13617  status = smsataLLIOStart( smRoot,
13618                            smIORequest,
13619                            smDeviceHandle,
13620                            smScsiRequest,
13621                            satIOContext);
13622  return status;
13623}
13624
13625osGLOBAL bit32
13626smsatLogSense_3(
13627                smRoot_t                  *smRoot,
13628                smIORequest_t             *smIORequest,
13629                smDeviceHandle_t          *smDeviceHandle,
13630                smScsiInitiatorRequest_t  *smScsiRequest,
13631                smSatIOContext_t            *satIOContext
13632               )
13633{
13634  bit32                     status;
13635  bit32                     agRequestType;
13636  agsaFisRegHostToDevice_t  *fis;
13637
13638  fis               = satIOContext->pFis;
13639  SM_DBG5(("smsatLogSense_3: start\n"));
13640  /* sends READ LOG EXT */
13641  fis->h.fisType        = 0x27;                   /* Reg host to device */
13642  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13643  fis->h.command        = SAT_SMART;              /* 0x2F */
13644  fis->h.features       = SAT_SMART_READ_LOG;     /* 0xd5 */
13645  fis->d.lbaLow         = 0x06;                   /* 0x06 */
13646  fis->d.lbaMid         = 0x4F;                   /* 0x4f */
13647  fis->d.lbaHigh        = 0xC2;                   /* 0xc2 */
13648  fis->d.device         = 0;                      /*  */
13649  fis->d.lbaLowExp      = 0;                      /*  */
13650  fis->d.lbaMidExp      = 0;                      /*  */
13651  fis->d.lbaHighExp     = 0;                      /*  */
13652  fis->d.featuresExp    = 0;                      /* FIS reserve */
13653  fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
13654  fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
13655  fis->d.reserved4      = 0;
13656  fis->d.control        = 0;                      /* FIS HOB bit clear */
13657  fis->d.reserved5      = 0;
13658  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
13659  /* Initialize CB for SATA completion.
13660   */
13661  satIOContext->satCompleteCB = &smsatLogSenseCB;
13662  /*
13663   * Prepare SGL and send FIS to LL layer.
13664   */
13665  satIOContext->reqType = agRequestType;       /* Save it */
13666  status = smsataLLIOStart( smRoot,
13667                            smIORequest,
13668                            smDeviceHandle,
13669                            smScsiRequest,
13670                            satIOContext);
13671  return status;
13672}
13673
13674
13675osGLOBAL bit32
13676smsatModeSelect6(
13677                 smRoot_t                  *smRoot,
13678                 smIORequest_t             *smIORequest,
13679                 smDeviceHandle_t          *smDeviceHandle,
13680                 smScsiInitiatorRequest_t  *smScsiRequest,
13681                 smSatIOContext_t            *satIOContext
13682                )
13683{
13684  bit32                     status;
13685  bit32                     agRequestType;
13686  smDeviceData_t            *pSatDevData;
13687  smScsiRspSense_t          *pSense;
13688  smIniScsiCmnd_t           *scsiCmnd;
13689  agsaFisRegHostToDevice_t  *fis;
13690  bit8                      *pLogPage;    /* Log Page data buffer */
13691  bit32                     StartingIndex = 0;
13692  bit8                      PageCode = 0;
13693  bit32                     chkCnd = agFALSE;
13694  bit32                     parameterListLen = 0;
13695
13696  pSense        = satIOContext->pSense;
13697  pSatDevData   = satIOContext->pSatDevData;
13698  scsiCmnd      = &smScsiRequest->scsiCmnd;
13699  fis           = satIOContext->pFis;
13700  pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
13701
13702  SM_DBG5(("smsatModeSelect6: start\n"));
13703
13704  /* checking CONTROL */
13705  /* NACA == 1 or LINK == 1*/
13706  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
13707  {
13708    smsatSetSensePayload( pSense,
13709                          SCSI_SNSKEY_ILLEGAL_REQUEST,
13710                          0,
13711                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13712                          satIOContext);
13713
13714    /*smEnqueueIO(smRoot, satIOContext);*/
13715
13716    tdsmIOCompletedCB( smRoot,
13717                       smIORequest,
13718                       smIOSuccess,
13719                       SCSI_STAT_CHECK_CONDITION,
13720                       satIOContext->pSmSenseData,
13721                       satIOContext->interruptContext );
13722
13723    SM_DBG1(("smsatModeSelect6: return control!!!\n"));
13724    return SM_RC_SUCCESS;
13725  }
13726
13727  /* checking PF bit */
13728  if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
13729  {
13730    smsatSetSensePayload( pSense,
13731                          SCSI_SNSKEY_ILLEGAL_REQUEST,
13732                          0,
13733                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13734                          satIOContext);
13735
13736    /*smEnqueueIO(smRoot, satIOContext);*/
13737
13738    tdsmIOCompletedCB( smRoot,
13739                       smIORequest,
13740                       smIOSuccess,
13741                       SCSI_STAT_CHECK_CONDITION,
13742                       satIOContext->pSmSenseData,
13743                       satIOContext->interruptContext );
13744
13745    SM_DBG1(("smsatModeSelect6: PF bit check!!!\n"));
13746    return SM_RC_SUCCESS;
13747  }
13748
13749  parameterListLen = scsiCmnd->cdb[4];
13750  parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength);
13751  if ((0 == parameterListLen) || (agNULL == pLogPage))
13752  {
13753    tdsmIOCompletedCB( smRoot,
13754                       smIORequest,
13755                       smIOSuccess,
13756                       SCSI_STAT_GOOD,
13757                       agNULL,
13758                       satIOContext->interruptContext);
13759    return SM_RC_SUCCESS;
13760  }
13761
13762  /* checking Block Descriptor Length on Mode parameter header(6)*/
13763  if (pLogPage[3] == 8)
13764  {
13765    /* mode parameter block descriptor exists */
13766    PageCode = (bit8)(pLogPage[12] & 0x3F);   /* page code and index is 4 + 8 */
13767    StartingIndex = 12;
13768  }
13769  else if (pLogPage[3] == 0)
13770  {
13771    /* mode parameter block descriptor does not exist */
13772    PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */
13773    StartingIndex = 4;
13774    /*smEnqueueIO(smRoot, satIOContext);*/
13775
13776    tdsmIOCompletedCB( smRoot,
13777                       smIORequest,
13778                       smIOSuccess,
13779                       SCSI_STAT_GOOD,
13780                       agNULL,
13781                       satIOContext->interruptContext);
13782    return SM_RC_SUCCESS;
13783  }
13784  else
13785  {
13786    SM_DBG1(("smsatModeSelect6: return mode parameter block descriptor 0x%x!!!\n", pLogPage[3]));
13787
13788    smsatSetSensePayload( pSense,
13789                          SCSI_SNSKEY_NO_SENSE,
13790                          0,
13791                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
13792                          satIOContext);
13793
13794    /*smEnqueueIO(smRoot, satIOContext);*/
13795
13796    tdsmIOCompletedCB( smRoot,
13797                       smIORequest,
13798                       smIOSuccess,
13799                       SCSI_STAT_CHECK_CONDITION,
13800                       satIOContext->pSmSenseData,
13801                       satIOContext->interruptContext );
13802    return SM_RC_SUCCESS;
13803  }
13804
13805
13806
13807  switch (PageCode) /* page code */
13808  {
13809  case MODESELECT_CONTROL_PAGE:
13810    SM_DBG1(("smsatModeSelect6: Control mode page!!!\n"));
13811
13812    if ( pLogPage[StartingIndex+1] != 0x0A ||
13813         pLogPage[StartingIndex+2] != 0x02 ||
13814         (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
13815         (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
13816         (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
13817         (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
13818         (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
13819
13820         (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
13821         (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
13822         (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
13823         (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
13824
13825         pLogPage[StartingIndex+8] != 0xFF ||
13826         pLogPage[StartingIndex+9] != 0xFF ||
13827         pLogPage[StartingIndex+10] != 0x00 ||
13828         pLogPage[StartingIndex+11] != 0x00
13829       )
13830    {
13831      chkCnd = agTRUE;
13832    }
13833    if (chkCnd == agTRUE)
13834    {
13835      smsatSetSensePayload( pSense,
13836                            SCSI_SNSKEY_ILLEGAL_REQUEST,
13837                            0,
13838                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13839                            satIOContext);
13840
13841      /*smEnqueueIO(smRoot, satIOContext);*/
13842
13843      tdsmIOCompletedCB( smRoot,
13844                         smIORequest,
13845                         smIOSuccess,
13846                         SCSI_STAT_CHECK_CONDITION,
13847                         satIOContext->pSmSenseData,
13848                         satIOContext->interruptContext );
13849
13850      SM_DBG1(("smsatModeSelect6: unexpected values!!!\n"));
13851    }
13852    else
13853    {
13854      /*smEnqueueIO(smRoot, satIOContext);*/
13855
13856      tdsmIOCompletedCB( smRoot,
13857                         smIORequest,
13858                         smIOSuccess,
13859                         SCSI_STAT_GOOD,
13860                         agNULL,
13861                         satIOContext->interruptContext);
13862    }
13863    return SM_RC_SUCCESS;
13864    break;
13865  case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
13866    SM_DBG1(("smsatModeSelect6: Read-Write Error Recovery mode page!!!\n"));
13867
13868    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) ||
13869         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) ||
13870         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) ||
13871         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) ||
13872         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) ||
13873         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) ||
13874         (pLogPage[StartingIndex + 10]) ||
13875         (pLogPage[StartingIndex + 11])
13876         )
13877    {
13878      SM_DBG5(("smsatModeSelect6: return check condition\n"));
13879
13880      smsatSetSensePayload( pSense,
13881                            SCSI_SNSKEY_ILLEGAL_REQUEST,
13882                            0,
13883                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13884                            satIOContext);
13885
13886      /*smEnqueueIO(smRoot, satIOContext);*/
13887
13888      tdsmIOCompletedCB( smRoot,
13889                         smIORequest,
13890                         smIOSuccess,
13891                         SCSI_STAT_CHECK_CONDITION,
13892                         satIOContext->pSmSenseData,
13893                         satIOContext->interruptContext );
13894      return SM_RC_SUCCESS;
13895    }
13896    else
13897    {
13898      SM_DBG5(("smsatModeSelect6: return GOOD \n"));
13899      /*smEnqueueIO(smRoot, satIOContext);*/
13900
13901      tdsmIOCompletedCB( smRoot,
13902                         smIORequest,
13903                         smIOSuccess,
13904                         SCSI_STAT_GOOD,
13905                         agNULL,
13906                         satIOContext->interruptContext);
13907      return SM_RC_SUCCESS;
13908    }
13909
13910    break;
13911  case MODESELECT_CACHING:
13912    /* SAT rev8 Table67, p69*/
13913    SM_DBG5(("smsatModeSelect6: Caching mode page\n"));
13914    if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
13915         (pLogPage[StartingIndex + 3]) ||
13916         (pLogPage[StartingIndex + 4]) ||
13917         (pLogPage[StartingIndex + 5]) ||
13918         (pLogPage[StartingIndex + 6]) ||
13919         (pLogPage[StartingIndex + 7]) ||
13920         (pLogPage[StartingIndex + 8]) ||
13921         (pLogPage[StartingIndex + 9]) ||
13922         (pLogPage[StartingIndex + 10]) ||
13923         (pLogPage[StartingIndex + 11]) ||
13924
13925         (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
13926         (pLogPage[StartingIndex + 13]) ||
13927         (pLogPage[StartingIndex + 14]) ||
13928         (pLogPage[StartingIndex + 15])
13929         )
13930    {
13931      SM_DBG1(("smsatModeSelect6: return check condition!!!\n"));
13932
13933      smsatSetSensePayload( pSense,
13934                            SCSI_SNSKEY_ILLEGAL_REQUEST,
13935                            0,
13936                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13937                            satIOContext);
13938
13939      /*smEnqueueIO(smRoot, satIOContext);*/
13940
13941      tdsmIOCompletedCB( smRoot,
13942                         smIORequest,
13943                         smIOSuccess,
13944                         SCSI_STAT_CHECK_CONDITION,
13945                         satIOContext->pSmSenseData,
13946                         satIOContext->interruptContext );
13947      return SM_RC_SUCCESS;
13948
13949    }
13950    else
13951    {
13952      /* sends ATA SET FEATURES based on WCE bit */
13953      if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
13954      {
13955        SM_DBG5(("smsatModeSelect6: disable write cache\n"));
13956        /* sends SET FEATURES */
13957        fis->h.fisType        = 0x27;                   /* Reg host to device */
13958        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13959
13960        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
13961        fis->h.features       = 0x82;                   /* disable write cache */
13962        fis->d.lbaLow         = 0;                      /* */
13963        fis->d.lbaMid         = 0;                      /* */
13964        fis->d.lbaHigh        = 0;                      /* */
13965        fis->d.device         = 0;                      /* */
13966        fis->d.lbaLowExp      = 0;                      /* */
13967        fis->d.lbaMidExp      = 0;                      /* */
13968        fis->d.lbaHighExp     = 0;                      /* */
13969        fis->d.featuresExp    = 0;                      /* */
13970        fis->d.sectorCount    = 0;                      /* */
13971        fis->d.sectorCountExp = 0;                      /* */
13972        fis->d.reserved4      = 0;
13973        fis->d.control        = 0;                      /* FIS HOB bit clear */
13974        fis->d.reserved5      = 0;
13975
13976        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13977
13978        /* Initialize CB for SATA completion.
13979         */
13980        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
13981
13982        /*
13983         * Prepare SGL and send FIS to LL layer.
13984         */
13985        satIOContext->reqType = agRequestType;       /* Save it */
13986
13987        status = smsataLLIOStart( smRoot,
13988                                  smIORequest,
13989                                  smDeviceHandle,
13990                                  smScsiRequest,
13991                                  satIOContext);
13992        return status;
13993      }
13994      else
13995      {
13996        SM_DBG5(("smsatModeSelect6: enable write cache\n"));
13997        /* sends SET FEATURES */
13998        fis->h.fisType        = 0x27;                   /* Reg host to device */
13999        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14000
14001        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
14002        fis->h.features       = 0x02;                   /* enable write cache */
14003        fis->d.lbaLow         = 0;                      /* */
14004        fis->d.lbaMid         = 0;                      /* */
14005        fis->d.lbaHigh        = 0;                      /* */
14006        fis->d.device         = 0;                      /* */
14007        fis->d.lbaLowExp      = 0;                      /* */
14008        fis->d.lbaMidExp      = 0;                      /* */
14009        fis->d.lbaHighExp     = 0;                      /* */
14010        fis->d.featuresExp    = 0;                      /* */
14011        fis->d.sectorCount    = 0;                      /* */
14012        fis->d.sectorCountExp = 0;                      /* */
14013        fis->d.reserved4      = 0;
14014        fis->d.control        = 0;                      /* FIS HOB bit clear */
14015        fis->d.reserved5      = 0;
14016
14017        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14018
14019        /* Initialize CB for SATA completion.
14020         */
14021        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14022
14023        /*
14024         * Prepare SGL and send FIS to LL layer.
14025         */
14026        satIOContext->reqType = agRequestType;       /* Save it */
14027
14028        status = smsataLLIOStart( smRoot,
14029                                  smIORequest,
14030                                  smDeviceHandle,
14031                                  smScsiRequest,
14032                                  satIOContext);
14033        return status;
14034
14035      }
14036    }
14037    break;
14038  case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
14039    SM_DBG5(("smsatModeSelect6: Informational Exception Control mode page\n"));
14040
14041    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
14042         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
14043         )
14044    {
14045      SM_DBG1(("smsatModeSelect6: return check condition!!! \n"));
14046
14047      smsatSetSensePayload( pSense,
14048                            SCSI_SNSKEY_ILLEGAL_REQUEST,
14049                            0,
14050                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14051                            satIOContext);
14052
14053      /*smEnqueueIO(smRoot, satIOContext);*/
14054
14055      tdsmIOCompletedCB( smRoot,
14056                         smIORequest,
14057                         smIOSuccess,
14058                         SCSI_STAT_CHECK_CONDITION,
14059                         satIOContext->pSmSenseData,
14060                         satIOContext->interruptContext );
14061      return SM_RC_SUCCESS;
14062    }
14063    else
14064    {
14065      /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
14066      if ( !(pLogPage[StartingIndex + 2] & 0x08) )
14067      {
14068        SM_DBG5(("smsatModeSelect6: enable information exceptions reporting\n"));
14069        /* sends SMART ENABLE OPERATIONS */
14070        fis->h.fisType        = 0x27;                   /* Reg host to device */
14071        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14072
14073        fis->h.command        = SAT_SMART;              /* 0xB0 */
14074        fis->h.features       = SAT_SMART_ENABLE_OPERATIONS;       /* enable */
14075        fis->d.lbaLow         = 0;                      /* */
14076        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14077        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14078        fis->d.device         = 0;                      /* */
14079        fis->d.lbaLowExp      = 0;                      /* */
14080        fis->d.lbaMidExp      = 0;                      /* */
14081        fis->d.lbaHighExp     = 0;                      /* */
14082        fis->d.featuresExp    = 0;                      /* */
14083        fis->d.sectorCount    = 0;                      /* */
14084        fis->d.sectorCountExp = 0;                      /* */
14085        fis->d.reserved4      = 0;
14086        fis->d.control        = 0;                      /* FIS HOB bit clear */
14087        fis->d.reserved5      = 0;
14088
14089        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14090
14091        /* Initialize CB for SATA completion.
14092         */
14093        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14094
14095        /*
14096         * Prepare SGL and send FIS to LL layer.
14097         */
14098        satIOContext->reqType = agRequestType;       /* Save it */
14099
14100        status = smsataLLIOStart( smRoot,
14101                                  smIORequest,
14102                                  smDeviceHandle,
14103                                  smScsiRequest,
14104                                  satIOContext);
14105        return status;
14106      }
14107      else
14108      {
14109        SM_DBG5(("smsatModeSelect6: disable information exceptions reporting\n"));
14110        /* sends SMART DISABLE OPERATIONS */
14111        fis->h.fisType        = 0x27;                   /* Reg host to device */
14112        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14113
14114        fis->h.command        = SAT_SMART;              /* 0xB0 */
14115        fis->h.features       = SAT_SMART_DISABLE_OPERATIONS; /* disable */
14116        fis->d.lbaLow         = 0;                      /* */
14117        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14118        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14119        fis->d.device         = 0;                      /* */
14120        fis->d.lbaLowExp      = 0;                      /* */
14121        fis->d.lbaMidExp      = 0;                      /* */
14122        fis->d.lbaHighExp     = 0;                      /* */
14123        fis->d.featuresExp    = 0;                      /* */
14124        fis->d.sectorCount    = 0;                      /* */
14125        fis->d.sectorCountExp = 0;                      /* */
14126        fis->d.reserved4      = 0;
14127        fis->d.control        = 0;                      /* FIS HOB bit clear */
14128        fis->d.reserved5      = 0;
14129
14130        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14131
14132        /* Initialize CB for SATA completion.
14133         */
14134        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14135
14136        /*
14137         * Prepare SGL and send FIS to LL layer.
14138         */
14139        satIOContext->reqType = agRequestType;       /* Save it */
14140
14141        status = smsataLLIOStart( smRoot,
14142                                  smIORequest,
14143                                  smDeviceHandle,
14144                                  smScsiRequest,
14145                                  satIOContext);
14146        return status;
14147
14148      }
14149    }
14150    break;
14151  default:
14152    SM_DBG1(("smsatModeSelect6: Error unknown page code 0x%x!!!\n", pLogPage[12]));
14153    smsatSetSensePayload( pSense,
14154                          SCSI_SNSKEY_NO_SENSE,
14155                          0,
14156                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14157                          satIOContext);
14158
14159    /*smEnqueueIO(smRoot, satIOContext);*/
14160
14161    tdsmIOCompletedCB( smRoot,
14162                       smIORequest,
14163                       smIOSuccess,
14164                       SCSI_STAT_CHECK_CONDITION,
14165                       satIOContext->pSmSenseData,
14166                       satIOContext->interruptContext );
14167    return SM_RC_SUCCESS;
14168  }
14169}
14170
14171
14172osGLOBAL bit32
14173smsatModeSelect10(
14174                  smRoot_t                  *smRoot,
14175                  smIORequest_t             *smIORequest,
14176                  smDeviceHandle_t          *smDeviceHandle,
14177                  smScsiInitiatorRequest_t  *smScsiRequest,
14178                  smSatIOContext_t            *satIOContext
14179                 )
14180{
14181  bit32                     status;
14182  bit32                     agRequestType;
14183  smDeviceData_t            *pSatDevData;
14184  smScsiRspSense_t          *pSense;
14185  smIniScsiCmnd_t           *scsiCmnd;
14186  agsaFisRegHostToDevice_t  *fis;
14187  bit8                      *pLogPage;    /* Log Page data buffer */
14188  bit16                     BlkDescLen = 0;     /* Block Descriptor Length */
14189  bit32                     StartingIndex = 0;
14190  bit8                      PageCode = 0;
14191  bit32                     chkCnd = agFALSE;
14192  bit32                     parameterListLen = 0;
14193
14194  pSense        = satIOContext->pSense;
14195  pSatDevData   = satIOContext->pSatDevData;
14196  scsiCmnd      = &smScsiRequest->scsiCmnd;
14197  fis           = satIOContext->pFis;
14198  pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
14199
14200  SM_DBG5(("smsatModeSelect10: start\n"));
14201
14202  /* checking CONTROL */
14203  /* NACA == 1 or LINK == 1*/
14204  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
14205  {
14206    smsatSetSensePayload( pSense,
14207                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14208                          0,
14209                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14210                          satIOContext);
14211
14212    /*smEnqueueIO(smRoot, satIOContext);*/
14213
14214    tdsmIOCompletedCB( smRoot,
14215                       smIORequest,
14216                       smIOSuccess,
14217                       SCSI_STAT_CHECK_CONDITION,
14218                       satIOContext->pSmSenseData,
14219                       satIOContext->interruptContext );
14220
14221    SM_DBG1(("smsatModeSelect10: return control!!!\n"));
14222    return SM_RC_SUCCESS;
14223  }
14224
14225  /* checking PF bit */
14226  if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
14227  {
14228    smsatSetSensePayload( pSense,
14229                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14230                          0,
14231                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14232                          satIOContext);
14233
14234    /*smEnqueueIO(smRoot, satIOContext);*/
14235
14236    tdsmIOCompletedCB( smRoot,
14237                       smIORequest,
14238                       smIOSuccess,
14239                       SCSI_STAT_CHECK_CONDITION,
14240                       satIOContext->pSmSenseData,
14241                       satIOContext->interruptContext );
14242
14243    SM_DBG1(("smsatModeSelect10: PF bit check!!!\n"));
14244    return SM_RC_SUCCESS;
14245  }
14246
14247  parameterListLen = ((scsiCmnd->cdb[7]) << 8) + scsiCmnd->cdb[8];
14248  parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength);
14249  if ((0 == parameterListLen) || (agNULL == pLogPage))
14250  {
14251    tdsmIOCompletedCB( smRoot,
14252                       smIORequest,
14253                       smIOSuccess,
14254                       SCSI_STAT_GOOD,
14255                       agNULL,
14256                       satIOContext->interruptContext);
14257    return SM_RC_SUCCESS;
14258  }
14259
14260  BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]);
14261
14262  /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/
14263  if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
14264  {
14265    /* mode parameter block descriptor exists and length is 8 byte */
14266    PageCode = (bit8)(pLogPage[16] & 0x3F);   /* page code and index is 8 + 8 */
14267    StartingIndex = 16;
14268  }
14269  else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
14270  {
14271    /* mode parameter block descriptor exists and length is 16 byte */
14272    PageCode = (bit8)(pLogPage[24] & 0x3F);   /* page code and index is 8 + 16 */
14273    StartingIndex = 24;
14274  }
14275  else if (BlkDescLen == 0)
14276  {
14277    PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */
14278    StartingIndex = 8;
14279    /*smEnqueueIO(smRoot, satIOContext);*/
14280
14281    tdsmIOCompletedCB( smRoot,
14282                       smIORequest,
14283                       smIOSuccess,
14284                       SCSI_STAT_GOOD,
14285                       agNULL,
14286                       satIOContext->interruptContext);
14287    return SM_RC_SUCCESS;
14288  }
14289  else
14290  {
14291    SM_DBG1(("smsatModeSelect10: return mode parameter block descriptor 0x%x!!!\n",  BlkDescLen));
14292    /* no more than one mode parameter block descriptor shall be supported */
14293    smsatSetSensePayload( pSense,
14294                          SCSI_SNSKEY_NO_SENSE,
14295                          0,
14296                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14297                          satIOContext);
14298
14299    /*smEnqueueIO(smRoot, satIOContext);*/
14300
14301    tdsmIOCompletedCB( smRoot,
14302                       smIORequest,
14303                       smIOSuccess,
14304                       SCSI_STAT_CHECK_CONDITION,
14305                       satIOContext->pSmSenseData,
14306                       satIOContext->interruptContext );
14307    return SM_RC_SUCCESS;
14308  }
14309  /*
14310    for debugging only
14311  */
14312  if (StartingIndex == 8)
14313  {
14314    smhexdump("startingindex 8", (bit8 *)pLogPage, 8);
14315  }
14316  else if(StartingIndex == 16)
14317  {
14318    if (PageCode == MODESELECT_CACHING)
14319    {
14320      smhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
14321    }
14322    else
14323    {
14324      smhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
14325    }
14326  }
14327  else
14328  {
14329    if (PageCode == MODESELECT_CACHING)
14330    {
14331      smhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
14332    }
14333    else
14334    {
14335      smhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
14336    }
14337  }
14338  switch (PageCode) /* page code */
14339  {
14340  case MODESELECT_CONTROL_PAGE:
14341    SM_DBG5(("smsatModeSelect10: Control mode page\n"));
14342    /*
14343      compare pLogPage to expected value (SAT Table 65, p67)
14344      If not match, return check condition
14345     */
14346    if ( pLogPage[StartingIndex+1] != 0x0A ||
14347         pLogPage[StartingIndex+2] != 0x02 ||
14348         (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
14349         (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
14350         (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
14351         (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
14352         (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
14353
14354         (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
14355         (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
14356         (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
14357         (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
14358
14359         pLogPage[StartingIndex+8] != 0xFF ||
14360         pLogPage[StartingIndex+9] != 0xFF ||
14361         pLogPage[StartingIndex+10] != 0x00 ||
14362         pLogPage[StartingIndex+11] != 0x00
14363       )
14364    {
14365      chkCnd = agTRUE;
14366    }
14367    if (chkCnd == agTRUE)
14368    {
14369      smsatSetSensePayload( pSense,
14370                            SCSI_SNSKEY_ILLEGAL_REQUEST,
14371                            0,
14372                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14373                            satIOContext);
14374
14375      /*smEnqueueIO(smRoot, satIOContext);*/
14376
14377      tdsmIOCompletedCB( smRoot,
14378                         smIORequest,
14379                         smIOSuccess,
14380                         SCSI_STAT_CHECK_CONDITION,
14381                         satIOContext->pSmSenseData,
14382                         satIOContext->interruptContext );
14383
14384      SM_DBG1(("smsatModeSelect10: unexpected values!!!\n"));
14385    }
14386    else
14387    {
14388      /*smEnqueueIO(smRoot, satIOContext);*/
14389
14390      tdsmIOCompletedCB( smRoot,
14391                         smIORequest,
14392                         smIOSuccess,
14393                         SCSI_STAT_GOOD,
14394                         agNULL,
14395                         satIOContext->interruptContext);
14396    }
14397    return SM_RC_SUCCESS;
14398    break;
14399  case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
14400    SM_DBG5(("smsatModeSelect10: Read-Write Error Recovery mode page\n"));
14401
14402    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) ||
14403         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) ||
14404         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) ||
14405         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) ||
14406         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) ||
14407         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) ||
14408         (pLogPage[StartingIndex + 10]) ||
14409         (pLogPage[StartingIndex + 11])
14410         )
14411    {
14412      SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14413
14414      smsatSetSensePayload( pSense,
14415                            SCSI_SNSKEY_ILLEGAL_REQUEST,
14416                            0,
14417                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14418                            satIOContext);
14419
14420      /*smEnqueueIO(smRoot, satIOContext);*/
14421
14422      tdsmIOCompletedCB( smRoot,
14423                         smIORequest,
14424                         smIOSuccess,
14425                         SCSI_STAT_CHECK_CONDITION,
14426                         satIOContext->pSmSenseData,
14427                         satIOContext->interruptContext );
14428      return SM_RC_SUCCESS;
14429    }
14430    else
14431    {
14432      SM_DBG2(("smsatModeSelect10: return GOOD \n"));
14433      /*smEnqueueIO(smRoot, satIOContext);*/
14434
14435      tdsmIOCompletedCB( smRoot,
14436                         smIORequest,
14437                         smIOSuccess,
14438                         SCSI_STAT_GOOD,
14439                         agNULL,
14440                         satIOContext->interruptContext);
14441      return SM_RC_SUCCESS;
14442    }
14443
14444    break;
14445  case MODESELECT_CACHING:
14446    /* SAT rev8 Table67, p69*/
14447    SM_DBG5(("smsatModeSelect10: Caching mode page\n"));
14448    if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
14449         (pLogPage[StartingIndex + 3]) ||
14450         (pLogPage[StartingIndex + 4]) ||
14451         (pLogPage[StartingIndex + 5]) ||
14452         (pLogPage[StartingIndex + 6]) ||
14453         (pLogPage[StartingIndex + 7]) ||
14454         (pLogPage[StartingIndex + 8]) ||
14455         (pLogPage[StartingIndex + 9]) ||
14456         (pLogPage[StartingIndex + 10]) ||
14457         (pLogPage[StartingIndex + 11]) ||
14458
14459         (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
14460         (pLogPage[StartingIndex + 13]) ||
14461         (pLogPage[StartingIndex + 14]) ||
14462         (pLogPage[StartingIndex + 15])
14463         )
14464    {
14465      SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14466
14467      smsatSetSensePayload( pSense,
14468                            SCSI_SNSKEY_ILLEGAL_REQUEST,
14469                            0,
14470                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14471                            satIOContext);
14472
14473      /*smEnqueueIO(smRoot, satIOContext);*/
14474
14475      tdsmIOCompletedCB( smRoot,
14476                         smIORequest,
14477                         smIOSuccess,
14478                         SCSI_STAT_CHECK_CONDITION,
14479                         satIOContext->pSmSenseData,
14480                         satIOContext->interruptContext );
14481      return SM_RC_SUCCESS;
14482
14483    }
14484    else
14485    {
14486      /* sends ATA SET FEATURES based on WCE bit */
14487      if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
14488      {
14489        SM_DBG5(("smsatModeSelect10: disable write cache\n"));
14490        /* sends SET FEATURES */
14491        fis->h.fisType        = 0x27;                   /* Reg host to device */
14492        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14493
14494        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
14495        fis->h.features       = 0x82;                   /* disable write cache */
14496        fis->d.lbaLow         = 0;                      /* */
14497        fis->d.lbaMid         = 0;                      /* */
14498        fis->d.lbaHigh        = 0;                      /* */
14499        fis->d.device         = 0;                      /* */
14500        fis->d.lbaLowExp      = 0;                      /* */
14501        fis->d.lbaMidExp      = 0;                      /* */
14502        fis->d.lbaHighExp     = 0;                      /* */
14503        fis->d.featuresExp    = 0;                      /* */
14504        fis->d.sectorCount    = 0;                      /* */
14505        fis->d.sectorCountExp = 0;                      /* */
14506        fis->d.reserved4      = 0;
14507        fis->d.control        = 0;                      /* FIS HOB bit clear */
14508        fis->d.reserved5      = 0;
14509
14510        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14511
14512        /* Initialize CB for SATA completion.
14513         */
14514        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14515
14516        /*
14517         * Prepare SGL and send FIS to LL layer.
14518         */
14519        satIOContext->reqType = agRequestType;       /* Save it */
14520
14521        status = smsataLLIOStart( smRoot,
14522                                  smIORequest,
14523                                  smDeviceHandle,
14524                                  smScsiRequest,
14525                                  satIOContext);
14526        return status;
14527      }
14528      else
14529      {
14530        SM_DBG5(("smsatModeSelect10: enable write cache\n"));
14531        /* sends SET FEATURES */
14532        fis->h.fisType        = 0x27;                   /* Reg host to device */
14533        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14534
14535        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
14536        fis->h.features       = 0x02;                   /* enable write cache */
14537        fis->d.lbaLow         = 0;                      /* */
14538        fis->d.lbaMid         = 0;                      /* */
14539        fis->d.lbaHigh        = 0;                      /* */
14540        fis->d.device         = 0;                      /* */
14541        fis->d.lbaLowExp      = 0;                      /* */
14542        fis->d.lbaMidExp      = 0;                      /* */
14543        fis->d.lbaHighExp     = 0;                      /* */
14544        fis->d.featuresExp    = 0;                      /* */
14545        fis->d.sectorCount    = 0;                      /* */
14546        fis->d.sectorCountExp = 0;                      /* */
14547        fis->d.reserved4      = 0;
14548        fis->d.control        = 0;                      /* FIS HOB bit clear */
14549        fis->d.reserved5      = 0;
14550
14551        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14552
14553        /* Initialize CB for SATA completion.
14554         */
14555        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14556
14557        /*
14558         * Prepare SGL and send FIS to LL layer.
14559         */
14560        satIOContext->reqType = agRequestType;       /* Save it */
14561
14562        status = smsataLLIOStart( smRoot,
14563                                  smIORequest,
14564                                  smDeviceHandle,
14565                                  smScsiRequest,
14566                                  satIOContext);
14567        return status;
14568
14569      }
14570    }
14571    break;
14572  case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
14573    SM_DBG5(("smsatModeSelect10: Informational Exception Control mode page\n"));
14574
14575    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
14576         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
14577         )
14578    {
14579      SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14580
14581      smsatSetSensePayload( pSense,
14582                            SCSI_SNSKEY_ILLEGAL_REQUEST,
14583                            0,
14584                            SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14585                            satIOContext);
14586
14587      /*smEnqueueIO(smRoot, satIOContext);*/
14588
14589      tdsmIOCompletedCB( smRoot,
14590                         smIORequest,
14591                         smIOSuccess,
14592                         SCSI_STAT_CHECK_CONDITION,
14593                         satIOContext->pSmSenseData,
14594                         satIOContext->interruptContext );
14595      return SM_RC_SUCCESS;
14596    }
14597    else
14598    {
14599      /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
14600      if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
14601      {
14602        SM_DBG5(("smsatModeSelect10: enable information exceptions reporting\n"));
14603        /* sends SMART ENABLE OPERATIONS */
14604        fis->h.fisType        = 0x27;                   /* Reg host to device */
14605        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14606
14607        fis->h.command        = SAT_SMART;              /* 0xB0 */
14608        fis->h.features       = SAT_SMART_ENABLE_OPERATIONS;       /* enable */
14609        fis->d.lbaLow         = 0;                      /* */
14610        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14611        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14612        fis->d.device         = 0;                      /* */
14613        fis->d.lbaLowExp      = 0;                      /* */
14614        fis->d.lbaMidExp      = 0;                      /* */
14615        fis->d.lbaHighExp     = 0;                      /* */
14616        fis->d.featuresExp    = 0;                      /* */
14617        fis->d.sectorCount    = 0;                      /* */
14618        fis->d.sectorCountExp = 0;                      /* */
14619        fis->d.reserved4      = 0;
14620        fis->d.control        = 0;                      /* FIS HOB bit clear */
14621        fis->d.reserved5      = 0;
14622
14623        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14624
14625        /* Initialize CB for SATA completion.
14626         */
14627        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14628
14629        /*
14630         * Prepare SGL and send FIS to LL layer.
14631         */
14632        satIOContext->reqType = agRequestType;       /* Save it */
14633
14634        status = smsataLLIOStart( smRoot,
14635                                  smIORequest,
14636                                  smDeviceHandle,
14637                                  smScsiRequest,
14638                                  satIOContext);
14639        return status;
14640      }
14641      else
14642      {
14643        SM_DBG5(("smsatModeSelect10: disable information exceptions reporting\n"));
14644        /* sends SMART DISABLE OPERATIONS */
14645        fis->h.fisType        = 0x27;                   /* Reg host to device */
14646        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14647
14648        fis->h.command        = SAT_SMART;              /* 0xB0 */
14649        fis->h.features       = SAT_SMART_DISABLE_OPERATIONS; /* disable */
14650        fis->d.lbaLow         = 0;                      /* */
14651        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14652        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14653        fis->d.device         = 0;                      /* */
14654        fis->d.lbaLowExp      = 0;                      /* */
14655        fis->d.lbaMidExp      = 0;                      /* */
14656        fis->d.lbaHighExp     = 0;                      /* */
14657        fis->d.featuresExp    = 0;                      /* */
14658        fis->d.sectorCount    = 0;                      /* */
14659        fis->d.sectorCountExp = 0;                      /* */
14660        fis->d.reserved4      = 0;
14661        fis->d.control        = 0;                      /* FIS HOB bit clear */
14662        fis->d.reserved5      = 0;
14663
14664        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14665
14666        /* Initialize CB for SATA completion.
14667         */
14668        satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14669
14670        /*
14671         * Prepare SGL and send FIS to LL layer.
14672         */
14673        satIOContext->reqType = agRequestType;       /* Save it */
14674
14675        status = smsataLLIOStart( smRoot,
14676                                  smIORequest,
14677                                  smDeviceHandle,
14678                                  smScsiRequest,
14679                                  satIOContext);
14680        return status;
14681
14682      }
14683    }
14684    break;
14685  default:
14686    SM_DBG1(("smsatModeSelect10: Error unknown page code 0x%x!!!\n", pLogPage[12]));
14687    smsatSetSensePayload( pSense,
14688                          SCSI_SNSKEY_NO_SENSE,
14689                          0,
14690                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14691                          satIOContext);
14692
14693    /*smEnqueueIO(smRoot, satIOContext);*/
14694
14695    tdsmIOCompletedCB( smRoot,
14696                       smIORequest,
14697                       smIOSuccess,
14698                       SCSI_STAT_CHECK_CONDITION,
14699                       satIOContext->pSmSenseData,
14700                       satIOContext->interruptContext );
14701    return SM_RC_SUCCESS;
14702  }
14703}
14704
14705osGLOBAL bit32
14706smsatSynchronizeCache10(
14707                        smRoot_t                  *smRoot,
14708                        smIORequest_t             *smIORequest,
14709                        smDeviceHandle_t          *smDeviceHandle,
14710                        smScsiInitiatorRequest_t  *smScsiRequest,
14711                        smSatIOContext_t            *satIOContext
14712                       )
14713{
14714  bit32                     status;
14715  bit32                     agRequestType;
14716  smDeviceData_t            *pSatDevData;
14717  smScsiRspSense_t          *pSense;
14718  smIniScsiCmnd_t           *scsiCmnd;
14719  agsaFisRegHostToDevice_t  *fis;
14720
14721  pSense        = satIOContext->pSense;
14722  pSatDevData   = satIOContext->pSatDevData;
14723  scsiCmnd      = &smScsiRequest->scsiCmnd;
14724  fis           = satIOContext->pFis;
14725
14726  SM_DBG5(("smsatSynchronizeCache10: start\n"));
14727
14728  /* checking CONTROL */
14729  /* NACA == 1 or LINK == 1*/
14730  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
14731  {
14732    smsatSetSensePayload( pSense,
14733                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14734                          0,
14735                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14736                          satIOContext);
14737
14738    /*smEnqueueIO(smRoot, satIOContext);*/
14739
14740    tdsmIOCompletedCB( smRoot,
14741                       smIORequest,
14742                       smIOSuccess,
14743                       SCSI_STAT_CHECK_CONDITION,
14744                       satIOContext->pSmSenseData,
14745                       satIOContext->interruptContext );
14746
14747    SM_DBG1(("smsatSynchronizeCache10: return control!!!\n"));
14748    return SM_RC_SUCCESS;
14749  }
14750
14751  /* checking IMMED bit */
14752  if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
14753  {
14754    SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n"));
14755
14756    /* return GOOD status first here */
14757    tdsmIOCompletedCB( smRoot,
14758                       smIORequest,
14759                       smIOSuccess,
14760                       SCSI_STAT_GOOD,
14761                       agNULL,
14762                       satIOContext->interruptContext);
14763  }
14764
14765  /* sends FLUSH CACHE or FLUSH CACHE EXT */
14766  if (pSatDevData->sat48BitSupport == agTRUE)
14767  {
14768    SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n"));
14769    /* FLUSH CACHE EXT */
14770    fis->h.fisType        = 0x27;                   /* Reg host to device */
14771    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14772
14773    fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
14774    fis->h.features       = 0;                      /* FIS reserve */
14775    fis->d.featuresExp    = 0;                      /* FIS reserve */
14776    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14777    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
14778    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14779    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
14780    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14781    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14782    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14783    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14784    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14785    fis->d.control        = 0;                      /* FIS HOB bit clear */
14786    fis->d.reserved4      = 0;
14787    fis->d.reserved5      = 0;
14788
14789  }
14790  else
14791  {
14792    SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n"));
14793    /* FLUSH CACHE */
14794    fis->h.fisType        = 0x27;                   /* Reg host to device */
14795    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14796
14797    fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
14798    fis->h.features       = 0;                      /* FIS features NA       */
14799    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14800    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14801    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14802    fis->d.lbaLowExp      = 0;
14803    fis->d.lbaMidExp      = 0;
14804    fis->d.lbaHighExp     = 0;
14805    fis->d.featuresExp    = 0;
14806    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14807    fis->d.sectorCountExp = 0;
14808    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14809    fis->d.control        = 0;                      /* FIS HOB bit clear */
14810    fis->d.reserved4      = 0;
14811    fis->d.reserved5      = 0;
14812
14813  }
14814
14815  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14816
14817  /* Initialize CB for SATA completion.
14818   */
14819  satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB;
14820
14821  /*
14822   * Prepare SGL and send FIS to LL layer.
14823   */
14824  satIOContext->reqType = agRequestType;       /* Save it */
14825
14826  status = smsataLLIOStart( smRoot,
14827                            smIORequest,
14828                            smDeviceHandle,
14829                            smScsiRequest,
14830                            satIOContext);
14831
14832
14833  return (status);
14834}
14835
14836osGLOBAL bit32
14837smsatSynchronizeCache16(
14838                        smRoot_t                  *smRoot,
14839                        smIORequest_t             *smIORequest,
14840                        smDeviceHandle_t          *smDeviceHandle,
14841                        smScsiInitiatorRequest_t  *smScsiRequest,
14842                        smSatIOContext_t            *satIOContext
14843                       )
14844{
14845  bit32                     status;
14846  bit32                     agRequestType;
14847  smDeviceData_t            *pSatDevData;
14848  smScsiRspSense_t          *pSense;
14849  smIniScsiCmnd_t           *scsiCmnd;
14850  agsaFisRegHostToDevice_t  *fis;
14851
14852  pSense        = satIOContext->pSense;
14853  pSatDevData   = satIOContext->pSatDevData;
14854  scsiCmnd      = &smScsiRequest->scsiCmnd;
14855  fis           = satIOContext->pFis;
14856
14857  SM_DBG5(("smsatSynchronizeCache10: start\n"));
14858
14859  /* checking CONTROL */
14860  /* NACA == 1 or LINK == 1*/
14861  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
14862  {
14863    smsatSetSensePayload( pSense,
14864                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14865                          0,
14866                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14867                          satIOContext);
14868
14869    /*smEnqueueIO(smRoot, satIOContext);*/
14870
14871    tdsmIOCompletedCB( smRoot,
14872                       smIORequest,
14873                       smIOSuccess,
14874                       SCSI_STAT_CHECK_CONDITION,
14875                       satIOContext->pSmSenseData,
14876                       satIOContext->interruptContext );
14877
14878    SM_DBG1(("smsatSynchronizeCache10: return control!!!\n"));
14879    return SM_RC_SUCCESS;
14880  }
14881
14882
14883  /* checking IMMED bit */
14884  if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
14885  {
14886    SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n"));
14887
14888    /* return GOOD status first here */
14889    tdsmIOCompletedCB( smRoot,
14890                       smIORequest,
14891                       smIOSuccess,
14892                       SCSI_STAT_GOOD,
14893                       agNULL,
14894                       satIOContext->interruptContext);
14895  }
14896
14897  /* sends FLUSH CACHE or FLUSH CACHE EXT */
14898  if (pSatDevData->sat48BitSupport == agTRUE)
14899  {
14900    SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n"));
14901    /* FLUSH CACHE EXT */
14902    fis->h.fisType        = 0x27;                   /* Reg host to device */
14903    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14904
14905    fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
14906    fis->h.features       = 0;                      /* FIS reserve */
14907    fis->d.featuresExp    = 0;                      /* FIS reserve */
14908    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14909    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
14910    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14911    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
14912    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14913    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14914    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14915    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14916    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14917    fis->d.control        = 0;                      /* FIS HOB bit clear */
14918    fis->d.reserved4      = 0;
14919    fis->d.reserved5      = 0;
14920
14921  }
14922  else
14923  {
14924    SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n"));
14925    /* FLUSH CACHE */
14926    fis->h.fisType        = 0x27;                   /* Reg host to device */
14927    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14928
14929    fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
14930    fis->h.features       = 0;                      /* FIS features NA       */
14931    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14932    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14933    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14934    fis->d.lbaLowExp      = 0;
14935    fis->d.lbaMidExp      = 0;
14936    fis->d.lbaHighExp     = 0;
14937    fis->d.featuresExp    = 0;
14938    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14939    fis->d.sectorCountExp = 0;
14940    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14941    fis->d.control        = 0;                      /* FIS HOB bit clear */
14942    fis->d.reserved4      = 0;
14943    fis->d.reserved5      = 0;
14944
14945  }
14946
14947  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14948
14949  /* Initialize CB for SATA completion.
14950   */
14951  satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB;
14952
14953  /*
14954   * Prepare SGL and send FIS to LL layer.
14955   */
14956  satIOContext->reqType = agRequestType;       /* Save it */
14957
14958  status = smsataLLIOStart( smRoot,
14959                            smIORequest,
14960                            smDeviceHandle,
14961                            smScsiRequest,
14962                            satIOContext);
14963
14964
14965  return (status);
14966}
14967
14968osGLOBAL bit32
14969smsatWriteAndVerify10(
14970                      smRoot_t                  *smRoot,
14971                      smIORequest_t             *smIORequest,
14972                      smDeviceHandle_t          *smDeviceHandle,
14973                      smScsiInitiatorRequest_t  *smScsiRequest,
14974                      smSatIOContext_t            *satIOContext
14975                     )
14976{
14977  /*
14978    combination of write10 and verify10
14979  */
14980
14981  bit32                     status;
14982  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14983  smDeviceData_t            *pSatDevData;
14984  smScsiRspSense_t          *pSense;
14985  smIniScsiCmnd_t           *scsiCmnd;
14986  agsaFisRegHostToDevice_t  *fis;
14987  bit32                     lba = 0;
14988  bit32                     tl = 0;
14989  bit32                     LoopNum = 1;
14990  bit8                      LBA[8];
14991  bit8                      TL[8];
14992  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
14993
14994  pSense        = satIOContext->pSense;
14995  pSatDevData   = satIOContext->pSatDevData;
14996  scsiCmnd      = &smScsiRequest->scsiCmnd;
14997  fis           = satIOContext->pFis;
14998
14999  SM_DBG5(("smsatWriteAndVerify10: start\n"));
15000
15001  /* checking BYTCHK bit */
15002  if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15003  {
15004    smsatSetSensePayload( pSense,
15005                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15006                          0,
15007                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15008                          satIOContext);
15009
15010    /*smEnqueueIO(smRoot, satIOContext);*/
15011
15012    tdsmIOCompletedCB( smRoot,
15013                       smIORequest,
15014                       smIOSuccess,
15015                       SCSI_STAT_CHECK_CONDITION,
15016                       satIOContext->pSmSenseData,
15017                       satIOContext->interruptContext );
15018
15019    SM_DBG1(("smsatWriteAndVerify10: BYTCHK bit checking!!!\n"));
15020    return SM_RC_SUCCESS;
15021  }
15022
15023
15024  /* checking CONTROL */
15025  /* NACA == 1 or LINK == 1*/
15026  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
15027  {
15028    smsatSetSensePayload( pSense,
15029                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15030                          0,
15031                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15032                          satIOContext);
15033
15034    /*smEnqueueIO(smRoot, satIOContext);*/
15035
15036    tdsmIOCompletedCB( smRoot,
15037                       smIORequest,
15038                       smIOSuccess,
15039                       SCSI_STAT_CHECK_CONDITION,
15040                       satIOContext->pSmSenseData,
15041                       satIOContext->interruptContext );
15042
15043    SM_DBG1(("smsatWriteAndVerify10: return control!!!\n"));
15044    return SM_RC_SUCCESS;
15045  }
15046
15047  sm_memset(LBA, 0, sizeof(LBA));
15048  sm_memset(TL, 0, sizeof(TL));
15049
15050  /* do not use memcpy due to indexing in LBA and TL */
15051  LBA[0] = 0;                  /* MSB */
15052  LBA[1] = 0;
15053  LBA[2] = 0;
15054  LBA[3] = 0;
15055  LBA[4] = scsiCmnd->cdb[2];
15056  LBA[5] = scsiCmnd->cdb[3];
15057  LBA[6] = scsiCmnd->cdb[4];
15058  LBA[7] = scsiCmnd->cdb[5];   /* LSB */
15059
15060  TL[0] = 0;
15061  TL[1] = 0;
15062  TL[2] = 0;
15063  TL[3] = 0;
15064  TL[4] = 0;
15065  TL[5] = 0;
15066  TL[6] = scsiCmnd->cdb[7];
15067  TL[7] = scsiCmnd->cdb[8];    /* LSB */
15068
15069
15070  /* cbd10; computing LBA and transfer length */
15071  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
15072    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
15073  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
15074
15075
15076  /* Table 34, 9.1, p 46 */
15077  /*
15078    note: As of 2/10/2006, no support for DMA QUEUED
15079   */
15080
15081  /*
15082    Table 34, 9.1, p 46, b
15083    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15084    return check condition
15085  */
15086  if (pSatDevData->satNCQ != agTRUE &&
15087      pSatDevData->sat48BitSupport != agTRUE
15088      )
15089  {
15090    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15091    if (AllChk)
15092    {
15093      SM_DBG1(("smsatWriteAndVerify10: return LBA out of range!!!\n"));
15094      smsatSetSensePayload( pSense,
15095                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15096                            0,
15097                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15098                            satIOContext);
15099
15100      /*smEnqueueIO(smRoot, satIOContext);*/
15101
15102      tdsmIOCompletedCB( smRoot,
15103                         smIORequest,
15104                         smIOSuccess,
15105                         SCSI_STAT_CHECK_CONDITION,
15106                         satIOContext->pSmSenseData,
15107                         satIOContext->interruptContext );
15108
15109    return SM_RC_SUCCESS;
15110    }
15111  }
15112  else
15113  {
15114    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15115    if (AllChk)
15116    {
15117      SM_DBG1(("smsatWriteAndVerify10: return LBA out of range, EXT!!!\n"));
15118      smsatSetSensePayload( pSense,
15119                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15120                            0,
15121                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15122                            satIOContext);
15123
15124      /*smEnqueueIO(smRoot, satIOContext);*/
15125
15126      tdsmIOCompletedCB( smRoot,
15127                         smIORequest,
15128                         smIOSuccess,
15129                         SCSI_STAT_CHECK_CONDITION,
15130                         satIOContext->pSmSenseData,
15131                         satIOContext->interruptContext );
15132
15133      return SM_RC_SUCCESS;
15134    }
15135  }
15136
15137
15138  /* case 1 and 2 */
15139    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15140    {
15141      /* case 2 */
15142      /* WRITE DMA*/
15143      /* can't fit the transfer length */
15144      SM_DBG5(("smsatWriteAndVerify10: case 2\n"));
15145      fis->h.fisType        = 0x27;                   /* Reg host to device */
15146      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15147      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
15148      fis->h.features       = 0;                      /* FIS reserve */
15149      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15150      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15151      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15152
15153      /* FIS LBA mode set LBA (27:24) */
15154      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15155
15156      fis->d.lbaLowExp      = 0;
15157      fis->d.lbaMidExp      = 0;
15158      fis->d.lbaHighExp     = 0;
15159      fis->d.featuresExp    = 0;
15160      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15161      fis->d.sectorCountExp = 0;
15162      fis->d.reserved4      = 0;
15163      fis->d.control        = 0;                      /* FIS HOB bit clear */
15164      fis->d.reserved5      = 0;
15165
15166      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15167      satIOContext->ATACmd = SAT_WRITE_DMA;
15168    }
15169    else
15170    {
15171      /* case 1 */
15172      /* WRITE MULTIPLE or WRITE SECTOR(S) */
15173      /* WRITE SECTORS for easier implemetation */
15174      /* can't fit the transfer length */
15175      SM_DBG5(("smsatWriteAndVerify10: case 1\n"));
15176      fis->h.fisType        = 0x27;                   /* Reg host to device */
15177      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15178      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
15179      fis->h.features       = 0;                      /* FIS reserve */
15180      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15181      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15182      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15183
15184      /* FIS LBA mode set LBA (27:24) */
15185      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15186
15187      fis->d.lbaLowExp      = 0;
15188      fis->d.lbaMidExp      = 0;
15189      fis->d.lbaHighExp     = 0;
15190      fis->d.featuresExp    = 0;
15191      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15192      fis->d.sectorCountExp = 0;
15193      fis->d.reserved4      = 0;
15194      fis->d.control        = 0;                      /* FIS HOB bit clear */
15195      fis->d.reserved5      = 0;
15196
15197      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15198      satIOContext->ATACmd = SAT_WRITE_SECTORS;
15199
15200  }
15201
15202  /* case 3 and 4 */
15203  if (pSatDevData->sat48BitSupport == agTRUE)
15204  {
15205    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15206    {
15207      /* case 3 */
15208      /* WRITE DMA EXT or WRITE DMA FUA EXT */
15209      SM_DBG5(("smsatWriteAndVerify10: case 3\n"));
15210      fis->h.fisType        = 0x27;                   /* Reg host to device */
15211      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15212
15213      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15214      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
15215
15216      fis->h.features       = 0;                      /* FIS reserve */
15217      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15218      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15219      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15220      fis->d.device         = 0x40;                   /* FIS LBA mode set */
15221      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15222      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15223      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15224      fis->d.featuresExp    = 0;                      /* FIS reserve */
15225      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15226      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15227      fis->d.reserved4      = 0;
15228      fis->d.control        = 0;                      /* FIS HOB bit clear */
15229      fis->d.reserved5      = 0;
15230
15231      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15232      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15233    }
15234    else
15235    {
15236      /* case 4 */
15237      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15238      /* WRITE SECTORS EXT for easier implemetation */
15239      SM_DBG5(("smsatWriteAndVerify10: case 4\n"));
15240      fis->h.fisType        = 0x27;                   /* Reg host to device */
15241      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15242      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
15243
15244      fis->h.features       = 0;                      /* FIS reserve */
15245      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15246      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15247      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15248      fis->d.device         = 0x40;                   /* FIS LBA mode set */
15249      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15250      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15251      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15252      fis->d.featuresExp    = 0;                      /* FIS reserve */
15253      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15254      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15255      fis->d.reserved4      = 0;
15256      fis->d.control        = 0;                      /* FIS HOB bit clear */
15257      fis->d.reserved5      = 0;
15258
15259      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15260      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15261    }
15262  }
15263  /* case 5 */
15264  if (pSatDevData->satNCQ == agTRUE)
15265  {
15266    /* WRITE FPDMA QUEUED */
15267    if (pSatDevData->sat48BitSupport != agTRUE)
15268    {
15269      SM_DBG1(("smsatWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
15270      smsatSetSensePayload( pSense,
15271                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15272                            0,
15273                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15274                            satIOContext);
15275
15276      /*smEnqueueIO(smRoot, satIOContext);*/
15277
15278      tdsmIOCompletedCB( smRoot,
15279                         smIORequest,
15280                         smIOSuccess,
15281                         SCSI_STAT_CHECK_CONDITION,
15282                         satIOContext->pSmSenseData,
15283                         satIOContext->interruptContext );
15284      return SM_RC_SUCCESS;
15285    }
15286    SM_DBG5(("smsatWriteAndVerify10: case 5\n"));
15287
15288    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15289
15290    fis->h.fisType        = 0x27;                   /* Reg host to device */
15291    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15292    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15293    fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15294    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15295    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15296    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15297
15298    /* Check FUA bit */
15299    if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
15300      fis->d.device       = 0xC0;                   /* FIS FUA set */
15301    else
15302      fis->d.device       = 0x40;                   /* FIS FUA clear */
15303
15304    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15305    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15306    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15307    fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15308    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15309    fis->d.sectorCountExp = 0;
15310    fis->d.reserved4      = 0;
15311    fis->d.control        = 0;                      /* FIS HOB bit clear */
15312    fis->d.reserved5      = 0;
15313
15314    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15315    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15316  }
15317
15318  satIOContext->currentLBA = lba;
15319  satIOContext->OrgTL = tl;
15320
15321  /*
15322    computing number of loop and remainder for tl
15323    0xFF in case not ext
15324    0xFFFF in case EXT
15325  */
15326  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15327  {
15328    LoopNum = smsatComputeLoopNum(tl, 0xFF);
15329  }
15330  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15331           fis->h.command == SAT_WRITE_DMA_EXT     ||
15332           fis->h.command == SAT_WRITE_DMA_FUA_EXT
15333           )
15334  {
15335    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15336    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15337  }
15338  else
15339  {
15340    /* SAT_WRITE_FPDMA_QUEUED */
15341    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15342  }
15343
15344  satIOContext->LoopNum = LoopNum;
15345
15346
15347  if (LoopNum == 1)
15348  {
15349    SM_DBG5(("smsatWriteAndVerify10: NON CHAINED data\n"));
15350    /* Initialize CB for SATA completion.
15351     */
15352    satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
15353  }
15354  else
15355  {
15356    SM_DBG1(("smsatWriteAndVerify10: CHAINED data!!!\n"));
15357    /* re-setting tl */
15358    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15359    {
15360       fis->d.sectorCount    = 0xFF;
15361    }
15362    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15363             fis->h.command == SAT_WRITE_DMA_EXT ||
15364             fis->h.command == SAT_WRITE_DMA_FUA_EXT
15365             )
15366    {
15367      fis->d.sectorCount    = 0xFF;
15368      fis->d.sectorCountExp = 0xFF;
15369    }
15370    else
15371    {
15372      /* SAT_WRITE_FPDMA_QUEUED */
15373      fis->h.features       = 0xFF;
15374      fis->d.featuresExp    = 0xFF;
15375    }
15376
15377    /* Initialize CB for SATA completion.
15378     */
15379    satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
15380  }
15381
15382
15383  /*
15384   * Prepare SGL and send FIS to LL layer.
15385   */
15386  satIOContext->reqType = agRequestType;       /* Save it */
15387
15388  status = smsataLLIOStart( smRoot,
15389                            smIORequest,
15390                            smDeviceHandle,
15391                            smScsiRequest,
15392                            satIOContext);
15393  return (status);
15394
15395}
15396
15397osGLOBAL bit32
15398smsatWriteAndVerify12(
15399                      smRoot_t                  *smRoot,
15400                      smIORequest_t             *smIORequest,
15401                      smDeviceHandle_t          *smDeviceHandle,
15402                      smScsiInitiatorRequest_t  *smScsiRequest,
15403                      smSatIOContext_t            *satIOContext
15404                     )
15405{
15406  /*
15407    combination of write12 and verify12
15408    temp: since write12 is not support (due to internal checking), no support
15409  */
15410  bit32                     status;
15411  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15412  smDeviceData_t            *pSatDevData;
15413  smScsiRspSense_t          *pSense;
15414  smIniScsiCmnd_t           *scsiCmnd;
15415  agsaFisRegHostToDevice_t  *fis;
15416  bit32                     lba = 0;
15417  bit32                     tl = 0;
15418  bit32                     LoopNum = 1;
15419  bit8                      LBA[8];
15420  bit8                      TL[8];
15421  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
15422
15423  pSense        = satIOContext->pSense;
15424  pSatDevData   = satIOContext->pSatDevData;
15425  scsiCmnd      = &smScsiRequest->scsiCmnd;
15426  fis           = satIOContext->pFis;
15427
15428  SM_DBG5(("smsatWriteAndVerify12: start\n"));
15429
15430  /* checking BYTCHK bit */
15431  if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15432  {
15433    smsatSetSensePayload( pSense,
15434                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15435                          0,
15436                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15437                          satIOContext);
15438
15439    /*smEnqueueIO(smRoot, satIOContext);*/
15440
15441    tdsmIOCompletedCB( smRoot,
15442                       smIORequest,
15443                       smIOSuccess,
15444                       SCSI_STAT_CHECK_CONDITION,
15445                       satIOContext->pSmSenseData,
15446                       satIOContext->interruptContext );
15447
15448    SM_DBG1(("smsatWriteAndVerify12: BYTCHK bit checking!!!\n"));
15449    return SM_RC_SUCCESS;
15450  }
15451
15452  /* checking CONTROL */
15453  /* NACA == 1 or LINK == 1*/
15454  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
15455  {
15456    smsatSetSensePayload( pSense,
15457                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15458                          0,
15459                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15460                          satIOContext);
15461
15462    /*smEnqueueIO(smRoot, satIOContext);*/
15463
15464    tdsmIOCompletedCB( smRoot,
15465                       smIORequest,
15466                       smIOSuccess,
15467                       SCSI_STAT_CHECK_CONDITION,
15468                       satIOContext->pSmSenseData,
15469                       satIOContext->interruptContext );
15470
15471    SM_DBG1(("smsatWriteAndVerify12: return control!!!\n"));
15472    return SM_RC_SUCCESS;
15473  }
15474
15475  sm_memset(LBA, 0, sizeof(LBA));
15476  sm_memset(TL, 0, sizeof(TL));
15477
15478  /* do not use memcpy due to indexing in LBA and TL */
15479  LBA[0] = 0;                  /* MSB */
15480  LBA[1] = 0;
15481  LBA[2] = 0;
15482  LBA[3] = 0;
15483  LBA[4] = scsiCmnd->cdb[2];
15484  LBA[5] = scsiCmnd->cdb[3];
15485  LBA[6] = scsiCmnd->cdb[4];
15486  LBA[7] = scsiCmnd->cdb[5];   /* LSB */
15487
15488  TL[0] = 0;                   /* MSB */
15489  TL[1] = 0;
15490  TL[2] = 0;
15491  TL[3] = 0;
15492  TL[4] = scsiCmnd->cdb[6];
15493  TL[5] = scsiCmnd->cdb[7];
15494  TL[6] = scsiCmnd->cdb[8];
15495  TL[7] = scsiCmnd->cdb[9];    /* LSB */
15496
15497
15498  lba = smsatComputeCDB12LBA(satIOContext);
15499  tl = smsatComputeCDB12TL(satIOContext);
15500
15501
15502  /* Table 34, 9.1, p 46 */
15503  /*
15504    note: As of 2/10/2006, no support for DMA QUEUED
15505   */
15506
15507  /*
15508    Table 34, 9.1, p 46, b
15509    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15510    return check condition
15511  */
15512  if (pSatDevData->satNCQ != agTRUE &&
15513      pSatDevData->sat48BitSupport != agTRUE
15514      )
15515  {
15516    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15517    if (AllChk)
15518    {
15519
15520      /*smEnqueueIO(smRoot, satIOContext);*/
15521
15522
15523      SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, not EXT!!!\n"));
15524
15525      smsatSetSensePayload( pSense,
15526                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15527                            0,
15528                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15529                            satIOContext);
15530
15531      /*smEnqueueIO(smRoot, satIOContext);*/
15532
15533      tdsmIOCompletedCB( smRoot,
15534                         smIORequest,
15535                         smIOSuccess,
15536                         SCSI_STAT_CHECK_CONDITION,
15537                         satIOContext->pSmSenseData,
15538                         satIOContext->interruptContext );
15539
15540    return SM_RC_SUCCESS;
15541    }
15542  }
15543  else
15544  {
15545    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15546    if (AllChk)
15547  {
15548      SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, EXT!!!\n"));
15549      smsatSetSensePayload( pSense,
15550                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15551                            0,
15552                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15553                            satIOContext);
15554      tdsmIOCompletedCB( smRoot,
15555                         smIORequest,
15556                         smIOSuccess,
15557                         SCSI_STAT_CHECK_CONDITION,
15558                         satIOContext->pSmSenseData,
15559                         satIOContext->interruptContext );
15560    return SM_RC_SUCCESS;
15561    }
15562  }
15563    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15564    {
15565      /* case 2 */
15566      /* WRITE DMA*/
15567      /* In case that we can't fit the transfer length, we loop */
15568      SM_DBG5(("smsatWriteAndVerify12: case 2\n"));
15569      fis->h.fisType        = 0x27;                   /* Reg host to device */
15570      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15571      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
15572      fis->h.features       = 0;                      /* FIS reserve */
15573      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15574      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15575      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15576
15577      /* FIS LBA mode set LBA (27:24) */
15578      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15579
15580      fis->d.lbaLowExp      = 0;
15581      fis->d.lbaMidExp      = 0;
15582      fis->d.lbaHighExp     = 0;
15583      fis->d.featuresExp    = 0;
15584      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15585      fis->d.sectorCountExp = 0;
15586      fis->d.reserved4      = 0;
15587      fis->d.control        = 0;                      /* FIS HOB bit clear */
15588      fis->d.reserved5      = 0;
15589
15590      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15591      satIOContext->ATACmd = SAT_WRITE_DMA;
15592    }
15593    else
15594    {
15595      /* case 1 */
15596      /* WRITE MULTIPLE or WRITE SECTOR(S) */
15597      /* WRITE SECTORS for easier implemetation */
15598      /* In case that we can't fit the transfer length, we loop */
15599      SM_DBG5(("smsatWriteAndVerify12: case 1\n"));
15600      fis->h.fisType        = 0x27;                   /* Reg host to device */
15601      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15602      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
15603      fis->h.features       = 0;                      /* FIS reserve */
15604      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15605      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15606      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15607
15608      /* FIS LBA mode set LBA (27:24) */
15609      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15610
15611      fis->d.lbaLowExp      = 0;
15612      fis->d.lbaMidExp      = 0;
15613      fis->d.lbaHighExp     = 0;
15614      fis->d.featuresExp    = 0;
15615      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15616      fis->d.sectorCountExp = 0;
15617      fis->d.reserved4      = 0;
15618      fis->d.control        = 0;                      /* FIS HOB bit clear */
15619      fis->d.reserved5      = 0;
15620
15621      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15622      satIOContext->ATACmd = SAT_WRITE_SECTORS;
15623  }
15624
15625  /* case 3 and 4 */
15626  if (pSatDevData->sat48BitSupport == agTRUE)
15627  {
15628    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15629    {
15630      /* case 3 */
15631      /* WRITE DMA EXT or WRITE DMA FUA EXT */
15632      SM_DBG5(("smsatWriteAndVerify12: case 3\n"));
15633      fis->h.fisType        = 0x27;                   /* Reg host to device */
15634      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15635
15636      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15637      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
15638
15639      fis->h.features       = 0;                      /* FIS reserve */
15640      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15641      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15642      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15643      fis->d.device         = 0x40;                   /* FIS LBA mode set */
15644      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15645      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15646      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15647      fis->d.featuresExp    = 0;                      /* FIS reserve */
15648      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15649      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
15650      fis->d.reserved4      = 0;
15651      fis->d.control        = 0;                      /* FIS HOB bit clear */
15652      fis->d.reserved5      = 0;
15653
15654      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15655      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15656    }
15657    else
15658    {
15659      /* case 4 */
15660      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15661      /* WRITE SECTORS EXT for easier implemetation */
15662      SM_DBG5(("smsatWriteAndVerify12: case 4\n"));
15663      fis->h.fisType        = 0x27;                   /* Reg host to device */
15664      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15665      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
15666
15667      fis->h.features       = 0;                      /* FIS reserve */
15668      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15669      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15670      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15671      fis->d.device         = 0x40;                   /* FIS LBA mode set */
15672      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15673      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15674      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15675      fis->d.featuresExp    = 0;                      /* FIS reserve */
15676      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15677      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
15678      fis->d.reserved4      = 0;
15679      fis->d.control        = 0;                      /* FIS HOB bit clear */
15680      fis->d.reserved5      = 0;
15681
15682      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15683      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15684    }
15685  }
15686
15687  /* case 5 */
15688  if (pSatDevData->satNCQ == agTRUE)
15689  {
15690    /* WRITE FPDMA QUEUED */
15691    if (pSatDevData->sat48BitSupport != agTRUE)
15692    {
15693      SM_DBG1(("smsatWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support!!!\n"));
15694      smsatSetSensePayload( pSense,
15695                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15696                            0,
15697                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15698                            satIOContext);
15699
15700      /*smEnqueueIO(smRoot, satIOContext);*/
15701
15702      tdsmIOCompletedCB( smRoot,
15703                         smIORequest,
15704                         smIOSuccess,
15705                         SCSI_STAT_CHECK_CONDITION,
15706                         satIOContext->pSmSenseData,
15707                         satIOContext->interruptContext );
15708      return SM_RC_SUCCESS;
15709    }
15710    SM_DBG6(("smsatWriteAndVerify12: case 5\n"));
15711
15712    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15713
15714    fis->h.fisType        = 0x27;                   /* Reg host to device */
15715    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15716    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15717    fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15718    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15719    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15720    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15721
15722    /* Check FUA bit */
15723    if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
15724      fis->d.device       = 0xC0;                   /* FIS FUA set */
15725    else
15726      fis->d.device       = 0x40;                   /* FIS FUA clear */
15727
15728    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15729    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15730    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15731    fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
15732    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15733    fis->d.sectorCountExp = 0;
15734    fis->d.reserved4      = 0;
15735    fis->d.control        = 0;                      /* FIS HOB bit clear */
15736    fis->d.reserved5      = 0;
15737
15738    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15739    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15740  }
15741
15742  satIOContext->currentLBA = lba;
15743//  satIOContext->OrgLBA = lba;
15744  satIOContext->OrgTL = tl;
15745
15746  /*
15747    computing number of loop and remainder for tl
15748    0xFF in case not ext
15749    0xFFFF in case EXT
15750  */
15751  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15752  {
15753    LoopNum = smsatComputeLoopNum(tl, 0xFF);
15754  }
15755  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15756           fis->h.command == SAT_WRITE_DMA_EXT     ||
15757           fis->h.command == SAT_WRITE_DMA_FUA_EXT
15758           )
15759  {
15760    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15761    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15762  }
15763  else
15764  {
15765    /* SAT_WRITE_FPDMA_QUEUEDK */
15766    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15767  }
15768
15769  satIOContext->LoopNum = LoopNum;
15770  satIOContext->LoopNum2 = LoopNum;
15771
15772
15773  if (LoopNum == 1)
15774  {
15775    SM_DBG5(("smsatWriteAndVerify12: NON CHAINED data\n"));
15776    /* Initialize CB for SATA completion.
15777     */
15778    satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
15779  }
15780  else
15781  {
15782    SM_DBG1(("smsatWriteAndVerify12: CHAINED data!!!\n"));
15783    /* re-setting tl */
15784    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15785    {
15786       fis->d.sectorCount    = 0xFF;
15787    }
15788    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15789             fis->h.command == SAT_WRITE_DMA_EXT ||
15790             fis->h.command == SAT_WRITE_DMA_FUA_EXT
15791             )
15792    {
15793      fis->d.sectorCount    = 0xFF;
15794      fis->d.sectorCountExp = 0xFF;
15795    }
15796    else
15797    {
15798      /* SAT_WRITE_FPDMA_QUEUED */
15799      fis->h.features       = 0xFF;
15800      fis->d.featuresExp    = 0xFF;
15801    }
15802
15803    /* Initialize CB for SATA completion.
15804     */
15805    satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
15806  }
15807
15808
15809  /*
15810   * Prepare SGL and send FIS to LL layer.
15811   */
15812  satIOContext->reqType = agRequestType;       /* Save it */
15813
15814  status = smsataLLIOStart( smRoot,
15815                            smIORequest,
15816                            smDeviceHandle,
15817                            smScsiRequest,
15818                            satIOContext);
15819  return (status);
15820}
15821
15822osGLOBAL bit32
15823smsatWriteAndVerify16(
15824                      smRoot_t                  *smRoot,
15825                      smIORequest_t             *smIORequest,
15826                      smDeviceHandle_t          *smDeviceHandle,
15827                      smScsiInitiatorRequest_t  *smScsiRequest,
15828                      smSatIOContext_t            *satIOContext
15829                     )
15830{
15831  /*
15832    combination of write16 and verify16
15833    since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support
15834  */
15835  bit32                     status;
15836  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15837  smDeviceData_t            *pSatDevData;
15838  smScsiRspSense_t          *pSense;
15839  smIniScsiCmnd_t           *scsiCmnd;
15840  agsaFisRegHostToDevice_t  *fis;
15841  bit32                     lba = 0;
15842  bit32                     tl = 0;
15843  bit32                     LoopNum = 1;
15844  bit8                      LBA[8];
15845  bit8                      TL[8];
15846  bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
15847
15848  pSense        = satIOContext->pSense;
15849  pSatDevData   = satIOContext->pSatDevData;
15850  scsiCmnd      = &smScsiRequest->scsiCmnd;
15851  fis           = satIOContext->pFis;
15852
15853  SM_DBG5(("smsatWriteAndVerify16: start\n"));
15854
15855  /* checking BYTCHK bit */
15856  if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15857  {
15858    smsatSetSensePayload( pSense,
15859                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15860                          0,
15861                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15862                          satIOContext);
15863
15864    /*smEnqueueIO(smRoot, satIOContext);*/
15865
15866    tdsmIOCompletedCB( smRoot,
15867                       smIORequest,
15868                       smIOSuccess,
15869                       SCSI_STAT_CHECK_CONDITION,
15870                       satIOContext->pSmSenseData,
15871                       satIOContext->interruptContext );
15872
15873    SM_DBG1(("smsatWriteAndVerify16: BYTCHK bit checking!!!\n"));
15874    return SM_RC_SUCCESS;
15875  }
15876
15877
15878  /* checking CONTROL */
15879  /* NACA == 1 or LINK == 1*/
15880  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
15881  {
15882    smsatSetSensePayload( pSense,
15883                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15884                          0,
15885                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15886                          satIOContext);
15887
15888    /*smEnqueueIO(smRoot, satIOContext);*/
15889
15890    tdsmIOCompletedCB( smRoot,
15891                       smIORequest,
15892                       smIOSuccess,
15893                       SCSI_STAT_CHECK_CONDITION,
15894                       satIOContext->pSmSenseData,
15895                       satIOContext->interruptContext );
15896
15897    SM_DBG1(("smsatWriteAndVerify16: return control!!!\n"));
15898    return SM_RC_SUCCESS;
15899  }
15900
15901  sm_memset(LBA, 0, sizeof(LBA));
15902  sm_memset(TL, 0, sizeof(TL));
15903
15904
15905  /* do not use memcpy due to indexing in LBA and TL */
15906  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
15907  LBA[1] = scsiCmnd->cdb[3];
15908  LBA[2] = scsiCmnd->cdb[4];
15909  LBA[3] = scsiCmnd->cdb[5];
15910  LBA[4] = scsiCmnd->cdb[6];
15911  LBA[5] = scsiCmnd->cdb[7];
15912  LBA[6] = scsiCmnd->cdb[8];
15913  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
15914
15915  TL[0] = 0;
15916  TL[1] = 0;
15917  TL[2] = 0;
15918  TL[3] = 0;
15919  TL[4] = scsiCmnd->cdb[10];   /* MSB */
15920  TL[5] = scsiCmnd->cdb[11];
15921  TL[6] = scsiCmnd->cdb[12];
15922  TL[7] = scsiCmnd->cdb[13];   /* LSB */
15923
15924
15925
15926  lba = smsatComputeCDB16LBA(satIOContext);
15927  tl = smsatComputeCDB16TL(satIOContext);
15928
15929
15930  /* Table 34, 9.1, p 46 */
15931  /*
15932    note: As of 2/10/2006, no support for DMA QUEUED
15933  */
15934
15935  /*
15936    Table 34, 9.1, p 46, b
15937    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15938    return check condition
15939  */
15940  if (pSatDevData->satNCQ != agTRUE &&
15941     pSatDevData->sat48BitSupport != agTRUE
15942     )
15943  {
15944    AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15945    if (AllChk)
15946    {
15947      SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, not EXT!!!\n"));
15948      smsatSetSensePayload( pSense,
15949                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15950                            0,
15951                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15952                            satIOContext);
15953
15954      /*smEnqueueIO(smRoot, satIOContext);*/
15955
15956      tdsmIOCompletedCB( smRoot,
15957                         smIORequest,
15958                         smIOSuccess,
15959                         SCSI_STAT_CHECK_CONDITION,
15960                         satIOContext->pSmSenseData,
15961                         satIOContext->interruptContext );
15962
15963      return SM_RC_SUCCESS;
15964    }
15965  }
15966  else
15967  {
15968    AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15969    if (AllChk)
15970    {
15971      SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, EXT!!!\n"));
15972      smsatSetSensePayload( pSense,
15973                            SCSI_SNSKEY_ILLEGAL_REQUEST,
15974                            0,
15975                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15976                            satIOContext);
15977
15978      /*smEnqueueIO(smRoot, satIOContext);*/
15979
15980      tdsmIOCompletedCB( smRoot,
15981                         smIORequest,
15982                         smIOSuccess,
15983                         SCSI_STAT_CHECK_CONDITION,
15984                         satIOContext->pSmSenseData,
15985                         satIOContext->interruptContext );
15986
15987      return SM_RC_SUCCESS;
15988    }
15989  }
15990
15991
15992  /* case 1 and 2 */
15993    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15994    {
15995      /* case 2 */
15996      /* WRITE DMA*/
15997      /* In case that we can't fit the transfer length, we loop */
15998      SM_DBG5(("smsatWriteAndVerify16: case 2\n"));
15999      fis->h.fisType        = 0x27;                   /* Reg host to device */
16000      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16001      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
16002      fis->h.features       = 0;                      /* FIS reserve */
16003      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16004      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16005      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16006
16007      /* FIS LBA mode set LBA (27:24) */
16008      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
16009
16010      fis->d.lbaLowExp      = 0;
16011      fis->d.lbaMidExp      = 0;
16012      fis->d.lbaHighExp     = 0;
16013      fis->d.featuresExp    = 0;
16014      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16015      fis->d.sectorCountExp = 0;
16016      fis->d.reserved4      = 0;
16017      fis->d.control        = 0;                      /* FIS HOB bit clear */
16018      fis->d.reserved5      = 0;
16019
16020      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16021      satIOContext->ATACmd = SAT_WRITE_DMA;
16022    }
16023    else
16024    {
16025      /* case 1 */
16026      /* WRITE MULTIPLE or WRITE SECTOR(S) */
16027      /* WRITE SECTORS for easier implemetation */
16028      /* In case that we can't fit the transfer length, we loop */
16029      SM_DBG5(("smsatWriteAndVerify16: case 1\n"));
16030      fis->h.fisType        = 0x27;                   /* Reg host to device */
16031      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16032      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
16033      fis->h.features       = 0;                      /* FIS reserve */
16034      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16035      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16036      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16037
16038      /* FIS LBA mode set LBA (27:24) */
16039      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
16040
16041      fis->d.lbaLowExp      = 0;
16042      fis->d.lbaMidExp      = 0;
16043      fis->d.lbaHighExp     = 0;
16044      fis->d.featuresExp    = 0;
16045      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16046      fis->d.sectorCountExp = 0;
16047      fis->d.reserved4      = 0;
16048      fis->d.control        = 0;                      /* FIS HOB bit clear */
16049      fis->d.reserved5      = 0;
16050
16051      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16052      satIOContext->ATACmd = SAT_WRITE_SECTORS;
16053  }
16054
16055  /* case 3 and 4 */
16056  if (pSatDevData->sat48BitSupport == agTRUE)
16057  {
16058    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16059    {
16060      /* case 3 */
16061      /* WRITE DMA EXT or WRITE DMA FUA EXT */
16062      SM_DBG5(("smsatWriteAndVerify16: case 3\n"));
16063      fis->h.fisType        = 0x27;                   /* Reg host to device */
16064      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16065
16066      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
16067      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
16068
16069      fis->h.features       = 0;                      /* FIS reserve */
16070      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16071      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16072      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16073      fis->d.device         = 0x40;                   /* FIS LBA mode set */
16074      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
16075      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
16076      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
16077      fis->d.featuresExp    = 0;                      /* FIS reserve */
16078      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16079      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
16080      fis->d.reserved4      = 0;
16081      fis->d.control        = 0;                      /* FIS HOB bit clear */
16082      fis->d.reserved5      = 0;
16083
16084      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16085      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
16086    }
16087    else
16088    {
16089      /* case 4 */
16090      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
16091      /* WRITE SECTORS EXT for easier implemetation */
16092      SM_DBG5(("smsatWriteAndVerify16: case 4\n"));
16093      fis->h.fisType        = 0x27;                   /* Reg host to device */
16094      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16095      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
16096
16097      fis->h.features       = 0;                      /* FIS reserve */
16098      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16099      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16100      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16101      fis->d.device         = 0x40;                   /* FIS LBA mode set */
16102      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
16103      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
16104      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
16105      fis->d.featuresExp    = 0;                      /* FIS reserve */
16106      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16107      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
16108      fis->d.reserved4      = 0;
16109      fis->d.control        = 0;                      /* FIS HOB bit clear */
16110      fis->d.reserved5      = 0;
16111
16112      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16113      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
16114    }
16115  }
16116
16117  /* case 5 */
16118  if (pSatDevData->satNCQ == agTRUE)
16119  {
16120    /* WRITE FPDMA QUEUED */
16121    if (pSatDevData->sat48BitSupport != agTRUE)
16122    {
16123      SM_DBG1(("smsatWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
16124      smsatSetSensePayload( pSense,
16125                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16126                            0,
16127                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16128                            satIOContext);
16129
16130      /*smEnqueueIO(smRoot, satIOContext);*/
16131
16132      tdsmIOCompletedCB( smRoot,
16133                         smIORequest,
16134                         smIOSuccess,
16135                         SCSI_STAT_CHECK_CONDITION,
16136                         satIOContext->pSmSenseData,
16137                         satIOContext->interruptContext );
16138      return SM_RC_SUCCESS;
16139    }
16140    SM_DBG6(("smsatWriteAndVerify16: case 5\n"));
16141
16142    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
16143
16144    fis->h.fisType        = 0x27;                   /* Reg host to device */
16145    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16146    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
16147    fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16148    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16149    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16150    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16151
16152    /* Check FUA bit */
16153    if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
16154      fis->d.device       = 0xC0;                   /* FIS FUA set */
16155    else
16156      fis->d.device       = 0x40;                   /* FIS FUA clear */
16157
16158    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
16159    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
16160    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
16161    fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
16162    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
16163    fis->d.sectorCountExp = 0;
16164    fis->d.reserved4      = 0;
16165    fis->d.control        = 0;                      /* FIS HOB bit clear */
16166    fis->d.reserved5      = 0;
16167
16168    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
16169    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
16170  }
16171
16172  satIOContext->currentLBA = lba;
16173  satIOContext->OrgTL = tl;
16174
16175  /*
16176    computing number of loop and remainder for tl
16177    0xFF in case not ext
16178    0xFFFF in case EXT
16179  */
16180  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
16181  {
16182    LoopNum = smsatComputeLoopNum(tl, 0xFF);
16183  }
16184  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
16185           fis->h.command == SAT_WRITE_DMA_EXT     ||
16186           fis->h.command == SAT_WRITE_DMA_FUA_EXT
16187           )
16188  {
16189    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
16190    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
16191  }
16192  else
16193  {
16194    /* SAT_WRITE_FPDMA_QUEUEDK */
16195    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
16196  }
16197
16198  satIOContext->LoopNum = LoopNum;
16199
16200
16201  if (LoopNum == 1)
16202  {
16203    SM_DBG5(("smsatWriteAndVerify16: NON CHAINED data\n"));
16204    /* Initialize CB for SATA completion.
16205     */
16206    satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
16207  }
16208  else
16209  {
16210    SM_DBG1(("smsatWriteAndVerify16: CHAINED data!!!\n"));
16211    /* re-setting tl */
16212    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
16213    {
16214       fis->d.sectorCount    = 0xFF;
16215    }
16216    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
16217             fis->h.command == SAT_WRITE_DMA_EXT ||
16218             fis->h.command == SAT_WRITE_DMA_FUA_EXT
16219             )
16220    {
16221      fis->d.sectorCount    = 0xFF;
16222      fis->d.sectorCountExp = 0xFF;
16223    }
16224    else
16225    {
16226      /* SAT_WRITE_FPDMA_QUEUED */
16227      fis->h.features       = 0xFF;
16228      fis->d.featuresExp    = 0xFF;
16229    }
16230
16231    /* Initialize CB for SATA completion.
16232     */
16233    satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
16234  }
16235
16236
16237  /*
16238   * Prepare SGL and send FIS to LL layer.
16239   */
16240  satIOContext->reqType = agRequestType;       /* Save it */
16241
16242  status = smsataLLIOStart( smRoot,
16243                            smIORequest,
16244                            smDeviceHandle,
16245                            smScsiRequest,
16246                            satIOContext);
16247  return (status);
16248}
16249
16250osGLOBAL bit32
16251smsatReadMediaSerialNumber(
16252                           smRoot_t                  *smRoot,
16253                           smIORequest_t             *smIORequest,
16254                           smDeviceHandle_t          *smDeviceHandle,
16255                           smScsiInitiatorRequest_t  *smScsiRequest,
16256                           smSatIOContext_t            *satIOContext
16257                          )
16258{
16259  bit32                     status;
16260  bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16261  smDeviceData_t            *pSatDevData;
16262  smScsiRspSense_t          *pSense;
16263  smIniScsiCmnd_t           *scsiCmnd;
16264  agsaFisRegHostToDevice_t  *fis;
16265  agsaSATAIdentifyData_t    *pSATAIdData;
16266  bit8                      *pSerialNumber;
16267  bit8                      MediaSerialNumber[64] = {0};
16268  bit32                     allocationLen = 0;
16269
16270  pSense        = satIOContext->pSense;
16271  pSatDevData   = satIOContext->pSatDevData;
16272  scsiCmnd      = &smScsiRequest->scsiCmnd;
16273  fis           = satIOContext->pFis;
16274  pSATAIdData   = &(pSatDevData->satIdentifyData);
16275  pSerialNumber = (bit8 *) smScsiRequest->sglVirtualAddr;
16276
16277  SM_DBG5(("smsatReadMediaSerialNumber: start\n"));
16278
16279  /* checking CONTROL */
16280  /* NACA == 1 or LINK == 1*/
16281  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
16282  {
16283    smsatSetSensePayload( pSense,
16284                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16285                          0,
16286                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16287                          satIOContext);
16288
16289    /*smEnqueueIO(smRoot, satIOContext);*/
16290
16291    tdsmIOCompletedCB( smRoot,
16292                       smIORequest,
16293                       smIOSuccess,
16294                       SCSI_STAT_CHECK_CONDITION,
16295                       satIOContext->pSmSenseData,
16296                       satIOContext->interruptContext );
16297
16298    SM_DBG1(("smsatReadMediaSerialNumber: return control!!!\n"));
16299    return SM_RC_SUCCESS;
16300  }
16301
16302  allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
16303                  (((bit32)scsiCmnd->cdb[7]) << 16) |
16304                  (((bit32)scsiCmnd->cdb[8]) << 8 ) |
16305                  (((bit32)scsiCmnd->cdb[9]));
16306  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
16307  if (allocationLen == 4)
16308  {
16309    if (pSATAIdData->commandSetFeatureDefault & 0x4)
16310    {
16311      SM_DBG1(("smsatReadMediaSerialNumber: Media serial number returning only length!!!\n"));
16312      /* SPC-3 6.16 p192; filling in length */
16313      MediaSerialNumber[0] = 0;
16314      MediaSerialNumber[1] = 0;
16315      MediaSerialNumber[2] = 0;
16316      MediaSerialNumber[3] = 0x3C;
16317    }
16318    else
16319    {
16320      /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/
16321      MediaSerialNumber[0] = 0;
16322      MediaSerialNumber[1] = 0;
16323      MediaSerialNumber[2] = 0x1;
16324      MediaSerialNumber[3] = 0xfc;
16325    }
16326
16327    sm_memcpy(pSerialNumber, MediaSerialNumber, 4);
16328    /*smEnqueueIO(smRoot, satIOContext);*/
16329
16330    tdsmIOCompletedCB( smRoot,
16331                       smIORequest,
16332                       smIOSuccess,
16333                       SCSI_STAT_GOOD,
16334                       agNULL,
16335                       satIOContext->interruptContext);
16336
16337    return SM_RC_SUCCESS;
16338  }
16339
16340  if ( pSatDevData->IDDeviceValid == agTRUE)
16341  {
16342    if (pSATAIdData->commandSetFeatureDefault & 0x4)
16343    {
16344      /* word87 bit2 Media serial number is valid */
16345      /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/
16346#ifdef LOG_ENABLE
16347      smhexdump("ID smsatReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
16348#endif
16349      /* SPC-3 6.16 p192; filling in length */
16350      MediaSerialNumber[0] = 0;
16351      MediaSerialNumber[1] = 0;
16352      MediaSerialNumber[2] = 0;
16353      MediaSerialNumber[3] = 0x3C;
16354      sm_memcpy(&MediaSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
16355#ifdef LOG_ENABLE
16356      smhexdump("smsatReadMediaSerialNumber", (bit8*)MediaSerialNumber, 2*30 + 4);
16357#endif
16358      sm_memcpy(pSerialNumber, MediaSerialNumber, MIN(allocationLen, 64));
16359      /*smEnqueueIO(smRoot, satIOContext);*/
16360
16361      tdsmIOCompletedCB( smRoot,
16362                         smIORequest,
16363                         smIOSuccess,
16364                         SCSI_STAT_GOOD,
16365                         agNULL,
16366                         satIOContext->interruptContext);
16367      return SM_RC_SUCCESS;
16368
16369
16370    }
16371    else
16372    {
16373     /* word87 bit2 Media serial number is NOT valid */
16374      SM_DBG1(("smsatReadMediaSerialNumber: Media serial number is NOT valid!!!\n"));
16375
16376      if (pSatDevData->sat48BitSupport == agTRUE)
16377      {
16378        /* READ VERIFY SECTORS EXT */
16379        fis->h.fisType        = 0x27;                   /* Reg host to device */
16380        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16381        fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
16382
16383        fis->h.features       = 0;                      /* FIS reserve */
16384        fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16385        fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16386        fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16387        fis->d.device         = 0x40;                   /* FIS LBA mode set */
16388        fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
16389        fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
16390        fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
16391        fis->d.featuresExp    = 0;                      /* FIS reserve */
16392        fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16393        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16394        fis->d.reserved4      = 0;
16395        fis->d.control        = 0;                      /* FIS HOB bit clear */
16396        fis->d.reserved5      = 0;
16397
16398        agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16399      }
16400      else
16401      {
16402        /* READ VERIFY SECTORS */
16403        fis->h.fisType        = 0x27;                   /* Reg host to device */
16404        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16405        fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
16406        fis->h.features       = 0;                      /* FIS reserve */
16407        fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16408        fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16409        fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16410        fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16411        fis->d.lbaLowExp      = 0;
16412        fis->d.lbaMidExp      = 0;
16413        fis->d.lbaHighExp     = 0;
16414        fis->d.featuresExp    = 0;
16415        fis->d.sectorCount    = 1;                       /* FIS sector count (7:0) */
16416        fis->d.sectorCountExp = 0;
16417        fis->d.reserved4      = 0;
16418        fis->d.control        = 0;                      /* FIS HOB bit clear */
16419        fis->d.reserved5      = 0;
16420
16421
16422        agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16423      }
16424      satIOContext->satCompleteCB = &smsatReadMediaSerialNumberCB;
16425      satIOContext->reqType = agRequestType;       /* Save it */
16426      status = smsataLLIOStart( smRoot,
16427                                smIORequest,
16428                                smDeviceHandle,
16429                                smScsiRequest,
16430                                satIOContext);
16431
16432      return status;
16433    }
16434  }
16435  else
16436  {
16437
16438    tdsmIOCompletedCB( smRoot,
16439                       smIORequest,
16440                       smIOFailed,
16441                       smDetailOtherError,
16442                       agNULL,
16443                       satIOContext->interruptContext);
16444
16445    return SM_RC_SUCCESS;
16446
16447  }
16448}
16449
16450osGLOBAL bit32
16451smsatReadBuffer(
16452                smRoot_t                  *smRoot,
16453                smIORequest_t             *smIORequest,
16454                smDeviceHandle_t          *smDeviceHandle,
16455                smScsiInitiatorRequest_t  *smScsiRequest,
16456                smSatIOContext_t            *satIOContext
16457               )
16458{
16459  bit32                      status = SM_RC_SUCCESS;
16460  bit32                      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16461  smScsiRspSense_t          *pSense;
16462  smIniScsiCmnd_t           *scsiCmnd;
16463  agsaFisRegHostToDevice_t  *fis;
16464  bit32                      bufferOffset;
16465  bit32                      tl;
16466  bit8                       mode;
16467  bit8                       bufferID;
16468  bit8                      *pBuff;
16469
16470  pSense        = satIOContext->pSense;
16471  scsiCmnd      = &smScsiRequest->scsiCmnd;
16472  fis           = satIOContext->pFis;
16473  pBuff         = (bit8 *) smScsiRequest->sglVirtualAddr;
16474
16475  SM_DBG5(("smsatReadBuffer: start\n"));
16476
16477  /* checking CONTROL */
16478  /* NACA == 1 or LINK == 1*/
16479  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16480  {
16481    smsatSetSensePayload( pSense,
16482                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16483                          0,
16484                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16485                          satIOContext);
16486
16487    /*smEnqueueIO(smRoot, satIOContext);*/
16488
16489    tdsmIOCompletedCB( smRoot,
16490                       smIORequest,
16491                       smIOSuccess,
16492                       SCSI_STAT_CHECK_CONDITION,
16493                       satIOContext->pSmSenseData,
16494                       satIOContext->interruptContext );
16495
16496    SM_DBG1(("smsatReadBuffer: return control!!!\n"));
16497    return SM_RC_SUCCESS;
16498  }
16499
16500  bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16501  tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16502
16503  mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16504  bufferID = scsiCmnd->cdb[2];
16505
16506  if (mode == READ_BUFFER_DATA_MODE) /* 2 */
16507  {
16508    if (bufferID == 0 && bufferOffset == 0 && tl == 512)
16509    {
16510      /* send ATA READ BUFFER */
16511      fis->h.fisType        = 0x27;                   /* Reg host to device */
16512      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16513      fis->h.command        = SAT_READ_BUFFER;        /* 0xE4 */
16514      fis->h.features       = 0;                      /* FIS reserve */
16515      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16516      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16517      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16518      fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16519      fis->d.lbaLowExp      = 0;
16520      fis->d.lbaMidExp      = 0;
16521      fis->d.lbaHighExp     = 0;
16522      fis->d.featuresExp    = 0;
16523      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16524      fis->d.sectorCountExp = 0;
16525      fis->d.reserved4      = 0;
16526      fis->d.control        = 0;                      /* FIS HOB bit clear */
16527      fis->d.reserved5      = 0;
16528
16529
16530      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16531
16532      satIOContext->satCompleteCB = &smsatReadBufferCB;
16533
16534      satIOContext->reqType = agRequestType;       /* Save it */
16535
16536      status = smsataLLIOStart( smRoot,
16537                                smIORequest,
16538                                smDeviceHandle,
16539                                smScsiRequest,
16540                                satIOContext);
16541      return status;
16542    }
16543
16544    if (bufferID == 0 && bufferOffset == 0 && tl != 512)
16545    {
16546      smsatSetSensePayload( pSense,
16547                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16548                            0,
16549                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16550                            satIOContext);
16551
16552      /*smEnqueueIO(smRoot, satIOContext);*/
16553
16554      tdsmIOCompletedCB( smRoot,
16555                         smIORequest,
16556                         smIOSuccess,
16557                         SCSI_STAT_CHECK_CONDITION,
16558                         satIOContext->pSmSenseData,
16559                         satIOContext->interruptContext );
16560
16561      SM_DBG1(("smsatReadBuffer: allocation length is not 512; it is %d!!!\n", tl));
16562      return SM_RC_SUCCESS;
16563    }
16564
16565    if (bufferID == 0 && bufferOffset != 0)
16566    {
16567      smsatSetSensePayload( pSense,
16568                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16569                            0,
16570                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16571                            satIOContext);
16572
16573      /*smEnqueueIO(smRoot, satIOContext);*/
16574
16575      tdsmIOCompletedCB( smRoot,
16576                         smIORequest,
16577                         smIOSuccess,
16578                         SCSI_STAT_CHECK_CONDITION,
16579                         satIOContext->pSmSenseData,
16580                         satIOContext->interruptContext );
16581
16582      SM_DBG1(("smsatReadBuffer: buffer offset is not 0; it is %d!!!\n", bufferOffset));
16583      return SM_RC_SUCCESS;
16584    }
16585    /* all other cases unsupported */
16586    SM_DBG1(("smsatReadBuffer: unsupported case 1!!!\n"));
16587    smsatSetSensePayload( pSense,
16588                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16589                          0,
16590                          SCSI_SNSCODE_INVALID_COMMAND,
16591                          satIOContext);
16592
16593    /*smEnqueueIO(smRoot, satIOContext);*/
16594
16595    tdsmIOCompletedCB( smRoot,
16596                       smIORequest,
16597                       smIOSuccess,
16598                       SCSI_STAT_CHECK_CONDITION,
16599                       satIOContext->pSmSenseData,
16600                       satIOContext->interruptContext );
16601
16602    return SM_RC_SUCCESS;
16603
16604  }
16605  else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */
16606  {
16607    if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */
16608    {
16609      smsatSetSensePayload( pSense,
16610                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16611                            0,
16612                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16613                            satIOContext);
16614
16615      /*smEnqueueIO(smRoot, satIOContext);*/
16616
16617      tdsmIOCompletedCB( smRoot,
16618                         smIORequest,
16619                         smIOSuccess,
16620                         SCSI_STAT_CHECK_CONDITION,
16621                         satIOContext->pSmSenseData,
16622                         satIOContext->interruptContext );
16623
16624      SM_DBG1(("smsatReadBuffer: tl < 4; tl is %d!!!\n", tl));
16625      return SM_RC_SUCCESS;
16626    }
16627    if (bufferID == 0)
16628    {
16629      /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/
16630      pBuff[0] = 0xFF;
16631      pBuff[1] = 0x00;
16632      pBuff[2] = 0x02;
16633      pBuff[3] = 0x00;
16634      if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
16635      {
16636        /* underrrun */
16637        SM_DBG1(("smsatReadBuffer: underrun tl %d data %d!!!\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
16638        /*smEnqueueIO(smRoot, satIOContext);*/
16639
16640        tdsmIOCompletedCB( smRoot,
16641                           smIORequest,
16642                           smIOUnderRun,
16643                           tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
16644                           agNULL,
16645                           satIOContext->interruptContext );
16646
16647        return SM_RC_SUCCESS;
16648      }
16649      else
16650      {
16651        /*smEnqueueIO(smRoot, satIOContext);*/
16652
16653        tdsmIOCompletedCB( smRoot,
16654                           smIORequest,
16655                           smIOSuccess,
16656                           SCSI_STAT_GOOD,
16657                           agNULL,
16658                           satIOContext->interruptContext);
16659        return SM_RC_SUCCESS;
16660      }
16661    }
16662    else
16663    {
16664      /* We don't support other than bufferID 0 */
16665      smsatSetSensePayload( pSense,
16666                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16667                            0,
16668                            SCSI_SNSCODE_INVALID_COMMAND,
16669                            satIOContext);
16670
16671      /*smEnqueueIO(smRoot, satIOContext);*/
16672
16673      tdsmIOCompletedCB( smRoot,
16674                         smIORequest,
16675                         smIOSuccess,
16676                         SCSI_STAT_CHECK_CONDITION,
16677                         satIOContext->pSmSenseData,
16678                         satIOContext->interruptContext );
16679
16680      return SM_RC_SUCCESS;
16681    }
16682  }
16683  else
16684  {
16685    /* We don't support any other mode */
16686    SM_DBG1(("smsatReadBuffer: unsupported mode %d!!!\n", mode));
16687    smsatSetSensePayload( pSense,
16688                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16689                          0,
16690                          SCSI_SNSCODE_INVALID_COMMAND,
16691                          satIOContext);
16692
16693    /*smEnqueueIO(smRoot, satIOContext);*/
16694
16695    tdsmIOCompletedCB( smRoot,
16696                       smIORequest,
16697                       smIOSuccess,
16698                       SCSI_STAT_CHECK_CONDITION,
16699                       satIOContext->pSmSenseData,
16700                       satIOContext->interruptContext );
16701
16702    return SM_RC_SUCCESS;
16703  }
16704}
16705
16706osGLOBAL bit32
16707smsatWriteBuffer(
16708                 smRoot_t                  *smRoot,
16709                 smIORequest_t             *smIORequest,
16710                 smDeviceHandle_t          *smDeviceHandle,
16711                 smScsiInitiatorRequest_t  *smScsiRequest,
16712                 smSatIOContext_t            *satIOContext
16713                )
16714{
16715#ifdef NOT_YET
16716  bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16717#endif
16718  smScsiRspSense_t          *pSense;
16719  smIniScsiCmnd_t           *scsiCmnd;
16720#ifdef NOT_YET
16721  agsaFisRegHostToDevice_t  *fis;
16722#endif
16723  bit32                     bufferOffset;
16724  bit32                     parmLen;
16725  bit8                      mode;
16726  bit8                      bufferID;
16727  bit8                      *pBuff;
16728
16729  pSense        = satIOContext->pSense;
16730  scsiCmnd      = &smScsiRequest->scsiCmnd;
16731#ifdef NOT_YET
16732  fis           = satIOContext->pFis;
16733#endif
16734  pBuff         = (bit8 *) smScsiRequest->sglVirtualAddr;
16735
16736  SM_DBG5(("smsatWriteBuffer: start\n"));
16737
16738  /* checking CONTROL */
16739  /* NACA == 1 or LINK == 1*/
16740  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16741  {
16742    smsatSetSensePayload( pSense,
16743                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16744                          0,
16745                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16746                          satIOContext);
16747
16748    /*smEnqueueIO(smRoot, satIOContext);*/
16749
16750    tdsmIOCompletedCB( smRoot,
16751                       smIORequest,
16752                       smIOSuccess,
16753                       SCSI_STAT_CHECK_CONDITION,
16754                       satIOContext->pSmSenseData,
16755                       satIOContext->interruptContext );
16756
16757    SM_DBG1(("smsatWriteBuffer: return control!!!\n"));
16758    return SM_RC_SUCCESS;
16759  }
16760
16761  bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16762  parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16763
16764  mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16765  bufferID = scsiCmnd->cdb[2];
16766
16767  /* for debugging only */
16768  smhexdump("smsatWriteBuffer pBuff", (bit8 *)pBuff, 24);
16769
16770  if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */
16771  {
16772    if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
16773    {
16774      SM_DBG1(("smsatWriteBuffer: sending ATA WRITE BUFFER!!!\n"));
16775      /* send ATA WRITE BUFFER */
16776#ifdef NOT_YET
16777      fis->h.fisType        = 0x27;                   /* Reg host to device */
16778      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16779      fis->h.command        = SAT_WRITE_BUFFER;       /* 0xE8 */
16780      fis->h.features       = 0;                      /* FIS reserve */
16781      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16782      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16783      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16784      fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16785      fis->d.lbaLowExp      = 0;
16786      fis->d.lbaMidExp      = 0;
16787      fis->d.lbaHighExp     = 0;
16788      fis->d.featuresExp    = 0;
16789      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16790      fis->d.sectorCountExp = 0;
16791      fis->d.reserved4      = 0;
16792      fis->d.control        = 0;                      /* FIS HOB bit clear */
16793      fis->d.reserved5      = 0;
16794
16795
16796      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16797
16798      satIOContext->satCompleteCB = &smsatWriteBufferCB;
16799
16800      satIOContext->reqType = agRequestType;       /* Save it */
16801
16802      status = smsataLLIOStart( smRoot,
16803                                smIORequest,
16804                                smDeviceHandle,
16805                                smScsiRequest,
16806                                satIOContext);
16807      return status;
16808#endif
16809      /* temp */
16810      /*smEnqueueIO(smRoot, satIOContext);*/
16811
16812      tdsmIOCompletedCB( smRoot,
16813                         smIORequest,
16814                         smIOSuccess,
16815                         SCSI_STAT_GOOD,
16816                         agNULL,
16817                         satIOContext->interruptContext);
16818      return SM_RC_SUCCESS;
16819    }
16820    if ( (bufferID == 0 && bufferOffset != 0) ||
16821         (bufferID == 0 && parmLen != 512)
16822        )
16823    {
16824      smsatSetSensePayload( pSense,
16825                            SCSI_SNSKEY_ILLEGAL_REQUEST,
16826                            0,
16827                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16828                            satIOContext);
16829
16830      /*smEnqueueIO(smRoot, satIOContext);*/
16831
16832      tdsmIOCompletedCB( smRoot,
16833                         smIORequest,
16834                         smIOSuccess,
16835                         SCSI_STAT_CHECK_CONDITION,
16836                         satIOContext->pSmSenseData,
16837                         satIOContext->interruptContext );
16838
16839      SM_DBG1(("smsatWriteBuffer: wrong buffer offset %d or parameter length parmLen %d!!!\n", bufferOffset, parmLen));
16840      return SM_RC_SUCCESS;
16841    }
16842
16843    /* all other cases unsupported */
16844    SM_DBG1(("smsatWriteBuffer: unsupported case 1!!!\n"));
16845    smsatSetSensePayload( pSense,
16846                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16847                          0,
16848                          SCSI_SNSCODE_INVALID_COMMAND,
16849                          satIOContext);
16850
16851    /*smEnqueueIO(smRoot, satIOContext);*/
16852
16853    tdsmIOCompletedCB( smRoot,
16854                       smIORequest,
16855                       smIOSuccess,
16856                       SCSI_STAT_CHECK_CONDITION,
16857                       satIOContext->pSmSenseData,
16858                       satIOContext->interruptContext );
16859
16860    return SM_RC_SUCCESS;
16861
16862  }
16863  else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */
16864  {
16865    /* temporary */
16866    SM_DBG1(("smsatWriteBuffer: not yet supported mode %d!!!\n", mode));
16867    smsatSetSensePayload( pSense,
16868                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16869                          0,
16870                          SCSI_SNSCODE_INVALID_COMMAND,
16871                          satIOContext);
16872
16873
16874    tdsmIOCompletedCB( smRoot,
16875                       smIORequest,
16876                       smIOSuccess,
16877                       SCSI_STAT_CHECK_CONDITION,
16878                       satIOContext->pSmSenseData,
16879                       satIOContext->interruptContext );
16880
16881    return SM_RC_SUCCESS;
16882  }
16883  else
16884  {
16885    /* We don't support any other mode */
16886    SM_DBG1(("smsatWriteBuffer: unsupported mode %d!!!\n", mode));
16887    smsatSetSensePayload( pSense,
16888                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16889                          0,
16890                          SCSI_SNSCODE_INVALID_COMMAND,
16891                          satIOContext);
16892
16893    /*smEnqueueIO(smRoot, satIOContext);*/
16894
16895    tdsmIOCompletedCB( smRoot,
16896                       smIORequest,
16897                       smIOSuccess,
16898                       SCSI_STAT_CHECK_CONDITION,
16899                       satIOContext->pSmSenseData,
16900                       satIOContext->interruptContext );
16901
16902    return SM_RC_SUCCESS;
16903  }
16904
16905}
16906
16907osGLOBAL bit32
16908smsatReassignBlocks(
16909                    smRoot_t                  *smRoot,
16910                    smIORequest_t             *smIORequest,
16911                    smDeviceHandle_t          *smDeviceHandle,
16912                    smScsiInitiatorRequest_t  *smScsiRequest,
16913                    smSatIOContext_t            *satIOContext
16914                   )
16915{
16916  /*
16917    assumes all LBA fits in ATA command; no boundary condition is checked here yet
16918  */
16919  bit32                     status;
16920  bit32                     agRequestType;
16921  smDeviceData_t            *pSatDevData;
16922  smScsiRspSense_t          *pSense;
16923  smIniScsiCmnd_t           *scsiCmnd;
16924  agsaFisRegHostToDevice_t  *fis;
16925  bit8                      *pParmList;    /* Log Page data buffer */
16926  bit8                      LongLBA;
16927  bit8                      LongList;
16928  bit32                     defectListLen;
16929  bit8                      LBA[8];
16930  bit32                     startingIndex;
16931
16932  pSense        = satIOContext->pSense;
16933  pSatDevData   = satIOContext->pSatDevData;
16934  scsiCmnd      = &smScsiRequest->scsiCmnd;
16935  fis           = satIOContext->pFis;
16936  pParmList     = (bit8 *) smScsiRequest->sglVirtualAddr;
16937
16938  SM_DBG5(("smsatReassignBlocks: start\n"));
16939
16940  /* checking CONTROL */
16941  /* NACA == 1 or LINK == 1*/
16942  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
16943  {
16944    smsatSetSensePayload( pSense,
16945                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16946                          0,
16947                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16948                          satIOContext);
16949
16950    /*smEnqueueIO(smRoot, satIOContext);*/
16951
16952    tdsmIOCompletedCB( smRoot,
16953                       smIORequest,
16954                       smIOSuccess,
16955                       SCSI_STAT_CHECK_CONDITION,
16956                       satIOContext->pSmSenseData,
16957                       satIOContext->interruptContext );
16958
16959    SM_DBG1(("smsatReassignBlocks: return control!!!\n"));
16960    return SM_RC_SUCCESS;
16961  }
16962
16963  sm_memset(satIOContext->LBA, 0, 8);
16964  satIOContext->ParmIndex = 0;
16965  satIOContext->ParmLen = 0;
16966
16967  LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK);
16968  LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16969  sm_memset(LBA, 0, sizeof(LBA));
16970
16971  if (LongList == 0)
16972  {
16973    defectListLen = (pParmList[2] << 8) + pParmList[3];
16974  }
16975  else
16976  {
16977    defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2))
16978                  + (pParmList[2] << 8) + pParmList[3];
16979  }
16980  /* SBC 5.16.2, p61*/
16981  satIOContext->ParmLen = defectListLen + 4 /* header size */;
16982
16983  startingIndex = 4;
16984
16985  if (LongLBA == 0)
16986  {
16987    LBA[4] = pParmList[startingIndex];   /* MSB */
16988    LBA[5] = pParmList[startingIndex+1];
16989    LBA[6] = pParmList[startingIndex+2];
16990    LBA[7] = pParmList[startingIndex+3];  /* LSB */
16991    startingIndex = startingIndex + 4;
16992  }
16993  else
16994  {
16995    LBA[0] = pParmList[startingIndex];    /* MSB */
16996    LBA[1] = pParmList[startingIndex+1];
16997    LBA[2] = pParmList[startingIndex+2];
16998    LBA[3] = pParmList[startingIndex+3];
16999    LBA[4] = pParmList[startingIndex+4];
17000    LBA[5] = pParmList[startingIndex+5];
17001    LBA[6] = pParmList[startingIndex+6];
17002    LBA[7] = pParmList[startingIndex+7];  /* LSB */
17003    startingIndex = startingIndex + 8;
17004  }
17005
17006  smhexdump("smsatReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen);
17007
17008  if (pSatDevData->sat48BitSupport == agTRUE)
17009  {
17010    /* sends READ VERIFY SECTOR(S) EXT*/
17011    fis->h.fisType        = 0x27;                   /* Reg host to device */
17012    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17013    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17014    fis->h.features       = 0;                      /* FIS reserve */
17015    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
17016    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
17017    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
17018    fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
17019    fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
17020    fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
17021    fis->d.featuresExp    = 0;                      /* FIS reserve */
17022    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
17023    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
17024    fis->d.reserved4      = 0;
17025    fis->d.device         = 0x40;                   /* 01000000 */
17026    fis->d.control        = 0;                      /* FIS HOB bit clear */
17027    fis->d.reserved5      = 0;
17028  }
17029  else
17030  {
17031    /* READ VERIFY SECTOR(S)*/
17032    fis->h.fisType        = 0x27;                   /* Reg host to device */
17033    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17034    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
17035    fis->h.features       = 0;                      /* FIS features NA       */
17036    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
17037    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
17038    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
17039    fis->d.lbaLowExp      = 0;
17040    fis->d.lbaMidExp      = 0;
17041    fis->d.lbaHighExp     = 0;
17042    fis->d.featuresExp    = 0;
17043    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
17044    fis->d.sectorCountExp = 0;
17045    fis->d.reserved4      = 0;
17046    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
17047                            /* DEV and LBA 27:24 */
17048    fis->d.control        = 0;                      /* FIS HOB bit clear */
17049    fis->d.reserved5      = 0;
17050  }
17051
17052  sm_memcpy(satIOContext->LBA, LBA, 8);
17053  satIOContext->ParmIndex = startingIndex;
17054
17055  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17056
17057  /* Initialize CB for SATA completion.
17058   */
17059  satIOContext->satCompleteCB = &smsatReassignBlocksCB;
17060
17061  /*
17062   * Prepare SGL and send FIS to LL layer.
17063   */
17064  satIOContext->reqType = agRequestType;       /* Save it */
17065
17066  status = smsataLLIOStart( smRoot,
17067                            smIORequest,
17068                            smDeviceHandle,
17069                            smScsiRequest,
17070                            satIOContext);
17071
17072  return status;
17073}
17074
17075osGLOBAL bit32
17076smsatRead_1(
17077            smRoot_t                  *smRoot,
17078            smIORequest_t             *smIORequest,
17079            smDeviceHandle_t          *smDeviceHandle,
17080            smScsiInitiatorRequest_t  *smScsiRequest,
17081            smSatIOContext_t            *satIOContext
17082          )
17083{
17084  /*
17085    Assumption: error check on lba and tl has been done in satRead*()
17086    lba = lba + tl;
17087  */
17088  bit32                     status;
17089  smSatIOContext_t            *satOrgIOContext = agNULL;
17090  smIniScsiCmnd_t           *scsiCmnd;
17091  agsaFisRegHostToDevice_t  *fis;
17092  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17093  bit32                     lba = 0;
17094  bit32                     DenomTL = 0xFF;
17095  bit32                     Remainder = 0;
17096  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
17097
17098  SM_DBG2(("smsatRead_1: start\n"));
17099
17100  fis             = satIOContext->pFis;
17101  satOrgIOContext = satIOContext->satOrgIOContext;
17102  scsiCmnd        = satOrgIOContext->pScsiCmnd;
17103
17104  sm_memset(LBA,0, sizeof(LBA));
17105
17106  switch (satOrgIOContext->ATACmd)
17107  {
17108  case SAT_READ_DMA:
17109    DenomTL = 0x100;
17110    break;
17111  case SAT_READ_SECTORS:
17112    DenomTL = 0x100;
17113    break;
17114  case SAT_READ_DMA_EXT:
17115    DenomTL = 0xFFFF;
17116    break;
17117  case SAT_READ_SECTORS_EXT:
17118    DenomTL = 0xFFFF;
17119    break;
17120  case SAT_READ_FPDMA_QUEUED:
17121    DenomTL = 0xFFFF;
17122    break;
17123  default:
17124    SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17125    return SM_RC_FAILURE;
17126    break;
17127  }
17128
17129  Remainder = satOrgIOContext->OrgTL % DenomTL;
17130  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
17131  lba = satOrgIOContext->currentLBA;
17132
17133  LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3));
17134  LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2));
17135  LBA[2] = (bit8)((lba & 0xFF00) >> 8);
17136  LBA[3] = (bit8)(lba & 0xFF);
17137
17138  switch (satOrgIOContext->ATACmd)
17139  {
17140  case SAT_READ_DMA:
17141    fis->h.fisType        = 0x27;                   /* Reg host to device */
17142    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17143    fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
17144    fis->h.features       = 0;                      /* FIS reserve */
17145    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17146    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17147    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17148    fis->d.device         =
17149      (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
17150    fis->d.lbaLowExp      = 0;
17151    fis->d.lbaMidExp      = 0;
17152    fis->d.lbaHighExp     = 0;
17153    fis->d.featuresExp    = 0;
17154
17155    if (satOrgIOContext->LoopNum == 1)
17156    {
17157      /* last loop */
17158      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
17159    }
17160    else
17161    {
17162      fis->d.sectorCount    = 0x0;                  /* FIS sector count (7:0) */
17163    }
17164
17165    fis->d.sectorCountExp = 0;
17166    fis->d.reserved4      = 0;
17167    fis->d.control        = 0;                      /* FIS HOB bit clear */
17168    fis->d.reserved5      = 0;
17169
17170    agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17171
17172    break;
17173  case SAT_READ_SECTORS:
17174    fis->h.fisType        = 0x27;                   /* Reg host to device */
17175    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17176    fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
17177    fis->h.features       = 0;                      /* FIS reserve */
17178    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17179    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17180    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17181    fis->d.device         =
17182      (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
17183    fis->d.lbaLowExp      = 0;
17184    fis->d.lbaMidExp      = 0;
17185    fis->d.lbaHighExp     = 0;
17186    fis->d.featuresExp    = 0;
17187    if (satOrgIOContext->LoopNum == 1)
17188    {
17189      /* last loop */
17190      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
17191    }
17192    else
17193    {
17194      fis->d.sectorCount    = 0x0;                   /* FIS sector count (7:0) */
17195    }
17196    fis->d.sectorCountExp = 0;
17197    fis->d.reserved4      = 0;
17198    fis->d.control        = 0;                      /* FIS HOB bit clear */
17199    fis->d.reserved5      = 0;
17200
17201    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
17202
17203    break;
17204  case SAT_READ_DMA_EXT:
17205    fis->h.fisType        = 0x27;                   /* Reg host to device */
17206    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17207    fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
17208    fis->h.features       = 0;                      /* FIS reserve */
17209    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17210    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17211    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17212    fis->d.device         = 0x40;                   /* FIS LBA mode set */
17213    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17214    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17215    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17216    fis->d.featuresExp    = 0;                      /* FIS reserve */
17217    if (satOrgIOContext->LoopNum == 1)
17218    {
17219      /* last loop */
17220      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17221      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17222
17223    }
17224    else
17225    {
17226      fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
17227      fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
17228    }
17229    fis->d.reserved4      = 0;
17230    fis->d.control        = 0;                      /* FIS HOB bit clear */
17231    fis->d.reserved5      = 0;
17232
17233    agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17234
17235    break;
17236  case SAT_READ_SECTORS_EXT:
17237    fis->h.fisType        = 0x27;                   /* Reg host to device */
17238    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17239    fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
17240    fis->h.features       = 0;                      /* FIS reserve */
17241    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17242    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17243    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17244    fis->d.device         = 0x40;                   /* FIS LBA mode set */
17245    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17246    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17247    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17248    fis->d.featuresExp    = 0;                      /* FIS reserve */
17249    if (satOrgIOContext->LoopNum == 1)
17250    {
17251      /* last loop */
17252      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17253      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);  /* FIS sector count (15:8) */
17254    }
17255    else
17256    {
17257      fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
17258      fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
17259    }
17260    fis->d.reserved4      = 0;
17261    fis->d.control        = 0;                      /* FIS HOB bit clear */
17262    fis->d.reserved5      = 0;
17263
17264    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
17265    break;
17266  case SAT_READ_FPDMA_QUEUED:
17267    fis->h.fisType        = 0x27;                   /* Reg host to device */
17268    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17269    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
17270    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17271    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17272    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17273
17274    /* Check FUA bit */
17275    if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
17276      fis->d.device       = 0xC0;                   /* FIS FUA set */
17277    else
17278      fis->d.device       = 0x40;                   /* FIS FUA clear */
17279
17280    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17281    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17282    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17283    if (satOrgIOContext->LoopNum == 1)
17284    {
17285      /* last loop */
17286      fis->h.features       = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
17287      fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17288    }
17289    else
17290    {
17291      fis->h.features       = 0xFF;       /* FIS sector count (7:0) */
17292      fis->d.featuresExp    = 0xFF;       /* FIS sector count (15:8) */
17293    }
17294    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
17295    fis->d.sectorCountExp = 0;
17296    fis->d.reserved4      = 0;
17297    fis->d.control        = 0;                      /* FIS HOB bit clear */
17298    fis->d.reserved5      = 0;
17299
17300    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
17301    break;
17302  default:
17303    SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17304    return SM_RC_FAILURE;
17305    break;
17306  }
17307
17308  /* Initialize CB for SATA completion.
17309   */
17310  /* chained data */
17311  satIOContext->satCompleteCB = &smsatChainedDataIOCB;
17312
17313  if (satOrgIOContext->ATACmd == SAT_READ_DMA || satOrgIOContext->ATACmd == SAT_READ_SECTORS)
17314  {
17315    smsatSplitSGL(smRoot,
17316                  smIORequest,
17317                  smDeviceHandle,
17318                  (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17319                  satOrgIOContext,
17320                  NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/
17321                  (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17322                  agFALSE);
17323  }
17324  else
17325  {
17326    smsatSplitSGL(smRoot,
17327                  smIORequest,
17328                  smDeviceHandle,
17329                  (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17330                  satOrgIOContext,
17331                  BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/
17332                  (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17333                  agFALSE);
17334  }
17335
17336  /*
17337   * Prepare SGL and send FIS to LL layer.
17338   */
17339  satIOContext->reqType = agRequestType;       /* Save it */
17340
17341  status = smsataLLIOStart( smRoot,
17342                            smIORequest,
17343                            smDeviceHandle,
17344                            (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest,
17345                            satIOContext);
17346
17347  SM_DBG5(("smsatRead_1: return\n"));
17348  return (status);
17349}
17350
17351osGLOBAL bit32
17352smsatWrite_1(
17353             smRoot_t                  *smRoot,
17354             smIORequest_t             *smIORequest,
17355             smDeviceHandle_t          *smDeviceHandle,
17356             smScsiInitiatorRequest_t  *smScsiRequest,
17357             smSatIOContext_t            *satIOContext
17358           )
17359{
17360  /*
17361    Assumption: error check on lba and tl has been done in satWrite*()
17362    lba = lba + tl;
17363  */
17364  bit32                     status;
17365  smSatIOContext_t            *satOrgIOContext = agNULL;
17366  smIniScsiCmnd_t           *scsiCmnd;
17367  agsaFisRegHostToDevice_t  *fis;
17368  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17369  bit32                     lba = 0;
17370  bit32                     DenomTL = 0xFF;
17371  bit32                     Remainder = 0;
17372  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
17373
17374  SM_DBG2(("smsatWrite_1: start\n"));
17375
17376  fis             = satIOContext->pFis;
17377  satOrgIOContext = satIOContext->satOrgIOContext;
17378  scsiCmnd        = satOrgIOContext->pScsiCmnd;
17379
17380  sm_memset(LBA,0, sizeof(LBA));
17381
17382  switch (satOrgIOContext->ATACmd)
17383  {
17384  case SAT_WRITE_DMA:
17385    DenomTL = 0x100;
17386    break;
17387  case SAT_WRITE_SECTORS:
17388    DenomTL = 0x100;
17389    break;
17390  case SAT_WRITE_DMA_EXT:
17391    DenomTL = 0xFFFF;
17392    break;
17393  case SAT_WRITE_DMA_FUA_EXT:
17394    DenomTL = 0xFFFF;
17395    break;
17396  case SAT_WRITE_SECTORS_EXT:
17397    DenomTL = 0xFFFF;
17398    break;
17399  case SAT_WRITE_FPDMA_QUEUED:
17400    DenomTL = 0xFFFF;
17401    break;
17402  default:
17403    SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17404    return SM_RC_FAILURE;
17405    break;
17406  }
17407
17408  Remainder = satOrgIOContext->OrgTL % DenomTL;
17409  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
17410  lba = satOrgIOContext->currentLBA;
17411
17412
17413  LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3));
17414  LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2));
17415  LBA[2] = (bit8)((lba & 0xFF00) >> 8);
17416  LBA[3] = (bit8)(lba & 0xFF);
17417
17418  switch (satOrgIOContext->ATACmd)
17419  {
17420  case SAT_WRITE_DMA:
17421    fis->h.fisType        = 0x27;                   /* Reg host to device */
17422    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
17423    fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
17424    fis->h.features       = 0;                      /* FIS reserve */
17425    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17426    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17427    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17428
17429    /* FIS LBA mode set LBA (27:24) */
17430    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
17431
17432    fis->d.lbaLowExp      = 0;
17433    fis->d.lbaMidExp      = 0;
17434    fis->d.lbaHighExp     = 0;
17435    fis->d.featuresExp    = 0;
17436    if (satOrgIOContext->LoopNum == 1)
17437    {
17438      /* last loop */
17439      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
17440    }
17441    else
17442    {
17443      fis->d.sectorCount    = 0x0;                   /* FIS sector count (7:0) */
17444    }
17445    fis->d.sectorCountExp = 0;
17446    fis->d.reserved4      = 0;
17447    fis->d.control        = 0;                      /* FIS HOB bit clear */
17448    fis->d.reserved5      = 0;
17449
17450    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17451
17452    break;
17453  case SAT_WRITE_SECTORS:
17454    fis->h.fisType        = 0x27;                   /* Reg host to device */
17455    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
17456    fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
17457    fis->h.features       = 0;                      /* FIS reserve */
17458    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17459    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17460    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17461
17462    /* FIS LBA mode set LBA (27:24) */
17463    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
17464
17465    fis->d.lbaLowExp      = 0;
17466    fis->d.lbaMidExp      = 0;
17467    fis->d.lbaHighExp     = 0;
17468    fis->d.featuresExp    = 0;
17469    if (satOrgIOContext->LoopNum == 1)
17470    {
17471      /* last loop */
17472      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
17473    }
17474    else
17475    {
17476      fis->d.sectorCount    = 0x0;                 /* FIS sector count (7:0) */
17477    }
17478    fis->d.sectorCountExp = 0;
17479    fis->d.reserved4      = 0;
17480    fis->d.control        = 0;                      /* FIS HOB bit clear */
17481    fis->d.reserved5      = 0;
17482
17483    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
17484
17485    break;
17486  case SAT_WRITE_DMA_EXT:
17487    fis->h.fisType        = 0x27;                   /* Reg host to device */
17488    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17489    fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
17490    fis->h.features       = 0;                      /* FIS reserve */
17491    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17492    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17493    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17494    fis->d.device         = 0x40;                   /* FIS LBA mode set */
17495    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17496    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17497    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17498    fis->d.featuresExp    = 0;                      /* FIS reserve */
17499    if (satOrgIOContext->LoopNum == 1)
17500    {
17501      /* last loop */
17502      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
17503      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17504    }
17505    else
17506    {
17507      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
17508      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
17509    }
17510    fis->d.reserved4      = 0;
17511    fis->d.control        = 0;                       /* FIS HOB bit clear */
17512    fis->d.reserved5      = 0;
17513
17514    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17515
17516    break;
17517  case SAT_WRITE_SECTORS_EXT:
17518    fis->h.fisType        = 0x27;                   /* Reg host to device */
17519    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17520    fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
17521
17522    fis->h.features       = 0;                      /* FIS reserve */
17523    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17524    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17525    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17526    fis->d.device         = 0x40;                   /* FIS LBA mode set */
17527    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17528    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17529    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17530    fis->d.featuresExp    = 0;                      /* FIS reserve */
17531    if (satOrgIOContext->LoopNum == 1)
17532    {
17533      /* last loop */
17534      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17535      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
17536    }
17537    else
17538    {
17539      fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
17540      fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
17541    }
17542    fis->d.reserved4      = 0;
17543    fis->d.control        = 0;                      /* FIS HOB bit clear */
17544    fis->d.reserved5      = 0;
17545
17546    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
17547
17548    break;
17549  case SAT_WRITE_FPDMA_QUEUED:
17550    fis->h.fisType        = 0x27;                   /* Reg host to device */
17551    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17552    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
17553    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17554    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17555    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17556
17557    /* Check FUA bit */
17558    if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
17559      fis->d.device       = 0xC0;                   /* FIS FUA set */
17560    else
17561      fis->d.device       = 0x40;                   /* FIS FUA clear */
17562
17563    fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
17564    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17565    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17566    if (satOrgIOContext->LoopNum == 1)
17567    {
17568      /* last loop */
17569      fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17570      fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17571    }
17572    else
17573    {
17574      fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
17575      fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
17576    }
17577    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
17578    fis->d.sectorCountExp = 0;
17579    fis->d.reserved4      = 0;
17580    fis->d.control        = 0;                      /* FIS HOB bit clear */
17581    fis->d.reserved5      = 0;
17582
17583    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
17584    break;
17585
17586  default:
17587    SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17588    return SM_RC_FAILURE;
17589    break;
17590  }
17591
17592  /* Initialize CB for SATA completion.
17593   */
17594  /* chained data */
17595  satIOContext->satCompleteCB = &smsatChainedDataIOCB;
17596
17597  if (satOrgIOContext->ATACmd == SAT_WRITE_DMA || satOrgIOContext->ATACmd == SAT_WRITE_SECTORS)
17598  {
17599    smsatSplitSGL(smRoot,
17600                  smIORequest,
17601                  smDeviceHandle,
17602                  (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17603                  satOrgIOContext,
17604                  NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/
17605                  (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17606                  agFALSE);
17607  }
17608  else
17609  {
17610    smsatSplitSGL(smRoot,
17611                  smIORequest,
17612                  smDeviceHandle,
17613                  (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17614                  satOrgIOContext,
17615                  BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/
17616                  (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17617                  agFALSE);
17618  }
17619
17620  /*
17621   * Prepare SGL and send FIS to LL layer.
17622   */
17623  satIOContext->reqType = agRequestType;       /* Save it */
17624
17625  status = smsataLLIOStart( smRoot,
17626                            smIORequest,
17627                            smDeviceHandle,
17628                            (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest,
17629                            satIOContext);
17630
17631  SM_DBG5(("smsatWrite_1: return\n"));
17632  return (status);
17633}
17634
17635osGLOBAL bit32
17636smsatPassthrough(
17637                    smRoot_t                  *smRoot,
17638                    smIORequest_t             *smIORequest,
17639                    smDeviceHandle_t          *smDeviceHandle,
17640                    smScsiInitiatorRequest_t  *smScsiRequest,
17641                    smSatIOContext_t            *satIOContext
17642                   )
17643{
17644  smScsiRspSense_t          *pSense;
17645  smIniScsiCmnd_t           *scsiCmnd;
17646  smDeviceData_t            *pSatDevData;
17647  agsaFisRegHostToDevice_t	  *fis;
17648  bit32                      status;
17649  bit32 					agRequestType;
17650  smAtaPassThroughHdr_t       ataPassThroughHdr;
17651
17652
17653  pSense      = satIOContext->pSense;
17654  scsiCmnd    = &smScsiRequest->scsiCmnd;
17655  pSatDevData = satIOContext->pSatDevData;
17656  fis           = satIOContext->pFis;
17657
17658  SM_DBG1(("smsatPassthrough: START!!!\n"));
17659
17660  osti_memset(&ataPassThroughHdr, 0 , sizeof(smAtaPassThroughHdr_t));
17661
17662  ataPassThroughHdr.opc = scsiCmnd->cdb[0];
17663  ataPassThroughHdr.mulCount = scsiCmnd->cdb[1] >> 5;
17664  ataPassThroughHdr.proto = (scsiCmnd->cdb[1] >> 1) & 0x0F;
17665  ataPassThroughHdr.extend = scsiCmnd->cdb[1] & 1;
17666  ataPassThroughHdr.offline = scsiCmnd->cdb[2] >> 6;
17667  ataPassThroughHdr.ckCond = (scsiCmnd->cdb[2] >> 5) & 1;
17668  ataPassThroughHdr.tType = (scsiCmnd->cdb[2] >> 4) & 1;
17669  ataPassThroughHdr.tDir = (scsiCmnd->cdb[2] >> 3) & 1;
17670  ataPassThroughHdr.byteBlock = (scsiCmnd->cdb[2] >> 2) & 1;
17671  ataPassThroughHdr.tlength = scsiCmnd->cdb[2] & 0x3;
17672
17673  switch(ataPassThroughHdr.proto)
17674  {
17675    case 0:
17676    case 9:
17677    	    agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;	//Device Reset
17678	    break;
17679    case 1:
17680       	    agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;		//Software reset
17681	    break;
17682    case 3:
17683            agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;	//Non Data mode
17684	    break;
17685    case 4:
17686       	    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;	//IO_Data_In mode
17687	    break;
17688    case 5:
17689            agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;		//PIO_Data_out
17690            break;
17691    case 6:
17692            agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;	//DMA READ and WRITE
17693            break;
17694    case 8:
17695            agRequestType = AGSA_SATA_ATAP_EXECDEVDIAG; 	//device diagnostic
17696	    break;
17697    case 12:
17698            agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;		//FPDMA Read and Write
17699            break;
17700    default:
17701            agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;	//Default Non Data Mode
17702            break;
17703  }
17704
17705
17706  if((ataPassThroughHdr.tlength == 0) && (agRequestType != AGSA_SATA_PROTOCOL_NON_DATA))
17707  {
17708    SM_DBG1(("smsatPassthrough SCSI_SNSCODE_INVALID_FIELD_IN_CDB\n"));
17709
17710    smsatSetSensePayload( pSense,
17711                          SCSI_SNSKEY_ILLEGAL_REQUEST,
17712                          0,
17713			  SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
17714                          satIOContext);
17715
17716    tdsmIOCompletedCB( smRoot,
17717                       smIORequest,
17718                       smIOSuccess,
17719                       SCSI_STAT_CHECK_CONDITION,
17720                       satIOContext->pSmSenseData,
17721                       satIOContext->interruptContext );
17722
17723    return SM_RC_SUCCESS;
17724  }
17725
17726  if(scsiCmnd->cdb[0] == 0xA1)
17727  {
17728    SM_DBG1(("smsatPassthrough A1h: COMMAND: %x  FEATURE: %x \n",scsiCmnd->cdb[9],scsiCmnd->cdb[3]));
17729
17730    fis->h.fisType        = 0x27;                   /* Reg host to device */
17731    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17732    fis->h.features       = scsiCmnd->cdb[3];
17733    fis->d.sectorCount	  = scsiCmnd->cdb[4];		  /* 0x01  FIS sector count (7:0) */
17734    fis->d.lbaLow 		  = scsiCmnd->cdb[5];		  /* Reading LBA  FIS LBA (7 :0 ) */
17735    fis->d.lbaMid         = scsiCmnd->cdb[6];
17736    fis->d.lbaHigh        = scsiCmnd->cdb[7];
17737    fis->d.device         = scsiCmnd->cdb[8];
17738    fis->h.command		  = scsiCmnd->cdb[9];
17739    fis->d.featuresExp	  = 0;
17740    fis->d.sectorCountExp = 0;
17741    fis->d.lbaLowExp	  = 0;
17742    fis->d.lbaMidExp	  = 0;
17743    fis->d.lbaHighExp 	  = 0;
17744    fis->d.reserved4	  = 0;
17745    fis->d.control		  = 0;					  /* FIS HOB bit clear */
17746    fis->d.reserved5	  = 0;
17747
17748    /* Initialize CB for SATA completion*/
17749    satIOContext->satCompleteCB = &smsatPassthroughCB;
17750
17751    /*
17752        * Prepare SGL and send FIS to LL layer.
17753    */
17754
17755    satIOContext->reqType = agRequestType;
17756    status = smsataLLIOStart( smRoot,
17757                              smIORequest,
17758	                      smDeviceHandle,
17759			      smScsiRequest,
17760                              satIOContext);
17761    return status;
17762
17763   }
17764   else if(scsiCmnd->cdb[0] == 0x85)
17765   {
17766     SM_DBG1(("smsatPassthrough 85h: COMMAND: %x  FEATURE: %x \n",scsiCmnd->cdb[14],scsiCmnd->cdb[4]));
17767
17768     fis->h.fisType        = 0x27;                   /* Reg host to device */
17769     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17770
17771     if(1 == ataPassThroughHdr.extend)
17772     {
17773       fis->d.featuresExp    = scsiCmnd->cdb[3];
17774       fis->d.sectorCountExp = scsiCmnd->cdb[5];
17775       fis->d.lbaMidExp      = scsiCmnd->cdb[9];
17776       fis->d.lbaHighExp     = scsiCmnd->cdb[11];
17777       fis->d.lbaLowExp      = scsiCmnd->cdb[7];
17778     }
17779     fis->h.features = scsiCmnd->cdb[4];
17780     fis->d.sectorCount = scsiCmnd->cdb[6];
17781     fis->d.lbaLow = scsiCmnd->cdb[8];
17782     fis->d.lbaMid = scsiCmnd->cdb[10];
17783     fis->d.lbaHigh = scsiCmnd->cdb[12];
17784     fis->d.device  = scsiCmnd->cdb[13];
17785     fis->h.command = scsiCmnd->cdb[14];
17786     fis->d.reserved4 = 0;
17787     fis->d.control = 0;
17788     fis->d.reserved5	  = 0;
17789
17790
17791     /* Initialize CB for SATA completion.
17792      */
17793
17794     satIOContext->satCompleteCB = &smsatPassthroughCB;
17795
17796     /*
17797       * Prepare SGL and send FIS to LL layer.
17798      */
17799     satIOContext->reqType = agRequestType;
17800     status = smsataLLIOStart( smRoot,
17801                               smIORequest,
17802                               smDeviceHandle,
17803                               smScsiRequest,
17804                               satIOContext);
17805     return status;
17806
17807   }
17808   else
17809   {
17810     SM_DBG1(("smsatPassthrough : INVALD PASSTHROUGH!!!\n"));
17811     smsatSetSensePayload( pSense,
17812                          SCSI_SNSKEY_ILLEGAL_REQUEST,
17813                          0,
17814                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
17815                          satIOContext);
17816     tdsmIOCompletedCB( smRoot,
17817                       smIORequest,
17818                       smIOSuccess,
17819                       SCSI_STAT_CHECK_CONDITION,
17820                       satIOContext->pSmSenseData,
17821                       satIOContext->interruptContext );
17822
17823     SM_DBG1(("smsatPassthrough : return control!!!\n"));
17824
17825     return SM_RC_SUCCESS;
17826   }
17827}
17828
17829osGLOBAL bit32
17830smsatNonChainedWriteNVerify_Verify(
17831                                   smRoot_t                  *smRoot,
17832                                   smIORequest_t             *smIORequest,
17833                                   smDeviceHandle_t          *smDeviceHandle,
17834                                   smScsiInitiatorRequest_t  *smScsiRequest,
17835                                   smSatIOContext_t            *satIOContext
17836                                  )
17837{
17838  bit32                     status;
17839  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17840  smDeviceData_t            *pSatDevData;
17841  smIniScsiCmnd_t           *scsiCmnd;
17842  agsaFisRegHostToDevice_t  *fis;
17843
17844  pSatDevData   = satIOContext->pSatDevData;
17845  scsiCmnd      = &smScsiRequest->scsiCmnd;
17846  fis           = satIOContext->pFis;
17847  SM_DBG5(("smsatNonChainedWriteNVerify_Verify: start\n"));
17848  if (pSatDevData->sat48BitSupport == agTRUE)
17849  {
17850    fis->h.fisType        = 0x27;                   /* Reg host to device */
17851    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17852
17853    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17854    fis->h.features       = 0;                      /* FIS reserve */
17855    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
17856    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
17857    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
17858    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
17859    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
17860    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17861    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17862    fis->d.featuresExp    = 0;                      /* FIS reserve */
17863    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
17864    fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
17865
17866    fis->d.reserved4      = 0;
17867    fis->d.control        = 0;                      /* FIS HOB bit clear */
17868    fis->d.reserved5      = 0;
17869
17870    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17871
17872    /* Initialize CB for SATA completion.
17873     */
17874    satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
17875
17876    /*
17877     * Prepare SGL and send FIS to LL layer.
17878     */
17879    satIOContext->reqType = agRequestType;       /* Save it */
17880
17881    status = smsataLLIOStart( smRoot,
17882                              smIORequest,
17883                              smDeviceHandle,
17884                              smScsiRequest,
17885                              satIOContext);
17886
17887
17888    SM_DBG1(("smsatNonChainedWriteNVerify_Verify: return status %d!!!\n", status));
17889    return (status);
17890  }
17891  else
17892  {
17893    /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
17894    SM_DBG1(("smsatNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS!!!\n"));
17895    return SM_RC_FAILURE;
17896  }
17897}
17898
17899osGLOBAL bit32
17900smsatChainedWriteNVerify_Start_Verify(
17901                                      smRoot_t                  *smRoot,
17902                                      smIORequest_t             *smIORequest,
17903                                      smDeviceHandle_t          *smDeviceHandle,
17904                                      smScsiInitiatorRequest_t  *smScsiRequest,
17905                                      smSatIOContext_t            *satIOContext
17906                                     )
17907{
17908  /*
17909    deal with transfer length; others have been handled previously at this point;
17910    no LBA check; no range check;
17911  */
17912  bit32                     status;
17913  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17914  smDeviceData_t            *pSatDevData;
17915  smIniScsiCmnd_t           *scsiCmnd;
17916  agsaFisRegHostToDevice_t  *fis;
17917  bit32                     lba = 0;
17918  bit32                     tl = 0;
17919  bit32                     LoopNum = 1;
17920  bit8                      LBA[4];
17921  bit8                      TL[4];
17922
17923  pSatDevData   = satIOContext->pSatDevData;
17924  scsiCmnd      = &smScsiRequest->scsiCmnd;
17925  fis           = satIOContext->pFis;
17926
17927  SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: start\n"));
17928  sm_memset(LBA, 0, sizeof(LBA));
17929  sm_memset(TL, 0, sizeof(TL));
17930  /* do not use memcpy due to indexing in LBA and TL */
17931  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
17932  LBA[1] = scsiCmnd->cdb[3];
17933  LBA[2] = scsiCmnd->cdb[4];
17934  LBA[3] = scsiCmnd->cdb[5];  /* LSB */
17935  TL[0] = scsiCmnd->cdb[6];   /* MSB */
17936  TL[1] = scsiCmnd->cdb[7];
17937  TL[2] = scsiCmnd->cdb[7];
17938  TL[3] = scsiCmnd->cdb[8];   /* LSB */
17939  lba = smsatComputeCDB12LBA(satIOContext);
17940  tl = smsatComputeCDB12TL(satIOContext);
17941  if (pSatDevData->sat48BitSupport == agTRUE)
17942  {
17943    SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n"));
17944    fis->h.fisType        = 0x27;                   /* Reg host to device */
17945    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17946
17947    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17948    fis->h.features       = 0;                      /* FIS reserve */
17949    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
17950    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
17951    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
17952    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
17953    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
17954    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17955    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17956    fis->d.featuresExp    = 0;                      /* FIS reserve */
17957    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
17958    fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
17959
17960    fis->d.reserved4      = 0;
17961    fis->d.control        = 0;                      /* FIS HOB bit clear */
17962    fis->d.reserved5      = 0;
17963
17964    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17965    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
17966  }
17967  else
17968  {
17969    SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n"));
17970    fis->h.fisType        = 0x27;                   /* Reg host to device */
17971    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
17972    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
17973    fis->h.features       = 0;                      /* FIS reserve */
17974    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
17975    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
17976    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
17977      /* FIS LBA mode set LBA (27:24) */
17978    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
17979    fis->d.lbaLowExp      = 0;
17980    fis->d.lbaMidExp      = 0;
17981    fis->d.lbaHighExp     = 0;
17982    fis->d.featuresExp    = 0;
17983    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
17984    fis->d.sectorCountExp = 0;
17985    fis->d.reserved4      = 0;
17986    fis->d.control        = 0;                      /* FIS HOB bit clear */
17987    fis->d.reserved5      = 0;
17988
17989    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17990    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
17991
17992 }
17993
17994  satIOContext->currentLBA = lba;
17995  satIOContext->OrgTL = tl;
17996
17997  /*
17998    computing number of loop and remainder for tl
17999    0xFF in case not ext
18000    0xFFFF in case EXT
18001  */
18002  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
18003  {
18004    LoopNum = smsatComputeLoopNum(tl, 0xFF);
18005  }
18006  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
18007  {
18008    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
18009    LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
18010  }
18011  else
18012  {
18013    SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
18014    LoopNum = 1;
18015  }
18016
18017  satIOContext->LoopNum = LoopNum;
18018
18019  if (LoopNum == 1)
18020  {
18021    SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
18022    /* Initialize CB for SATA completion.
18023     */
18024    satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
18025  }
18026  else
18027  {
18028    SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: CHAINED data!!!\n"));
18029    /* re-setting tl */
18030    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
18031    {
18032       fis->d.sectorCount    = 0xFF;
18033    }
18034    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
18035    {
18036      fis->d.sectorCount    = 0xFF;
18037      fis->d.sectorCountExp = 0xFF;
18038    }
18039    else
18040    {
18041      SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
18042    }
18043
18044    /* Initialize CB for SATA completion.
18045     */
18046    satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18047  }
18048
18049
18050  /*
18051   * Prepare SGL and send FIS to LL layer.
18052   */
18053  satIOContext->reqType = agRequestType;       /* Save it */
18054
18055  status = smsataLLIOStart( smRoot,
18056                            smIORequest,
18057                            smDeviceHandle,
18058                            smScsiRequest,
18059                            satIOContext);
18060  return (status);
18061
18062
18063}
18064
18065osGLOBAL bit32
18066smsatChainedWriteNVerify_Write(
18067                               smRoot_t                  *smRoot,
18068                               smIORequest_t             *smIORequest,
18069                               smDeviceHandle_t          *smDeviceHandle,
18070                               smScsiInitiatorRequest_t  *smScsiRequest,
18071                               smSatIOContext_t            *satIOContext
18072                              )
18073{
18074  /*
18075    Assumption: error check on lba and tl has been done in satWrite*()
18076    lba = lba + tl;
18077  */
18078  bit32                     status;
18079  smSatIOContext_t            *satOrgIOContext = agNULL;
18080  smIniScsiCmnd_t           *scsiCmnd;
18081  agsaFisRegHostToDevice_t  *fis;
18082  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18083  bit32                     lba = 0;
18084  bit32                     DenomTL = 0xFF;
18085  bit32                     Remainder = 0;
18086  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
18087
18088  SM_DBG1(("smsatChainedWriteNVerify_Write: start\n"));
18089
18090  fis             = satIOContext->pFis;
18091  satOrgIOContext = satIOContext->satOrgIOContext;
18092  scsiCmnd        = satOrgIOContext->pScsiCmnd;
18093
18094
18095  sm_memset(LBA,0, sizeof(LBA));
18096
18097  switch (satOrgIOContext->ATACmd)
18098  {
18099  case SAT_WRITE_DMA:
18100    DenomTL = 0xFF;
18101    break;
18102  case SAT_WRITE_SECTORS:
18103    DenomTL = 0xFF;
18104    break;
18105  case SAT_WRITE_DMA_EXT:
18106    DenomTL = 0xFFFF;
18107    break;
18108  case SAT_WRITE_DMA_FUA_EXT:
18109    DenomTL = 0xFFFF;
18110    break;
18111  case SAT_WRITE_SECTORS_EXT:
18112    DenomTL = 0xFFFF;
18113    break;
18114  case SAT_WRITE_FPDMA_QUEUED:
18115    DenomTL = 0xFFFF;
18116    break;
18117  default:
18118    SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18119    return SM_RC_FAILURE;
18120    break;
18121  }
18122
18123  Remainder = satOrgIOContext->OrgTL % DenomTL;
18124  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18125  lba = satOrgIOContext->currentLBA;
18126
18127  LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18128  LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18129  LBA[2] = (bit8)((lba & 0xF0) >> 8);
18130  LBA[3] = (bit8)(lba & 0xF);               /* LSB */
18131
18132  switch (satOrgIOContext->ATACmd)
18133  {
18134  case SAT_WRITE_DMA:
18135    fis->h.fisType        = 0x27;                   /* Reg host to device */
18136    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18137    fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
18138    fis->h.features       = 0;                      /* FIS reserve */
18139    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18140    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18141    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18142
18143    /* FIS LBA mode set LBA (27:24) */
18144    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18145
18146    fis->d.lbaLowExp      = 0;
18147    fis->d.lbaMidExp      = 0;
18148    fis->d.lbaHighExp     = 0;
18149    fis->d.featuresExp    = 0;
18150    if (satOrgIOContext->LoopNum == 1)
18151    {
18152      /* last loop */
18153      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
18154    }
18155    else
18156    {
18157      fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
18158    }
18159    fis->d.sectorCountExp = 0;
18160    fis->d.reserved4      = 0;
18161    fis->d.control        = 0;                      /* FIS HOB bit clear */
18162    fis->d.reserved5      = 0;
18163
18164    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18165
18166    break;
18167  case SAT_WRITE_SECTORS:
18168    fis->h.fisType        = 0x27;                   /* Reg host to device */
18169    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18170    fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
18171    fis->h.features       = 0;                      /* FIS reserve */
18172    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18173    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18174    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18175
18176    /* FIS LBA mode set LBA (27:24) */
18177    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18178
18179    fis->d.lbaLowExp      = 0;
18180    fis->d.lbaMidExp      = 0;
18181    fis->d.lbaHighExp     = 0;
18182    fis->d.featuresExp    = 0;
18183    if (satOrgIOContext->LoopNum == 1)
18184    {
18185      /* last loop */
18186      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
18187    }
18188    else
18189    {
18190      fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
18191    }
18192    fis->d.sectorCountExp = 0;
18193    fis->d.reserved4      = 0;
18194    fis->d.control        = 0;                      /* FIS HOB bit clear */
18195    fis->d.reserved5      = 0;
18196
18197    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18198
18199    break;
18200  case SAT_WRITE_DMA_EXT:
18201    fis->h.fisType        = 0x27;                   /* Reg host to device */
18202    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18203    fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
18204    fis->h.features       = 0;                      /* FIS reserve */
18205    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18206    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18207    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18208    fis->d.device         = 0x40;                   /* FIS LBA mode set */
18209    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18210    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18211    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18212    fis->d.featuresExp    = 0;                      /* FIS reserve */
18213    if (satOrgIOContext->LoopNum == 1)
18214    {
18215      /* last loop */
18216      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
18217      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18218    }
18219    else
18220    {
18221      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
18222      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
18223    }
18224    fis->d.reserved4      = 0;
18225    fis->d.control        = 0;                       /* FIS HOB bit clear */
18226    fis->d.reserved5      = 0;
18227
18228    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18229
18230    break;
18231  case SAT_WRITE_SECTORS_EXT:
18232    fis->h.fisType        = 0x27;                   /* Reg host to device */
18233    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18234    fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
18235
18236    fis->h.features       = 0;                      /* FIS reserve */
18237    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18238    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18239    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18240    fis->d.device         = 0x40;                   /* FIS LBA mode set */
18241    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18242    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18243    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18244    fis->d.featuresExp    = 0;                      /* FIS reserve */
18245    if (satOrgIOContext->LoopNum == 1)
18246    {
18247      /* last loop */
18248      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
18249      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
18250    }
18251    else
18252    {
18253      fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
18254      fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
18255    }
18256    fis->d.reserved4      = 0;
18257    fis->d.control        = 0;                      /* FIS HOB bit clear */
18258    fis->d.reserved5      = 0;
18259
18260    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18261
18262    break;
18263  case SAT_WRITE_FPDMA_QUEUED:
18264    fis->h.fisType        = 0x27;                   /* Reg host to device */
18265    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18266    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
18267    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18268    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18269    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18270
18271    /* Check FUA bit */
18272    if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
18273      fis->d.device       = 0xC0;                   /* FIS FUA set */
18274    else
18275      fis->d.device       = 0x40;                   /* FIS FUA clear */
18276
18277    fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
18278    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18279    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18280    if (satOrgIOContext->LoopNum == 1)
18281    {
18282      /* last loop */
18283      fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
18284      fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18285    }
18286    else
18287    {
18288      fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
18289      fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
18290    }
18291    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
18292    fis->d.sectorCountExp = 0;
18293    fis->d.reserved4      = 0;
18294    fis->d.control        = 0;                      /* FIS HOB bit clear */
18295    fis->d.reserved5      = 0;
18296
18297    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
18298    break;
18299
18300  default:
18301    SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18302    return SM_RC_FAILURE;
18303    break;
18304  }
18305
18306  /* Initialize CB for SATA completion.
18307   */
18308  /* chained data */
18309  satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18310
18311
18312  /*
18313   * Prepare SGL and send FIS to LL layer.
18314   */
18315  satIOContext->reqType = agRequestType;       /* Save it */
18316
18317  status = smsataLLIOStart( smRoot,
18318                            smIORequest,
18319                            smDeviceHandle,
18320                            smScsiRequest,
18321                            satIOContext);
18322
18323  SM_DBG5(("satChainedWriteNVerify_Write: return\n"));
18324  return (status);
18325}
18326
18327osGLOBAL bit32
18328smsatChainedWriteNVerify_Verify(
18329                                smRoot_t                  *smRoot,
18330                                smIORequest_t             *smIORequest,
18331                                smDeviceHandle_t          *smDeviceHandle,
18332                                smScsiInitiatorRequest_t  *smScsiRequest,
18333                                smSatIOContext_t            *satIOContext
18334                               )
18335{
18336  bit32                     status;
18337  smSatIOContext_t         *satOrgIOContext = agNULL;
18338  agsaFisRegHostToDevice_t *fis;
18339  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18340  bit32                     lba = 0;
18341  bit32                     DenomTL = 0xFF;
18342  bit32                     Remainder = 0;
18343  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
18344
18345  SM_DBG2(("smsatChainedWriteNVerify_Verify: start\n"));
18346  fis             = satIOContext->pFis;
18347  satOrgIOContext = satIOContext->satOrgIOContext;
18348  sm_memset(LBA,0, sizeof(LBA));
18349  switch (satOrgIOContext->ATACmd)
18350  {
18351  case SAT_READ_VERIFY_SECTORS:
18352    DenomTL = 0xFF;
18353    break;
18354  case SAT_READ_VERIFY_SECTORS_EXT:
18355    DenomTL = 0xFFFF;
18356    break;
18357  default:
18358    SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18359    return SM_RC_FAILURE;
18360    break;
18361  }
18362
18363  Remainder = satOrgIOContext->OrgTL % DenomTL;
18364  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18365  lba = satOrgIOContext->currentLBA;
18366
18367  LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18368  LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18369  LBA[2] = (bit8)((lba & 0xF0) >> 8);
18370  LBA[3] = (bit8)(lba & 0xF);               /* LSB */
18371
18372  switch (satOrgIOContext->ATACmd)
18373  {
18374  case SAT_READ_VERIFY_SECTORS:
18375    fis->h.fisType        = 0x27;                   /* Reg host to device */
18376    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18377    fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
18378    fis->h.features       = 0;                      /* FIS reserve */
18379    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18380    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18381    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18382
18383    /* FIS LBA mode set LBA (27:24) */
18384    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18385
18386    fis->d.lbaLowExp      = 0;
18387    fis->d.lbaMidExp      = 0;
18388    fis->d.lbaHighExp     = 0;
18389    fis->d.featuresExp    = 0;
18390    if (satOrgIOContext->LoopNum == 1)
18391    {
18392      /* last loop */
18393      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
18394    }
18395    else
18396    {
18397      fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
18398    }
18399    fis->d.sectorCountExp = 0;
18400    fis->d.reserved4      = 0;
18401    fis->d.control        = 0;                      /* FIS HOB bit clear */
18402    fis->d.reserved5      = 0;
18403
18404    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18405
18406    break;
18407  case SAT_READ_VERIFY_SECTORS_EXT:
18408    fis->h.fisType        = 0x27;                   /* Reg host to device */
18409    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18410    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
18411    fis->h.features       = 0;                      /* FIS reserve */
18412    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18413    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18414    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18415    fis->d.device         = 0x40;                   /* FIS LBA mode set */
18416    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18417    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18418    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18419    fis->d.featuresExp    = 0;                      /* FIS reserve */
18420    if (satOrgIOContext->LoopNum == 1)
18421    {
18422      /* last loop */
18423      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
18424      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18425    }
18426    else
18427    {
18428      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
18429      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
18430    }
18431    fis->d.reserved4      = 0;
18432    fis->d.control        = 0;                       /* FIS HOB bit clear */
18433    fis->d.reserved5      = 0;
18434
18435    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18436
18437    break;
18438
18439  default:
18440    SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18441    return SM_RC_FAILURE;
18442    break;
18443  }
18444
18445  /* Initialize CB for SATA completion.
18446   */
18447  /* chained data */
18448  satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18449
18450
18451  /*
18452   * Prepare SGL and send FIS to LL layer.
18453   */
18454  satIOContext->reqType = agRequestType;       /* Save it */
18455
18456  status = smsataLLIOStart( smRoot,
18457                            smIORequest,
18458                            smDeviceHandle,
18459                            smScsiRequest,
18460                            satIOContext);
18461
18462  SM_DBG5(("smsatChainedWriteNVerify_Verify: return\n"));
18463  return (status);
18464}
18465
18466osGLOBAL bit32
18467smsatChainedVerify(
18468                    smRoot_t                  *smRoot,
18469                    smIORequest_t             *smIORequest,
18470                    smDeviceHandle_t          *smDeviceHandle,
18471                    smScsiInitiatorRequest_t  *smScsiRequest,
18472                    smSatIOContext_t            *satIOContext
18473       )
18474{
18475  bit32                     status;
18476  smSatIOContext_t         *satOrgIOContext = agNULL;
18477  agsaFisRegHostToDevice_t *fis;
18478  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18479  bit32                     lba = 0;
18480  bit32                     DenomTL = 0xFF;
18481  bit32                     Remainder = 0;
18482  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
18483
18484  SM_DBG2(("smsatChainedVerify: start\n"));
18485  fis             = satIOContext->pFis;
18486  satOrgIOContext = satIOContext->satOrgIOContext;
18487  sm_memset(LBA,0, sizeof(LBA));
18488  switch (satOrgIOContext->ATACmd)
18489  {
18490  case SAT_READ_VERIFY_SECTORS:
18491    DenomTL = 0xFF;
18492    break;
18493  case SAT_READ_VERIFY_SECTORS_EXT:
18494    DenomTL = 0xFFFF;
18495    break;
18496  default:
18497    SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18498    return tiError;
18499    break;
18500  }
18501
18502  Remainder = satOrgIOContext->OrgTL % DenomTL;
18503  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18504  lba = satOrgIOContext->currentLBA;
18505
18506  LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18507  LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18508  LBA[2] = (bit8)((lba & 0xF0) >> 8);
18509  LBA[3] = (bit8)(lba & 0xF);               /* LSB */
18510
18511  switch (satOrgIOContext->ATACmd)
18512  {
18513  case SAT_READ_VERIFY_SECTORS:
18514    fis->h.fisType        = 0x27;                   /* Reg host to device */
18515    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18516    fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
18517    fis->h.features       = 0;                      /* FIS reserve */
18518    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18519    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18520    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18521
18522    /* FIS LBA mode set LBA (27:24) */
18523    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18524
18525    fis->d.lbaLowExp      = 0;
18526    fis->d.lbaMidExp      = 0;
18527    fis->d.lbaHighExp     = 0;
18528    fis->d.featuresExp    = 0;
18529    if (satOrgIOContext->LoopNum == 1)
18530    {
18531      /* last loop */
18532      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
18533    }
18534    else
18535    {
18536      fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
18537    }
18538    fis->d.sectorCountExp = 0;
18539    fis->d.reserved4      = 0;
18540    fis->d.control        = 0;                      /* FIS HOB bit clear */
18541    fis->d.reserved5      = 0;
18542
18543    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18544
18545    break;
18546  case SAT_READ_VERIFY_SECTORS_EXT:
18547    fis->h.fisType        = 0x27;                   /* Reg host to device */
18548    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18549    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
18550    fis->h.features       = 0;                      /* FIS reserve */
18551    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18552    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18553    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18554    fis->d.device         = 0x40;                   /* FIS LBA mode set */
18555    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18556    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18557    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18558    fis->d.featuresExp    = 0;                      /* FIS reserve */
18559    if (satOrgIOContext->LoopNum == 1)
18560    {
18561      /* last loop */
18562      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
18563      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18564    }
18565    else
18566    {
18567      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
18568      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
18569    }
18570    fis->d.reserved4      = 0;
18571    fis->d.control        = 0;                       /* FIS HOB bit clear */
18572    fis->d.reserved5      = 0;
18573
18574    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18575
18576    break;
18577
18578  default:
18579    SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18580    return tiError;
18581    break;
18582  }
18583
18584  /* Initialize CB for SATA completion.
18585   */
18586  /* chained data */
18587  satIOContext->satCompleteCB = &smsatChainedVerifyCB;
18588
18589
18590  /*
18591   * Prepare SGL and send FIS to LL layer.
18592   */
18593  satIOContext->reqType = agRequestType;       /* Save it */
18594
18595  status = smsataLLIOStart( smRoot,
18596                            smIORequest,
18597                            smDeviceHandle,
18598                            smScsiRequest,
18599                            satIOContext);
18600
18601  SM_DBG5(("satChainedVerify: return\n"));
18602  return (status);
18603}
18604
18605osGLOBAL bit32
18606smsatWriteSame10_1(
18607                    smRoot_t                  *smRoot,
18608                    smIORequest_t             *smIORequest,
18609                    smDeviceHandle_t          *smDeviceHandle,
18610                    smScsiInitiatorRequest_t  *smScsiRequest,
18611                    smSatIOContext_t            *satIOContext,
18612                    bit32                     lba
18613                  )
18614{
18615  /*
18616    sends SAT_WRITE_DMA_EXT
18617  */
18618
18619  bit32                     status;
18620  bit32                     agRequestType;
18621  agsaFisRegHostToDevice_t  *fis;
18622  bit8                      lba1, lba2 ,lba3, lba4;
18623
18624  SM_DBG5(("smsatWriteSame10_1: start\n"));
18625  fis               = satIOContext->pFis;
18626  /* MSB */
18627  lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18628  lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18629  lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18630  /* LSB */
18631  lba4 = (bit8)(lba & 0x000000FF);
18632  /* SAT_WRITE_DMA_EXT */
18633  fis->h.fisType        = 0x27;                   /* Reg host to device */
18634  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18635  fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
18636  fis->h.features       = 0;                      /* FIS reserve */
18637  fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
18638  fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
18639  fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
18640  fis->d.device         = 0x40;                   /* FIS LBA mode set */
18641  fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
18642  fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18643  fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18644  fis->d.featuresExp    = 0;                      /* FIS reserve */
18645  /* one sector at a time */
18646  fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18647  fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18648  fis->d.reserved4      = 0;
18649  fis->d.control        = 0;                      /* FIS HOB bit clear */
18650  fis->d.reserved5      = 0;
18651  agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18652  /* Initialize CB for SATA completion.
18653   */
18654  satIOContext->satCompleteCB = &smsatWriteSame10CB;
18655  /*
18656   * Prepare SGL and send FIS to LL layer.
18657   */
18658  satIOContext->reqType = agRequestType;       /* Save it */
18659  status = smsataLLIOStart( smRoot,
18660                            smIORequest,
18661                            smDeviceHandle,
18662                            smScsiRequest,
18663                            satIOContext);
18664  SM_DBG5(("smsatWriteSame10_1 return status %d\n", status));
18665  return status;
18666}
18667
18668
18669osGLOBAL bit32
18670smsatWriteSame10_2(
18671                    smRoot_t                  *smRoot,
18672                    smIORequest_t             *smIORequest,
18673                    smDeviceHandle_t          *smDeviceHandle,
18674                    smScsiInitiatorRequest_t  *smScsiRequest,
18675                    smSatIOContext_t            *satIOContext,
18676                    bit32                     lba
18677                  )
18678{
18679  /*
18680    sends SAT_WRITE_SECTORS_EXT
18681  */
18682
18683  bit32                     status;
18684  bit32                     agRequestType;
18685  agsaFisRegHostToDevice_t  *fis;
18686  bit8                      lba1, lba2 ,lba3, lba4;
18687
18688  SM_DBG5(("smsatWriteSame10_2: start\n"));
18689  fis               = satIOContext->pFis;
18690  /* MSB */
18691  lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18692  lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18693  lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18694  /* LSB */
18695  lba4 = (bit8)(lba & 0x000000FF);
18696  /* SAT_WRITE_SECTORS_EXT */
18697  fis->h.fisType        = 0x27;                   /* Reg host to device */
18698  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18699  fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
18700  fis->h.features       = 0;                      /* FIS reserve */
18701  fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
18702  fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
18703  fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
18704  fis->d.device         = 0x40;                   /* FIS LBA mode set */
18705  fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
18706  fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18707  fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18708  fis->d.featuresExp    = 0;                      /* FIS reserve */
18709  /* one sector at a time */
18710  fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18711  fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18712  fis->d.reserved4      = 0;
18713  fis->d.control        = 0;                      /* FIS HOB bit clear */
18714  fis->d.reserved5      = 0;
18715  agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18716  /* Initialize CB for SATA completion.
18717   */
18718  satIOContext->satCompleteCB = &smsatWriteSame10CB;
18719  /*
18720   * Prepare SGL and send FIS to LL layer.
18721   */
18722  satIOContext->reqType = agRequestType;       /* Save it */
18723  status = smsataLLIOStart( smRoot,
18724                            smIORequest,
18725                            smDeviceHandle,
18726                            smScsiRequest,
18727                            satIOContext);
18728  SM_DBG5(("smsatWriteSame10_2 return status %d\n", status));
18729  return status;
18730}
18731
18732
18733osGLOBAL bit32
18734smsatWriteSame10_3(
18735                    smRoot_t                  *smRoot,
18736                    smIORequest_t             *smIORequest,
18737                    smDeviceHandle_t          *smDeviceHandle,
18738                    smScsiInitiatorRequest_t  *smScsiRequest,
18739                    smSatIOContext_t            *satIOContext,
18740                    bit32                     lba
18741                  )
18742{
18743  /*
18744    sends SAT_WRITE_FPDMA_QUEUED
18745  */
18746
18747  bit32                     status;
18748  bit32                     agRequestType;
18749  agsaFisRegHostToDevice_t  *fis;
18750  bit8                      lba1, lba2 ,lba3, lba4;
18751
18752  SM_DBG5(("smsatWriteSame10_3: start\n"));
18753  fis               = satIOContext->pFis;
18754  /* MSB */
18755  lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18756  lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18757  lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18758  /* LSB */
18759  lba4 = (bit8)(lba & 0x000000FF);
18760
18761  /* SAT_WRITE_FPDMA_QUEUED */
18762  fis->h.fisType        = 0x27;                   /* Reg host to device */
18763  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18764  fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
18765
18766
18767  /* one sector at a time */
18768  fis->h.features       = 1;                      /* FIS sector count (7:0) */
18769  fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
18770
18771  fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
18772  fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
18773  fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
18774  /* NO FUA bit in the WRITE SAME 10 */
18775  fis->d.device         = 0x40;                   /* FIS FUA clear */
18776  fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
18777  fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18778  fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18779  fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
18780  fis->d.sectorCountExp = 0;
18781  fis->d.reserved4      = 0;
18782  fis->d.control        = 0;                      /* FIS HOB bit clear */
18783  fis->d.reserved5      = 0;
18784  agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
18785
18786  /* Initialize CB for SATA completion.
18787   */
18788  satIOContext->satCompleteCB = &smsatWriteSame10CB;
18789  /*
18790   * Prepare SGL and send FIS to LL layer.
18791   */
18792  satIOContext->reqType = agRequestType;       /* Save it */
18793  status = smsataLLIOStart( smRoot,
18794                            smIORequest,
18795                            smDeviceHandle,
18796                            smScsiRequest,
18797                            satIOContext);
18798
18799  SM_DBG5(("smsatWriteSame10_3 return status %d\n", status));
18800  return status;
18801}
18802
18803osGLOBAL bit32
18804smsatStartStopUnit_1(
18805                     smRoot_t                  *smRoot,
18806                     smIORequest_t             *smIORequest,
18807                     smDeviceHandle_t          *smDeviceHandle,
18808                     smScsiInitiatorRequest_t  *smScsiRequest,
18809                     smSatIOContext_t            *satIOContext
18810        )
18811{
18812  /*
18813    SAT Rev 8, Table 48, 9.11.3 p55
18814    sends STANDBY
18815  */
18816  bit32                     status;
18817  bit32                     agRequestType;
18818  agsaFisRegHostToDevice_t  *fis;
18819
18820  SM_DBG5(("smsatStartStopUnit_1: start\n"));
18821  fis               = satIOContext->pFis;
18822  /* STANDBY */
18823  fis->h.fisType        = 0x27;                   /* Reg host to device */
18824  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18825  fis->h.command        = SAT_STANDBY;            /* 0xE2 */
18826  fis->h.features       = 0;                      /* FIS features NA       */
18827  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
18828  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
18829  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
18830  fis->d.lbaLowExp      = 0;
18831  fis->d.lbaMidExp      = 0;
18832  fis->d.lbaHighExp     = 0;
18833  fis->d.featuresExp    = 0;
18834  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
18835  fis->d.sectorCountExp = 0;
18836  fis->d.reserved4      = 0;
18837  fis->d.device         = 0;                      /* 0 */
18838  fis->d.control        = 0;                      /* FIS HOB bit clear */
18839  fis->d.reserved5      = 0;
18840
18841  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18842
18843  /* Initialize CB for SATA completion.
18844   */
18845  satIOContext->satCompleteCB = &smsatStartStopUnitCB;
18846
18847  /*
18848   * Prepare SGL and send FIS to LL layer.
18849   */
18850  satIOContext->reqType = agRequestType;       /* Save it */
18851
18852  status = smsataLLIOStart( smRoot,
18853                            smIORequest,
18854                            smDeviceHandle,
18855                            smScsiRequest,
18856                            satIOContext);
18857
18858  SM_DBG5(("smsatStartStopUnit_1 return status %d\n", status));
18859  return status;
18860}
18861
18862osGLOBAL bit32
18863smsatSendDiagnostic_1(
18864                      smRoot_t                  *smRoot,
18865                      smIORequest_t             *smIORequest,
18866                      smDeviceHandle_t          *smDeviceHandle,
18867                      smScsiInitiatorRequest_t  *smScsiRequest,
18868                      smSatIOContext_t            *satIOContext
18869         )
18870{
18871  /*
18872    SAT Rev9, Table29, p41
18873    send 2nd SAT_READ_VERIFY_SECTORS(_EXT)
18874  */
18875  bit32                     status;
18876  bit32                     agRequestType;
18877  smDeviceData_t            *pSatDevData;
18878  agsaFisRegHostToDevice_t  *fis;
18879
18880  SM_DBG5(("smsatSendDiagnostic_1: start\n"));
18881  pSatDevData       = satIOContext->pSatDevData;
18882  fis               = satIOContext->pFis;
18883  /*
18884    sector count 1, LBA MAX
18885  */
18886  if (pSatDevData->sat48BitSupport == agTRUE)
18887  {
18888    /* sends READ VERIFY SECTOR(S) EXT*/
18889    fis->h.fisType        = 0x27;                   /* Reg host to device */
18890    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18891    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
18892    fis->h.features       = 0;                      /* FIS reserve */
18893    fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
18894    fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
18895    fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
18896    fis->d.lbaLowExp      = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */
18897    fis->d.lbaMidExp      = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */
18898    fis->d.lbaHighExp     = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */
18899    fis->d.featuresExp    = 0;                      /* FIS reserve */
18900    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18901    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18902    fis->d.reserved4      = 0;
18903    fis->d.device         = 0x40;                   /* 01000000 */
18904    fis->d.control        = 0;                      /* FIS HOB bit clear */
18905    fis->d.reserved5      = 0;
18906
18907  }
18908  else
18909  {
18910    /* READ VERIFY SECTOR(S)*/
18911    fis->h.fisType        = 0x27;                   /* Reg host to device */
18912    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18913    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
18914    fis->h.features       = 0;                      /* FIS features NA       */
18915    fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
18916    fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
18917    fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
18918    fis->d.lbaLowExp      = 0;
18919    fis->d.lbaMidExp      = 0;
18920    fis->d.lbaHighExp     = 0;
18921    fis->d.featuresExp    = 0;
18922    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18923    fis->d.sectorCountExp = 0;
18924    fis->d.reserved4      = 0;
18925    fis->d.device         = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF));
18926                            /* DEV and LBA 27:24 */
18927    fis->d.control        = 0;                      /* FIS HOB bit clear */
18928    fis->d.reserved5      = 0;
18929
18930  }
18931
18932  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18933
18934  /* Initialize CB for SATA completion.
18935   */
18936  satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
18937
18938  /*
18939   * Prepare SGL and send FIS to LL layer.
18940   */
18941  satIOContext->reqType = agRequestType;       /* Save it */
18942
18943  status = smsataLLIOStart( smRoot,
18944                            smIORequest,
18945                            smDeviceHandle,
18946                            smScsiRequest,
18947                            satIOContext);
18948
18949
18950  return status;
18951}
18952
18953osGLOBAL bit32
18954smsatSendDiagnostic_2(
18955                      smRoot_t                  *smRoot,
18956                      smIORequest_t             *smIORequest,
18957                      smDeviceHandle_t          *smDeviceHandle,
18958                      smScsiInitiatorRequest_t  *smScsiRequest,
18959                      smSatIOContext_t            *satIOContext
18960         )
18961{
18962  /*
18963    SAT Rev9, Table29, p41
18964    send 3rd SAT_READ_VERIFY_SECTORS(_EXT)
18965  */
18966  bit32                     status;
18967  bit32                     agRequestType;
18968  smDeviceData_t            *pSatDevData;
18969  agsaFisRegHostToDevice_t  *fis;
18970
18971  SM_DBG5(("smsatSendDiagnostic_2: start\n"));
18972
18973  pSatDevData       = satIOContext->pSatDevData;
18974  fis               = satIOContext->pFis;
18975  /*
18976    sector count 1, LBA Random
18977  */
18978  if (pSatDevData->sat48BitSupport == agTRUE)
18979  {
18980    /* sends READ VERIFY SECTOR(S) EXT*/
18981    fis->h.fisType        = 0x27;                   /* Reg host to device */
18982    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18983    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
18984    fis->h.features       = 0;                      /* FIS reserve */
18985    fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
18986    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
18987    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
18988    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
18989    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18990    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18991    fis->d.featuresExp    = 0;                      /* FIS reserve */
18992    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18993    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18994    fis->d.reserved4      = 0;
18995    fis->d.device         = 0x40;                   /* 01000000 */
18996    fis->d.control        = 0;                      /* FIS HOB bit clear */
18997    fis->d.reserved5      = 0;
18998
18999  }
19000  else
19001  {
19002    /* READ VERIFY SECTOR(S)*/
19003    fis->h.fisType        = 0x27;                   /* Reg host to device */
19004    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19005    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
19006    fis->h.features       = 0;                      /* FIS features NA       */
19007    fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
19008    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19009    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19010    fis->d.lbaLowExp      = 0;
19011    fis->d.lbaMidExp      = 0;
19012    fis->d.lbaHighExp     = 0;
19013    fis->d.featuresExp    = 0;
19014    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19015    fis->d.sectorCountExp = 0;
19016    fis->d.reserved4      = 0;
19017    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
19018    fis->d.control        = 0;                      /* FIS HOB bit clear */
19019    fis->d.reserved5      = 0;
19020
19021  }
19022
19023  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19024
19025  /* Initialize CB for SATA completion.
19026   */
19027  satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
19028
19029  /*
19030   * Prepare SGL and send FIS to LL layer.
19031   */
19032  satIOContext->reqType = agRequestType;       /* Save it */
19033
19034  status = smsataLLIOStart( smRoot,
19035                            smIORequest,
19036                            smDeviceHandle,
19037                            smScsiRequest,
19038                            satIOContext);
19039
19040
19041  return status;
19042}
19043
19044osGLOBAL bit32
19045smsatModeSelect6n10_1(
19046                      smRoot_t                  *smRoot,
19047                      smIORequest_t             *smIORequest,
19048                      smDeviceHandle_t          *smDeviceHandle,
19049                      smScsiInitiatorRequest_t  *smScsiRequest,
19050                      smSatIOContext_t            *satIOContext
19051         )
19052{
19053  /* sends either ATA SET FEATURES based on DRA bit */
19054  bit32                     status;
19055  bit32                     agRequestType;
19056  agsaFisRegHostToDevice_t  *fis;
19057  bit8                      *pLogPage;    /* Log Page data buffer */
19058  bit32                     StartingIndex = 0;
19059
19060  fis           = satIOContext->pFis;
19061  pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
19062  SM_DBG5(("smsatModeSelect6n10_1: start\n"));
19063
19064  if (pLogPage[3] == 8)
19065  {
19066    /* mode parameter block descriptor exists */
19067    StartingIndex = 12;
19068  }
19069  else
19070  {
19071    /* mode parameter block descriptor does not exist */
19072    StartingIndex = 4;
19073  }
19074
19075  /* sends ATA SET FEATURES based on DRA bit */
19076  if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
19077  {
19078    SM_DBG5(("smsatModeSelect6n10_1: enable read look-ahead feature\n"));
19079    /* sends SET FEATURES */
19080    fis->h.fisType        = 0x27;                   /* Reg host to device */
19081    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19082
19083    fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19084    fis->h.features       = 0xAA;                   /* enable read look-ahead */
19085    fis->d.lbaLow         = 0;                      /* */
19086    fis->d.lbaMid         = 0;                      /* */
19087    fis->d.lbaHigh        = 0;                      /* */
19088    fis->d.device         = 0;                      /* */
19089    fis->d.lbaLowExp      = 0;                      /* */
19090    fis->d.lbaMidExp      = 0;                      /* */
19091    fis->d.lbaHighExp     = 0;                      /* */
19092    fis->d.featuresExp    = 0;                      /* */
19093    fis->d.sectorCount    = 0;                      /* */
19094    fis->d.sectorCountExp = 0;                      /* */
19095    fis->d.reserved4      = 0;
19096    fis->d.control        = 0;                      /* FIS HOB bit clear */
19097    fis->d.reserved5      = 0;
19098
19099    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19100
19101    /* Initialize CB for SATA completion.
19102     */
19103    satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
19104
19105    /*
19106     * Prepare SGL and send FIS to LL layer.
19107     */
19108    satIOContext->reqType = agRequestType;       /* Save it */
19109
19110  status = smsataLLIOStart( smRoot,
19111                            smIORequest,
19112                            smDeviceHandle,
19113                            smScsiRequest,
19114                            satIOContext);
19115    return status;
19116  }
19117  else
19118  {
19119    SM_DBG5(("smsatModeSelect6n10_1: disable read look-ahead feature\n"));
19120        /* sends SET FEATURES */
19121    fis->h.fisType        = 0x27;                   /* Reg host to device */
19122    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19123
19124    fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19125    fis->h.features       = 0x55;                   /* disable read look-ahead */
19126    fis->d.lbaLow         = 0;                      /* */
19127    fis->d.lbaMid         = 0;                      /* */
19128    fis->d.lbaHigh        = 0;                      /* */
19129    fis->d.device         = 0;                      /* */
19130    fis->d.lbaLowExp      = 0;                      /* */
19131    fis->d.lbaMidExp      = 0;                      /* */
19132    fis->d.lbaHighExp     = 0;                      /* */
19133    fis->d.featuresExp    = 0;                      /* */
19134    fis->d.sectorCount    = 0;                      /* */
19135    fis->d.sectorCountExp = 0;                      /* */
19136    fis->d.reserved4      = 0;
19137    fis->d.control        = 0;                      /* FIS HOB bit clear */
19138    fis->d.reserved5      = 0;
19139
19140    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19141
19142    /* Initialize CB for SATA completion.
19143     */
19144    satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
19145
19146    /*
19147     * Prepare SGL and send FIS to LL layer.
19148     */
19149    satIOContext->reqType = agRequestType;       /* Save it */
19150
19151  status = smsataLLIOStart( smRoot,
19152                            smIORequest,
19153                            smDeviceHandle,
19154                            smScsiRequest,
19155                            satIOContext);
19156    return status;
19157  }
19158}
19159
19160
19161osGLOBAL bit32
19162smsatLogSense_1(
19163                smRoot_t                  *smRoot,
19164                smIORequest_t             *smIORequest,
19165                smDeviceHandle_t          *smDeviceHandle,
19166                smScsiInitiatorRequest_t  *smScsiRequest,
19167                smSatIOContext_t            *satIOContext
19168               )
19169{
19170  bit32                     status;
19171  bit32                     agRequestType;
19172  smDeviceData_t            *pSatDevData;
19173  agsaFisRegHostToDevice_t  *fis;
19174
19175  pSatDevData   = satIOContext->pSatDevData;
19176  fis           = satIOContext->pFis;
19177
19178  SM_DBG5(("smsatLogSense_1: start\n"));
19179
19180  /* SAT Rev 8, 10.2.4 p74 */
19181  if ( pSatDevData->sat48BitSupport == agTRUE )
19182  {
19183    SM_DBG5(("smsatLogSense_1: case 2-1 sends READ LOG EXT\n"));
19184    /* sends READ LOG EXT */
19185    fis->h.fisType        = 0x27;                   /* Reg host to device */
19186    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19187
19188    fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
19189    fis->h.features       = 0;                      /* FIS reserve */
19190    fis->d.lbaLow         = 0x07;                   /* 0x07 */
19191    fis->d.lbaMid         = 0;                      /*  */
19192    fis->d.lbaHigh        = 0;                      /*  */
19193    fis->d.device         = 0;                      /*  */
19194    fis->d.lbaLowExp      = 0;                      /*  */
19195    fis->d.lbaMidExp      = 0;                      /*  */
19196    fis->d.lbaHighExp     = 0;                      /*  */
19197    fis->d.featuresExp    = 0;                      /* FIS reserve */
19198    fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
19199    fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
19200    fis->d.reserved4      = 0;
19201    fis->d.control        = 0;                      /* FIS HOB bit clear */
19202    fis->d.reserved5      = 0;
19203
19204    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19205
19206    /* Initialize CB for SATA completion.
19207     */
19208    satIOContext->satCompleteCB = &smsatLogSenseCB;
19209
19210    /*
19211     * Prepare SGL and send FIS to LL layer.
19212     */
19213    satIOContext->reqType = agRequestType;       /* Save it */
19214
19215  status = smsataLLIOStart( smRoot,
19216                            smIORequest,
19217                            smDeviceHandle,
19218                            smScsiRequest,
19219                            satIOContext);
19220    return status;
19221
19222  }
19223  else
19224  {
19225    SM_DBG5(("smsatLogSense_1: case 2-2 sends SMART READ LOG\n"));
19226    /* sends SMART READ LOG */
19227    fis->h.fisType        = 0x27;                   /* Reg host to device */
19228    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19229
19230    fis->h.command        = SAT_SMART;              /* 0x2F */
19231    fis->h.features       = SAT_SMART_READ_LOG;     /* 0xd5 */
19232    fis->d.lbaLow         = 0x06;                   /* 0x06 */
19233    fis->d.lbaMid         = 0x00;                   /* 0x4f */
19234    fis->d.lbaHigh        = 0x00;                   /* 0xc2 */
19235    fis->d.device         = 0;                      /*  */
19236    fis->d.lbaLowExp      = 0;                      /*  */
19237    fis->d.lbaMidExp      = 0;                      /*  */
19238    fis->d.lbaHighExp     = 0;                      /*  */
19239    fis->d.featuresExp    = 0;                      /* FIS reserve */
19240    fis->d.sectorCount    = 0x01;                      /*  */
19241    fis->d.sectorCountExp = 0x00;                      /*  */
19242    fis->d.reserved4      = 0;
19243    fis->d.control        = 0;                      /* FIS HOB bit clear */
19244    fis->d.reserved5      = 0;
19245
19246    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19247
19248    /* Initialize CB for SATA completion.
19249     */
19250    satIOContext->satCompleteCB = &smsatLogSenseCB;
19251
19252    /*
19253     * Prepare SGL and send FIS to LL layer.
19254     */
19255    satIOContext->reqType = agRequestType;       /* Save it */
19256
19257  status = smsataLLIOStart( smRoot,
19258                            smIORequest,
19259                            smDeviceHandle,
19260                            smScsiRequest,
19261                            satIOContext);
19262    return status;
19263
19264  }
19265}
19266
19267osGLOBAL bit32
19268smsatReassignBlocks_2(
19269                      smRoot_t                  *smRoot,
19270                      smIORequest_t             *smIORequest,
19271                      smDeviceHandle_t          *smDeviceHandle,
19272                      smScsiInitiatorRequest_t  *smScsiRequest,
19273                      smSatIOContext_t            *satIOContext,
19274                      bit8                      *LBA
19275                     )
19276{
19277  /*
19278    assumes all LBA fits in ATA command; no boundary condition is checked here yet
19279    tiScsiRequest is TD generated for writing
19280  */
19281  bit32                     status;
19282  bit32                     agRequestType;
19283  smDeviceData_t            *pSatDevData;
19284  smScsiRspSense_t          *pSense;
19285  agsaFisRegHostToDevice_t  *fis;
19286
19287  pSense        = satIOContext->pSense;
19288  pSatDevData   = satIOContext->pSatDevData;
19289  fis           = satIOContext->pFis;
19290  SM_DBG5(("smsatReassignBlocks_2: start\n"));
19291
19292  if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
19293  {
19294    /* case 2 */
19295    /* WRITE DMA*/
19296    /* can't fit the transfer length */
19297    SM_DBG5(("smsatReassignBlocks_2: case 2\n"));
19298    fis->h.fisType        = 0x27;                   /* Reg host to device */
19299    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
19300    fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
19301    fis->h.features       = 0;                      /* FIS reserve */
19302    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19303    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19304    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19305
19306    /* FIS LBA mode set LBA (27:24) */
19307    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19308
19309    fis->d.lbaLowExp      = 0;
19310    fis->d.lbaMidExp      = 0;
19311    fis->d.lbaHighExp     = 0;
19312    fis->d.featuresExp    = 0;
19313    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19314    fis->d.sectorCountExp = 0;
19315    fis->d.reserved4      = 0;
19316    fis->d.control        = 0;                      /* FIS HOB bit clear */
19317    fis->d.reserved5      = 0;
19318
19319    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
19320    satIOContext->ATACmd = SAT_WRITE_DMA;
19321  }
19322  else
19323  {
19324    /* case 1 */
19325    /* WRITE MULTIPLE or WRITE SECTOR(S) */
19326    /* WRITE SECTORS for easier implemetation */
19327    /* can't fit the transfer length */
19328    SM_DBG5(("smsatReassignBlocks_2: case 1\n"));
19329    fis->h.fisType        = 0x27;                   /* Reg host to device */
19330    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
19331    fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
19332    fis->h.features       = 0;                      /* FIS reserve */
19333    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19334    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19335    fis->d.lbaHigh        = LBA[7];                 /* FIS LBA (23:16) */
19336
19337    /* FIS LBA mode set LBA (27:24) */
19338    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19339
19340    fis->d.lbaLowExp      = 0;
19341    fis->d.lbaMidExp      = 0;
19342    fis->d.lbaHighExp     = 0;
19343    fis->d.featuresExp    = 0;
19344    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19345    fis->d.sectorCountExp = 0;
19346    fis->d.reserved4      = 0;
19347    fis->d.control        = 0;                      /* FIS HOB bit clear */
19348    fis->d.reserved5      = 0;
19349
19350    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
19351    satIOContext->ATACmd = SAT_WRITE_SECTORS;
19352  }
19353
19354  /* case 3 and 4 */
19355  if (pSatDevData->sat48BitSupport == agTRUE)
19356  {
19357    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
19358    {
19359      /* case 3 */
19360      /* WRITE DMA EXT or WRITE DMA FUA EXT */
19361      SM_DBG5(("smsatReassignBlocks_2: case 3\n"));
19362      fis->h.fisType        = 0x27;                   /* Reg host to device */
19363      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19364
19365      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
19366      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
19367      satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
19368
19369      fis->h.features       = 0;                      /* FIS reserve */
19370      fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19371      fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19372      fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19373      fis->d.device         = 0x40;                   /* FIS LBA mode set */
19374      fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19375      fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19376      fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19377      fis->d.featuresExp    = 0;                      /* FIS reserve */
19378      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19379      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
19380      fis->d.reserved4      = 0;
19381      fis->d.control        = 0;                      /* FIS HOB bit clear */
19382      fis->d.reserved5      = 0;
19383
19384      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
19385    }
19386    else
19387    {
19388      /* case 4 */
19389      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
19390      /* WRITE SECTORS EXT for easier implemetation */
19391      SM_DBG5(("smsatReassignBlocks_2: case 4\n"));
19392      fis->h.fisType        = 0x27;                   /* Reg host to device */
19393      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19394      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
19395
19396      fis->h.features       = 0;                      /* FIS reserve */
19397      fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19398      fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19399      fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19400      fis->d.device         = 0x40;                   /* FIS LBA mode set */
19401      fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19402      fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19403      fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19404      fis->d.featuresExp    = 0;                      /* FIS reserve */
19405      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19406      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
19407      fis->d.reserved4      = 0;
19408      fis->d.control        = 0;                      /* FIS HOB bit clear */
19409      fis->d.reserved5      = 0;
19410
19411      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
19412      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
19413    }
19414  }
19415  /* case 5 */
19416  if (pSatDevData->satNCQ == agTRUE)
19417  {
19418    /* WRITE FPDMA QUEUED */
19419    if (pSatDevData->sat48BitSupport != agTRUE)
19420    {
19421      SM_DBG5(("smsatReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
19422      smsatSetSensePayload( pSense,
19423                            SCSI_SNSKEY_HARDWARE_ERROR,
19424                            0,
19425                            SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
19426                            satIOContext);
19427
19428      /*smEnqueueIO(smRoot, satIOContext);*/
19429
19430      tdsmIOCompletedCB( smRoot,
19431                         smIORequest,
19432                         smIOSuccess,
19433                         SCSI_STAT_CHECK_CONDITION,
19434                         satIOContext->pSmSenseData,
19435                         satIOContext->interruptContext );
19436      return SM_RC_SUCCESS;
19437    }
19438    SM_DBG6(("satWrite10: case 5\n"));
19439
19440    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
19441
19442    fis->h.fisType        = 0x27;                   /* Reg host to device */
19443    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19444    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
19445    fis->h.features       = 1;                      /* FIS sector count (7:0) */
19446    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19447    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19448    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19449
19450    /* Check FUA bit */
19451    fis->d.device       = 0x40;                     /* FIS FUA clear */
19452
19453    fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19454    fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19455    fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19456    fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
19457    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
19458    fis->d.sectorCountExp = 0;
19459    fis->d.reserved4      = 0;
19460    fis->d.control        = 0;                      /* FIS HOB bit clear */
19461    fis->d.reserved5      = 0;
19462
19463    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
19464    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
19465  }
19466
19467  satIOContext->satCompleteCB = &smsatReassignBlocksCB;
19468
19469  /*
19470   * Prepare SGL and send FIS to LL layer.
19471   */
19472  satIOContext->reqType = agRequestType;       /* Save it */
19473
19474  status = smsataLLIOStart( smRoot,
19475                            smIORequest,
19476                            smDeviceHandle,
19477                            /* not the original, should be the TD generated one */
19478                            smScsiRequest,
19479                            satIOContext);
19480  return (status);
19481}
19482
19483osGLOBAL bit32
19484smsatReassignBlocks_1(
19485                      smRoot_t                  *smRoot,
19486                      smIORequest_t             *smIORequest,
19487                      smDeviceHandle_t          *smDeviceHandle,
19488                      smScsiInitiatorRequest_t  *smScsiRequest,
19489                      smSatIOContext_t            *satIOContext,
19490                      smSatIOContext_t            *satOrgIOContext
19491                     )
19492{
19493  /*
19494    assumes all LBA fits in ATA command; no boundary condition is checked here yet
19495    tiScsiRequest is OS generated; needs for accessing parameter list
19496  */
19497  bit32                     agRequestType;
19498  smDeviceData_t            *pSatDevData;
19499  smIniScsiCmnd_t           *scsiCmnd;
19500  agsaFisRegHostToDevice_t  *fis;
19501  bit8                      *pParmList;    /* Log Page data buffer */
19502  bit8                      LongLBA;
19503  bit8                      LBA[8];
19504  bit32                     startingIndex;
19505
19506  pSatDevData   = satIOContext->pSatDevData;
19507  scsiCmnd      = &smScsiRequest->scsiCmnd;
19508  fis           = satIOContext->pFis;
19509  pParmList     = (bit8 *) smScsiRequest->sglVirtualAddr;
19510  SM_DBG5(("smsatReassignBlocks_1: start\n"));
19511  LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
19512  sm_memset(LBA, 0, sizeof(LBA));
19513  startingIndex = satOrgIOContext->ParmIndex;
19514  if (LongLBA == 0)
19515  {
19516    LBA[4] = pParmList[startingIndex];
19517    LBA[5] = pParmList[startingIndex+1];
19518    LBA[6] = pParmList[startingIndex+2];
19519    LBA[7] = pParmList[startingIndex+3];
19520    startingIndex = startingIndex + 4;
19521  }
19522  else
19523  {
19524    LBA[0] = pParmList[startingIndex];
19525    LBA[1] = pParmList[startingIndex+1];
19526    LBA[2] = pParmList[startingIndex+2];
19527    LBA[3] = pParmList[startingIndex+3];
19528    LBA[4] = pParmList[startingIndex+4];
19529    LBA[5] = pParmList[startingIndex+5];
19530    LBA[6] = pParmList[startingIndex+6];
19531    LBA[7] = pParmList[startingIndex+7];
19532    startingIndex = startingIndex + 8;
19533  }
19534
19535  if (pSatDevData->sat48BitSupport == agTRUE)
19536  {
19537    /* sends READ VERIFY SECTOR(S) EXT*/
19538    fis->h.fisType        = 0x27;                   /* Reg host to device */
19539    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19540    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
19541    fis->h.features       = 0;                      /* FIS reserve */
19542    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19543    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19544    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19545    fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19546    fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19547    fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19548    fis->d.featuresExp    = 0;                      /* FIS reserve */
19549    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19550    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
19551    fis->d.reserved4      = 0;
19552    fis->d.device         = 0x40;                   /* 01000000 */
19553    fis->d.control        = 0;                      /* FIS HOB bit clear */
19554    fis->d.reserved5      = 0;
19555  }
19556  else
19557  {
19558    /* READ VERIFY SECTOR(S)*/
19559    fis->h.fisType        = 0x27;                   /* Reg host to device */
19560    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19561    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
19562    fis->h.features       = 0;                      /* FIS features NA       */
19563    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19564    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19565    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19566    fis->d.lbaLowExp      = 0;
19567    fis->d.lbaMidExp      = 0;
19568    fis->d.lbaHighExp     = 0;
19569    fis->d.featuresExp    = 0;
19570    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19571    fis->d.sectorCountExp = 0;
19572    fis->d.reserved4      = 0;
19573    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19574                            /* DEV and LBA 27:24 */
19575    fis->d.control        = 0;                      /* FIS HOB bit clear */
19576    fis->d.reserved5      = 0;
19577  }
19578
19579  sm_memcpy(satOrgIOContext->LBA, LBA, 8);
19580  satOrgIOContext->ParmIndex = startingIndex;
19581
19582  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19583
19584  /* Initialize CB for SATA completion.
19585   */
19586  satIOContext->satCompleteCB = &smsatReassignBlocksCB;
19587
19588  /*
19589   * Prepare SGL and send FIS to LL layer.
19590   */
19591  satIOContext->reqType = agRequestType;       /* Save it */
19592
19593  smsataLLIOStart( smRoot,
19594                            smIORequest,
19595                            smDeviceHandle,
19596                            smScsiRequest,
19597                            satIOContext);
19598
19599  return SM_RC_SUCCESS;
19600}
19601
19602osGLOBAL bit32
19603smsatSendReadLogExt(
19604                     smRoot_t                  *smRoot,
19605                     smIORequest_t             *smIORequest,
19606                     smDeviceHandle_t          *smDeviceHandle,
19607                     smScsiInitiatorRequest_t  *smScsiRequest,
19608                     smSatIOContext_t            *satIOContext
19609       )
19610{
19611  bit32                     status;
19612  bit32                     agRequestType;
19613  agsaFisRegHostToDevice_t  *fis;
19614
19615  fis           = satIOContext->pFis;
19616  SM_DBG1(("smsatSendReadLogExt: start\n"));
19617  fis->h.fisType        = 0x27;                   /* Reg host to device */
19618  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19619  fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
19620  fis->h.features       = 0;                      /* FIS reserve */
19621  fis->d.lbaLow         = 0x10;                   /* Page number */
19622  fis->d.lbaMid         = 0;                      /*  */
19623  fis->d.lbaHigh        = 0;                      /*  */
19624  fis->d.device         = 0;                      /* DEV is ignored in SATA */
19625  fis->d.lbaLowExp      = 0;                      /*  */
19626  fis->d.lbaMidExp      = 0;                      /*  */
19627  fis->d.lbaHighExp     = 0;                      /*  */
19628  fis->d.featuresExp    = 0;                      /* FIS reserve */
19629  fis->d.sectorCount    = 0x01;                   /*  1 sector counts*/
19630  fis->d.sectorCountExp = 0x00;                   /*  1 sector counts */
19631  fis->d.reserved4      = 0;
19632  fis->d.control        = 0;                      /* FIS HOB bit clear */
19633  fis->d.reserved5      = 0;
19634
19635  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19636
19637  /* Initialize CB for SATA completion.
19638   */
19639  satIOContext->satCompleteCB = &smsatReadLogExtCB;
19640
19641  /*
19642   * Prepare SGL and send FIS to LL layer.
19643   */
19644  satIOContext->reqType = agRequestType;       /* Save it */
19645
19646  status = smsataLLIOStart( smRoot,
19647                            smIORequest,
19648                            smDeviceHandle,
19649                            smScsiRequest,
19650                            satIOContext);
19651
19652  SM_DBG1(("smsatSendReadLogExt: end status %d!!!\n", status));
19653
19654  return (status);
19655}
19656
19657osGLOBAL bit32
19658smsatCheckPowerMode(
19659                     smRoot_t                  *smRoot,
19660                     smIORequest_t             *smIORequest,
19661                     smDeviceHandle_t          *smDeviceHandle,
19662                     smScsiInitiatorRequest_t  *smScsiRequest,
19663                     smSatIOContext_t          *satIOContext
19664       )
19665{
19666  /*
19667    sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands
19668    internally generated - no directly corresponding scsi
19669  */
19670  bit32                     status;
19671  bit32                     agRequestType;
19672  agsaFisRegHostToDevice_t  *fis;
19673
19674  fis           = satIOContext->pFis;
19675  SM_DBG1(("smsatCheckPowerMode: start\n"));
19676  /*
19677   * Send the ATA CHECK POWER MODE command.
19678   */
19679  fis->h.fisType        = 0x27;                   /* Reg host to device */
19680  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19681  fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
19682  fis->h.features       = 0;
19683  fis->d.lbaLow         = 0;
19684  fis->d.lbaMid         = 0;
19685  fis->d.lbaHigh        = 0;
19686  fis->d.device         = 0;
19687  fis->d.lbaLowExp      = 0;
19688  fis->d.lbaMidExp      = 0;
19689  fis->d.lbaHighExp     = 0;
19690  fis->d.featuresExp    = 0;
19691  fis->d.sectorCount    = 0;
19692  fis->d.sectorCountExp = 0;
19693  fis->d.reserved4      = 0;
19694  fis->d.control        = 0;                      /* FIS HOB bit clear */
19695  fis->d.reserved5      = 0;
19696
19697  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19698
19699  /* Initialize CB for SATA completion.
19700   */
19701  satIOContext->satCompleteCB = &smsatCheckPowerModeCB;
19702
19703  /*
19704   * Prepare SGL and send FIS to LL layer.
19705   */
19706  satIOContext->reqType = agRequestType;       /* Save it */
19707
19708  status = smsataLLIOStart( smRoot,
19709                            smIORequest,
19710                            smDeviceHandle,
19711                            smScsiRequest,
19712                            satIOContext);
19713
19714  SM_DBG5(("smsatCheckPowerMode: return\n"));
19715
19716  return status;
19717}
19718
19719osGLOBAL bit32
19720smsatResetDevice(
19721                  smRoot_t                  *smRoot,
19722                  smIORequest_t             *smIORequest,
19723                  smDeviceHandle_t          *smDeviceHandle,
19724                  smScsiInitiatorRequest_t  *smScsiRequest, /* NULL */
19725                  smSatIOContext_t            *satIOContext
19726                )
19727{
19728  bit32                     status;
19729  bit32                     agRequestType;
19730  agsaFisRegHostToDevice_t  *fis;
19731#ifdef  TD_DEBUG_ENABLE
19732  smIORequestBody_t         *smIORequestBody;
19733  smSatInternalIo_t           *satIntIoContext;
19734#endif
19735
19736  fis           = satIOContext->pFis;
19737  SM_DBG1(("smsatResetDevice: start\n"));
19738#ifdef  TD_DEBUG_ENABLE
19739  satIntIoContext = satIOContext->satIntIoContext;
19740  smIORequestBody = satIntIoContext->satIntRequestBody;
19741#endif
19742  SM_DBG5(("smsatResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody));
19743  /* any fis should work */
19744  fis->h.fisType        = 0x27;                   /* Reg host to device */
19745  fis->h.c_pmPort       = 0;                      /* C Bit is not set */
19746  fis->h.command        = 0;                      /* any command */
19747  fis->h.features       = 0;                      /* FIS reserve */
19748  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
19749  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19750  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19751  fis->d.device         = 0;                      /* FIS LBA mode  */
19752  fis->d.lbaLowExp      = 0;
19753  fis->d.lbaMidExp      = 0;
19754  fis->d.lbaHighExp     = 0;
19755  fis->d.featuresExp    = 0;
19756  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
19757  fis->d.sectorCountExp = 0;
19758  fis->d.reserved4      = 0;
19759  fis->d.control        = 0x4;                    /* SRST bit is set  */
19760  fis->d.reserved5      = 0;
19761
19762  agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
19763
19764  /* Initialize CB for SATA completion.
19765   */
19766  satIOContext->satCompleteCB = &smsatResetDeviceCB;
19767
19768  /*
19769   * Prepare SGL and send FIS to LL layer.
19770   */
19771  satIOContext->reqType = agRequestType;       /* Save it */
19772
19773#ifdef SM_INTERNAL_DEBUG
19774  smhexdump("smsatResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19775#ifdef  TD_DEBUG_ENABLE
19776  smhexdump("smsatResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19777#endif
19778#endif
19779
19780  status = smsataLLIOStart( smRoot,
19781                            smIORequest,
19782                            smDeviceHandle,
19783                            smScsiRequest,
19784                            satIOContext);
19785
19786  SM_DBG6(("smsatResetDevice: end status %d\n", status));
19787  return status;
19788}
19789
19790osGLOBAL bit32
19791smsatDeResetDevice(
19792                    smRoot_t                  *smRoot,
19793                    smIORequest_t             *smIORequest,
19794                    smDeviceHandle_t          *smDeviceHandle,
19795                    smScsiInitiatorRequest_t  *smScsiRequest,
19796                    smSatIOContext_t            *satIOContext
19797                   )
19798{
19799  bit32                     status;
19800  bit32                     agRequestType;
19801  agsaFisRegHostToDevice_t  *fis;
19802#ifdef  TD_DEBUG_ENABLE
19803  smIORequestBody_t         *smIORequestBody;
19804  smSatInternalIo_t           *satIntIoContext;
19805#endif
19806
19807  fis           = satIOContext->pFis;
19808  SM_DBG1(("smsatDeResetDevice: start\n"));
19809#ifdef  TD_DEBUG_ENABLE
19810  satIntIoContext = satIOContext->satIntIoContext;
19811  smIORequestBody = satIntIoContext->satIntRequestBody;
19812#endif
19813  SM_DBG5(("smsatDeResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody));
19814  /* any fis should work */
19815  fis->h.fisType        = 0x27;                   /* Reg host to device */
19816  fis->h.c_pmPort       = 0;                      /* C Bit is not set */
19817  fis->h.command        = 0;                      /* any command */
19818  fis->h.features       = 0;                      /* FIS reserve */
19819  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
19820  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19821  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19822  fis->d.device         = 0;                      /* FIS LBA mode  */
19823  fis->d.lbaLowExp      = 0;
19824  fis->d.lbaMidExp      = 0;
19825  fis->d.lbaHighExp     = 0;
19826  fis->d.featuresExp    = 0;
19827  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
19828  fis->d.sectorCountExp = 0;
19829  fis->d.reserved4      = 0;
19830  fis->d.control        = 0;                    /* SRST bit is not set  */
19831  fis->d.reserved5      = 0;
19832
19833  agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT;
19834
19835  /* Initialize CB for SATA completion.
19836   */
19837  satIOContext->satCompleteCB = &smsatDeResetDeviceCB;
19838
19839  /*
19840   * Prepare SGL and send FIS to LL layer.
19841   */
19842  satIOContext->reqType = agRequestType;       /* Save it */
19843
19844#ifdef SM_INTERNAL_DEBUG
19845  smhexdump("smsatDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19846#ifdef  TD_DEBUG_ENABLE
19847  smhexdump("smsatDeResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19848#endif
19849#endif
19850
19851  status = smsataLLIOStart( smRoot,
19852                            smIORequest,
19853                            smDeviceHandle,
19854                            smScsiRequest,
19855                            satIOContext);
19856
19857  SM_DBG6(("smsatDeResetDevice: end status %d\n", status));
19858  return status;
19859}
19860
19861/* set feature for auto activate */
19862osGLOBAL bit32
19863smsatSetFeaturesAA(
19864           smRoot_t                  *smRoot,
19865           smIORequest_t             *smIORequest,
19866           smDeviceHandle_t          *smDeviceHandle,
19867           smScsiInitiatorRequest_t  *smScsiRequest,
19868           smSatIOContext_t          *satIOContext
19869           )
19870{
19871  bit32                     status = SM_RC_FAILURE;
19872  bit32                     agRequestType;
19873  agsaFisRegHostToDevice_t  *fis;
19874
19875  fis           = satIOContext->pFis;
19876  SM_DBG2(("smsatSetFeaturesAA: start\n"));
19877  /*
19878   * Send the Set Features command.
19879   * See SATA II 1.0a spec
19880   */
19881  fis->h.fisType        = 0x27;                   /* Reg host to device */
19882  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19883  fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19884  fis->h.features       = 0x10;                   /* enable SATA feature */
19885  fis->d.lbaLow         = 0;
19886  fis->d.lbaMid         = 0;
19887  fis->d.lbaHigh        = 0;
19888  fis->d.device         = 0;
19889  fis->d.lbaLowExp      = 0;
19890  fis->d.lbaMidExp      = 0;
19891  fis->d.lbaHighExp     = 0;
19892  fis->d.featuresExp    = 0;
19893  fis->d.sectorCount    = 0x02;                   /* DMA Setup FIS Auto-Activate */
19894  fis->d.sectorCountExp = 0;
19895  fis->d.reserved4      = 0;
19896  fis->d.control        = 0;                      /* FIS HOB bit clear */
19897  fis->d.reserved5      = 0;
19898
19899  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19900
19901  /* Initialize CB for SATA completion.
19902   */
19903  satIOContext->satCompleteCB = &smsatSetFeaturesAACB;
19904
19905  /*
19906   * Prepare SGL and send FIS to LL layer.
19907   */
19908  satIOContext->reqType = agRequestType;       /* Save it */
19909
19910  status = smsataLLIOStart( smRoot,
19911                          smIORequest,
19912                          smDeviceHandle,
19913                          smScsiRequest,
19914                          satIOContext);
19915
19916  /* debugging code */
19917  if (smIORequest->tdData == smIORequest->smData)
19918  {
19919    SM_DBG1(("smsatSetFeaturesAA: incorrect smIORequest\n"));
19920  }
19921  SM_DBG2(("smsatSetFeatures: return\n"));
19922  return status;
19923}
19924
19925
19926/* set feature for DMA transfer mode*/
19927osGLOBAL bit32
19928smsatSetFeaturesDMA(
19929           smRoot_t                  *smRoot,
19930           smIORequest_t             *smIORequest,
19931           smDeviceHandle_t          *smDeviceHandle,
19932           smScsiInitiatorRequest_t  *smScsiRequest,
19933           smSatIOContext_t          *satIOContext
19934           )
19935{
19936  bit32                     status = SM_RC_FAILURE;
19937  bit32                     agRequestType;
19938  smDeviceData_t            *pSatDevData;
19939  agsaFisRegHostToDevice_t  *fis;
19940
19941  pSatDevData   = satIOContext->pSatDevData;
19942  fis           = satIOContext->pFis;
19943  SM_DBG2(("smsatSetFeaturesDMA: start\n"));
19944  /*
19945   * Send the Set Features command.
19946   * See SATA II 1.0a spec
19947   */
19948  fis->h.fisType        = 0x27;                   /* Reg host to device */
19949  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19950  fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19951  fis->h.features       = 0x03;                   /* enable ATA transfer mode */
19952  fis->d.lbaLow         = 0;
19953  fis->d.lbaMid         = 0;
19954  fis->d.lbaHigh        = 0;
19955  fis->d.device         = 0;
19956  fis->d.lbaLowExp      = 0;
19957  fis->d.lbaMidExp      = 0;
19958  fis->d.lbaHighExp     = 0;
19959  fis->d.featuresExp    = 0;
19960  fis->d.sectorCount    = 0x40 |(bit8)pSatDevData->satUltraDMAMode;   /* enable Ultra DMA mode */
19961  fis->d.sectorCountExp = 0;
19962  fis->d.reserved4      = 0;
19963  fis->d.control        = 0;                      /* FIS HOB bit clear */
19964  fis->d.reserved5      = 0;
19965
19966  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19967
19968  /* Initialize CB for SATA completion.
19969   */
19970  satIOContext->satCompleteCB = &smsatSetFeaturesDMACB;
19971
19972  /*
19973   * Prepare SGL and send FIS to LL layer.
19974   */
19975  satIOContext->reqType = agRequestType;       /* Save it */
19976
19977  status = smsataLLIOStart( smRoot,
19978                          smIORequest,
19979                          smDeviceHandle,
19980                          smScsiRequest,
19981                          satIOContext);
19982
19983  /* debugging code */
19984  if (smIORequest->tdData == smIORequest->smData)
19985  {
19986    SM_DBG1(("smsatSetFeaturesDMA: incorrect smIORequest\n"));
19987  }
19988
19989  SM_DBG2(("smsatSetFeaturesDMA: return\n"));
19990
19991  return status;
19992}
19993
19994/* set feature for Read Look Ahead*/
19995osGLOBAL bit32
19996smsatSetFeaturesReadLookAhead(
19997           smRoot_t                  *smRoot,
19998           smIORequest_t             *smIORequest,
19999           smDeviceHandle_t          *smDeviceHandle,
20000           smScsiInitiatorRequest_t  *smScsiRequest,
20001           smSatIOContext_t          *satIOContext
20002           )
20003{
20004  bit32                     status = SM_RC_FAILURE;
20005  bit32                     agRequestType;
20006  agsaFisRegHostToDevice_t  *fis;
20007
20008  fis           = satIOContext->pFis;
20009  SM_DBG2(("smsatSetFeaturesReadLookAhead: start\n"));
20010  /*
20011   * Send the Set Features command.
20012   * See SATA II 1.0a spec
20013   */
20014  fis->h.fisType        = 0x27;                   /* Reg host to device */
20015  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
20016  fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
20017  fis->h.features       = 0xAA;                   /* Enable read look-ahead feature */
20018  fis->d.lbaLow         = 0;
20019  fis->d.lbaMid         = 0;
20020  fis->d.lbaHigh        = 0;
20021  fis->d.device         = 0;
20022  fis->d.lbaLowExp      = 0;
20023  fis->d.lbaMidExp      = 0;
20024  fis->d.lbaHighExp     = 0;
20025  fis->d.featuresExp    = 0;
20026  fis->d.sectorCount    = 0;
20027  fis->d.sectorCountExp = 0;
20028  fis->d.reserved4      = 0;
20029  fis->d.control        = 0;                      /* FIS HOB bit clear */
20030  fis->d.reserved5      = 0;
20031
20032  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
20033
20034  /* Initialize CB for SATA completion.
20035   */
20036  satIOContext->satCompleteCB = &smsatSetFeaturesReadLookAheadCB;
20037
20038  /*
20039   * Prepare SGL and send FIS to LL layer.
20040   */
20041  satIOContext->reqType = agRequestType;       /* Save it */
20042
20043  status = smsataLLIOStart( smRoot,
20044                          smIORequest,
20045                          smDeviceHandle,
20046                          smScsiRequest,
20047                          satIOContext);
20048
20049  /* debugging code */
20050  if (smIORequest->tdData == smIORequest->smData)
20051  {
20052    SM_DBG1(("smsatSetFeaturesReadLookAhead: incorrect smIORequest\n"));
20053  }
20054
20055  SM_DBG2(("smsatSetFeaturesReadLookAhead: return\n"));
20056
20057  return status;
20058}
20059
20060/* set feature for Volatile Write Cache*/
20061osGLOBAL bit32
20062smsatSetFeaturesVolatileWriteCache(
20063           smRoot_t                  *smRoot,
20064           smIORequest_t             *smIORequest,
20065           smDeviceHandle_t          *smDeviceHandle,
20066           smScsiInitiatorRequest_t  *smScsiRequest,
20067           smSatIOContext_t            *satIOContext
20068           )
20069{
20070  bit32                     status = SM_RC_FAILURE;
20071  bit32                     agRequestType;
20072  agsaFisRegHostToDevice_t  *fis;
20073
20074  fis           = satIOContext->pFis;
20075  SM_DBG2(("smsatSetFeaturesVolatileWriteCache: start\n"));
20076  /*
20077   * Send the Set Features command.
20078   * See SATA II 1.0a spec
20079   */
20080  fis->h.fisType        = 0x27;                   /* Reg host to device */
20081  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
20082  fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
20083  fis->h.features       = 0x02;                   /* Enable Volatile Write Cache feature */
20084  fis->d.lbaLow         = 0;
20085  fis->d.lbaMid         = 0;
20086  fis->d.lbaHigh        = 0;
20087  fis->d.device         = 0;
20088  fis->d.lbaLowExp      = 0;
20089  fis->d.lbaMidExp      = 0;
20090  fis->d.lbaHighExp     = 0;
20091  fis->d.featuresExp    = 0;
20092  fis->d.sectorCount    = 0;
20093  fis->d.sectorCountExp = 0;
20094  fis->d.reserved4      = 0;
20095  fis->d.control        = 0;                      /* FIS HOB bit clear */
20096  fis->d.reserved5      = 0;
20097
20098  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
20099
20100  /* Initialize CB for SATA completion.
20101   */
20102  satIOContext->satCompleteCB = &smsatSetFeaturesVolatileWriteCacheCB;
20103  /*
20104   * Prepare SGL and send FIS to LL layer.
20105   */
20106  satIOContext->reqType = agRequestType;       /* Save it */
20107
20108  status = smsataLLIOStart( smRoot,
20109                          smIORequest,
20110                          smDeviceHandle,
20111                          smScsiRequest,
20112                          satIOContext);
20113  /* debugging code */
20114  if (smIORequest->tdData == smIORequest->smData)
20115  {
20116    SM_DBG1(("smsatSetFeaturesVolatileWriteCache: incorrect smIORequest\n"));
20117  }
20118  SM_DBG2(("smsatSetFeaturesVolatileWriteCache: return\n"));
20119
20120  return status;
20121}
20122
20123
20124
20125/******************************** start of utils    ***********************************************************/
20126osGLOBAL FORCEINLINE void
20127smsatBitSet(smRoot_t *smRoot, bit8 *data, bit32 index)
20128{
20129  data[index>>3] |= (1 << (index&7));
20130}
20131
20132osGLOBAL FORCEINLINE void
20133smsatBitClear(smRoot_t *smRoot, bit8 *data, bit32 index)
20134{
20135  data[index>>3] &= ~(1 << (index&7));
20136}
20137
20138osGLOBAL FORCEINLINE BOOLEAN
20139smsatBitTest(smRoot_t *smRoot, bit8 *data, bit32 index)
20140{
20141   return ( (BOOLEAN)((data[index>>3] & (1 << (index&7)) ) ? 1: 0));
20142}
20143
20144
20145FORCEINLINE bit32
20146smsatTagAlloc(
20147               smRoot_t         *smRoot,
20148               smDeviceData_t   *pSatDevData,
20149               bit8             *pTag
20150             )
20151{
20152  bit32             retCode = agFALSE;
20153  bit32             i;
20154
20155  tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK);
20156
20157#ifdef CCFLAG_OPTIMIZE_SAT_LOCK
20158
20159  if (tdsmBitScanForward(smRoot, &i, ~(pSatDevData->freeSATAFDMATagBitmap)))
20160  {
20161    smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20162    *pTag = (bit8)i;
20163    retCode = agTRUE;
20164  }
20165
20166#else
20167
20168  for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
20169  {
20170    if ( 0 == smsatBitTest(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
20171    {
20172      smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20173      *pTag = (bit8) i;
20174      retCode = agTRUE;
20175      break;
20176    }
20177  }
20178
20179#endif
20180
20181  tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK);
20182
20183  return retCode;
20184}
20185
20186FORCEINLINE bit32
20187smsatTagRelease(
20188                smRoot_t         *smRoot,
20189                smDeviceData_t   *pSatDevData,
20190                bit8              tag
20191               )
20192{
20193  bit32             retCode = agFALSE;
20194
20195  if ( tag < pSatDevData->satNCQMaxIO )
20196  {
20197    tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK);
20198    smsatBitClear(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
20199    tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK);
20200    /*tdsmInterlockedAnd(smRoot, (volatile LONG *)(&pSatDevData->freeSATAFDMATagBitmap), ~(1 << (tag&31)));*/
20201    retCode = agTRUE;
20202  }
20203  else
20204  {
20205    SM_DBG1(("smsatTagRelease: tag %d >= satNCQMaxIO %d!!!!\n", tag, pSatDevData->satNCQMaxIO));
20206  }
20207  return retCode;
20208}
20209
20210
20211
20212osGLOBAL bit32
20213smsatComputeCDB10LBA(smSatIOContext_t            *satIOContext)
20214{
20215  smIniScsiCmnd_t           *scsiCmnd;
20216  smScsiInitiatorRequest_t  *smScsiRequest;
20217  bit32                     lba = 0;
20218
20219  SM_DBG5(("smsatComputeCDB10LBA: start\n"));
20220  smScsiRequest = satIOContext->smScsiXchg;
20221  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20222
20223  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
20224    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
20225
20226  return lba;
20227}
20228
20229osGLOBAL bit32
20230smsatComputeCDB10TL(smSatIOContext_t            *satIOContext)
20231{
20232
20233  smIniScsiCmnd_t           *scsiCmnd;
20234  smScsiInitiatorRequest_t  *smScsiRequest;
20235  bit32                     tl = 0;
20236
20237  SM_DBG5(("smsatComputeCDB10TL: start\n"));
20238  smScsiRequest = satIOContext->smScsiXchg;
20239  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20240
20241  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
20242  return tl;
20243}
20244
20245osGLOBAL bit32
20246smsatComputeCDB12LBA(smSatIOContext_t            *satIOContext)
20247{
20248  smIniScsiCmnd_t           *scsiCmnd;
20249  smScsiInitiatorRequest_t  *smScsiRequest;
20250  bit32                     lba = 0;
20251
20252  SM_DBG5(("smsatComputeCDB12LBA: start\n"));
20253  smScsiRequest = satIOContext->smScsiXchg;
20254  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20255
20256  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
20257    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
20258
20259  return lba;
20260}
20261
20262osGLOBAL bit32
20263smsatComputeCDB12TL(smSatIOContext_t            *satIOContext)
20264{
20265
20266  smIniScsiCmnd_t           *scsiCmnd;
20267  smScsiInitiatorRequest_t  *smScsiRequest;
20268  bit32                     tl = 0;
20269
20270  SM_DBG5(("smsatComputeCDB12TL: start\n"));
20271  smScsiRequest = satIOContext->smScsiXchg;
20272  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20273
20274  tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
20275    + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
20276  return tl;
20277}
20278
20279/*
20280  CBD16 has bit64 LBA
20281  But it has to be less than (2^28 - 1)
20282  Therefore, use last four bytes to compute LBA is OK
20283*/
20284osGLOBAL bit32
20285smsatComputeCDB16LBA(smSatIOContext_t            *satIOContext)
20286{
20287  smIniScsiCmnd_t           *scsiCmnd;
20288  smScsiInitiatorRequest_t  *smScsiRequest;
20289  bit32                     lba = 0;
20290
20291  SM_DBG5(("smsatComputeCDB16LBA: start\n"));
20292  smScsiRequest = satIOContext->smScsiXchg;
20293  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20294
20295  lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
20296    + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
20297
20298  return lba;
20299}
20300
20301osGLOBAL bit32
20302smsatComputeCDB16TL(smSatIOContext_t            *satIOContext)
20303{
20304
20305  smIniScsiCmnd_t           *scsiCmnd;
20306  smScsiInitiatorRequest_t  *smScsiRequest;
20307  bit32                     tl = 0;
20308
20309  SM_DBG5(("smsatComputeCDB16TL: start\n"));
20310  smScsiRequest = satIOContext->smScsiXchg;
20311  scsiCmnd      = &(smScsiRequest->scsiCmnd);
20312
20313  tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
20314    + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
20315  return tl;
20316}
20317
20318/*
20319  (tl, denom)
20320  tl can be upto bit32 because CDB16 has bit32 tl
20321  Therefore, fine
20322  either (tl, 0xFF) or (tl, 0xFFFF)
20323*/
20324osGLOBAL FORCEINLINE bit32
20325smsatComputeLoopNum(bit32 a, bit32 b)
20326{
20327  bit32 LoopNum = 0;
20328
20329  SM_DBG5(("smsatComputeLoopNum: start\n"));
20330
20331  if (a < b || a == 0)
20332  {
20333    LoopNum = 1;
20334  }
20335  else
20336  {
20337    if (a == b || a == 0)
20338    {
20339      LoopNum = a/b;
20340    }
20341    else
20342    {
20343      LoopNum = a/b + 1;
20344    }
20345  }
20346
20347  return LoopNum;
20348}
20349
20350/*
20351  Generic new function for checking
20352  LBA itself, LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT
20353  and LBA+TL < Read Capacity Limit
20354  flag: false - not 48BitSupport; true - 48BitSupport
20355  returns TRUE when over the limit
20356
20357*/
20358osGLOBAL FORCEINLINE bit32
20359smsatCheckLimit(bit8 *lba, bit8 *tl, int flag, smDeviceData_t *pSatDevData)
20360{
20361  bit32 lbaCheck = agFALSE;
20362  int i;
20363  bit8 limit[8];
20364  bit32 rangeCheck = agFALSE;
20365  bit16 ans[8];       // 0 MSB, 8 LSB
20366  bit8  final_ans[9]; // 0 MSB, 9 LSB
20367  bit8  Bit28max[8];
20368  bit8  Bit48max[8];
20369  bit32 ReadCapCheck = agFALSE;
20370  bit32 ret;
20371
20372  bit8  final_satMaxLBA[9];
20373  bit8  oneTL[8];
20374  bit8  temp_satMaxLBA[8];       // 0 MSB, 8 LSB
20375  /*
20376    check LBA
20377  */
20378  if (flag == agFALSE)
20379  {
20380    /* limit is 0xF FF FF = 2^28 - 1 */
20381    limit[0] = 0x0;   /* MSB */
20382    limit[1] = 0x0;
20383    limit[2] = 0x0;
20384    limit[3] = 0x0;
20385    limit[4] = 0xF;
20386    limit[5] = 0xFF;
20387    limit[6] = 0xFF;
20388    limit[7] = 0xFF;  /* LSB */
20389  }
20390  else
20391  {
20392    /* limit is 0xF FF FF = 2^48 - 1 */
20393    limit[0] = 0x0;   /* MSB */
20394    limit[1] = 0x0;
20395    limit[2] = 0xFF;
20396    limit[3] = 0xFF;
20397    limit[4] = 0xFF;
20398    limit[5] = 0xFF;
20399    limit[6] = 0xFF;
20400    limit[7] = 0xFF;  /* LSB */
20401  }
20402  //compare lba to limit
20403  for(i=0;i<8;i++)
20404  {
20405    if (lba[i] > limit[i])
20406    {
20407      SM_DBG1(("smsatCheckLimit: LBA check True at %d\n", i));
20408      lbaCheck = agTRUE;
20409      break;
20410    }
20411    else if (lba[i] < limit[i])
20412    {
20413      SM_DBG5(("smsatCheckLimit: LBA check False at %d\n", i));
20414      lbaCheck = agFALSE;
20415      break;
20416    }
20417    else
20418    {
20419      continue;
20420    }
20421  }
20422
20423  if (lbaCheck == agTRUE)
20424  {
20425    SM_DBG1(("smsatCheckLimit: return LBA check True\n"));
20426    return agTRUE;
20427  }
20428
20429  /*
20430    check LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT
20431  */
20432  sm_memset(ans, 0, sizeof(ans));
20433  sm_memset(final_ans, 0, sizeof(final_ans));
20434
20435  // adding from LSB to MSB
20436  for(i=7;i>=0;i--)
20437  {
20438    ans[i] = (bit16)(lba[i] + tl[i]);
20439    if (i != 7)
20440    {
20441      ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
20442    }
20443  }
20444
20445  /*
20446    filling in the final answer
20447   */
20448  final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
20449
20450  for(i=1;i<=8;i++)
20451  {
20452    final_ans[i] = (bit8)(ans[i-1] & 0xFF);
20453  }
20454
20455
20456  if (flag == agFALSE)
20457  {
20458    sm_memset(Bit28max, 0, sizeof(Bit28max));
20459    Bit28max[4] = 0x10; // max =0x1000 0000
20460
20461    //compare final_ans to max
20462    if (final_ans[0] != 0 || final_ans[1] != 0 || final_ans[2] != 0
20463        || final_ans[3] != 0 || final_ans[4] != 0)
20464    {
20465      SM_DBG1(("smsatCheckLimit: before 28Bit addressing TRUE\n"));
20466      rangeCheck = agTRUE;
20467    }
20468    else
20469    {
20470      for(i=5;i<=8;i++)
20471      {
20472        if (final_ans[i] > Bit28max[i-1])
20473        {
20474          SM_DBG1(("smsatCheckLimit: 28Bit addressing TRUE at %d\n", i));
20475          rangeCheck = agTRUE;
20476          break;
20477        }
20478        else if (final_ans[i] < Bit28max[i-1])
20479        {
20480          SM_DBG5(("smsatCheckLimit: 28Bit addressing FALSE at %d\n", i));
20481          rangeCheck = agFALSE;
20482          break;
20483        }
20484        else
20485        {
20486          continue;
20487        }
20488      }
20489    }
20490  }
20491  else
20492  {
20493    sm_memset(Bit48max, 0, sizeof(Bit48max));
20494    Bit48max[1] = 0x1; //max = 0x1 0000 0000 0000
20495
20496    //compare final_ans to max
20497    if (final_ans[0] != 0 || final_ans[1] != 0)
20498    {
20499      SM_DBG1(("smsatCheckLimit: before 48Bit addressing TRUE\n"));
20500      rangeCheck = agTRUE;
20501    }
20502    else
20503    {
20504      for(i=2;i<=8;i++)
20505      {
20506        if (final_ans[i] > Bit48max[i-1])
20507        {
20508          SM_DBG1(("smsatCheckLimit: 48Bit addressing TRUE at %d\n", i));
20509          rangeCheck = agTRUE;
20510	  break;
20511        }
20512        else if (final_ans[i] < Bit48max[i-1])
20513        {
20514          SM_DBG5(("smsatCheckLimit: 48Bit addressing FALSE at %d\n", i));
20515          rangeCheck = agFALSE;
20516	  break;
20517        }
20518        else
20519        {
20520          continue;
20521        }
20522      }
20523    }
20524  }
20525  if (rangeCheck == agTRUE)
20526  {
20527    SM_DBG1(("smsatCheckLimit: return rangeCheck True\n"));
20528    return agTRUE;
20529  }
20530
20531  /*
20532    LBA+TL < Read Capacity Limit
20533  */
20534  sm_memset(temp_satMaxLBA, 0, sizeof(temp_satMaxLBA));
20535  sm_memset(oneTL, 0, sizeof(oneTL));
20536  sm_memset(final_satMaxLBA, 0, sizeof(final_satMaxLBA));
20537  sm_memset(ans, 0, sizeof(ans));
20538
20539  sm_memcpy(&temp_satMaxLBA, &pSatDevData->satMaxLBA, sizeof(temp_satMaxLBA));
20540  oneTL[7] = 1;
20541
20542  // adding temp_satMaxLBA to oneTL
20543  for(i=7;i>=0;i--)
20544  {
20545    ans[i] = (bit16)(temp_satMaxLBA[i] + oneTL[i]);
20546    if (i != 7)
20547    {
20548      ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
20549    }
20550  }
20551
20552  /*
20553    filling in the final answer
20554   */
20555  final_satMaxLBA[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
20556
20557  for(i=1;i<=8;i++)
20558  {
20559    final_satMaxLBA[i] = (bit8)(ans[i-1] & 0xFF);
20560  }
20561  if ( pSatDevData->ReadCapacity == 10)
20562  {
20563    for (i=0;i<=8;i++)
20564    {
20565      if (final_ans[i] > final_satMaxLBA[i])
20566      {
20567        SM_DBG1(("smsatCheckLimit: Read Capacity 10 TRUE at %d\n", i));
20568        ReadCapCheck = agTRUE;
20569        break;
20570      }
20571      else if (final_ans[i] < final_satMaxLBA[i])
20572      {
20573        SM_DBG5(("smsatCheckLimit: Read Capacity 10 FALSE at %d\n", i));
20574        ReadCapCheck = agFALSE;
20575        break;
20576      }
20577      else
20578      {
20579        continue;
20580      }
20581    }
20582    if ( ReadCapCheck)
20583    {
20584      SM_DBG1(("smsatCheckLimit: after Read Capacity 10 TRUE\n"));
20585    }
20586    else
20587    {
20588      SM_DBG5(("smsatCheckLimit: after Read Capacity 10 FALSE\n"));
20589    }
20590  }
20591  else if ( pSatDevData->ReadCapacity == 16)
20592  {
20593    for (i=0;i<=8;i++)
20594    {
20595      if (final_ans[i] > final_satMaxLBA[i])
20596      {
20597        SM_DBG1(("smsatCheckLimit: Read Capacity 16 TRUE at %d\n", i));
20598        ReadCapCheck = agTRUE;
20599        break;
20600      }
20601      else if (final_ans[i] < final_satMaxLBA[i])
20602      {
20603        SM_DBG5(("smsatCheckLimit: Read Capacity 16 FALSE at %d\n", i));
20604        ReadCapCheck = agFALSE;
20605        break;
20606      }
20607      else
20608      {
20609        continue;
20610      }
20611    }
20612    if ( ReadCapCheck)
20613    {
20614      SM_DBG1(("smsatCheckLimit: after Read Capacity 16 TRUE\n"));
20615    }
20616    else
20617    {
20618      SM_DBG5(("smsatCheckLimit: after Read Capacity 16 FALSE\n"));
20619    }
20620  }
20621  else
20622  {
20623    SM_DBG5(("smsatCheckLimit: unknown pSatDevData->ReadCapacity %d\n", pSatDevData->ReadCapacity));
20624  }
20625
20626  if (ReadCapCheck == agTRUE)
20627  {
20628    SM_DBG1(("smsatCheckLimit: return ReadCapCheck True\n"));
20629    return agTRUE;
20630  }
20631
20632
20633  ret = (lbaCheck | rangeCheck | ReadCapCheck);
20634  if (ret == agTRUE)
20635  {
20636    SM_DBG1(("smsatCheckLimit: final check TRUE\n"));
20637  }
20638  else
20639  {
20640    SM_DBG5(("smsatCheckLimit: final check FALSE\n"));
20641  }
20642  return   ret;
20643}
20644
20645
20646
20647osGLOBAL void
20648smsatPrintSgl(
20649            smRoot_t                  *smRoot,
20650            agsaEsgl_t                *agEsgl,
20651      bit32                     idx
20652      )
20653{
20654  bit32                     i=0;
20655#ifdef  TD_DEBUG_ENABLE
20656  agsaSgl_t                 *agSgl;
20657#endif
20658
20659  for (i=0;i<idx;i++)
20660  {
20661#ifdef  TD_DEBUG_ENABLE
20662    agSgl = &(agEsgl->descriptor[i]);
20663#endif
20664    SM_DBG3(("smsatPrintSgl: agSgl %d upperAddr 0x%08x lowerAddr 0x%08x len 0x%08x ext 0x%08x\n",
20665      i, agSgl->sgUpper, agSgl->sgLower, agSgl->len,  agSgl->extReserved));
20666  }
20667
20668  return;
20669}
20670
20671
20672osGLOBAL void
20673smsatSplitSGL(
20674     smRoot_t                  *smRoot,
20675     smIORequest_t             *smIORequest,
20676     smDeviceHandle_t          *smDeviceHandle,
20677     smScsiInitiatorRequest_t  *smScsiRequest,
20678     smSatIOContext_t          *satIOContext,
20679     bit32                     split, /*in sector number, depeding on IO value */
20680     bit32                     tl, /* in sector number */
20681     bit32                     flag
20682    )
20683{
20684  agsaSgl_t                 *agSgl;
20685  agsaEsgl_t                *agEsgl;
20686  bit32                     i=0;
20687  smIniScsiCmnd_t           *scsiCmnd;
20688  bit32                     totalLen=0; /* in bytes */
20689  bit32                     splitLen=0; /* in bytes */
20690  bit32                     splitDiffByte = 0; /* in bytes */
20691  bit32                     splitDiffExtra = 0; /* in bytes */
20692  bit32                     splitIdx = 0;
20693  bit32                     UpperAddr, LowerAddr;
20694  bit32                     tmpLowerAddr;
20695  void                      *sglVirtualAddr;
20696  void                      *sglSplitVirtualAddr;
20697
20698  scsiCmnd      = &smScsiRequest->scsiCmnd;
20699  SM_DBG3(("smsatSplitSGL: start\n"));
20700
20701  if (smScsiRequest->smSgl1.type == 0x80000000) /* esgl */
20702  {
20703    if (flag == agFALSE)
20704    {
20705      SM_DBG3(("smsatSplitSGL: Not first time\n"));
20706      SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x LowerAddr 0x%08x\n", satIOContext->UpperAddr, satIOContext->LowerAddr));
20707      SM_DBG3(("smsatSplitSGL: SplitIdx %d AdjustBytes 0x%08x\n", satIOContext->SplitIdx, satIOContext->AdjustBytes));
20708
20709      sglVirtualAddr = smScsiRequest->sglVirtualAddr;
20710
20711      agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20712
20713      sglSplitVirtualAddr = &(agEsgl->descriptor[satIOContext->SplitIdx]);
20714
20715      agEsgl = (agsaEsgl_t *)sglSplitVirtualAddr;
20716
20717      if (agEsgl == agNULL)
20718      {
20719        SM_DBG1(("smsatSplitSGL: error!\n"));
20720        return;
20721      }
20722      /* first sgl ajustment */
20723      agSgl = &(agEsgl->descriptor[0]);
20724      agSgl->sgUpper = satIOContext->UpperAddr;
20725      agSgl->sgLower = satIOContext->LowerAddr;
20726      agSgl->len = satIOContext->AdjustBytes;
20727      sm_memcpy(sglVirtualAddr, sglSplitVirtualAddr, (satIOContext->EsglLen) * sizeof(agsaSgl_t));
20728      agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20729      smsatPrintSgl(smRoot, (agsaEsgl_t *)sglVirtualAddr, satIOContext->EsglLen);
20730    }
20731    else
20732    {
20733      /* first time */
20734      SM_DBG3(("smsatSplitSGL: first time\n"));
20735      satIOContext->EsglLen = smScsiRequest->smSgl1.len;
20736      agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20737      if (agEsgl == agNULL)
20738      {
20739        return;
20740      }
20741      smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20742    }
20743
20744    if (tl > split)
20745    {
20746      /* split */
20747      SM_DBG3(("smsatSplitSGL: split case\n"));
20748      i = 0;
20749      while (1)
20750      {
20751        agSgl = &(agEsgl->descriptor[i]);
20752        splitLen = splitLen + agSgl->len;
20753        if (splitLen >= split)
20754        {
20755          splitDiffExtra = splitLen - split;
20756          splitDiffByte = agSgl->len - splitDiffExtra;
20757          splitIdx = i;
20758          break;
20759        }
20760        i++;
20761      }
20762      SM_DBG3(("smsatSplitSGL: splitIdx %d\n", splitIdx));
20763      SM_DBG3(("smsatSplitSGL: splitDiffByte 0x%8x\n", splitDiffByte));
20764      SM_DBG3(("smsatSplitSGL: splitDiffExtra 0x%8x \n", splitDiffExtra));
20765
20766
20767      agSgl = &(agEsgl->descriptor[splitIdx]);
20768      UpperAddr = agSgl->sgUpper;
20769      LowerAddr = agSgl->sgLower;
20770      tmpLowerAddr = LowerAddr + splitDiffByte;
20771      if (tmpLowerAddr < LowerAddr)
20772      {
20773        UpperAddr = UpperAddr + 1;
20774      }
20775      SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x tmpLowerAddr 0x%08x\n", UpperAddr, tmpLowerAddr));
20776      agSgl->len = splitDiffByte;
20777      /* Esgl len adjustment */
20778      smScsiRequest->smSgl1.len =  splitIdx;
20779      /* expected data lent adjustment */
20780      scsiCmnd->expDataLength = 0x20000;
20781      /* remeber for the next round */
20782      satIOContext->UpperAddr = UpperAddr;
20783      satIOContext->LowerAddr = tmpLowerAddr;
20784      satIOContext->SplitIdx = splitIdx;
20785      satIOContext->AdjustBytes = splitDiffExtra;
20786      satIOContext->EsglLen =  satIOContext->EsglLen - smScsiRequest->smSgl1.len;
20787      satIOContext->OrgTL = satIOContext->OrgTL - 0x100;
20788//    smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20789
20790    }
20791    else
20792    {
20793      /* no split */
20794      SM_DBG3(("smsatSplitSGL: no split case\n"));
20795      /* Esgl len adjustment */
20796      smScsiRequest->smSgl1.len = satIOContext->EsglLen;
20797      for (i=0;i< smScsiRequest->smSgl1.len;i++)
20798      {
20799        agSgl = &(agEsgl->descriptor[i]);
20800        totalLen = totalLen + (agSgl->len);
20801      }
20802      /* expected data lent adjustment */
20803      scsiCmnd->expDataLength = totalLen;
20804//    smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20805    }
20806  }
20807  else
20808  {
20809    SM_DBG1(("not exntened esgl\n"));
20810
20811  }
20812
20813  return;
20814}
20815
20816
20817/******************************** end   of utils    ***********************************************************/
20818
20819
20820
20821