]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - sys/dev/pms/RefTisa/sat/src/smsat.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / sys / dev / pms / RefTisa / sat / src / smsat.c
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 */
45 osGLOBAL bit32
46 smRegisterDevice(
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
84 osGLOBAL bit32
85 smDeregisterDevice(
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
112 osGLOBAL bit32
113 smIOAbort(
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
238 osGLOBAL bit32
239 smIOAbortAll(
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
350 osGLOBAL bit32
351 smSuperIOStart(
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 /*
437 osGLOBAL bit32
438 tiINIIOStart(
439              tiRoot_t                  *tiRoot,
440              tiIORequest_t             *tiIORequest,
441              tiDeviceHandle_t          *tiDeviceHandle,
442              tiScsiInitiatorRequest_t  *tiScsiRequest,
443              void                      *tiRequestBody,
444              bit32                     interruptContext
445              )
446
447 GLOBAL bit32  satIOStart(
448                    tiRoot_t                  *tiRoot,
449                    tiIORequest_t             *tiIORequest,
450                    tiDeviceHandle_t          *tiDeviceHandle,
451                    tiScsiInitiatorRequest_t  *tiScsiRequest,
452                    smSatIOContext_t            *satIOContext
453                   )
454 smIOStart(
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 */
465 FORCEINLINE bit32
466 smIOStart(
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
542 osGLOBAL bit32
543 smTaskManagement(
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 */
682 osGLOBAL smIORequestBody_t *
683 smDequeueIO(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
731 osGLOBAL void
732 smsatAbort(
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
815 osGLOBAL bit32 
816 smsatStartCheckPowerMode(
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
891 osGLOBAL bit32
892 smsatStartResetDevice(
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
979 osGLOBAL bit32
980 smsatTmAbortTask(
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() */
1118 osGLOBAL bit32
1119 smsatTaskManagement(
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
1181 osGLOBAL bit32
1182 smPhyControlSend(
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 */
1424 osGLOBAL void
1425 smEnqueueIO(
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
1489 FORCEINLINE void
1490 smsatFreeIntIoResource(
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
1546 osGLOBAL smSatInternalIo_t *
1547 smsatAllocIntIoResource(
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
1770 osGLOBAL smDeviceData_t *
1771 smAddToSharedcontext(
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
1873 osGLOBAL bit32
1874 smRemoveFromSharedcontext(
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
1916 osGLOBAL smDeviceData_t *
1917 smFindInSharedcontext(
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
1963 osGLOBAL smSatIOContext_t *
1964 smsatPrepareNewIO(
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
2007 osGLOBAL void
2008 smsatSetDevInfo(
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
2272 osGLOBAL void
2273 smsatInquiryStandard(
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
2451 osGLOBAL void
2452 smsatInquiryPage0(
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
2478 osGLOBAL void
2479 smsatInquiryPage83(
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
2774 osGLOBAL void
2775 smsatInquiryPage89(
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
2898 osGLOBAL void
2899 smsatInquiryPage80(
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
2939 osGLOBAL void
2940 smsatInquiryPageB1(
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
2981 osGLOBAL void
2982 smsatDefaultTranslation(
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
3142 osGLOBAL bit32
3143 smIDStart(
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 */
3215 osGLOBAL bit32
3216 smsatIDSubStart(
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
3304 osGLOBAL bit32
3305 smsatIDStart(
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
3383 osGLOBAL FORCEINLINE bit32
3384 smsatIOStart(
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
3849 osGLOBAL void
3850 smsatSetSensePayload(
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  */
3950 GLOBAL bit32
3951 smsatDecodeSATADeviceType(
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 /*****************************************************************************/
4016 osGLOBAL bit32
4017 smsatPacket(
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 /*****************************************************************************/
4132 osGLOBAL bit32
4133 smsatSetFeaturesPIO(
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 /*****************************************************************************/
4212 osGLOBAL bit32
4213 smsatRequestSenseForATAPI(
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 /*****************************************************************************/
4316 osGLOBAL bit32
4317 smsatDeviceReset(
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 /*****************************************************************************/
4393 osGLOBAL bit32
4394 smsatExecuteDeviceDiagnostic(
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
4452 osGLOBAL void
4453 smsatSetDeferredSensePayload(
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
4466 GLOBAL bit32
4467 smsatRead6(
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
4783 osGLOBAL FORCEINLINE bit32
4784 smsatRead10(
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
5250 osGLOBAL bit32
5251 smsatRead12(
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
5689 osGLOBAL bit32
5690 smsatRead16(
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
6141 osGLOBAL bit32
6142 smsatWrite6(
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
6457 osGLOBAL FORCEINLINE bit32
6458 smsatWrite10(
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
6901 osGLOBAL bit32
6902 smsatWrite12(
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
7323 osGLOBAL bit32
7324 smsatWrite16(
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
7749 osGLOBAL bit32
7750 smsatVerify10(
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
8032 osGLOBAL bit32
8033 smsatVerify12(
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
8314 osGLOBAL bit32
8315 smsatVerify16(
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
8576 osGLOBAL bit32
8577 smsatTestUnitReady(
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
8750 osGLOBAL bit32
8751 smsatTestUnitReady_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
8813 osGLOBAL bit32
8814 smsatInquiry(
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
8908 osGLOBAL bit32
8909 smsatStartIDDev(
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
9000 osGLOBAL bit32
9001 smsatSendIDDev(
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
9072 osGLOBAL bit32
9073 smsatRequestSense(
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
9317 osGLOBAL bit32
9318 smsatRequestSense_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
9389 osGLOBAL bit32
9390 smsatModeSense6(
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
9929 osGLOBAL bit32
9930 smsatModeSense10(
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
10766 osGLOBAL bit32
10767 smsatReadCapacity10(
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 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
11003 osGLOBAL bit32
11004 smsatReadCapacity16(
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
11252 osGLOBAL bit32
11253 smsatReportLun(
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
11354 osGLOBAL bit32
11355 smsatFormatUnit(
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
11569 osGLOBAL bit32
11570 smsatSendDiagnostic(
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
12165 osGLOBAL bit32
12166 smsatStartStopUnit(
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
12497 osGLOBAL bit32
12498 smsatWriteSame10(
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
12947 osGLOBAL bit32
12948 smsatWriteSame16(
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
12981 osGLOBAL bit32
12982 smsatLogSense(
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
13404 osGLOBAL bit32
13405 smsatLogSenseAllocate(
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
13513 osGLOBAL bit32
13514 smsatSMARTEnable(
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
13570 osGLOBAL bit32
13571 smsatLogSense_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
13625 osGLOBAL bit32
13626 smsatLogSense_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
13675 osGLOBAL bit32
13676 smsatModeSelect6(
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
14172 osGLOBAL bit32
14173 smsatModeSelect10(
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
14705 osGLOBAL bit32
14706 smsatSynchronizeCache10(
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
14836 osGLOBAL bit32
14837 smsatSynchronizeCache16(
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
14968 osGLOBAL bit32
14969 smsatWriteAndVerify10(
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
15397 osGLOBAL bit32
15398 smsatWriteAndVerify12(
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
15822 osGLOBAL bit32
15823 smsatWriteAndVerify16(
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
16250 osGLOBAL bit32
16251 smsatReadMediaSerialNumber(
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
16450 osGLOBAL bit32
16451 smsatReadBuffer(
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
16706 osGLOBAL bit32
16707 smsatWriteBuffer(
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
16907 osGLOBAL bit32
16908 smsatReassignBlocks(
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
17075 osGLOBAL bit32
17076 smsatRead_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
17351 osGLOBAL bit32
17352 smsatWrite_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
17635 osGLOBAL bit32  
17636 smsatPassthrough(
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
17829 osGLOBAL bit32
17830 smsatNonChainedWriteNVerify_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
17899 osGLOBAL bit32
17900 smsatChainedWriteNVerify_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
18065 osGLOBAL bit32
18066 smsatChainedWriteNVerify_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
18327 osGLOBAL bit32
18328 smsatChainedWriteNVerify_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
18466 osGLOBAL bit32
18467 smsatChainedVerify(
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
18605 osGLOBAL bit32
18606 smsatWriteSame10_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
18669 osGLOBAL bit32
18670 smsatWriteSame10_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
18733 osGLOBAL bit32
18734 smsatWriteSame10_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
18803 osGLOBAL bit32
18804 smsatStartStopUnit_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
18862 osGLOBAL bit32
18863 smsatSendDiagnostic_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
18953 osGLOBAL bit32
18954 smsatSendDiagnostic_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
19044 osGLOBAL bit32
19045 smsatModeSelect6n10_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
19161 osGLOBAL bit32
19162 smsatLogSense_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
19267 osGLOBAL bit32
19268 smsatReassignBlocks_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
19483 osGLOBAL bit32
19484 smsatReassignBlocks_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
19602 osGLOBAL bit32
19603 smsatSendReadLogExt(
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
19657 osGLOBAL bit32
19658 smsatCheckPowerMode(
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
19719 osGLOBAL bit32
19720 smsatResetDevice(
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
19790 osGLOBAL bit32
19791 smsatDeResetDevice(
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 */
19862 osGLOBAL bit32
19863 smsatSetFeaturesAA(
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*/
19927 osGLOBAL bit32
19928 smsatSetFeaturesDMA(
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*/
19995 osGLOBAL bit32
19996 smsatSetFeaturesReadLookAhead(
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*/
20061 osGLOBAL bit32
20062 smsatSetFeaturesVolatileWriteCache(
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    ***********************************************************/
20126 osGLOBAL FORCEINLINE void
20127 smsatBitSet(smRoot_t *smRoot, bit8 *data, bit32 index)
20128 {
20129   data[index>>3] |= (1 << (index&7));
20130 }
20131
20132 osGLOBAL FORCEINLINE void
20133 smsatBitClear(smRoot_t *smRoot, bit8 *data, bit32 index)
20134 {
20135   data[index>>3] &= ~(1 << (index&7));
20136 }
20137
20138 osGLOBAL FORCEINLINE BOOLEAN
20139 smsatBitTest(smRoot_t *smRoot, bit8 *data, bit32 index)
20140 {
20141    return ( (BOOLEAN)((data[index>>3] & (1 << (index&7)) ) ? 1: 0));
20142 }
20143
20144
20145 FORCEINLINE bit32
20146 smsatTagAlloc(
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
20186 FORCEINLINE bit32
20187 smsatTagRelease(
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
20212 osGLOBAL bit32
20213 smsatComputeCDB10LBA(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
20229 osGLOBAL bit32
20230 smsatComputeCDB10TL(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
20245 osGLOBAL bit32
20246 smsatComputeCDB12LBA(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
20262 osGLOBAL bit32
20263 smsatComputeCDB12TL(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 */
20284 osGLOBAL bit32
20285 smsatComputeCDB16LBA(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
20301 osGLOBAL bit32
20302 smsatComputeCDB16TL(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 */
20324 osGLOBAL FORCEINLINE bit32
20325 smsatComputeLoopNum(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 */
20358 osGLOBAL FORCEINLINE bit32
20359 smsatCheckLimit(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
20647 osGLOBAL void
20648 smsatPrintSgl(
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
20672 osGLOBAL void
20673 smsatSplitSGL(
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