xref: /freebsd/sys/dev/pms/RefTisa/sat/src/smsat.c (revision c697fb7f)
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 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 
20821