xref: /freebsd/sys/dev/pms/RefTisa/sat/src/smsat.c (revision 069ac184)
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 #include <dev/pms/config.h>
24 
25 #include <dev/pms/freebsd/driver/common/osenv.h>
26 #include <dev/pms/freebsd/driver/common/ostypes.h>
27 #include <dev/pms/freebsd/driver/common/osdebug.h>
28 
29 #include <dev/pms/RefTisa/tisa/api/titypes.h>
30 
31 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
32 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
33 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
34 
35 #include <dev/pms/RefTisa/sat/api/sm.h>
36 #include <dev/pms/RefTisa/sat/api/smapi.h>
37 #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
38 
39 #include <dev/pms/RefTisa/sat/src/smdefs.h>
40 #include <dev/pms/RefTisa/sat/src/smproto.h>
41 #include <dev/pms/RefTisa/sat/src/smtypes.h>
42 
43 /* start smapi defined APIs */
44 osGLOBAL bit32
45 smRegisterDevice(
46                  smRoot_t                       *smRoot,
47                  agsaDevHandle_t                *agDevHandle,
48                  smDeviceHandle_t               *smDeviceHandle,
49                  agsaDevHandle_t                *agExpDevHandle,
50                  bit32                          phyID,
51                  bit32                          DeviceType
52                 )
53 {
54   smDeviceData_t            *oneDeviceData = agNULL;
55 
56   SM_DBG2(("smRegisterDevice: start\n"));
57 
58   if (smDeviceHandle == agNULL)
59   {
60     SM_DBG1(("smRegisterDevice: smDeviceHandle is NULL!!!\n"));
61     return SM_RC_FAILURE;
62   }
63 
64   if (agDevHandle == agNULL)
65   {
66     SM_DBG1(("smRegisterDevice: agDevHandle is NULL!!!\n"));
67     return SM_RC_FAILURE;
68   }
69 
70   oneDeviceData = smAddToSharedcontext(smRoot, agDevHandle, smDeviceHandle, agExpDevHandle, phyID);
71   if (oneDeviceData != agNULL)
72   {
73     oneDeviceData->satDeviceType = DeviceType;
74     return SM_RC_SUCCESS;
75   }
76   else
77   {
78     return SM_RC_FAILURE;
79   }
80 
81 }
82 
83 osGLOBAL bit32
84 smDeregisterDevice(
85                    smRoot_t                     *smRoot,
86                    agsaDevHandle_t              *agDevHandle,
87                    smDeviceHandle_t             *smDeviceHandle
88                   )
89 {
90   bit32                     status = SM_RC_FAILURE;
91 
92   SM_DBG2(("smDeregisterDevice: start\n"));
93 
94   if (smDeviceHandle == agNULL)
95   {
96     SM_DBG1(("smDeregisterDevice: smDeviceHandle is NULL!!!\n"));
97     return SM_RC_FAILURE;
98   }
99 
100   if (agDevHandle == agNULL)
101   {
102     SM_DBG1(("smDeregisterDevice: agDevHandle is NULL!!!\n"));
103     return SM_RC_FAILURE;
104   }
105 
106   status = smRemoveFromSharedcontext(smRoot, agDevHandle, smDeviceHandle);
107 
108   return status;
109 }
110 
111 osGLOBAL bit32
112 smIOAbort(
113            smRoot_t                     *smRoot,
114            smIORequest_t                *tasktag
115          )
116 
117 {
118   smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
119   smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
120   agsaRoot_t                *agRoot;
121   smIORequestBody_t         *smIORequestBody = agNULL;
122   smIORequestBody_t         *smIONewRequestBody = agNULL;
123   agsaIORequest_t           *agIORequest = agNULL; /* IO to be aborted */
124   bit32                     status = SM_RC_FAILURE;
125   agsaIORequest_t           *agAbortIORequest;  /* abort IO itself */
126   smIORequestBody_t         *smAbortIORequestBody;
127 #if 1
128   bit32                     PhysUpper32;
129   bit32                     PhysLower32;
130   bit32                     memAllocStatus;
131   void                      *osMemHandle;
132 #endif
133   smSatIOContext_t            *satIOContext;
134   smSatInternalIo_t           *satIntIo;
135   smSatIOContext_t            *satAbortIOContext;
136 
137   SM_DBG1(("smIOAbort: start\n"));
138   SM_DBG2(("smIOAbort: tasktag %p\n", tasktag));
139   /*
140     alloc smIORequestBody for abort itself
141     call saSATAAbort()
142   */
143 
144   agRoot = smAllShared->agRoot;
145   smIORequestBody =  (smIORequestBody_t *)tasktag->smData;
146 
147   if (smIORequestBody == agNULL)
148   {
149     SM_DBG1(("smIOAbort: smIORequestBody is NULL!!!\n"));
150     return SM_RC_FAILURE;
151   }
152 
153   /* needs to distinguish internally generated or externally generated */
154   satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
155   satIntIo     = satIOContext->satIntIoContext;
156   if (satIntIo == agNULL)
157   {
158     SM_DBG2(("smIOAbort: External, OS generated\n"));
159     agIORequest     = &(smIORequestBody->agIORequest);
160   }
161   else
162   {
163     SM_DBG2(("smIOAbort: Internal, SM generated\n"));
164     smIONewRequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
165     agIORequest     = &(smIONewRequestBody->agIORequest);
166   }
167 
168   /*
169     allocate smAbortIORequestBody for abort request itself
170   */
171 
172 #if 1
173   /* allocating agIORequest for abort itself */
174   memAllocStatus = tdsmAllocMemory(
175                                    smRoot,
176                                    &osMemHandle,
177                                    (void **)&smAbortIORequestBody,
178                                    &PhysUpper32,
179                                    &PhysLower32,
180                                    8,
181                                    sizeof(smIORequestBody_t),
182                                    agTRUE
183                                    );
184   if (memAllocStatus != SM_RC_SUCCESS)
185   {
186     /* let os process IO */
187     SM_DBG1(("smIOAbort: tdsmAllocMemory failed...!!!\n"));
188     return SM_RC_FAILURE;
189   }
190 
191   if (smAbortIORequestBody == agNULL)
192   {
193     /* let os process IO */
194     SM_DBG1(("smIOAbort: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n"));
195     return SM_RC_FAILURE;
196   }
197 
198   smIOReInit(smRoot, smAbortIORequestBody);
199 
200   /* setup task management structure */
201   smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
202   satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext);
203   satAbortIOContext->smRequestBody = smAbortIORequestBody;
204 
205   smAbortIORequestBody->smDevHandle = smIORequestBody->smDevHandle;
206 
207   /* initialize agIORequest */
208   agAbortIORequest = &(smAbortIORequestBody->agIORequest);
209   agAbortIORequest->osData = (void *) smAbortIORequestBody;
210   agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
211 
212   /* remember IO to be aborted */
213   smAbortIORequestBody->smIOToBeAbortedRequest = tasktag;
214 
215   status = saSATAAbort(agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, smaSATAAbortCB);
216 
217   SM_DBG2(("smIOAbort: return status=0x%x\n", status));
218 
219 #endif /* 1 */
220 
221 
222   if (status == AGSA_RC_SUCCESS)
223   {
224     return SM_RC_SUCCESS;
225   }
226   else
227   {
228     SM_DBG1(("smIOAbort: failed to call saSATAAbort, status=%d!!!\n", status));
229     tdsmFreeMemory(smRoot,
230                smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle,
231                sizeof(smIORequestBody_t)
232                );
233     return SM_RC_FAILURE;
234   }
235 }
236 
237 osGLOBAL bit32
238 smIOAbortAll(
239              smRoot_t                     *smRoot,
240              smDeviceHandle_t             *smDeviceHandle
241             )
242 {
243   smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
244   smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
245   agsaRoot_t                *agRoot;
246   bit32                     status = SM_RC_FAILURE;
247   agsaIORequest_t           *agAbortIORequest;
248   smIORequestBody_t         *smAbortIORequestBody;
249   smSatIOContext_t          *satAbortIOContext;
250   smDeviceData_t            *oneDeviceData = agNULL;
251   agsaDevHandle_t           *agDevHandle;
252 
253   bit32                     PhysUpper32;
254   bit32                     PhysLower32;
255   bit32                     memAllocStatus;
256   void                      *osMemHandle;
257 
258 
259   SM_DBG2(("smIOAbortAll: start\n"));
260 
261   agRoot = smAllShared->agRoot;
262 
263   if (smDeviceHandle == agNULL)
264   {
265     SM_DBG1(("smIOAbortAll: smDeviceHandle is NULL!!!\n"));
266     return SM_RC_FAILURE;
267   }
268 
269   oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
270   if (oneDeviceData == agNULL)
271   {
272     SM_DBG1(("smIOAbortAll: oneDeviceData is NULL!!!\n"));
273     return SM_RC_FAILURE;
274   }
275   if (oneDeviceData->valid == agFALSE)
276   {
277     SM_DBG1(("smIOAbortAll: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
278     return SM_RC_FAILURE;
279   }
280 
281   agDevHandle     = oneDeviceData->agDevHandle;
282   if (agDevHandle == agNULL)
283   {
284     SM_DBG1(("smIOAbortAll: agDevHandle is NULL!!!\n"));
285     return SM_RC_FAILURE;
286   }
287 /*
288   smAbortIORequestBody = smDequeueIO(smRoot);
289   if (smAbortIORequestBody == agNULL)
290   {
291     SM_DBG1(("smIOAbortAll: empty freeIOList!!!\n"));
292     return SM_RC_FAILURE;
293   }
294 */
295   /* allocating agIORequest for abort itself */
296   memAllocStatus = tdsmAllocMemory(
297                                    smRoot,
298                                    &osMemHandle,
299                                    (void **)&smAbortIORequestBody,
300                                    &PhysUpper32,
301                                    &PhysLower32,
302                                    8,
303                                    sizeof(smIORequestBody_t),
304                                    agTRUE
305                                    );
306   if (memAllocStatus != SM_RC_SUCCESS)
307   {
308      /* let os process IO */
309      SM_DBG1(("smIOAbortAll: tdsmAllocMemory failed...!!!\n"));
310      return SM_RC_FAILURE;
311   }
312 
313   if (smAbortIORequestBody == agNULL)
314   {
315     /* let os process IO */
316     SM_DBG1(("smIOAbortAll: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n"));
317     return SM_RC_FAILURE;
318   }
319 
320   smIOReInit(smRoot, smAbortIORequestBody);
321 
322   /* setup task management structure */
323   smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
324 
325   satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext);
326   satAbortIOContext->smRequestBody = smAbortIORequestBody;
327   smAbortIORequestBody->smDevHandle = smDeviceHandle;
328 
329   /* initialize agIORequest */
330   agAbortIORequest = &(smAbortIORequestBody->agIORequest);
331   agAbortIORequest->osData = (void *) smAbortIORequestBody;
332   agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
333 
334   oneDeviceData->OSAbortAll = agTRUE;
335   /* abort all */
336   status = saSATAAbort(agRoot, agAbortIORequest, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, 1, agNULL, smaSATAAbortCB);
337   if (status != AGSA_RC_SUCCESS)
338   {
339     SM_DBG1(("smIOAbortAll: failed to call saSATAAbort, status=%d!!!\n", status));
340     tdsmFreeMemory(smRoot,
341                    smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle,
342                    sizeof(smIORequestBody_t)
343                    );
344   }
345 
346   return status;
347 }
348 
349 osGLOBAL bit32
350 smSuperIOStart(
351                smRoot_t                         *smRoot,
352                smIORequest_t                    *smIORequest,
353                smDeviceHandle_t                 *smDeviceHandle,
354                smSuperScsiInitiatorRequest_t    *smSCSIRequest,
355                bit32                            AddrHi,
356                bit32                            AddrLo,
357                bit32                            interruptContext
358               )
359 {
360   smDeviceData_t            *oneDeviceData = agNULL;
361   smIORequestBody_t         *smIORequestBody = agNULL;
362   smSatIOContext_t            *satIOContext = agNULL;
363   bit32                     status = SM_RC_FAILURE;
364 
365   SM_DBG2(("smSuperIOStart: start\n"));
366 
367   oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
368   if (oneDeviceData == agNULL)
369   {
370     SM_DBG1(("smSuperIOStart: oneDeviceData is NULL!!!\n"));
371     return SM_RC_FAILURE;
372   }
373   if (oneDeviceData->valid == agFALSE)
374   {
375     SM_DBG1(("smSuperIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
376     return SM_RC_FAILURE;
377   }
378   smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
379 
380   if (smIORequestBody == agNULL)
381   {
382     SM_DBG1(("smSuperIOStart: smIORequestBody is NULL!!!\n"));
383     return SM_RC_FAILURE;
384   }
385 
386   smIOReInit(smRoot, smIORequestBody);
387 
388   SM_DBG3(("smSuperIOStart: io ID %d!!!\n", smIORequestBody->id ));
389 
390   oneDeviceData->sasAddressHi = AddrHi;
391   oneDeviceData->sasAddressLo = AddrLo;
392 
393   smIORequestBody->smIORequest = smIORequest;
394   smIORequestBody->smDevHandle = smDeviceHandle;
395 
396   satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
397 
398   /*
399    * Need to initialize all the fields within satIOContext except
400    * reqType and satCompleteCB which will be set later in SM.
401    */
402   smIORequestBody->transport.SATA.smSenseData.senseData = agNULL;
403   smIORequestBody->transport.SATA.smSenseData.senseLen = 0;
404   satIOContext->pSatDevData   = oneDeviceData;
405   satIOContext->pFis          =
406     &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
407   satIOContext->pScsiCmnd     = &smSCSIRequest->scsiCmnd;
408   satIOContext->pSense        = &smIORequestBody->transport.SATA.sensePayload;
409   satIOContext->pSmSenseData  = &smIORequestBody->transport.SATA.smSenseData;
410   satIOContext->pSmSenseData->senseData = satIOContext->pSense;
411   /*    satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */
412   satIOContext->smRequestBody = smIORequestBody;
413   satIOContext->interruptContext = interruptContext;
414   satIOContext->psmDeviceHandle = smDeviceHandle;
415   satIOContext->smScsiXchg = smSCSIRequest;
416   satIOContext->superIOFlag = agTRUE;
417 //  satIOContext->superIOFlag = agFALSE;
418 
419   satIOContext->satIntIoContext  = agNULL;
420   satIOContext->satOrgIOContext  = agNULL;
421   /*    satIOContext->tiIORequest      = tiIORequest; */
422 
423   /* save context if we need to abort later */
424   /*smIORequest->smData = smIORequestBody;*/
425 
426   /* followings are used only for internal IO */
427   satIOContext->currentLBA = 0;
428   satIOContext->OrgTL = 0;
429 
430   status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, (smScsiInitiatorRequest_t *)smSCSIRequest, satIOContext);
431 
432   return status;
433 }
434 
435 /*
436 osGLOBAL bit32
437 tiINIIOStart(
438              tiRoot_t                  *tiRoot,
439              tiIORequest_t             *tiIORequest,
440              tiDeviceHandle_t          *tiDeviceHandle,
441              tiScsiInitiatorRequest_t  *tiScsiRequest,
442              void                      *tiRequestBody,
443              bit32                     interruptContext
444              )
445 
446 GLOBAL bit32  satIOStart(
447                    tiRoot_t                  *tiRoot,
448                    tiIORequest_t             *tiIORequest,
449                    tiDeviceHandle_t          *tiDeviceHandle,
450                    tiScsiInitiatorRequest_t  *tiScsiRequest,
451                    smSatIOContext_t            *satIOContext
452                   )
453 smIOStart(
454           smRoot_t      *smRoot,
455           smIORequest_t     *smIORequest,
456           smDeviceHandle_t    *smDeviceHandle,
457           smScsiInitiatorRequest_t  *smSCSIRequest,
458           smIORequestBody_t             *smRequestBody,
459           bit32       interruptContext
460          )
461 
462 
463 */
464 FORCEINLINE bit32
465 smIOStart(
466           smRoot_t                      *smRoot,
467           smIORequest_t                 *smIORequest,
468           smDeviceHandle_t              *smDeviceHandle,
469           smScsiInitiatorRequest_t      *smSCSIRequest,
470           bit32                         interruptContext
471          )
472 {
473   smDeviceData_t            *oneDeviceData = agNULL;
474   smIORequestBody_t         *smIORequestBody = agNULL;
475   smSatIOContext_t          *satIOContext = agNULL;
476   bit32                     status = SM_RC_FAILURE;
477 
478   SM_DBG2(("smIOStart: start\n"));
479 
480   oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
481   if (oneDeviceData == agNULL)
482   {
483     SM_DBG1(("smIOStart: oneDeviceData is NULL!!!\n"));
484     return SM_RC_FAILURE;
485   }
486   if (oneDeviceData->valid == agFALSE)
487   {
488     SM_DBG1(("smIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
489     return SM_RC_FAILURE;
490   }
491   smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
492 
493   if (smIORequestBody == agNULL)
494   {
495     SM_DBG1(("smIOStart: smIORequestBody is NULL!!!\n"));
496     return SM_RC_FAILURE;
497   }
498 
499   smIOReInit(smRoot, smIORequestBody);
500 
501   SM_DBG3(("smIOStart: io ID %d!!!\n", smIORequestBody->id ));
502 
503   smIORequestBody->smIORequest = smIORequest;
504   smIORequestBody->smDevHandle = smDeviceHandle;
505 
506   satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
507 
508   /*
509    * Need to initialize all the fields within satIOContext except
510    * reqType and satCompleteCB which will be set later in SM.
511    */
512   smIORequestBody->transport.SATA.smSenseData.senseData = agNULL;
513   smIORequestBody->transport.SATA.smSenseData.senseLen = 0;
514   satIOContext->pSatDevData   = oneDeviceData;
515   satIOContext->pFis          =
516     &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
517   satIOContext->pScsiCmnd     = &smSCSIRequest->scsiCmnd;
518   satIOContext->pSense        = &smIORequestBody->transport.SATA.sensePayload;
519   satIOContext->pSmSenseData  = &smIORequestBody->transport.SATA.smSenseData;
520   satIOContext->pSmSenseData->senseData = satIOContext->pSense;
521   /*    satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */
522   satIOContext->smRequestBody = smIORequestBody;
523   satIOContext->interruptContext = interruptContext;
524   satIOContext->psmDeviceHandle = smDeviceHandle;
525   satIOContext->smScsiXchg = smSCSIRequest;
526   satIOContext->superIOFlag = agFALSE;
527 
528   satIOContext->satIntIoContext  = agNULL;
529   satIOContext->satOrgIOContext  = agNULL;
530   satIOContext->currentLBA = 0;
531   satIOContext->OrgTL = 0;
532 
533   status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
534 
535   return status;
536 
537 }
538 
539 
540 
541 osGLOBAL bit32
542 smTaskManagement(
543                  smRoot_t                       *smRoot,
544                  smDeviceHandle_t               *smDeviceHandle,
545                  bit32                          task,
546                  smLUN_t                        *lun,
547                  smIORequest_t                  *taskTag, /* io to be aborted */
548                  smIORequest_t                  *currentTaskTag /* task management */
549                 )
550 {
551   smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
552   smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
553   agsaRoot_t                *agRoot = smAllShared->agRoot;
554   smDeviceData_t            *oneDeviceData = agNULL;
555   smIORequestBody_t         *smIORequestBody = agNULL;
556   bit32                     status;
557   agsaContext_t             *agContext = agNULL;
558   smSatIOContext_t          *satIOContext;
559 
560   SM_DBG1(("smTaskManagement: start\n"));
561   oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
562 
563   if (task == SM_LOGICAL_UNIT_RESET || task == SM_TARGET_WARM_RESET || task == SM_ABORT_TASK)
564   {
565     if (task == AG_LOGICAL_UNIT_RESET)
566     {
567       if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
568             lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
569       {
570         SM_DBG1(("smTaskManagement: *** REJECT *** LUN not zero, did %d!!!\n",
571                 oneDeviceData->id));
572         return SM_RC_FAILURE;
573       }
574     }
575 
576     oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
577     oneDeviceData->satAbortAfterReset = agFALSE;
578 
579     saSetDeviceState(agRoot,
580                      agNULL,
581                      tdsmRotateQnumber(smRoot, smDeviceHandle),
582                      oneDeviceData->agDevHandle,
583                      SA_DS_IN_RECOVERY
584                      );
585 
586     if (oneDeviceData->directlyAttached == agFALSE)
587     {
588       /* expander attached */
589       SM_DBG1(("smTaskManagement: LUN reset or device reset expander attached!!!\n"));
590       status = smPhyControlSend(smRoot,
591                                 oneDeviceData,
592                                 SMP_PHY_CONTROL_HARD_RESET,
593                                 currentTaskTag,
594                                 tdsmRotateQnumber(smRoot, smDeviceHandle)
595                                );
596       return status;
597     }
598     else
599     {
600       SM_DBG1(("smTaskManagement: LUN reset or device reset directly attached\n"));
601 
602       smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot);
603 
604       if (smIORequestBody == agNULL)
605       {
606         SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n"));
607         return SM_RC_FAILURE;
608       }
609 
610       smIOReInit(smRoot, smIORequestBody);
611 
612       satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
613       satIOContext->smRequestBody = smIORequestBody;
614       smIORequestBody->smDevHandle = smDeviceHandle;
615 
616       agContext = &(oneDeviceData->agDeviceResetContext);
617       agContext->osData = currentTaskTag;
618 
619       status = saLocalPhyControl(agRoot,
620                                  agContext,
621                                  tdsmRotateQnumber(smRoot, smDeviceHandle) &0xFFFF,
622                                  oneDeviceData->phyID,
623                                  AGSA_PHY_HARD_RESET,
624                                  smLocalPhyControlCB
625                                  );
626 
627       if ( status == AGSA_RC_SUCCESS)
628       {
629         return SM_RC_SUCCESS;
630       }
631       else if (status == AGSA_RC_BUSY)
632       {
633         return SM_RC_BUSY;
634       }
635       else if (status == AGSA_RC_FAILURE)
636       {
637         return SM_RC_FAILURE;
638       }
639       else
640       {
641         SM_DBG1(("smTaskManagement: unknown status %d\n",status));
642         return SM_RC_FAILURE;
643       }
644     }
645   }
646   else
647   {
648     /* smsatsmTaskManagement() which is satTM() */
649     smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot);
650 
651     if (smIORequestBody == agNULL)
652     {
653       SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n"));
654       return SM_RC_FAILURE;
655     }
656 
657     smIOReInit(smRoot, smIORequestBody);
658     /*currentTaskTag->smData = smIORequestBody;*/
659 
660     status = smsatTaskManagement(smRoot,
661                                  smDeviceHandle,
662                                  task,
663                                  lun,
664                                  taskTag,
665                                  currentTaskTag,
666                                  smIORequestBody
667                                 );
668 
669     return status;
670   }
671   return SM_RC_SUCCESS;
672 }
673 
674 
675 
676 /********************************************************* end smapi defined APIS */
677 /* counterpart is
678    smEnqueueIO(smRoot_t       *smRoot,
679                smSatIOContext_t       *satIOContext)
680 */
681 osGLOBAL smIORequestBody_t *
682 smDequeueIO(smRoot_t          *smRoot)
683 {
684   smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
685   smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
686   smIORequestBody_t         *smIORequestBody = agNULL;
687   smList_t                  *IOListList;
688 
689   SM_DBG2(("smDequeueIO: start\n"));
690 
691   tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
692   if (SMLIST_EMPTY(&(smAllShared->freeIOList)))
693   {
694     SM_DBG1(("smDequeueIO: empty freeIOList!!!\n"));
695     tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
696     return agNULL;
697   }
698 
699   SMLIST_DEQUEUE_FROM_HEAD(&IOListList, &(smAllShared->freeIOList));
700   smIORequestBody = SMLIST_OBJECT_BASE(smIORequestBody_t, satIoBodyLink, IOListList);
701   SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink));
702   SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->mainIOList));
703   tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
704 
705   if (smIORequestBody->InUse == agTRUE)
706   {
707     SM_DBG1(("smDequeueIO: wrong. already in USE ID %d!!!!\n", smIORequestBody->id));
708   }
709   smIOReInit(smRoot, smIORequestBody);
710 
711 
712   SM_DBG2(("smDequeueIO: io ID %d!\n", smIORequestBody->id));
713 
714   /* debugging */
715   if (smIORequestBody->satIoBodyLink.flink == agNULL)
716   {
717     SM_DBG1(("smDequeueIO: io ID %d, flink is NULL!!!\n", smIORequestBody->id));
718   }
719   if (smIORequestBody->satIoBodyLink.blink == agNULL)
720   {
721     SM_DBG1(("smDequeueIO: io ID %d, blink is NULL!!!\n", smIORequestBody->id));
722   }
723 
724   return smIORequestBody;
725 }
726 
727 //start here
728 //compare with ossaSATAAbortCB()
729 //qqq1
730 osGLOBAL void
731 smsatAbort(
732            smRoot_t          *smRoot,
733            agsaRoot_t        *agRoot,
734            smSatIOContext_t  *satIOContext
735     )
736 {
737   smIORequestBody_t         *smIORequestBody = agNULL; /* abort itself */
738   smIORequestBody_t         *smToBeAbortedIORequestBody; /* io to be aborted */
739   agsaIORequest_t           *agToBeAbortedIORequest; /* io to be aborted */
740   agsaIORequest_t           *agAbortIORequest;  /* abort io itself */
741   smSatIOContext_t          *satAbortIOContext;
742   bit32                      PhysUpper32;
743   bit32                      PhysLower32;
744   bit32                      memAllocStatus;
745   void                       *osMemHandle;
746 
747 
748   SM_DBG2(("smsatAbort: start\n"));
749 
750   if (satIOContext == agNULL)
751   {
752     SM_DBG1(("smsatAbort: satIOContext is NULL, wrong!!!\n"));
753     return;
754   }
755 
756   smToBeAbortedIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
757   agToBeAbortedIORequest = (agsaIORequest_t *)&(smToBeAbortedIORequestBody->agIORequest);
758   /*
759   smIORequestBody = smDequeueIO(smRoot);
760 
761   if (smIORequestBody == agNULL)
762   {
763     SM_DBG1(("smsatAbort: empty freeIOList!!!\n"));
764     return;
765   }
766    */
767   /* allocating agIORequest for abort itself */
768   memAllocStatus = tdsmAllocMemory(
769                                    smRoot,
770                                    &osMemHandle,
771                                    (void **)&smIORequestBody,
772                                    &PhysUpper32,
773                                    &PhysLower32,
774                                    8,
775                                    sizeof(smIORequestBody_t),
776                                    agTRUE
777                                    );
778   if (memAllocStatus != tiSuccess)
779   {
780     /* let os process IO */
781     SM_DBG1(("smsatAbort: ostiAllocMemory failed...\n"));
782     return;
783   }
784 
785   if (smIORequestBody == agNULL)
786   {
787     /* let os process IO */
788     SM_DBG1(("smsatAbort: ostiAllocMemory returned NULL smIORequestBody\n"));
789     return;
790   }
791   smIOReInit(smRoot, smIORequestBody);
792 
793   smIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
794   smIORequestBody->smDevHandle = smToBeAbortedIORequestBody->smDevHandle;
795   /* initialize agIORequest */
796   satAbortIOContext = &(smIORequestBody->transport.SATA.satIOContext);
797   satAbortIOContext->smRequestBody = smIORequestBody;
798 
799   agAbortIORequest = &(smIORequestBody->agIORequest);
800   agAbortIORequest->osData = (void *) smIORequestBody;
801   agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
802 
803   /*
804    * Issue abort
805    */
806                                                                                                                                                                  saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, smaSATAAbortCB);
807 
808 
809   SM_DBG1(("satAbort: end!!!\n"));
810 
811   return;
812 }
813 
814 osGLOBAL bit32
815 smsatStartCheckPowerMode(
816                          smRoot_t                  *smRoot,
817                          smIORequest_t             *currentTaskTag,
818                          smDeviceHandle_t          *smDeviceHandle,
819                          smScsiInitiatorRequest_t  *smScsiRequest,
820                          smSatIOContext_t            *satIOContext
821                         )
822 {
823   smSatInternalIo_t           *satIntIo = agNULL;
824   smDeviceData_t            *oneDeviceData = agNULL;
825   smSatIOContext_t            *satNewIOContext;
826   bit32                     status;
827 
828   SM_DBG1(("smsatStartCheckPowerMode: start\n"));
829 
830   oneDeviceData = satIOContext->pSatDevData;
831 
832   SM_DBG6(("smsatStartCheckPowerMode: before alloc\n"));
833 
834   /* allocate any fis for seting SRT bit in device control */
835   satIntIo = smsatAllocIntIoResource( smRoot,
836                                       currentTaskTag,
837                                       oneDeviceData,
838                                       0,
839                                       satIntIo);
840 
841   SM_DBG6(("smsatStartCheckPowerMode: before after\n"));
842 
843   if (satIntIo == agNULL)
844   {
845     SM_DBG1(("smsatStartCheckPowerMode: can't alloacate!!!\n"));
846     /*smEnqueueIO(smRoot, satIOContext);*/
847     return SM_RC_FAILURE;
848   }
849 
850   satNewIOContext = smsatPrepareNewIO(satIntIo,
851                                       currentTaskTag,
852                                       oneDeviceData,
853                                       agNULL,
854                                       satIOContext);
855 
856   SM_DBG6(("smsatStartCheckPowerMode: TD satIOContext %p \n", satIOContext));
857   SM_DBG6(("smsatStartCheckPowerMode: SM satNewIOContext %p \n", satNewIOContext));
858   SM_DBG6(("smsatStartCheckPowerMode: TD smScsiXchg %p \n", satIOContext->smScsiXchg));
859   SM_DBG6(("smsatStartCheckPowerMode: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg));
860 
861 
862 
863   SM_DBG2(("smsatStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
864 
865   status = smsatCheckPowerMode(smRoot,
866                                &satIntIo->satIntSmIORequest, /* New smIORequest */
867                                smDeviceHandle,
868                                satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *smScsiRequest, */
869                                satNewIOContext);
870 
871   if (status != SM_RC_SUCCESS)
872   {
873     SM_DBG1(("smsatStartCheckPowerMode: failed in sending!!!\n"));
874 
875     smsatFreeIntIoResource( smRoot,
876                             oneDeviceData,
877                             satIntIo);
878 
879     /*smEnqueueIO(smRoot, satIOContext);*/
880 
881     return SM_RC_FAILURE;
882   }
883 
884 
885   SM_DBG6(("smsatStartCheckPowerMode: end\n"));
886 
887   return status;
888 }
889 
890 osGLOBAL bit32
891 smsatStartResetDevice(
892                        smRoot_t                  *smRoot,
893                        smIORequest_t             *currentTaskTag,
894                        smDeviceHandle_t          *smDeviceHandle,
895                        smScsiInitiatorRequest_t  *smScsiRequest,
896                        smSatIOContext_t            *satIOContext
897                      )
898 {
899   smSatInternalIo_t           *satIntIo = agNULL;
900   smDeviceData_t            *oneDeviceData = agNULL;
901   smSatIOContext_t            *satNewIOContext;
902   bit32                     status;
903 
904   SM_DBG1(("smsatStartResetDevice: start\n"));
905 
906   oneDeviceData = satIOContext->pSatDevData;
907 
908   SM_DBG6(("smsatStartResetDevice: before alloc\n"));
909 
910   /* allocate any fis for seting SRT bit in device control */
911   satIntIo = smsatAllocIntIoResource( smRoot,
912                                       currentTaskTag,
913                                       oneDeviceData,
914                                       0,
915                                       satIntIo);
916 
917   SM_DBG6(("smsatStartResetDevice: before after\n"));
918 
919   if (satIntIo == agNULL)
920   {
921     SM_DBG1(("smsatStartResetDevice: can't alloacate!!!\n"));
922     /*smEnqueueIO(smRoot, satIOContext);*/
923     return SM_RC_FAILURE;
924   }
925 
926   satNewIOContext = smsatPrepareNewIO(satIntIo,
927                                       currentTaskTag,
928                                       oneDeviceData,
929                                       agNULL,
930                                       satIOContext);
931 
932   SM_DBG6(("smsatStartResetDevice: TD satIOContext %p \n", satIOContext));
933   SM_DBG6(("smsatStartResetDevice: SM satNewIOContext %p \n", satNewIOContext));
934   SM_DBG6(("smsatStartResetDevice: TD smScsiXchg %p \n", satIOContext->smScsiXchg));
935   SM_DBG6(("smsatStartResetDevice: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg));
936 
937 
938 
939   SM_DBG6(("smsatStartResetDevice: satNewIOContext %p \n", satNewIOContext));
940 
941   if (oneDeviceData->satDeviceType == SATA_ATAPI_DEVICE)
942   {
943       /*if ATAPI device, send DEVICE RESET command to ATAPI device*/
944       status = smsatDeviceReset(smRoot,
945                             &satIntIo->satIntSmIORequest, /* New smIORequest */
946                             smDeviceHandle,
947                             satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */
948                             satNewIOContext);
949   }
950   else
951   {
952       status = smsatResetDevice(smRoot,
953                             &satIntIo->satIntSmIORequest, /* New smIORequest */
954                             smDeviceHandle,
955                             satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */
956                             satNewIOContext);
957    }
958 
959   if (status != SM_RC_SUCCESS)
960   {
961     SM_DBG1(("smsatStartResetDevice: failed in sending!!!\n"));
962 
963     smsatFreeIntIoResource( smRoot,
964                             oneDeviceData,
965                             satIntIo);
966 
967     /*smEnqueueIO(smRoot, satIOContext);*/
968 
969     return SM_RC_FAILURE;
970   }
971 
972 
973   SM_DBG6(("smsatStartResetDevice: end\n"));
974 
975   return status;
976 }
977 
978 osGLOBAL bit32
979 smsatTmAbortTask(
980                   smRoot_t                  *smRoot,
981                   smIORequest_t             *currentTaskTag, /* task management */
982                   smDeviceHandle_t          *smDeviceHandle,
983                   smScsiInitiatorRequest_t  *smScsiRequest, /* NULL */
984                   smSatIOContext_t            *satIOContext, /* task management */
985                   smIORequest_t             *taskTag) /* io to be aborted */
986 {
987   smDeviceData_t          *oneDeviceData = agNULL;
988   smSatIOContext_t        *satTempIOContext = agNULL;
989   smList_t                *elementHdr;
990   bit32                   found = agFALSE;
991   smIORequestBody_t       *smIORequestBody = agNULL;
992   smIORequest_t           *smIOReq = agNULL;
993   bit32                   status;
994 
995   SM_DBG1(("smsatTmAbortTask: start\n"));
996 
997   oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
998 
999   /*
1000    * Check that the only pending I/O matches taskTag. If not return tiError.
1001    */
1002   tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
1003 
1004   elementHdr = oneDeviceData->satIoLinkList.flink;
1005 
1006   while (elementHdr != &oneDeviceData->satIoLinkList)
1007   {
1008     satTempIOContext = SMLIST_OBJECT_BASE( smSatIOContext_t,
1009                                            satIoContextLink,
1010                                            elementHdr );
1011 
1012     if ( satTempIOContext != agNULL)
1013     {
1014       smIORequestBody = (smIORequestBody_t *) satTempIOContext->smRequestBody;
1015       smIOReq = smIORequestBody->smIORequest;
1016     }
1017 
1018     elementHdr = elementHdr->flink;   /* for the next while loop  */
1019 
1020     /*
1021      * Check if the tag matches
1022      */
1023     if ( smIOReq == taskTag)
1024     {
1025       found = agTRUE;
1026       satIOContext->satToBeAbortedIOContext = satTempIOContext;
1027       SM_DBG1(("smsatTmAbortTask: found matching tag.\n"));
1028 
1029       break;
1030 
1031     } /* if matching tag */
1032 
1033   } /* while loop */
1034 
1035   tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
1036 
1037   if (found == agFALSE )
1038   {
1039     SM_DBG1(("smsatTmAbortTask: *** REJECT *** no match!!!\n"));
1040 
1041     /*smEnqueueIO(smRoot, satIOContext);*/
1042     /* clean up TD layer's smIORequestBody */
1043     if (smIORequestBody)
1044     {
1045       if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL)
1046       {
1047         tdsmFreeMemory(
1048                      smRoot,
1049                      smIORequestBody->IOType.InitiatorTMIO.osMemHandle,
1050                      sizeof(smIORequestBody_t)
1051                      );
1052       }
1053     }
1054     else
1055     {
1056       SM_DBG1(("smsatTmAbortTask: smIORequestBody is NULL!!!\n"));
1057     }
1058 
1059     return SM_RC_FAILURE;
1060   }
1061 
1062   if (satTempIOContext == agNULL)
1063   {
1064     SM_DBG1(("smsatTmAbortTask: satTempIOContext is NULL!!!\n"));
1065     return SM_RC_FAILURE;
1066   }
1067 
1068   /*
1069    * Save smIORequest, will be returned at device reset completion to return
1070    * the TM completion.
1071    */
1072   oneDeviceData->satTmTaskTag = currentTaskTag;
1073 
1074   /*
1075    * Set flag to indicate device in recovery mode.
1076    */
1077   oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
1078 
1079 
1080   /*
1081    * Issue SATA device reset or check power mode.. Set flag to to automatically abort
1082    * at the completion of SATA device reset.
1083    * SAT r09 p25
1084    */
1085   oneDeviceData->satAbortAfterReset = agTRUE;
1086 
1087   if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
1088        (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
1089       )
1090   {
1091     SM_DBG1(("smsatTmAbortTask: calling satStartCheckPowerMode!!!\n"));
1092     /* send check power mode */
1093     status = smsatStartCheckPowerMode(
1094                                        smRoot,
1095                                        currentTaskTag, /* currentTaskTag */
1096                                        smDeviceHandle,
1097                                        smScsiRequest, /* NULL */
1098                                        satIOContext
1099                                      );
1100   }
1101   else
1102   {
1103     SM_DBG1(("smsatTmAbortTask: calling satStartResetDevice!!!\n"));
1104     /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */
1105     status = smsatStartResetDevice(
1106                                     smRoot,
1107                                     currentTaskTag, /* currentTaskTag */
1108                                     smDeviceHandle,
1109                                     smScsiRequest, /* NULL */
1110                                     satIOContext
1111                                   );
1112   }
1113   return status;
1114 }
1115 
1116 /* satTM() */
1117 osGLOBAL bit32
1118 smsatTaskManagement(
1119                     smRoot_t          *smRoot,
1120                     smDeviceHandle_t  *smDeviceHandle,
1121                     bit32             task,
1122                     smLUN_t           *lun,
1123                     smIORequest_t     *taskTag, /* io to be aborted */
1124                     smIORequest_t     *currentTaskTag, /* task management */
1125                     smIORequestBody_t *smIORequestBody
1126        )
1127 {
1128   smSatIOContext_t              *satIOContext = agNULL;
1129   smDeviceData_t              *oneDeviceData = agNULL;
1130   bit32                       status;
1131 
1132   SM_DBG1(("smsatTaskManagement: start\n"));
1133   oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
1134 
1135   satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
1136 
1137   satIOContext->pSatDevData   = oneDeviceData;
1138   satIOContext->pFis          =
1139     &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
1140 
1141 
1142   satIOContext->smRequestBody = smIORequestBody;
1143   satIOContext->psmDeviceHandle = smDeviceHandle;
1144   satIOContext->satIntIoContext  = agNULL;
1145   satIOContext->satOrgIOContext  = agNULL;
1146 
1147   /* followings are used only for internal IO */
1148   satIOContext->currentLBA = 0;
1149   satIOContext->OrgTL = 0;
1150 
1151   /* saving task in satIOContext */
1152   satIOContext->TMF = task;
1153 
1154   satIOContext->satToBeAbortedIOContext = agNULL;
1155 
1156   if (task == AG_ABORT_TASK)
1157   {
1158     status = smsatTmAbortTask( smRoot,
1159                                currentTaskTag,
1160                                smDeviceHandle,
1161                                agNULL,
1162                                satIOContext,
1163                                taskTag);
1164 
1165     return status;
1166   }
1167   else
1168   {
1169     SM_DBG1(("smsatTaskManagement: UNSUPPORTED TM task=0x%x!!!\n", task ));
1170 
1171     /*smEnqueueIO(smRoot, satIOContext);*/
1172 
1173     return SM_RC_FAILURE;
1174   }
1175 
1176   return SM_RC_SUCCESS;
1177 }
1178 
1179 
1180 osGLOBAL bit32
1181 smPhyControlSend(
1182                   smRoot_t             *smRoot,
1183                   smDeviceData_t       *oneDeviceData, /* sata disk itself */
1184                   bit8                 phyOp,
1185                   smIORequest_t        *CurrentTaskTag,
1186                   bit32                queueNumber
1187                 )
1188 {
1189   smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1190   smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1191   agsaRoot_t                *agRoot = smAllShared->agRoot;
1192   agsaDevHandle_t           *agExpDevHandle;
1193   smpReqPhyControl_t        smpPhyControlReq;
1194   void                      *osMemHandle;
1195   bit32                     PhysUpper32;
1196   bit32                     PhysLower32;
1197   bit32                     memAllocStatus;
1198   bit32                     expectedRspLen = 0;
1199   smSMPRequestBody_t        *smSMPRequestBody;
1200   agsaSASRequestBody_t      *agSASRequestBody;
1201   agsaSMPFrame_t            *agSMPFrame;
1202   agsaIORequest_t           *agIORequest;
1203 //  agsaDevHandle_t           *agDevHandle;
1204   smSMPFrameHeader_t        smSMPFrameHeader;
1205   bit32                     status;
1206   bit8                      *pSmpBody; /* smp payload itself w/o first 4 bytes(header) */
1207   bit32                     smpBodySize; /* smp payload size w/o first 4 bytes(header) */
1208   bit32                     agRequestType;
1209 
1210   SM_DBG2(("smPhyControlSend: start\n"));
1211 
1212   agExpDevHandle = oneDeviceData->agExpDevHandle;
1213 
1214   if (agExpDevHandle == agNULL)
1215   {
1216     SM_DBG1(("smPhyControlSend: agExpDevHandle is NULL!!!\n"));
1217     return SM_RC_FAILURE;
1218   }
1219 
1220   SM_DBG5(("smPhyControlSend: phyID %d\n", oneDeviceData->phyID));
1221 
1222   sm_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t));
1223 
1224   /* fill in SMP payload */
1225   smpPhyControlReq.phyIdentifier = (bit8)oneDeviceData->phyID;
1226   smpPhyControlReq.phyOperation = phyOp;
1227 
1228   /* allocate smp and send it */
1229   memAllocStatus = tdsmAllocMemory(
1230                                    smRoot,
1231                                    &osMemHandle,
1232                                    (void **)&smSMPRequestBody,
1233                                    &PhysUpper32,
1234                                    &PhysLower32,
1235                                    8,
1236                                    sizeof(smSMPRequestBody_t),
1237                                    agTRUE
1238                                    );
1239 
1240   if (memAllocStatus != SM_RC_SUCCESS)
1241   {
1242     SM_DBG1(("smPhyControlSend: tdsmAllocMemory failed...!!!\n"));
1243     return SM_RC_FAILURE;
1244   }
1245 
1246   if (smSMPRequestBody == agNULL)
1247   {
1248     SM_DBG1(("smPhyControlSend: tdsmAllocMemory returned NULL smSMPRequestBody!!!\n"));
1249     return SM_RC_FAILURE;
1250   }
1251 
1252   /* saves mem handle for freeing later */
1253   smSMPRequestBody->osMemHandle = osMemHandle;
1254 
1255   /* saves oneDeviceData */
1256   smSMPRequestBody->smDeviceData = oneDeviceData; /* sata disk */
1257 
1258   /* saves oneDeviceData */
1259   smSMPRequestBody->smDevHandle = oneDeviceData->smDevHandle;
1260 
1261 //  agDevHandle = oneDeviceData->agDevHandle;
1262 
1263   /* save the callback funtion */
1264   smSMPRequestBody->SMPCompletionFunc = smSMPCompleted; /* in satcb.c */
1265 
1266   /* for simulate warm target reset */
1267   smSMPRequestBody->CurrentTaskTag = CurrentTaskTag;
1268 
1269   if (CurrentTaskTag != agNULL)
1270   {
1271     CurrentTaskTag->smData = smSMPRequestBody;
1272   }
1273 
1274   /* initializes the number of SMP retries */
1275   smSMPRequestBody->retries = 0;
1276 
1277 #ifdef TD_INTERNAL_DEBUG  /* debugging */
1278   SM_DBG4(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody));
1279   SM_DBG4(("smPhyControlSend: callback fn %p\n", smSMPRequestBody->SMPCompletionFunc));
1280 #endif
1281 
1282   agIORequest = &(smSMPRequestBody->agIORequest);
1283   agIORequest->osData = (void *) smSMPRequestBody;
1284   agIORequest->sdkData = agNULL; /* SALL takes care of this */
1285 
1286 
1287   agSASRequestBody = &(smSMPRequestBody->agSASRequestBody);
1288   agSMPFrame = &(agSASRequestBody->smpFrame);
1289 
1290   SM_DBG3(("smPhyControlSend: agIORequest %p\n", agIORequest));
1291   SM_DBG3(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody));
1292 
1293   expectedRspLen = 4;
1294 
1295   pSmpBody = (bit8 *)&smpPhyControlReq;
1296   smpBodySize = sizeof(smpReqPhyControl_t);
1297   agRequestType = AGSA_SMP_INIT_REQ;
1298 
1299   if (SMIsSPC(agRoot))
1300   {
1301     if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */
1302     {
1303       SM_DBG3(("smPhyControlSend: DIRECT smp payload\n"));
1304       sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t));
1305       sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
1306 
1307       /* SMP header */
1308       smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
1309       smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL;
1310       smSMPFrameHeader.smpFunctionResult = 0;
1311       smSMPFrameHeader.smpReserved = 0;
1312 
1313       sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4);
1314       sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
1315 
1316       /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
1317       agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload;
1318       agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
1319       /* to specify DIRECT SMP response */
1320       agSMPFrame->inFrameLen = 0;
1321 
1322       /* temporary solution for T2D Combo*/
1323 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
1324       /* force smp repsonse to be direct */
1325       agSMPFrame->expectedRespLen = 0;
1326 #else
1327       agSMPFrame->expectedRespLen = expectedRspLen;
1328 #endif
1329   //    smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
1330   //    smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen);
1331   //    smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t));
1332     }
1333     else
1334     {
1335       SM_DBG1(("smPhyControlSend: INDIRECT smp payload, not supported!!!\n"));
1336       tdsmFreeMemory(
1337                      smRoot,
1338                      osMemHandle,
1339                      sizeof(smSMPRequestBody_t)
1340                      );
1341 
1342       return SM_RC_FAILURE;
1343     }
1344   }
1345   else /* SPCv controller */
1346   {
1347     /* only direct mode for both request and response */
1348     SM_DBG3(("smPhyControlSend: DIRECT smp payload\n"));
1349     agSMPFrame->flag = 0;
1350     sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t));
1351     sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
1352 
1353     /* SMP header */
1354     smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
1355     smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL;
1356     smSMPFrameHeader.smpFunctionResult = 0;
1357     smSMPFrameHeader.smpReserved = 0;
1358 
1359     sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4);
1360     sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
1361 
1362     /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
1363     agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload;
1364     agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
1365     /* to specify DIRECT SMP response */
1366     agSMPFrame->inFrameLen = 0;
1367 
1368     /* temporary solution for T2D Combo*/
1369 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
1370     /* force smp repsonse to be direct */
1371     agSMPFrame->expectedRespLen = 0;
1372 #else
1373     agSMPFrame->expectedRespLen = expectedRspLen;
1374 #endif
1375 //    smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
1376 //    smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen);
1377 //    smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t));
1378   }
1379 
1380   status = saSMPStart(
1381                       agRoot,
1382                       agIORequest,
1383                       queueNumber,
1384                       agExpDevHandle,
1385                       agRequestType,
1386                       agSASRequestBody,
1387                       &smSMPCompletedCB
1388                       );
1389 
1390   if (status == AGSA_RC_SUCCESS)
1391   {
1392     return SM_RC_SUCCESS;
1393   }
1394   else if (status == AGSA_RC_BUSY)
1395   {
1396     SM_DBG1(("smPhyControlSend: saSMPStart is busy!!!\n"));
1397     tdsmFreeMemory(
1398                    smRoot,
1399                    osMemHandle,
1400                    sizeof(smSMPRequestBody_t)
1401                    );
1402 
1403     return SM_RC_BUSY;
1404   }
1405   else /* AGSA_RC_FAILURE */
1406   {
1407     SM_DBG1(("smPhyControlSend: saSMPStart is failed. status %d!!!\n", status));
1408     tdsmFreeMemory(
1409                    smRoot,
1410                    osMemHandle,
1411                    sizeof(smSMPRequestBody_t)
1412                    );
1413 
1414     return SM_RC_FAILURE;
1415   }
1416 }
1417 
1418 /* free IO which are internally completed within SM
1419    counterpart is
1420    osGLOBAL smIORequestBody_t *
1421    smDequeueIO(smRoot_t          *smRoot)
1422 */
1423 osGLOBAL void
1424 smEnqueueIO(
1425              smRoot_t               *smRoot,
1426              smSatIOContext_t         *satIOContext
1427       )
1428 {
1429   smIntRoot_t          *smIntRoot = agNULL;
1430   smIntContext_t       *smAllShared = agNULL;
1431   smIORequestBody_t    *smIORequestBody;
1432 
1433   SM_DBG3(("smEnqueueIO: start\n"));
1434   smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
1435   smIntRoot       = (smIntRoot_t *)smRoot->smData;
1436   smAllShared     = (smIntContext_t *)&smIntRoot->smAllShared;
1437 
1438   /* enque back to smAllShared->freeIOList */
1439   if (satIOContext->satIntIoContext == agNULL)
1440   {
1441     SM_DBG2(("smEnqueueIO: external command!!!, io ID %d!!!\n", smIORequestBody->id));
1442     /* debugging only */
1443     if (smIORequestBody->satIoBodyLink.flink == agNULL)
1444     {
1445       SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id));
1446     }
1447     if (smIORequestBody->satIoBodyLink.blink == agNULL)
1448     {
1449       SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id));
1450     }
1451   }
1452   else
1453   {
1454     SM_DBG2(("smEnqueueIO: internal command!!!, io ID %d!!!\n", smIORequestBody->id));
1455     /* debugging only */
1456     if (smIORequestBody->satIoBodyLink.flink == agNULL)
1457     {
1458       SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id));
1459     }
1460     if (smIORequestBody->satIoBodyLink.blink == agNULL)
1461     {
1462       SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id));
1463     }
1464   }
1465 
1466   if (smIORequestBody->smIORequest == agNULL)
1467   {
1468     SM_DBG1(("smEnqueueIO: smIORequest is NULL, io ID %d!!!\n", smIORequestBody->id));
1469   }
1470 
1471   if (smIORequestBody->InUse == agTRUE)
1472   {
1473     smIORequestBody->InUse = agFALSE;
1474     tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
1475     SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink));
1476     SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->freeIOList));
1477     tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
1478   }
1479   else
1480   {
1481     SM_DBG2(("smEnqueueIO: check!!!, io ID %d!!!\n", smIORequestBody->id));
1482   }
1483 
1484 
1485   return;
1486 }
1487 
1488 FORCEINLINE void
1489 smsatFreeIntIoResource(
1490        smRoot_t              *smRoot,
1491        smDeviceData_t        *satDevData,
1492        smSatInternalIo_t     *satIntIo
1493        )
1494 {
1495   SM_DBG3(("smsatFreeIntIoResource: start\n"));
1496 
1497   if (satIntIo == agNULL)
1498   {
1499     SM_DBG2(("smsatFreeIntIoResource: allowed call\n"));
1500     return;
1501   }
1502 
1503   /* sets the original smIOrequest to agNULL for internally generated ATA cmnd */
1504   satIntIo->satOrgSmIORequest = agNULL;
1505 
1506   /*
1507    * Free DMA memory if previosly alocated
1508    */
1509   if (satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength != 0)
1510   {
1511     SM_DBG3(("smsatFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
1512     SM_DBG3(("smsatFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
1513 
1514     tdsmFreeMemory( smRoot,
1515                     satIntIo->satIntDmaMem.osHandle,
1516                     satIntIo->satIntDmaMem.totalLength);
1517     satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0;
1518   }
1519 
1520   if (satIntIo->satIntReqBodyMem.totalLength != 0)
1521   {
1522     SM_DBG3(("smsatFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
1523     /*
1524      * Free mem allocated for Req body
1525      */
1526     tdsmFreeMemory( smRoot,
1527                     satIntIo->satIntReqBodyMem.osHandle,
1528                     satIntIo->satIntReqBodyMem.totalLength);
1529 
1530     satIntIo->satIntReqBodyMem.totalLength = 0;
1531   }
1532 
1533   SM_DBG3(("smsatFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1534   /*
1535    * Return satIntIo to the free list
1536    */
1537   tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1538   SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
1539   SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
1540   tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1541 
1542   return;
1543 }
1544 //start here
1545 osGLOBAL smSatInternalIo_t *
1546 smsatAllocIntIoResource(
1547                         smRoot_t              *smRoot,
1548                         smIORequest_t         *smIORequest,
1549                         smDeviceData_t        *satDevData,
1550                         bit32                 dmaAllocLength,
1551                         smSatInternalIo_t     *satIntIo)
1552 {
1553   smList_t          *smList = agNULL;
1554   bit32             memAllocStatus;
1555 
1556   SM_DBG3(("smsatAllocIntIoResource: start\n"));
1557   SM_DBG3(("smsatAllocIntIoResource: satIntIo %p\n", satIntIo));
1558   if (satDevData == agNULL)
1559   {
1560     SM_DBG1(("smsatAllocIntIoResource: ***** ASSERT satDevData is null!!!\n"));
1561     return agNULL;
1562   }
1563 
1564   tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1565   if (!SMLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
1566   {
1567     SMLIST_DEQUEUE_FROM_HEAD(&smList, &(satDevData->satFreeIntIoLinkList));
1568   }
1569   else
1570   {
1571     tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1572     SM_DBG1(("smsatAllocIntIoResource() no more internal free link!!!\n"));
1573     return agNULL;
1574   }
1575 
1576   if (smList == agNULL)
1577   {
1578     tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1579     SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc satIntIo!!!\n"));
1580     return agNULL;
1581   }
1582 
1583   satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList);
1584   SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1585 
1586   /* Put in active list */
1587   SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
1588   SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
1589   tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1590 
1591 #ifdef REMOVED
1592   /* Put in active list */
1593   tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1594   SMLIST_DEQUEUE_THIS (smList);
1595   SMLIST_ENQUEUE_AT_TAIL (smList, &(satDevData->satActiveIntIoLinkList));
1596   tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1597 
1598   satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList);
1599   SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1600 #endif
1601 
1602   /*
1603     typedef struct
1604     {
1605       tdList_t                    satIntIoLink;
1606       smIORequest_t               satIntSmIORequest;
1607       void                        *satIntRequestBody;
1608       smScsiInitiatorRequest_t    satIntSmScsiXchg;
1609       smMem_t                     satIntDmaMem;
1610       smMem_t                     satIntReqBodyMem;
1611       bit32                       satIntFlag;
1612     } smSatInternalIo_t;
1613   */
1614 
1615   /*
1616    * Allocate mem for Request Body
1617    */
1618   satIntIo->satIntReqBodyMem.totalLength = sizeof(smIORequestBody_t);
1619 
1620   memAllocStatus = tdsmAllocMemory( smRoot,
1621                                     &satIntIo->satIntReqBodyMem.osHandle,
1622                                     (void **)&satIntIo->satIntRequestBody,
1623                                     &satIntIo->satIntReqBodyMem.physAddrUpper,
1624                                     &satIntIo->satIntReqBodyMem.physAddrLower,
1625                                     8,
1626                                     satIntIo->satIntReqBodyMem.totalLength,
1627                                     agTRUE );
1628 
1629   if (memAllocStatus != SM_RC_SUCCESS)
1630   {
1631     SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for Req Body!!!\n"));
1632     /*
1633      * Return satIntIo to the free list
1634      */
1635     tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1636     SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
1637     SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
1638     tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1639 
1640     return agNULL;
1641   }
1642 
1643   /*
1644    *   Allocate DMA memory if required
1645    */
1646   if (dmaAllocLength != 0)
1647   {
1648     satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
1649 
1650     memAllocStatus = tdsmAllocMemory( smRoot,
1651                                       &satIntIo->satIntDmaMem.osHandle,
1652                                       (void **)&satIntIo->satIntDmaMem.virtPtr,
1653                                       &satIntIo->satIntDmaMem.physAddrUpper,
1654                                       &satIntIo->satIntDmaMem.physAddrLower,
1655                                       8,
1656                                       satIntIo->satIntDmaMem.totalLength,
1657                                       agFALSE);
1658     SM_DBG3(("smsatAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
1659     SM_DBG3(("smsatAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
1660 
1661     if (memAllocStatus != SM_RC_SUCCESS)
1662     {
1663       SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for DMA mem!!!\n"));
1664       /*
1665        * Return satIntIo to the free list
1666        */
1667       tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1668       SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
1669       SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
1670       tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1671 
1672       /*
1673        * Free mem allocated for Req body
1674        */
1675       tdsmFreeMemory( smRoot,
1676                       satIntIo->satIntReqBodyMem.osHandle,
1677                       satIntIo->satIntReqBodyMem.totalLength);
1678 
1679       return agNULL;
1680     }
1681   }
1682 
1683   /*
1684     typedef struct
1685     {
1686       smList_t                    satIntIoLink;
1687       smIORequest_t               satIntSmIORequest;
1688       void                        *satIntRequestBody;
1689       smScsiInitiatorRequest_t    satIntSmScsiXchg;
1690       smMem_t                     satIntDmaMem;
1691       smMem_t                     satIntReqBodyMem;
1692       bit32                       satIntFlag;
1693     } smSatInternalIo_t;
1694   */
1695 
1696   /*
1697    * Initialize satIntSmIORequest field
1698    */
1699   satIntIo->satIntSmIORequest.tdData = agNULL;  /* Not used for internal SAT I/O */
1700   satIntIo->satIntSmIORequest.smData = satIntIo->satIntRequestBody;
1701 
1702   /*
1703    * saves the original smIOrequest
1704    */
1705   satIntIo->satOrgSmIORequest = smIORequest;
1706   /*
1707     typedef struct tiIniScsiCmnd
1708     {
1709       tiLUN_t     lun;
1710       bit32       expDataLength;
1711       bit32       taskAttribute;
1712       bit32       crn;
1713       bit8        cdb[16];
1714     } tiIniScsiCmnd_t;
1715 
1716     typedef struct tiScsiInitiatorExchange
1717     {
1718       void                *sglVirtualAddr;
1719       tiIniScsiCmnd_t     scsiCmnd;
1720       tiSgl_t             agSgl1;
1721       tiSgl_t             agSgl2;
1722       tiDataDirection_t   dataDirection;
1723     } tiScsiInitiatorRequest_t;
1724 
1725   */
1726 
1727   /*
1728    * Initialize satIntSmScsiXchg. Since the internal SAT request is NOT
1729    * originated from SCSI request, only the following fields are initialized:
1730    *  - sglVirtualAddr if DMA transfer is involved
1731    *  - agSgl1 if DMA transfer is involved
1732    *  - expDataLength in scsiCmnd since this field is read by smsataLLIOStart()
1733    */
1734   if (dmaAllocLength != 0)
1735   {
1736     satIntIo->satIntSmScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
1737 
1738     OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntSmScsiXchg.smSgl1.len, 0,
1739                      satIntIo->satIntDmaMem.totalLength);
1740     satIntIo->satIntSmScsiXchg.smSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
1741     satIntIo->satIntSmScsiXchg.smSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
1742     satIntIo->satIntSmScsiXchg.smSgl1.type  = tiSgl;
1743 
1744     satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
1745   }
1746   else
1747   {
1748     satIntIo->satIntSmScsiXchg.sglVirtualAddr = agNULL;
1749 
1750     satIntIo->satIntSmScsiXchg.smSgl1.len   = 0;
1751     satIntIo->satIntSmScsiXchg.smSgl1.lower = 0;
1752     satIntIo->satIntSmScsiXchg.smSgl1.upper = 0;
1753     satIntIo->satIntSmScsiXchg.smSgl1.type  = tiSgl;
1754 
1755     satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0;
1756   }
1757 
1758   SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len));
1759 
1760   SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper));
1761 
1762   SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower));
1763 
1764   SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type));
1765   SM_DBG5(("smsatAllocIntIoResource: return satIntIo %p\n", satIntIo));
1766   return  satIntIo;
1767 }
1768 
1769 osGLOBAL smDeviceData_t *
1770 smAddToSharedcontext(
1771                      smRoot_t                   *smRoot,
1772                      agsaDevHandle_t            *agDevHandle,
1773                      smDeviceHandle_t           *smDeviceHandle,
1774                      agsaDevHandle_t            *agExpDevHandle,
1775                      bit32                      phyID
1776                     )
1777 {
1778   smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1779   smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1780   smDeviceData_t            *oneDeviceData = agNULL;
1781   smList_t                  *DeviceListList;
1782   bit32                     new_device = agTRUE;
1783 
1784   SM_DBG2(("smAddToSharedcontext: start\n"));
1785 
1786   /* find a device's existence */
1787   DeviceListList = smAllShared->MainDeviceList.flink;
1788   while (DeviceListList != &(smAllShared->MainDeviceList))
1789   {
1790     oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList);
1791     if (oneDeviceData == agNULL)
1792     {
1793       SM_DBG1(("smAddToSharedcontext: oneDeviceData is NULL!!!\n"));
1794       return agNULL;
1795     }
1796     if (oneDeviceData->agDevHandle == agDevHandle)
1797     {
1798       SM_DBG2(("smAddToSharedcontext: did %d\n", oneDeviceData->id));
1799       new_device = agFALSE;
1800       break;
1801     }
1802     DeviceListList = DeviceListList->flink;
1803   }
1804 
1805   /* new device */
1806   if (new_device == agTRUE)
1807   {
1808     SM_DBG2(("smAddToSharedcontext: new device\n"));
1809     tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1810     if (SMLIST_EMPTY(&(smAllShared->FreeDeviceList)))
1811     {
1812       tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1813       SM_DBG1(("smAddToSharedcontext: empty DeviceData FreeLink!!!\n"));
1814       smDeviceHandle->smData = agNULL;
1815       return agNULL;
1816     }
1817 
1818     SMLIST_DEQUEUE_FROM_HEAD(&DeviceListList, &(smAllShared->FreeDeviceList));
1819     tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1820     oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, FreeLink, DeviceListList);
1821     oneDeviceData->smRoot = smRoot;
1822     oneDeviceData->agDevHandle = agDevHandle;
1823     oneDeviceData->valid = agTRUE;
1824     smDeviceHandle->smData = oneDeviceData;
1825     oneDeviceData->smDevHandle = smDeviceHandle;
1826     if (agExpDevHandle == agNULL)
1827     {
1828       oneDeviceData->directlyAttached = agTRUE;
1829     }
1830     else
1831     {
1832       oneDeviceData->directlyAttached = agFALSE;
1833     }
1834     oneDeviceData->agExpDevHandle = agExpDevHandle;
1835     oneDeviceData->phyID = phyID;
1836     oneDeviceData->satPendingIO = 0;
1837     oneDeviceData->satPendingNCQIO = 0;
1838     oneDeviceData->satPendingNONNCQIO = 0;
1839     /* add the devicedata to the portcontext */
1840     tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1841     SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->MainLink), &(smAllShared->MainDeviceList));
1842     tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1843     SM_DBG2(("smAddToSharedcontext: new case did %d\n", oneDeviceData->id));
1844   }
1845   else
1846   {
1847     SM_DBG2(("smAddToSharedcontext: old device\n"));
1848     oneDeviceData->smRoot = smRoot;
1849     oneDeviceData->agDevHandle = agDevHandle;
1850     oneDeviceData->valid = agTRUE;
1851     smDeviceHandle->smData = oneDeviceData;
1852     oneDeviceData->smDevHandle = smDeviceHandle;
1853     if (agExpDevHandle == agNULL)
1854     {
1855       oneDeviceData->directlyAttached = agTRUE;
1856     }
1857     else
1858     {
1859       oneDeviceData->directlyAttached = agFALSE;
1860     }
1861     oneDeviceData->agExpDevHandle = agExpDevHandle;
1862     oneDeviceData->phyID = phyID;
1863     oneDeviceData->satPendingIO = 0;
1864     oneDeviceData->satPendingNCQIO = 0;
1865     oneDeviceData->satPendingNONNCQIO = 0;
1866     SM_DBG2(("smAddToSharedcontext: old case did %d\n", oneDeviceData->id));
1867   }
1868 
1869   return  oneDeviceData;
1870 }
1871 
1872 osGLOBAL bit32
1873 smRemoveFromSharedcontext(
1874                           smRoot_t                      *smRoot,
1875                           agsaDevHandle_t               *agDevHandle,
1876                           smDeviceHandle_t              *smDeviceHandle
1877                          )
1878 {
1879   smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1880   smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1881   smDeviceData_t            *oneDeviceData = agNULL;
1882 
1883   SM_DBG2(("smRemoveFromSharedcontext: start\n"));
1884 
1885   //due to device all and completion
1886   //smDeviceHandle->smData = agNULL;
1887 
1888   /* find oneDeviceData from MainLink */
1889   oneDeviceData = smFindInSharedcontext(smRoot, agDevHandle);
1890 
1891   if (oneDeviceData == agNULL)
1892   {
1893     return SM_RC_FAILURE;
1894   }
1895   else
1896   {
1897     if (oneDeviceData->valid == agTRUE)
1898     {
1899       smDeviceDataReInit(smRoot, oneDeviceData);
1900       tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1901       SMLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
1902       SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(smAllShared->FreeDeviceList));
1903       tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1904       return SM_RC_SUCCESS;
1905     }
1906     else
1907     {
1908       SM_DBG1(("smRemoveFromSharedcontext: did %d bad case!!!\n", oneDeviceData->id));
1909       return SM_RC_FAILURE;
1910     }
1911   }
1912 
1913 }
1914 
1915 osGLOBAL smDeviceData_t *
1916 smFindInSharedcontext(
1917                       smRoot_t                  *smRoot,
1918                       agsaDevHandle_t           *agDevHandle
1919                       )
1920 {
1921   smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
1922   smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1923   smDeviceData_t            *oneDeviceData = agNULL;
1924   smList_t                  *DeviceListList;
1925 
1926   SM_DBG2(("smFindInSharedcontext: start\n"));
1927 
1928   tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1929   if (SMLIST_EMPTY(&(smAllShared->MainDeviceList)))
1930   {
1931     SM_DBG1(("smFindInSharedcontext: empty MainDeviceList!!!\n"));
1932     tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1933     return agNULL;
1934   }
1935   else
1936   {
1937     tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1938   }
1939 
1940   DeviceListList = smAllShared->MainDeviceList.flink;
1941   while (DeviceListList != &(smAllShared->MainDeviceList))
1942   {
1943     oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList);
1944     if (oneDeviceData == agNULL)
1945     {
1946       SM_DBG1(("smFindInSharedcontext: oneDeviceData is NULL!!!\n"));
1947       return agNULL;
1948     }
1949     if ((oneDeviceData->agDevHandle == agDevHandle) &&
1950         (oneDeviceData->valid == agTRUE)
1951        )
1952     {
1953       SM_DBG2(("smFindInSharedcontext: found, did %d\n", oneDeviceData->id));
1954       return oneDeviceData;
1955     }
1956     DeviceListList = DeviceListList->flink;
1957   }
1958   SM_DBG2(("smFindInSharedcontext: not found\n"));
1959   return agNULL;
1960 }
1961 
1962 osGLOBAL smSatIOContext_t *
1963 smsatPrepareNewIO(
1964                   smSatInternalIo_t       *satNewIntIo,
1965                   smIORequest_t           *smOrgIORequest,
1966                   smDeviceData_t          *satDevData,
1967                   smIniScsiCmnd_t         *scsiCmnd,
1968                   smSatIOContext_t        *satOrgIOContext
1969                  )
1970 {
1971   smSatIOContext_t        *satNewIOContext;
1972   smIORequestBody_t       *smNewIORequestBody;
1973 
1974   SM_DBG3(("smsatPrepareNewIO: start\n"));
1975 
1976   /* the one to be used; good 8/2/07 */
1977   satNewIntIo->satOrgSmIORequest = smOrgIORequest; /* this is already done in
1978                                                       smsatAllocIntIoResource() */
1979 
1980   smNewIORequestBody = (smIORequestBody_t *)satNewIntIo->satIntRequestBody;
1981   satNewIOContext = &(smNewIORequestBody->transport.SATA.satIOContext);
1982 
1983   satNewIOContext->pSatDevData   = satDevData;
1984   satNewIOContext->pFis          = &(smNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
1985   satNewIOContext->pScsiCmnd     = &(satNewIntIo->satIntSmScsiXchg.scsiCmnd);
1986   if (scsiCmnd != agNULL)
1987   {
1988     /* saves only CBD; not scsi command for LBA and number of blocks */
1989     sm_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
1990   }
1991   satNewIOContext->pSense        = &(smNewIORequestBody->transport.SATA.sensePayload);
1992   satNewIOContext->pSmSenseData  = &(smNewIORequestBody->transport.SATA.smSenseData);
1993   satNewIOContext->pSmSenseData->senseData = satNewIOContext->pSense;
1994   satNewIOContext->smRequestBody = satNewIntIo->satIntRequestBody;
1995   satNewIOContext->interruptContext = satNewIOContext->interruptContext;
1996   satNewIOContext->satIntIoContext  = satNewIntIo;
1997   satNewIOContext->psmDeviceHandle = satOrgIOContext->psmDeviceHandle;
1998   satNewIOContext->satOrgIOContext = satOrgIOContext;
1999   /* saves tiScsiXchg; only for writesame10() */
2000   satNewIOContext->smScsiXchg = satOrgIOContext->smScsiXchg;
2001 
2002   return satNewIOContext;
2003 }
2004 
2005 
2006 osGLOBAL void
2007 smsatSetDevInfo(
2008                  smDeviceData_t            *oneDeviceData,
2009                  agsaSATAIdentifyData_t    *SATAIdData
2010                )
2011 {
2012   SM_DBG3(("smsatSetDevInfo: start\n"));
2013 
2014   oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
2015   oneDeviceData->satFormatState = agFALSE;
2016   oneDeviceData->satDeviceFaultState = agFALSE;
2017   oneDeviceData->satTmTaskTag  = agNULL;
2018   oneDeviceData->satAbortAfterReset = agFALSE;
2019   oneDeviceData->satAbortCalled = agFALSE;
2020   oneDeviceData->satSectorDone  = 0;
2021 
2022   /* Qeueu depth, Word 75 */
2023   oneDeviceData->satNCQMaxIO = SATAIdData->queueDepth + 1;
2024   SM_DBG3(("smsatSetDevInfo: max queue depth %d\n",oneDeviceData->satNCQMaxIO));
2025 
2026   /* Support NCQ, if Word 76 bit 8 is set */
2027   if (SATAIdData->sataCapabilities & 0x100)
2028   {
2029     SM_DBG3(("smsatSetDevInfo: device supports NCQ\n"));
2030     oneDeviceData->satNCQ   = agTRUE;
2031   }
2032   else
2033   {
2034     SM_DBG3(("smsatSetDevInfo: no NCQ\n"));
2035     oneDeviceData->satNCQ = agFALSE;
2036   }
2037 
2038   /* Support 48 bit addressing, if Word 83 bit 10 and Word 86 bit 10 are set */
2039   if ((SATAIdData->commandSetSupported1 & 0x400) &&
2040       (SATAIdData->commandSetFeatureEnabled1 & 0x400) )
2041   {
2042     SM_DBG3(("smsatSetDevInfo: support 48 bit addressing\n"));
2043     oneDeviceData->sat48BitSupport = agTRUE;
2044   }
2045   else
2046   {
2047     SM_DBG3(("smsatSetDevInfo: NO 48 bit addressing\n"));
2048     oneDeviceData->sat48BitSupport = agFALSE;
2049   }
2050 
2051   /* Support SMART Self Test, word84 bit 1 */
2052   if (SATAIdData->commandSetFeatureSupportedExt & 0x02)
2053   {
2054     SM_DBG3(("smsatSetDevInfo: SMART self-test supported \n"));
2055     oneDeviceData->satSMARTSelfTest   = agTRUE;
2056   }
2057   else
2058   {
2059     SM_DBG3(("smsatSetDevInfo: no SMART self-test suppored\n"));
2060     oneDeviceData->satSMARTSelfTest = agFALSE;
2061   }
2062 
2063   /* Support SMART feature set, word82 bit 0 */
2064   if (SATAIdData->commandSetSupported & 0x01)
2065   {
2066     SM_DBG3(("smsatSetDevInfo: SMART feature set supported \n"));
2067     oneDeviceData->satSMARTFeatureSet   = agTRUE;
2068   }
2069   else
2070   {
2071     SM_DBG3(("smsatSetDevInfo: no SMART feature set suppored\n"));
2072     oneDeviceData->satSMARTFeatureSet = agFALSE;
2073   }
2074 
2075   /* Support SMART enabled, word85 bit 0 */
2076   if (SATAIdData->commandSetFeatureEnabled & 0x01)
2077   {
2078     SM_DBG3(("smsatSetDevInfo: SMART enabled \n"));
2079     oneDeviceData->satSMARTEnabled   = agTRUE;
2080   }
2081   else
2082   {
2083     SM_DBG3(("smsatSetDevInfo: no SMART enabled\n"));
2084     oneDeviceData->satSMARTEnabled = agFALSE;
2085   }
2086 
2087   oneDeviceData->satVerifyState = 0;
2088 
2089   /* Removable Media feature set support, word82 bit 2 */
2090   if (SATAIdData->commandSetSupported & 0x4)
2091   {
2092     SM_DBG3(("smsatSetDevInfo: Removable Media supported \n"));
2093     oneDeviceData->satRemovableMedia   = agTRUE;
2094   }
2095   else
2096   {
2097     SM_DBG3(("smsatSetDevInfo: no Removable Media suppored\n"));
2098     oneDeviceData->satRemovableMedia = agFALSE;
2099   }
2100 
2101   /* Removable Media feature set enabled, word 85, bit 2 */
2102   if (SATAIdData->commandSetFeatureEnabled & 0x4)
2103   {
2104     SM_DBG3(("smsatSetDevInfo: Removable Media enabled\n"));
2105     oneDeviceData->satRemovableMediaEnabled   = agTRUE;
2106   }
2107   else
2108   {
2109     SM_DBG3(("smsatSetDevInfo: no Removable Media enabled\n"));
2110     oneDeviceData->satRemovableMediaEnabled = agFALSE;
2111   }
2112 
2113   /* DMA Support, word49 bit8 */
2114   if (SATAIdData->dma_lba_iod_ios_stimer & 0x100)
2115   {
2116     SM_DBG3(("smsatSetDevInfo: DMA supported \n"));
2117     oneDeviceData->satDMASupport   = agTRUE;
2118   }
2119   else
2120   {
2121     SM_DBG3(("smsatSetDevInfo: no DMA suppored\n"));
2122     oneDeviceData->satDMASupport = agFALSE;
2123   }
2124 
2125   /* Support DMADIR, if Word 62 bit 8 is set */
2126   if (SATAIdData->word62_74[0] & 0x8000)
2127   {
2128      SM_DBG3(("satSetDevInfo: DMADIR enabled\n"));
2129      oneDeviceData->satDMADIRSupport   = agTRUE;
2130   }
2131   else
2132   {
2133      SM_DBG3(("satSetDevInfo: DMADIR disabled\n"));
2134      oneDeviceData->satDMADIRSupport   = agFALSE;
2135   }
2136 
2137   /* DMA Enabled, word88 bit0-6, bit8-14*/
2138   /* 0x7F7F = 0111 1111 0111 1111*/
2139   if (SATAIdData->ultraDMAModes & 0x7F7F)
2140   {
2141     SM_DBG3(("smsatSetDevInfo: DMA enabled \n"));
2142     oneDeviceData->satDMAEnabled   = agTRUE;
2143     if (SATAIdData->ultraDMAModes & 0x40)
2144     {
2145        oneDeviceData->satUltraDMAMode = 6;
2146     }
2147     else if (SATAIdData->ultraDMAModes & 0x20)
2148     {
2149        oneDeviceData->satUltraDMAMode = 5;
2150     }
2151     else if (SATAIdData->ultraDMAModes & 0x10)
2152     {
2153        oneDeviceData->satUltraDMAMode = 4;
2154     }
2155     else if (SATAIdData->ultraDMAModes & 0x08)
2156     {
2157        oneDeviceData->satUltraDMAMode = 3;
2158     }
2159     else if (SATAIdData->ultraDMAModes & 0x04)
2160     {
2161        oneDeviceData->satUltraDMAMode = 2;
2162     }
2163     else if (SATAIdData->ultraDMAModes & 0x01)
2164     {
2165        oneDeviceData->satUltraDMAMode = 1;
2166     }
2167   }
2168   else
2169   {
2170     SM_DBG3(("smsatSetDevInfo: no DMA enabled\n"));
2171     oneDeviceData->satDMAEnabled = agFALSE;
2172     oneDeviceData->satUltraDMAMode = 0;
2173   }
2174 
2175   /*
2176     setting MaxUserAddrSectors: max user addressable setctors
2177     word60 - 61, should be 0x 0F FF FF FF
2178   */
2179   oneDeviceData->satMaxUserAddrSectors
2180     = (SATAIdData->numOfUserAddressableSectorsHi << (8*2) )
2181     + SATAIdData->numOfUserAddressableSectorsLo;
2182   SM_DBG3(("smsatSetDevInfo: MaxUserAddrSectors 0x%x decimal %d\n", oneDeviceData->satMaxUserAddrSectors, oneDeviceData->satMaxUserAddrSectors));
2183 
2184   /* Read Look-ahead is supported */
2185   if (SATAIdData->commandSetSupported & 0x40)
2186   {
2187     SM_DBG3(("smsatSetDevInfo: Read Look-ahead is supported\n"));
2188     oneDeviceData->satReadLookAheadSupport= agTRUE;
2189   }
2190   else
2191   {
2192     SM_DBG3(("smsatSetDevInfo: Read Look-ahead is not supported\n"));
2193     oneDeviceData->satReadLookAheadSupport= agFALSE;
2194   }
2195 
2196   /* Volatile Write Cache is supported */
2197   if (SATAIdData->commandSetSupported & 0x20)
2198   {
2199     SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is supported\n"));
2200     oneDeviceData->satVolatileWriteCacheSupport = agTRUE;
2201   }
2202   else
2203   {
2204     SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is not supported\n"));
2205     oneDeviceData->satVolatileWriteCacheSupport = agFALSE;
2206   }
2207 
2208   /* write cache enabled for caching mode page SAT Table 67 p69, word85 bit5 */
2209   if (SATAIdData->commandSetFeatureEnabled & 0x20)
2210   {
2211     SM_DBG3(("smsatSetDevInfo: write cache enabled\n"));
2212     oneDeviceData->satWriteCacheEnabled   = agTRUE;
2213   }
2214   else
2215   {
2216     SM_DBG3(("smsatSetDevInfo: no write cache enabled\n"));
2217     oneDeviceData->satWriteCacheEnabled = agFALSE;
2218   }
2219 
2220   /* look ahead enabled for caching mode page SAT Table 67 p69, word85 bit6 */
2221   if (SATAIdData->commandSetFeatureEnabled & 0x40)
2222   {
2223     SM_DBG3(("smsatSetDevInfo: look ahead enabled\n"));
2224     oneDeviceData->satLookAheadEnabled   = agTRUE;
2225   }
2226   else
2227   {
2228     SM_DBG3(("smsatSetDevInfo: no look ahead enabled\n"));
2229     oneDeviceData->satLookAheadEnabled = agFALSE;
2230   }
2231 
2232   /* Support WWN, if Word 87 bit 8 is set */
2233   if (SATAIdData->commandSetFeatureDefault & 0x100)
2234   {
2235     SM_DBG3(("smsatSetDevInfo: device supports WWN\n"));
2236     oneDeviceData->satWWNSupport   = agTRUE;
2237   }
2238   else
2239   {
2240     SM_DBG3(("smsatSetDevInfo: no WWN\n"));
2241     oneDeviceData->satWWNSupport = agFALSE;
2242   }
2243 
2244   /* Support DMA Setup Auto-Activate, if Word 78 bit 2 is set */
2245   if (SATAIdData->sataFeaturesSupported & 0x4)
2246   {
2247     SM_DBG3(("smsatSetDevInfo: device supports DMA Setup Auto-Activate\n"));
2248     oneDeviceData->satDMASetupAA   = agTRUE;
2249   }
2250   else
2251   {
2252     SM_DBG3(("smsatSetDevInfo: no DMA Setup Auto-Activate\n"));
2253     oneDeviceData->satDMASetupAA = agFALSE;
2254   }
2255 
2256   /* Support NCQ Queue Management Command, if Word 77 bit 5 is set */
2257   if (SATAIdData->word77 & 0x10)
2258   {
2259     SM_DBG3(("smsatSetDevInfo: device supports NCQ Queue Management Command\n"));
2260     oneDeviceData->satNCQQMgntCmd   = agTRUE;
2261   }
2262   else
2263   {
2264     SM_DBG3(("smsatSetDevInfo: no NCQ Queue Management Command\n"));
2265     oneDeviceData->satNCQQMgntCmd = agFALSE;
2266   }
2267   return;
2268 }
2269 
2270 
2271 osGLOBAL void
2272 smsatInquiryStandard(
2273                      bit8                    *pInquiry,
2274                      agsaSATAIdentifyData_t  *pSATAIdData,
2275                      smIniScsiCmnd_t         *scsiCmnd
2276                     )
2277 {
2278   smLUN_t       *pLun;
2279   pLun          = &scsiCmnd->lun;
2280 
2281   /*
2282     Assumption: Basic Task Mangement is supported
2283     -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147
2284   */
2285  /*
2286     See SPC-4, 6.4.2, p 143
2287     and SAT revision 8, 8.1.2, p 28
2288    */
2289   SM_DBG5(("smsatInquiryStandard: start\n"));
2290 
2291   if (pInquiry == agNULL)
2292   {
2293     SM_DBG1(("smsatInquiryStandard: pInquiry is NULL, wrong\n"));
2294     return;
2295   }
2296   else
2297   {
2298     SM_DBG5(("smsatInquiryStandard: pInquiry is NOT NULL\n"));
2299   }
2300   /*
2301    * Reject all other LUN other than LUN 0.
2302    */
2303   if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
2304          pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) )
2305   {
2306     /* SAT Spec Table 8, p27, footnote 'a' */
2307     pInquiry[0] = 0x7F;
2308 
2309   }
2310   else
2311   {
2312     pInquiry[0] = 0x00;
2313   }
2314 
2315   if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
2316   {
2317     pInquiry[1] = 0x80;
2318   }
2319   else
2320   {
2321     pInquiry[1] = 0x00;
2322   }
2323   pInquiry[2] = 0x05;   /* SPC-3 */
2324   pInquiry[3] = 0x12;   /* set HiSup 1; resp data format set to 2 */
2325   pInquiry[4] = 0x1F;   /* 35 - 4 = 31; Additional length */
2326   pInquiry[5] = 0x00;
2327   /* The following two are for task management. SAT Rev8, p20 */
2328   if (pSATAIdData->sataCapabilities & 0x100)
2329   {
2330     /* NCQ supported; multiple outstanding SCSI IO are supported */
2331     pInquiry[6] = 0x00;   /* BQUE bit is not set */
2332     pInquiry[7] = 0x02;   /* CMDQUE bit is set */
2333   }
2334   else
2335   {
2336     pInquiry[6] = 0x80;   /* BQUE bit is set */
2337     pInquiry[7] = 0x00;   /* CMDQUE bit is not set */
2338   }
2339   /*
2340    * Vendor ID.
2341    */
2342   sm_strncpy((char*)&pInquiry[8],  AG_SAT_VENDOR_ID_STRING, 8);   /* 8 bytes   */
2343 
2344   /*
2345    * Product ID
2346    */
2347   /* when flipped by LL */
2348   pInquiry[16] = pSATAIdData->modelNumber[1];
2349   pInquiry[17] = pSATAIdData->modelNumber[0];
2350   pInquiry[18] = pSATAIdData->modelNumber[3];
2351   pInquiry[19] = pSATAIdData->modelNumber[2];
2352   pInquiry[20] = pSATAIdData->modelNumber[5];
2353   pInquiry[21] = pSATAIdData->modelNumber[4];
2354   pInquiry[22] = pSATAIdData->modelNumber[7];
2355   pInquiry[23] = pSATAIdData->modelNumber[6];
2356   pInquiry[24] = pSATAIdData->modelNumber[9];
2357   pInquiry[25] = pSATAIdData->modelNumber[8];
2358   pInquiry[26] = pSATAIdData->modelNumber[11];
2359   pInquiry[27] = pSATAIdData->modelNumber[10];
2360   pInquiry[28] = pSATAIdData->modelNumber[13];
2361   pInquiry[29] = pSATAIdData->modelNumber[12];
2362   pInquiry[30] = pSATAIdData->modelNumber[15];
2363   pInquiry[31] = pSATAIdData->modelNumber[14];
2364 
2365   /* when flipped */
2366   /*
2367    * Product Revision level.
2368    */
2369 
2370   /*
2371    * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
2372    * device are ASCII spaces (20h), do this translation.
2373    */
2374   if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
2375        (pSATAIdData->firmwareVersion[5] == 0x20 ) &&
2376        (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
2377        (pSATAIdData->firmwareVersion[7] == 0x20 )
2378        )
2379   {
2380     pInquiry[32] = pSATAIdData->firmwareVersion[1];
2381     pInquiry[33] = pSATAIdData->firmwareVersion[0];
2382     pInquiry[34] = pSATAIdData->firmwareVersion[3];
2383     pInquiry[35] = pSATAIdData->firmwareVersion[2];
2384   }
2385   else
2386   {
2387     pInquiry[32] = pSATAIdData->firmwareVersion[5];
2388     pInquiry[33] = pSATAIdData->firmwareVersion[4];
2389     pInquiry[34] = pSATAIdData->firmwareVersion[7];
2390     pInquiry[35] = pSATAIdData->firmwareVersion[6];
2391   }
2392 
2393 
2394 #ifdef REMOVED
2395   /*
2396    * Product ID
2397    */
2398   /* when flipped by LL */
2399   pInquiry[16] = pSATAIdData->modelNumber[0];
2400   pInquiry[17] = pSATAIdData->modelNumber[1];
2401   pInquiry[18] = pSATAIdData->modelNumber[2];
2402   pInquiry[19] = pSATAIdData->modelNumber[3];
2403   pInquiry[20] = pSATAIdData->modelNumber[4];
2404   pInquiry[21] = pSATAIdData->modelNumber[5];
2405   pInquiry[22] = pSATAIdData->modelNumber[6];
2406   pInquiry[23] = pSATAIdData->modelNumber[7];
2407   pInquiry[24] = pSATAIdData->modelNumber[8];
2408   pInquiry[25] = pSATAIdData->modelNumber[9];
2409   pInquiry[26] = pSATAIdData->modelNumber[10];
2410   pInquiry[27] = pSATAIdData->modelNumber[11];
2411   pInquiry[28] = pSATAIdData->modelNumber[12];
2412   pInquiry[29] = pSATAIdData->modelNumber[13];
2413   pInquiry[30] = pSATAIdData->modelNumber[14];
2414   pInquiry[31] = pSATAIdData->modelNumber[15];
2415 
2416   /* when flipped */
2417   /*
2418    * Product Revision level.
2419    */
2420 
2421   /*
2422    * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
2423    * device are ASCII spaces (20h), do this translation.
2424    */
2425   if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
2426        (pSATAIdData->firmwareVersion[5] == 0x20 ) &&
2427        (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
2428        (pSATAIdData->firmwareVersion[7] == 0x20 )
2429        )
2430   {
2431     pInquiry[32] = pSATAIdData->firmwareVersion[0];
2432     pInquiry[33] = pSATAIdData->firmwareVersion[1];
2433     pInquiry[34] = pSATAIdData->firmwareVersion[2];
2434     pInquiry[35] = pSATAIdData->firmwareVersion[3];
2435   }
2436   else
2437   {
2438     pInquiry[32] = pSATAIdData->firmwareVersion[4];
2439     pInquiry[33] = pSATAIdData->firmwareVersion[5];
2440     pInquiry[34] = pSATAIdData->firmwareVersion[6];
2441     pInquiry[35] = pSATAIdData->firmwareVersion[7];
2442   }
2443 #endif
2444 
2445   SM_DBG5(("smsatInquiryStandard: end\n"));
2446 
2447   return;
2448 }
2449 
2450 osGLOBAL void
2451 smsatInquiryPage0(
2452                    bit8                    *pInquiry,
2453                    agsaSATAIdentifyData_t  *pSATAIdData
2454      )
2455 {
2456   SM_DBG5(("smsatInquiryPage0: start\n"));
2457 
2458   /*
2459     See SPC-4, 7.6.9, p 345
2460     and SAT revision 8, 10.3.2, p 77
2461    */
2462   pInquiry[0] = 0x00;
2463   pInquiry[1] = 0x00; /* page code */
2464   pInquiry[2] = 0x00; /* reserved */
2465   pInquiry[3] = 8 - 3; /* last index(in this case, 6) - 3; page length */
2466 
2467   /* supported vpd page list */
2468   pInquiry[4] = 0x00; /* page 0x00 supported */
2469   pInquiry[5] = 0x80; /* page 0x80 supported */
2470   pInquiry[6] = 0x83; /* page 0x83 supported */
2471   pInquiry[7] = 0x89; /* page 0x89 supported */
2472   pInquiry[8] = 0xB1; /* page 0xB1 supported */
2473 
2474   return;
2475 }
2476 
2477 osGLOBAL void
2478 smsatInquiryPage83(
2479                     bit8                    *pInquiry,
2480                     agsaSATAIdentifyData_t  *pSATAIdData,
2481                     smDeviceData_t          *oneDeviceData
2482       )
2483 {
2484   satSimpleSATAIdentifyData_t   *pSimpleData;
2485 
2486   /*
2487    * When translating the fields, in some cases using the simple form of SATA
2488    * Identify Device Data is easier. So we define it here.
2489    * Both pSimpleData and pSATAIdData points to the same data.
2490    */
2491   pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2492 
2493   SM_DBG5(("smsatInquiryPage83: start\n"));
2494 
2495   pInquiry[0] = 0x00;
2496   pInquiry[1] = 0x83; /* page code */
2497   pInquiry[2] = 0;    /* Reserved */
2498   /*
2499    * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE
2500    * data indicating that it supports the WORLD WIDE NAME field
2501    * (i.e., words 108-111), the SATL shall include an identification descriptor
2502    * containing a logical unit name.
2503    */
2504   if ( oneDeviceData->satWWNSupport)
2505   {
2506 #ifndef PMC_FREEBSD
2507     /* Fill in SAT Rev8 Table85 */
2508     /*
2509      * Logical unit name derived from the world wide name.
2510      */
2511     pInquiry[3] = 12;         /* 15-3; page length, no addition ID descriptor assumed*/
2512 
2513     /*
2514      * Identifier descriptor
2515      */
2516     pInquiry[4]  = 0x01;                        /* Code set: binary codes */
2517     pInquiry[5]  = 0x03;                        /* Identifier type : NAA  */
2518     pInquiry[6]  = 0x00;                        /* Reserved               */
2519     pInquiry[7]  = 0x08;                        /* Identifier length      */
2520 
2521     /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
2522     pInquiry[8]  = (bit8)((pSATAIdData->namingAuthority) >> 8);
2523     pInquiry[9]  = (bit8)((pSATAIdData->namingAuthority) & 0xFF);           /* IEEE Company ID */
2524     pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8);            /* IEEE Company ID */
2525     /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
2526     pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
2527     pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8);       /* Vendor Specific ID  */
2528     pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF);     /* Vendor Specific ID  */
2529     pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8);        /* Vendor Specific ID  */
2530     pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF);      /* Vendor Specific ID  */
2531 
2532 #else
2533 
2534     /* For FreeBSD */
2535 
2536     /* Fill in SAT Rev8 Table85 */
2537     /*
2538      * Logical unit name derived from the world wide name.
2539      */
2540     pInquiry[3] = 24;         /* 35-3; page length, no addition ID descriptor assumed*/
2541    /*
2542      * Identifier descriptor
2543      */
2544     pInquiry[4]  = 0x01;                        /* Code set: binary codes; this is proto_codeset in FreeBSD */
2545     pInquiry[5]  = 0x03;                        /* Identifier type : NAA ; this is  id_type in FreeBSD*/
2546     pInquiry[6]  = 0x00;                        /* Reserved               */
2547     pInquiry[7]  = 0x08;                        /* Identifier length      */
2548 
2549     /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
2550     pInquiry[8]  = (bit8)((pSATAIdData->namingAuthority) >> 8);
2551     pInquiry[9]  = (bit8)((pSATAIdData->namingAuthority) & 0xFF);           /* IEEE Company ID */
2552     pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8);            /* IEEE Company ID */
2553     /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
2554     pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
2555     pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8);       /* Vendor Specific ID  */
2556     pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF);     /* Vendor Specific ID  */
2557     pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8);        /* Vendor Specific ID  */
2558     pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF);      /* Vendor Specific ID  */
2559 
2560     pInquiry[16]  = 0x61;                        /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */
2561     pInquiry[17]  = 0x93;                        /* Identifier type : NAA ; this is  id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h)   */
2562     pInquiry[18]  = 0x00;                        /* Reserved               */
2563     pInquiry[19]  = 0x08;                        /* Identifier length      */
2564 
2565     SM_DBG5(("smsatInquiryPage83: sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi));
2566     SM_DBG5(("smsatInquiryPage83: sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo));
2567 
2568     /* SAS address of SATA */
2569     pInquiry[20]  = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24;
2570     pInquiry[21]  = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16;
2571     pInquiry[22]  = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8;
2572     pInquiry[23]  = (oneDeviceData->sasAddressHi) & 0xFF;
2573     pInquiry[24]  = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24;
2574     pInquiry[25]  = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16;
2575     pInquiry[26]  = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8;
2576     pInquiry[27]  = (oneDeviceData->sasAddressLo) & 0xFF;
2577 #endif
2578   }
2579   else
2580   {
2581 #ifndef PMC_FREEBSD
2582     /* Fill in SAT Rev8 Table86 */
2583     /*
2584      * Logical unit name derived from the model number and serial number.
2585      */
2586     pInquiry[3] = 72;    /* 75 - 3; page length */
2587 
2588     /*
2589      * Identifier descriptor
2590      */
2591     pInquiry[4] = 0x02;             /* Code set: ASCII codes */
2592     pInquiry[5] = 0x01;             /* Identifier type : T10 vendor ID based */
2593     pInquiry[6] = 0x00;             /* Reserved */
2594     pInquiry[7] = 0x44;               /* 0x44, 68 Identifier length */
2595 
2596     /* Byte 8 to 15 is the vendor id string 'ATA     '. */
2597     sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
2598 
2599 
2600         /*
2601      * Byte 16 to 75 is vendor specific id
2602      */
2603     pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
2604     pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
2605     pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
2606     pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
2607     pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
2608     pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
2609     pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
2610     pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
2611     pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
2612     pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
2613     pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
2614     pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
2615     pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
2616     pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
2617     pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
2618     pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
2619     pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
2620     pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
2621     pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
2622     pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
2623     pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
2624     pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
2625     pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
2626     pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
2627     pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
2628     pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
2629     pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
2630     pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
2631     pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
2632     pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
2633     pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
2634     pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
2635     pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
2636     pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
2637     pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
2638     pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
2639     pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
2640     pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
2641     pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
2642     pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
2643 
2644     pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
2645     pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
2646     pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
2647     pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
2648     pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
2649     pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
2650     pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
2651     pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
2652     pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
2653     pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
2654     pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
2655     pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
2656     pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
2657     pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
2658     pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
2659     pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
2660     pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
2661     pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
2662     pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
2663     pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
2664 #else
2665     /* for the FreeBSD */
2666     /* Fill in SAT Rev8 Table86 */
2667     /*
2668      * Logical unit name derived from the model number and serial number.
2669      */
2670     pInquiry[3] = 84;    /* 87 - 3; page length */
2671 
2672     /*
2673      * Identifier descriptor
2674      */
2675     pInquiry[4] = 0x02;             /* Code set: ASCII codes */
2676     pInquiry[5] = 0x01;             /* Identifier type : T10 vendor ID based */
2677     pInquiry[6] = 0x00;             /* Reserved */
2678     pInquiry[7] = 0x44;               /* 0x44, 68 Identifier length */
2679 
2680     /* Byte 8 to 15 is the vendor id string 'ATA     '. */
2681     sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
2682 
2683 
2684         /*
2685      * Byte 16 to 75 is vendor specific id
2686      */
2687     pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
2688     pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
2689     pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
2690     pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
2691     pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
2692     pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
2693     pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
2694     pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
2695     pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
2696     pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
2697     pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
2698     pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
2699     pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
2700     pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
2701     pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
2702     pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
2703     pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
2704     pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
2705     pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
2706     pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
2707     pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
2708     pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
2709     pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
2710     pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
2711     pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
2712     pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
2713     pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
2714     pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
2715     pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
2716     pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
2717     pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
2718     pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
2719     pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
2720     pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
2721     pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
2722     pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
2723     pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
2724     pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
2725     pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
2726     pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
2727 
2728     pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
2729     pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
2730     pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
2731     pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
2732     pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
2733     pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
2734     pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
2735     pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
2736     pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
2737     pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
2738     pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
2739     pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
2740     pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
2741     pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
2742     pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
2743     pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
2744     pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
2745     pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
2746     pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
2747     pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
2748 
2749     pInquiry[76]  = 0x61;                        /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */
2750     pInquiry[77]  = 0x93;                        /* Identifier type : NAA ; this is  id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h)   */
2751     pInquiry[78]  = 0x00;                        /* Reserved               */
2752     pInquiry[79]  = 0x08;                        /* Identifier length      */
2753 
2754     SM_DBG5(("smsatInquiryPage83: NO WWN sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi));
2755     SM_DBG5(("smsatInquiryPage83: No WWN sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo));
2756 
2757     /* SAS address of SATA */
2758     pInquiry[80]  = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24;
2759     pInquiry[81]  = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16;
2760     pInquiry[82]  = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8;
2761     pInquiry[83]  = (oneDeviceData->sasAddressHi) & 0xFF;
2762     pInquiry[84]  = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24;
2763     pInquiry[85]  = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16;
2764     pInquiry[86]  = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8;
2765     pInquiry[87]  = (oneDeviceData->sasAddressLo) & 0xFF;
2766 
2767 #endif
2768   }
2769 
2770   return;
2771 }
2772 
2773 osGLOBAL void
2774 smsatInquiryPage89(
2775                     bit8                    *pInquiry,
2776                     agsaSATAIdentifyData_t  *pSATAIdData,
2777                     smDeviceData_t          *oneDeviceData,
2778                     bit32                   len
2779       )
2780 {
2781   /*
2782     SAT revision 8, 10.3.5, p 83
2783    */
2784   satSimpleSATAIdentifyData_t   *pSimpleData;
2785 
2786   /*
2787    * When translating the fields, in some cases using the simple form of SATA
2788    * Identify Device Data is easier. So we define it here.
2789    * Both pSimpleData and pSATAIdData points to the same data.
2790    */
2791   pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2792 
2793   SM_DBG5(("smsatInquiryPage89: start\n"));
2794 
2795   pInquiry[0] = 0x00;   /* Peripheral Qualifier and Peripheral Device Type */
2796   pInquiry[1] = 0x89;   /* page code */
2797 
2798   /* Page length 0x238 */
2799   pInquiry[2] = 0x02;
2800   pInquiry[3] = 0x38;
2801 
2802   pInquiry[4] = 0x0;    /* reserved */
2803   pInquiry[5] = 0x0;    /* reserved */
2804   pInquiry[6] = 0x0;    /* reserved */
2805   pInquiry[7] = 0x0;    /* reserved */
2806 
2807   /* SAT Vendor Identification */
2808   sm_strncpy((char*)&pInquiry[8],  "PMC-SIERRA", 8);   /* 8 bytes   */
2809 
2810   /* SAT Product Idetification */
2811   sm_strncpy((char*)&pInquiry[16],  "Tachyon-SPC    ", 16);   /* 16 bytes   */
2812 
2813   /* SAT Product Revision Level */
2814   sm_strncpy((char*)&pInquiry[32],  "01", 4);   /* 4 bytes   */
2815 
2816   /* Signature, SAT revision8, Table88, p85 */
2817 
2818 
2819   pInquiry[36] = 0x34;    /* FIS type */
2820   if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2821   {
2822     /* interrupt assume to be 0 */
2823     pInquiry[37] = (bit8)((oneDeviceData->satPMField) >> (4 * 7)); /* first four bits of PM field */
2824   }
2825   else
2826   {
2827     /* interrupt assume to be 1 */
2828     pInquiry[37] = (bit8)(0x40 + (bit8)(((oneDeviceData->satPMField) >> (4 * 7)))); /* first four bits of PM field */
2829   }
2830   pInquiry[38] = 0;
2831   pInquiry[39] = 0;
2832 
2833   if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2834   {
2835     pInquiry[40] = 0x01; /* LBA Low          */
2836     pInquiry[41] = 0x00; /* LBA Mid          */
2837     pInquiry[42] = 0x00; /* LBA High         */
2838     pInquiry[43] = 0x00; /* Device           */
2839     pInquiry[44] = 0x00; /* LBA Low Exp      */
2840     pInquiry[45] = 0x00; /* LBA Mid Exp      */
2841     pInquiry[46] = 0x00; /* LBA High Exp     */
2842     pInquiry[47] = 0x00; /* Reserved         */
2843     pInquiry[48] = 0x01; /* Sector Count     */
2844     pInquiry[49] = 0x00; /* Sector Count Exp */
2845   }
2846   else
2847   {
2848     pInquiry[40] = 0x01; /* LBA Low          */
2849     pInquiry[41] = 0x00; /* LBA Mid          */
2850     pInquiry[42] = 0x00; /* LBA High         */
2851     pInquiry[43] = 0x00; /* Device           */
2852     pInquiry[44] = 0x00; /* LBA Low Exp      */
2853     pInquiry[45] = 0x00; /* LBA Mid Exp      */
2854     pInquiry[46] = 0x00; /* LBA High Exp     */
2855     pInquiry[47] = 0x00; /* Reserved         */
2856     pInquiry[48] = 0x01; /* Sector Count     */
2857     pInquiry[49] = 0x00; /* Sector Count Exp */
2858   }
2859 
2860   /* Reserved */
2861   pInquiry[50] = 0x00;
2862   pInquiry[51] = 0x00;
2863   pInquiry[52] = 0x00;
2864   pInquiry[53] = 0x00;
2865   pInquiry[54] = 0x00;
2866   pInquiry[55] = 0x00;
2867 
2868   /* Command Code */
2869   if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2870   {
2871     pInquiry[56] = 0xEC;    /* IDENTIFY DEVICE */
2872   }
2873   else
2874   {
2875     pInquiry[56] = 0xA1;    /* IDENTIFY PACKET DEVICE */
2876   }
2877   /* Reserved */
2878   pInquiry[57] = 0x0;
2879   pInquiry[58] = 0x0;
2880   pInquiry[59] = 0x0;
2881 
2882   /* check the length; len is assumed to be at least 60  */
2883   if (len < SATA_PAGE89_INQUIRY_SIZE)
2884   {
2885     /* Identify Device */
2886     sm_memcpy(&pInquiry[60], pSimpleData, MIN((len - 60), sizeof(satSimpleSATAIdentifyData_t)));
2887   }
2888   else
2889   {
2890     /* Identify Device */
2891     sm_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
2892   }
2893 
2894   return;
2895 }
2896 
2897 osGLOBAL void
2898 smsatInquiryPage80(
2899                     bit8                    *pInquiry,
2900                     agsaSATAIdentifyData_t  *pSATAIdData
2901        )
2902 {
2903   SM_DBG5(("smsatInquiryPage89: start\n"));
2904   /*
2905     See SPC-4, 7.6.9, p 345
2906     and SAT revision 8, 10.3.3, p 77
2907    */
2908   pInquiry[0] = 0x00;
2909   pInquiry[1] = 0x80; /* page code */
2910   pInquiry[2] = 0x00; /* reserved */
2911   pInquiry[3] = 0x14; /* page length */
2912 
2913   /* product serial number */
2914   pInquiry[4] = pSATAIdData->serialNumber[1];
2915   pInquiry[5] = pSATAIdData->serialNumber[0];
2916   pInquiry[6] = pSATAIdData->serialNumber[3];
2917   pInquiry[7] = pSATAIdData->serialNumber[2];
2918   pInquiry[8] = pSATAIdData->serialNumber[5];
2919   pInquiry[9] = pSATAIdData->serialNumber[4];
2920   pInquiry[10] = pSATAIdData->serialNumber[7];
2921   pInquiry[11] = pSATAIdData->serialNumber[6];
2922   pInquiry[12] = pSATAIdData->serialNumber[9];
2923   pInquiry[13] = pSATAIdData->serialNumber[8];
2924   pInquiry[14] = pSATAIdData->serialNumber[11];
2925   pInquiry[15] = pSATAIdData->serialNumber[10];
2926   pInquiry[16] = pSATAIdData->serialNumber[13];
2927   pInquiry[17] = pSATAIdData->serialNumber[12];
2928   pInquiry[18] = pSATAIdData->serialNumber[15];
2929   pInquiry[19] = pSATAIdData->serialNumber[14];
2930   pInquiry[20] = pSATAIdData->serialNumber[17];
2931   pInquiry[21] = pSATAIdData->serialNumber[16];
2932   pInquiry[22] = pSATAIdData->serialNumber[19];
2933   pInquiry[23] = pSATAIdData->serialNumber[18];
2934 
2935   return;
2936 }
2937 
2938 osGLOBAL void
2939 smsatInquiryPageB1(
2940                     bit8                    *pInquiry,
2941                     agsaSATAIdentifyData_t  *pSATAIdData
2942        )
2943 {
2944   bit32 i;
2945   satSimpleSATAIdentifyData_t   *pSimpleData;
2946 
2947   SM_DBG5(("smsatInquiryPageB1: start\n"));
2948 
2949   pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2950   /*
2951     See SBC-3, revision31, Table193, p273
2952     and SAT-3 revision 3, 10.3.6, p141
2953    */
2954   pInquiry[0] = 0x00;   /* Peripheral Qualifier and Peripheral Device Type */
2955   pInquiry[1] = 0xB1; /* page code */
2956 
2957   /* page length */
2958   pInquiry[2] = 0x0;
2959   pInquiry[3] = 0x3C;
2960 
2961   /* medium rotation rate */
2962   pInquiry[4] = (bit8) ((pSimpleData->word[217]) >> 8);
2963   pInquiry[5] = (bit8) ((pSimpleData->word[217]) & 0xFF);
2964 
2965   /* reserved */
2966   pInquiry[6] = 0x0;
2967 
2968   /* nominal form factor bits 3:0 */
2969   pInquiry[7] = (bit8) ((pSimpleData->word[168]) & 0xF);
2970 
2971 
2972   /* reserved */
2973   for (i=8;i<64;i++)
2974   {
2975     pInquiry[i] = 0x0;
2976   }
2977   return;
2978 }
2979 
2980 osGLOBAL void
2981 smsatDefaultTranslation(
2982                         smRoot_t                  *smRoot,
2983                         smIORequest_t             *smIORequest,
2984                         smSatIOContext_t            *satIOContext,
2985                         smScsiRspSense_t          *pSense,
2986                         bit8                      ataStatus,
2987                         bit8                      ataError,
2988                         bit32                     interruptContext
2989                        )
2990 {
2991   SM_DBG5(("smsatDefaultTranslation: start\n"));
2992   /*
2993    * Check for device fault case
2994    */
2995   if ( ataStatus & DF_ATA_STATUS_MASK )
2996   {
2997     smsatSetSensePayload( pSense,
2998                           SCSI_SNSKEY_HARDWARE_ERROR,
2999                           0,
3000                           SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3001                           satIOContext);
3002 
3003     tdsmIOCompletedCB( smRoot,
3004                        smIORequest,
3005                        smIOSuccess,
3006                        SCSI_STAT_CHECK_CONDITION,
3007                        satIOContext->pSmSenseData,
3008                        interruptContext );
3009     return;
3010   }
3011 
3012   /*
3013    * If status error bit it set, need to check the error register
3014    */
3015   if ( ataStatus & ERR_ATA_STATUS_MASK )
3016   {
3017     if ( ataError & NM_ATA_ERROR_MASK )
3018     {
3019       SM_DBG1(("smsatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3020                  ataError, smIORequest));
3021       smsatSetSensePayload( pSense,
3022                             SCSI_SNSKEY_NOT_READY,
3023                             0,
3024                             SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
3025                             satIOContext);
3026     }
3027 
3028     else if (ataError & UNC_ATA_ERROR_MASK)
3029     {
3030       SM_DBG1(("smsatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3031                  ataError, smIORequest));
3032       smsatSetSensePayload( pSense,
3033                             SCSI_SNSKEY_MEDIUM_ERROR,
3034                             0,
3035                             SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
3036                             satIOContext);
3037     }
3038 
3039     else if (ataError & IDNF_ATA_ERROR_MASK)
3040     {
3041       SM_DBG1(("smsatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3042                  ataError, smIORequest));
3043       smsatSetSensePayload( pSense,
3044                             SCSI_SNSKEY_MEDIUM_ERROR,
3045                             0,
3046                             SCSI_SNSCODE_RECORD_NOT_FOUND,
3047                             satIOContext);
3048     }
3049 
3050     else if (ataError & MC_ATA_ERROR_MASK)
3051     {
3052       SM_DBG1(("smsatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3053                  ataError, smIORequest));
3054       smsatSetSensePayload( pSense,
3055                             SCSI_SNSKEY_UNIT_ATTENTION,
3056                             0,
3057                             SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
3058                             satIOContext);
3059     }
3060 
3061     else if (ataError & MCR_ATA_ERROR_MASK)
3062     {
3063       SM_DBG1(("smsatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3064                  ataError, smIORequest));
3065       smsatSetSensePayload( pSense,
3066                             SCSI_SNSKEY_UNIT_ATTENTION,
3067                             0,
3068                             SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
3069                             satIOContext);
3070     }
3071 
3072     else if (ataError & ICRC_ATA_ERROR_MASK)
3073     {
3074       SM_DBG1(("smsatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3075                  ataError, smIORequest));
3076       smsatSetSensePayload( pSense,
3077                             SCSI_SNSKEY_ABORTED_COMMAND,
3078                             0,
3079                             SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
3080                             satIOContext);
3081     }
3082 
3083     else if (ataError & ABRT_ATA_ERROR_MASK)
3084     {
3085       SM_DBG1(("smsatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3086                  ataError, smIORequest));
3087       smsatSetSensePayload( pSense,
3088                             SCSI_SNSKEY_ABORTED_COMMAND,
3089                             0,
3090                             SCSI_SNSCODE_NO_ADDITIONAL_INFO,
3091                             satIOContext);
3092     }
3093 
3094     else
3095     {
3096       SM_DBG1(("smsatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, smIORequest=%p!!!\n",
3097                  ataError, smIORequest));
3098       smsatSetSensePayload( pSense,
3099                             SCSI_SNSKEY_HARDWARE_ERROR,
3100                             0,
3101                             SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3102                             satIOContext);
3103     }
3104 
3105     /* Send the completion response now */
3106     tdsmIOCompletedCB( smRoot,
3107                        smIORequest,
3108                        smIOSuccess,
3109                        SCSI_STAT_CHECK_CONDITION,
3110                        satIOContext->pSmSenseData,
3111                        interruptContext );
3112     return;
3113 
3114 
3115   }
3116 
3117   else /*  (ataStatus & ERR_ATA_STATUS_MASK ) is false */
3118   {
3119     /* This case should never happen */
3120     SM_DBG1(("smsatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** smIORequest=%p!!!\n",
3121                  ataStatus, smIORequest));
3122     smsatSetSensePayload( pSense,
3123                           SCSI_SNSKEY_HARDWARE_ERROR,
3124                           0,
3125                           SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3126                           satIOContext);
3127 
3128     tdsmIOCompletedCB( smRoot,
3129                        smIORequest,
3130                        smIOSuccess,
3131                        SCSI_STAT_CHECK_CONDITION,
3132                        satIOContext->pSmSenseData,
3133                        interruptContext );
3134     return;
3135 
3136   }
3137 
3138   return;
3139 }
3140 
3141 osGLOBAL bit32
3142 smIDStart(
3143           smRoot_t                     *smRoot,
3144           smIORequest_t                *smIORequest,
3145           smDeviceHandle_t             *smDeviceHandle
3146          )
3147 {
3148   smDeviceData_t            *oneDeviceData = agNULL;
3149   smIORequestBody_t         *smIORequestBody = agNULL;
3150   smSatIOContext_t            *satIOContext = agNULL;
3151   bit32                     status = SM_RC_FAILURE;
3152 
3153   SM_DBG2(("smIDStart: start, smIORequest %p\n", smIORequest));
3154 
3155   oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
3156   if (oneDeviceData == agNULL)
3157   {
3158     SM_DBG1(("smIDStart: oneDeviceData is NULL!!!\n"));
3159     return SM_RC_FAILURE;
3160   }
3161   if (oneDeviceData->valid == agFALSE)
3162   {
3163     SM_DBG1(("smIDStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
3164     return SM_RC_FAILURE;
3165   }
3166 
3167   smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
3168 
3169   if (smIORequestBody == agNULL)
3170   {
3171     SM_DBG1(("smIDStart: smIORequestBody is NULL!!!\n"));
3172     return SM_RC_FAILURE;
3173   }
3174 
3175   smIOReInit(smRoot, smIORequestBody);
3176 
3177   SM_DBG3(("smIDStart: io ID %d!!!\n", smIORequestBody->id ));
3178 
3179   smIORequestBody->smIORequest = smIORequest;
3180   smIORequestBody->smDevHandle = smDeviceHandle;
3181   satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
3182 
3183   /* setting up satIOContext */
3184   satIOContext->pSatDevData   = oneDeviceData;
3185   satIOContext->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
3186   satIOContext->smRequestBody = smIORequestBody;
3187   satIOContext->psmDeviceHandle = smDeviceHandle;
3188   satIOContext->smScsiXchg = agNULL;
3189 
3190   /*smIORequest->smData = smIORequestBody;*/
3191   SM_DBG3(("smIDStart: smIORequestBody %p smIORequestBody->smIORequest %p!!!\n", smIORequestBody, smIORequestBody->smIORequest));
3192   SM_DBG1(("smIDStart: did %d\n",  oneDeviceData->id));
3193 
3194   status = smsatIDSubStart( smRoot,
3195                             smIORequest,
3196                             smDeviceHandle,
3197                             agNULL,
3198                             satIOContext);
3199 
3200   if (status != SM_RC_SUCCESS)
3201   {
3202     SM_DBG1(("smIDStart: smsatIDSubStart failure %d!!!\n", status));
3203     /*smEnqueueIO(smRoot, satIOContext);*/
3204   }
3205   SM_DBG2(("smIDStart: exit\n"));
3206 
3207   return status;
3208 }
3209 
3210 /*
3211   SM generated IO, needs to call smsatAllocIntIoResource()
3212   allocating using smsatAllocIntIoResource
3213 */
3214 osGLOBAL bit32
3215 smsatIDSubStart(
3216                  smRoot_t                 *smRoot,
3217                  smIORequest_t            *smIORequest,
3218                  smDeviceHandle_t         *smDeviceHandle,
3219                  smScsiInitiatorRequest_t *smSCSIRequest, /* agNULL */
3220                  smSatIOContext_t         *satIOContext
3221                )
3222 {
3223   smSatInternalIo_t           *satIntIo = agNULL;
3224   smDeviceData_t            *satDevData = agNULL;
3225   smIORequestBody_t         *smIORequestBody;
3226   smSatIOContext_t            *satNewIOContext;
3227   bit32                     status;
3228   SM_DBG2(("smsatIDSubStart: start\n"));
3229 
3230   satDevData = satIOContext->pSatDevData;
3231 
3232   /* allocate identify device command */
3233   satIntIo = smsatAllocIntIoResource( smRoot,
3234                                       smIORequest,
3235                                       satDevData,
3236                                       sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
3237                                       satIntIo);
3238 
3239   if (satIntIo == agNULL)
3240   {
3241     SM_DBG1(("smsatIDSubStart: can't alloacate!!!\n"));
3242     return SM_RC_FAILURE;
3243   }
3244 
3245   satIOContext->satIntIoContext = satIntIo;
3246 
3247   /* fill in fields */
3248   /* real ttttttthe one worked and the same; 5/21/07/ */
3249   satIntIo->satOrgSmIORequest = smIORequest; /* changed */
3250   smIORequestBody = satIntIo->satIntRequestBody;
3251   satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext);
3252 
3253   satNewIOContext->pSatDevData   = satDevData;
3254   satNewIOContext->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
3255   satNewIOContext->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
3256   satNewIOContext->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
3257   satNewIOContext->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
3258   satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */
3259   //  satNewIOContext->interruptContext = tiInterruptContext;
3260   satNewIOContext->satIntIoContext  = satIntIo;
3261 
3262   satNewIOContext->psmDeviceHandle = smDeviceHandle;
3263   satNewIOContext->satOrgIOContext = satIOContext; /* changed */
3264 
3265   /* this is valid only for TD layer generated (not triggered by OS at all) IO */
3266   satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg);
3267 
3268 
3269   SM_DBG6(("smsatIDSubStart: SM satIOContext %p \n", satIOContext));
3270   SM_DBG6(("smsatIDSubStart: SM satNewIOContext %p \n", satNewIOContext));
3271   SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satIOContext->smScsiXchg));
3272   SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satNewIOContext->smScsiXchg));
3273 
3274 
3275 
3276   SM_DBG3(("smsatIDSubStart: satNewIOContext %p smIORequestBody %p\n", satNewIOContext, smIORequestBody));
3277 
3278   status = smsatIDStart(smRoot,
3279                         &satIntIo->satIntSmIORequest, /* New smIORequest */
3280                         smDeviceHandle,
3281                         satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, */
3282                         satNewIOContext);
3283 
3284   if (status != SM_RC_SUCCESS)
3285   {
3286     SM_DBG1(("smsatIDSubStart: failed in sending %d!!!\n", status));
3287 
3288     smsatFreeIntIoResource( smRoot,
3289                             satDevData,
3290                             satIntIo);
3291 
3292     return SM_RC_FAILURE;
3293   }
3294 
3295 
3296   SM_DBG2(("smsatIDSubStart: end\n"));
3297 
3298   return status;
3299 
3300 }
3301 
3302 
3303 osGLOBAL bit32
3304 smsatIDStart(
3305               smRoot_t                  *smRoot,
3306               smIORequest_t             *smIORequest,
3307               smDeviceHandle_t          *smDeviceHandle,
3308               smScsiInitiatorRequest_t  *smSCSIRequest,
3309               smSatIOContext_t            *satIOContext
3310              )
3311 {
3312   bit32                     status;
3313   bit32                     agRequestType;
3314   smDeviceData_t            *pSatDevData;
3315   agsaFisRegHostToDevice_t  *fis;
3316 #ifdef SM_INTERNAL_DEBUG
3317   smIORequestBody_t         *smIORequestBody;
3318   smSatInternalIo_t         *satIntIoContext;
3319 #endif
3320 
3321   pSatDevData   = satIOContext->pSatDevData;
3322   fis           = satIOContext->pFis;
3323   SM_DBG2(("smsatIDStart: start\n"));
3324 #ifdef SM_INTERNAL_DEBUG
3325   satIntIoContext = satIOContext->satIntIoContext;
3326   smIORequestBody = satIntIoContext->satIntRequestBody;
3327 #endif
3328   fis->h.fisType        = 0x27;                   /* Reg host to device */
3329   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3330   if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
3331   {
3332     SM_DBG2(("smsatIDStart: IDENTIFY_PACKET_DEVICE\n"));
3333     fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
3334   }
3335   else
3336   {
3337     SM_DBG2(("smsatIDStart: IDENTIFY_DEVICE\n"));
3338     fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
3339   }
3340   fis->h.features       = 0;                      /* FIS reserve */
3341   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
3342   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
3343   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
3344   fis->d.device         = 0;                      /* FIS LBA mode  */
3345   fis->d.lbaLowExp      = 0;
3346   fis->d.lbaMidExp      = 0;
3347   fis->d.lbaHighExp     = 0;
3348   fis->d.featuresExp    = 0;
3349   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
3350   fis->d.sectorCountExp = 0;
3351   fis->d.reserved4      = 0;
3352   fis->d.control        = 0;                      /* FIS HOB bit clear */
3353   fis->d.reserved5      = 0;
3354 
3355   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
3356 
3357   /* Initialize CB for SATA completion.
3358    */
3359   satIOContext->satCompleteCB = &smsatIDStartCB;
3360 
3361   /*
3362    * Prepare SGL and send FIS to LL layer.
3363    */
3364   satIOContext->reqType = agRequestType;       /* Save it */
3365 
3366 #ifdef SM_INTERNAL_DEBUG
3367   smhexdump("smsatIDStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
3368   smhexdump("smsatIDStart LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
3369 #endif
3370   status = smsataLLIOStart( smRoot,
3371                             smIORequest,
3372                             smDeviceHandle,
3373                             smSCSIRequest,
3374                             satIOContext);
3375 
3376   SM_DBG2(("smsatIDStart: end status %d\n", status));
3377 
3378   return status;
3379 }
3380 
3381 
3382 osGLOBAL FORCEINLINE bit32
3383 smsatIOStart(
3384               smRoot_t                  *smRoot,
3385               smIORequest_t             *smIORequest,
3386               smDeviceHandle_t          *smDeviceHandle,
3387               smScsiInitiatorRequest_t  *smSCSIRequest,
3388               smSatIOContext_t            *satIOContext
3389              )
3390 {
3391   smDeviceData_t            *pSatDevData = satIOContext->pSatDevData;
3392   smScsiRspSense_t          *pSense      = satIOContext->pSense;
3393   smIniScsiCmnd_t           *scsiCmnd    = &smSCSIRequest->scsiCmnd;
3394   smLUN_t                   *pLun        = &scsiCmnd->lun;
3395   smSatInternalIo_t         *pSatIntIo   = agNULL;
3396   bit32                     status       = SM_RC_FAILURE;
3397 
3398   SM_DBG2(("smsatIOStart: start\n"));
3399 
3400   /*
3401    * Reject all other LUN other than LUN 0.
3402    */
3403   if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
3404          pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) &&
3405         (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)
3406      )
3407   {
3408     SM_DBG1(("smsatIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x did %d !!!\n",
3409                  scsiCmnd->cdb[0], pSatDevData->id));
3410     smsatSetSensePayload( pSense,
3411                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3412                           0,
3413                           SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
3414                           satIOContext);
3415 
3416     /*smEnqueueIO(smRoot, satIOContext);*/
3417 
3418     tdsmIOCompletedCB( smRoot,
3419                        smIORequest,
3420                        smIOSuccess,
3421                        SCSI_STAT_CHECK_CONDITION,
3422                        satIOContext->pSmSenseData,
3423                        satIOContext->interruptContext );
3424 
3425     return SM_RC_SUCCESS;
3426   }
3427 
3428   SM_DBG2(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3429 
3430   /* this may happen after tiCOMReset until OS sends inquiry */
3431   if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
3432   {
3433     SM_DBG1(("smsatIOStart: invalid identify device data did %d !!!\n", pSatDevData->id));
3434     SM_DBG1(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n", pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3435     SM_DBG1(("smsatIOStart: satPendingNCQIO %d satPendingNONNCQIO %d\n", pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3436 
3437     /*smEnqueueIO(smRoot, satIOContext);*/
3438 
3439     return SM_RC_NODEVICE;
3440   }
3441 
3442   /*
3443    * Check if we need to return BUSY, i.e. recovery in progress
3444    */
3445   if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
3446   {
3447     SM_DBG1(("smsatIOStart: IN RECOVERY STATE cdb[0]=0x%x did=%d !!!\n",
3448                  scsiCmnd->cdb[0], pSatDevData->id));
3449     SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n", pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3450     SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3451 
3452     /*smEnqueueIO(smRoot, satIOContext);*/
3453 
3454 //    return  SM_RC_FAILURE;
3455     return SM_RC_DEVICE_BUSY;
3456   }
3457 
3458   if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
3459   {
3460      if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
3461      {
3462         return smsatReportLun(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
3463      }
3464      else
3465      {
3466         return smsatPacket(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
3467      }
3468   }
3469   else
3470   {
3471      /* Parse CDB */
3472      switch(scsiCmnd->cdb[0])
3473      {
3474        case SCSIOPC_READ_10:
3475          status = smsatRead10( smRoot,
3476                               smIORequest,
3477                               smDeviceHandle,
3478                               smSCSIRequest,
3479                               satIOContext);
3480          break;
3481 
3482        case SCSIOPC_WRITE_10:
3483          status = smsatWrite10( smRoot,
3484                                 smIORequest,
3485                                 smDeviceHandle,
3486                                 smSCSIRequest,
3487                                 satIOContext);
3488          break;
3489 
3490        case SCSIOPC_READ_6:
3491          status = smsatRead6( smRoot,
3492                               smIORequest,
3493                               smDeviceHandle,
3494                               smSCSIRequest,
3495                               satIOContext);
3496          break;
3497 
3498        case SCSIOPC_READ_12:
3499          SM_DBG5(("smsatIOStart: SCSIOPC_READ_12\n"));
3500          status = smsatRead12( smRoot,
3501                                smIORequest,
3502                                smDeviceHandle,
3503                                smSCSIRequest,
3504                                satIOContext);
3505          break;
3506 
3507        case SCSIOPC_READ_16:
3508          status = smsatRead16( smRoot,
3509                                smIORequest,
3510                                smDeviceHandle,
3511                                smSCSIRequest,
3512                                satIOContext);
3513          break;
3514 
3515        case SCSIOPC_WRITE_6:
3516          status = smsatWrite6( smRoot,
3517                                smIORequest,
3518                                smDeviceHandle,
3519                                smSCSIRequest,
3520                                satIOContext);
3521          break;
3522 
3523        case SCSIOPC_WRITE_12:
3524          SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_12 \n"));
3525          status = smsatWrite12( smRoot,
3526                                 smIORequest,
3527                                 smDeviceHandle,
3528                                 smSCSIRequest,
3529                                 satIOContext);
3530          break;
3531 
3532        case SCSIOPC_WRITE_16:
3533          SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_16 \n"));
3534          status = smsatWrite16( smRoot,
3535                                 smIORequest,
3536                                 smDeviceHandle,
3537                                 smSCSIRequest,
3538                                 satIOContext);
3539          break;
3540 
3541        case SCSIOPC_VERIFY_10:
3542          status = smsatVerify10( smRoot,
3543                                  smIORequest,
3544                                  smDeviceHandle,
3545                                  smSCSIRequest,
3546                                  satIOContext);
3547          break;
3548 
3549        case SCSIOPC_VERIFY_12:
3550          SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_12\n"));
3551          status = smsatVerify12( smRoot,
3552                                  smIORequest,
3553                                  smDeviceHandle,
3554                                  smSCSIRequest,
3555                                  satIOContext);
3556          break;
3557 
3558        case SCSIOPC_VERIFY_16:
3559          SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_16\n"));
3560          status = smsatVerify16( smRoot,
3561                                  smIORequest,
3562                                  smDeviceHandle,
3563                                  smSCSIRequest,
3564                                  satIOContext);
3565          break;
3566 
3567        case SCSIOPC_TEST_UNIT_READY:
3568          status = smsatTestUnitReady( smRoot,
3569                                       smIORequest,
3570                                       smDeviceHandle,
3571                                       smSCSIRequest,
3572                                       satIOContext);
3573          break;
3574 
3575        case SCSIOPC_INQUIRY:
3576          status = smsatInquiry( smRoot,
3577                                 smIORequest,
3578                                 smDeviceHandle,
3579                                 smSCSIRequest,
3580                                 satIOContext);
3581          break;
3582 
3583        case SCSIOPC_REQUEST_SENSE:
3584          status = smsatRequestSense( smRoot,
3585                                      smIORequest,
3586                                      smDeviceHandle,
3587                                      smSCSIRequest,
3588                                      satIOContext);
3589          break;
3590 
3591        case SCSIOPC_MODE_SENSE_6:
3592          status = smsatModeSense6( smRoot,
3593                                    smIORequest,
3594                                    smDeviceHandle,
3595                                    smSCSIRequest,
3596                                    satIOContext);
3597          break;
3598 
3599        case SCSIOPC_MODE_SENSE_10:
3600          status = smsatModeSense10( smRoot,
3601                                     smIORequest,
3602                                     smDeviceHandle,
3603                                     smSCSIRequest,
3604                                     satIOContext);
3605          break;
3606 
3607        case SCSIOPC_READ_CAPACITY_10:
3608          status = smsatReadCapacity10( smRoot,
3609                                        smIORequest,
3610                                        smDeviceHandle,
3611                                        smSCSIRequest,
3612                                        satIOContext);
3613          break;
3614 
3615        case SCSIOPC_READ_CAPACITY_16:
3616          status = smsatReadCapacity16( smRoot,
3617                                        smIORequest,
3618                                        smDeviceHandle,
3619                                        smSCSIRequest,
3620                                        satIOContext);
3621          break;
3622 
3623 
3624        case SCSIOPC_REPORT_LUN:
3625          status = smsatReportLun( smRoot,
3626                                   smIORequest,
3627                                   smDeviceHandle,
3628                                   smSCSIRequest,
3629                                   satIOContext);
3630          break;
3631 
3632        case SCSIOPC_FORMAT_UNIT:
3633          SM_DBG5(("smsatIOStart: SCSIOPC_FORMAT_UNIT\n"));
3634          status = smsatFormatUnit( smRoot,
3635                                    smIORequest,
3636                                    smDeviceHandle,
3637                                    smSCSIRequest,
3638                                    satIOContext);
3639          break;
3640 
3641        case SCSIOPC_SEND_DIAGNOSTIC:
3642          SM_DBG5(("smsatIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
3643          status = smsatSendDiagnostic( smRoot,
3644                                        smIORequest,
3645                                        smDeviceHandle,
3646                                        smSCSIRequest,
3647                                        satIOContext);
3648          break;
3649 
3650        case SCSIOPC_START_STOP_UNIT:
3651          SM_DBG5(("smsatIOStart: SCSIOPC_START_STOP_UNIT\n"));
3652          status = smsatStartStopUnit( smRoot,
3653                                       smIORequest,
3654                                       smDeviceHandle,
3655                                       smSCSIRequest,
3656                                       satIOContext);
3657          break;
3658 
3659        case SCSIOPC_WRITE_SAME_10:
3660          SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_10\n"));
3661          status = smsatWriteSame10( smRoot,
3662                                     smIORequest,
3663                                     smDeviceHandle,
3664                                     smSCSIRequest,
3665                                     satIOContext);
3666          break;
3667 
3668        case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */
3669          SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_16\n"));
3670          status = smsatWriteSame16( smRoot,
3671                                     smIORequest,
3672                                     smDeviceHandle,
3673                                     smSCSIRequest,
3674                                     satIOContext);
3675          break;
3676 
3677        case SCSIOPC_LOG_SENSE:
3678          SM_DBG5(("smsatIOStart: SCSIOPC_LOG_SENSE\n"));
3679          status = smsatLogSense( smRoot,
3680                                  smIORequest,
3681                                  smDeviceHandle,
3682                                  smSCSIRequest,
3683                                  satIOContext);
3684          break;
3685 
3686        case SCSIOPC_MODE_SELECT_6:
3687          SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_6\n"));
3688          status = smsatModeSelect6( smRoot,
3689                                     smIORequest,
3690                                     smDeviceHandle,
3691                                     smSCSIRequest,
3692                                     satIOContext);
3693          break;
3694 
3695        case SCSIOPC_MODE_SELECT_10:
3696          SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_10\n"));
3697          status = smsatModeSelect10( smRoot,
3698                                      smIORequest,
3699                                      smDeviceHandle,
3700                                      smSCSIRequest,
3701                                      satIOContext);
3702          break;
3703 
3704        case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with
3705                                            satSynchronizeCache16 */
3706          SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
3707          status = smsatSynchronizeCache10( smRoot,
3708                                            smIORequest,
3709                                            smDeviceHandle,
3710                                            smSCSIRequest,
3711                                            satIOContext);
3712          break;
3713 
3714        case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with
3715                                             satSynchronizeCache16 */
3716 
3717          SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
3718          status = smsatSynchronizeCache16( smRoot,
3719                                            smIORequest,
3720                                            smDeviceHandle,
3721                                            smSCSIRequest,
3722                                            satIOContext);
3723          break;
3724 
3725        case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */
3726          SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
3727          status = smsatWriteAndVerify10( smRoot,
3728                                          smIORequest,
3729                                          smDeviceHandle,
3730                                          smSCSIRequest,
3731                                          satIOContext);
3732          break;
3733 
3734        case SCSIOPC_WRITE_AND_VERIFY_12:
3735          SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
3736          status = smsatWriteAndVerify12( smRoot,
3737                                          smIORequest,
3738                                          smDeviceHandle,
3739                                          smSCSIRequest,
3740                                          satIOContext);
3741          break;
3742 
3743        case SCSIOPC_WRITE_AND_VERIFY_16:
3744          SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
3745          status = smsatWriteAndVerify16( smRoot,
3746                                          smIORequest,
3747                                          smDeviceHandle,
3748                                          smSCSIRequest,
3749                                          satIOContext);
3750 
3751          break;
3752 
3753        case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
3754          SM_DBG5(("smsatIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
3755          status = smsatReadMediaSerialNumber( smRoot,
3756                                               smIORequest,
3757                                               smDeviceHandle,
3758                                               smSCSIRequest,
3759                                               satIOContext);
3760 
3761          break;
3762 
3763        case SCSIOPC_READ_BUFFER:
3764          SM_DBG5(("smsatIOStart: SCSIOPC_READ_BUFFER\n"));
3765          status = smsatReadBuffer( smRoot,
3766                                    smIORequest,
3767                                    smDeviceHandle,
3768                                    smSCSIRequest,
3769                                    satIOContext);
3770 
3771          break;
3772 
3773        case SCSIOPC_WRITE_BUFFER:
3774          SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_BUFFER\n"));
3775          status = smsatWriteBuffer( smRoot,
3776                                     smIORequest,
3777                                     smDeviceHandle,
3778                                     smSCSIRequest,
3779                                     satIOContext);
3780 
3781          break;
3782 
3783        case SCSIOPC_REASSIGN_BLOCKS:
3784          SM_DBG5(("smsatIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
3785          status = smsatReassignBlocks( smRoot,
3786                                        smIORequest,
3787                                        smDeviceHandle,
3788                                        smSCSIRequest,
3789                                        satIOContext);
3790 
3791          break;
3792 
3793        case SCSIOPC_ATA_PASS_THROUGH12: /* fall through */
3794        case SCSIOPC_ATA_PASS_THROUGH16:
3795          SM_DBG5(("smsatIOStart: SCSIOPC_ATA_PASS_THROUGH\n"));
3796          status = smsatPassthrough( smRoot,
3797                                     smIORequest,
3798                                     smDeviceHandle,
3799                                     smSCSIRequest,
3800                                     satIOContext);
3801          break;
3802 
3803        default:
3804          /* Not implemented SCSI cmd, set up error response */
3805          SM_DBG1(("smsatIOStart: unsupported SCSI cdb[0]=0x%x did=%d !!!\n",
3806                     scsiCmnd->cdb[0], pSatDevData->id));
3807 
3808          smsatSetSensePayload( pSense,
3809                                SCSI_SNSKEY_ILLEGAL_REQUEST,
3810                                0,
3811                                SCSI_SNSCODE_INVALID_COMMAND,
3812                                satIOContext);
3813 
3814          /*smEnqueueIO(smRoot, satIOContext);*/
3815 
3816          tdsmIOCompletedCB( smRoot,
3817                             smIORequest,
3818                             smIOSuccess,
3819                             SCSI_STAT_CHECK_CONDITION,
3820                             satIOContext->pSmSenseData,
3821                             satIOContext->interruptContext );
3822          status = SM_RC_SUCCESS;
3823 
3824          break;
3825 
3826      }  /* end switch  */
3827   }
3828 
3829   if (status == SM_RC_BUSY || status == SM_RC_DEVICE_BUSY)
3830   {
3831     SM_DBG1(("smsatIOStart: BUSY did %d!!!\n", pSatDevData->id));
3832     SM_DBG2(("smsatIOStart: LL is busy or target queue is full\n"));
3833     SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3834     SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3835     pSatIntIo               = satIOContext->satIntIoContext;
3836 
3837     /*smEnqueueIO(smRoot, satIOContext);*/
3838 
3839     /* interal structure free */
3840     smsatFreeIntIoResource( smRoot,
3841                             pSatDevData,
3842                             pSatIntIo);
3843   }
3844 
3845   return status;
3846 }
3847 
3848 osGLOBAL void
3849 smsatSetSensePayload(
3850                      smScsiRspSense_t   *pSense,
3851                      bit8               SnsKey,
3852                      bit32              SnsInfo,
3853                      bit16              SnsCode,
3854                      smSatIOContext_t     *satIOContext)
3855 {
3856   /* for fixed format sense data, SPC-4, p37 */
3857   bit32      i;
3858   bit32      senseLength;
3859   bit8       tmp = 0;
3860 
3861   SM_DBG2(("smsatSetSensePayload: start\n"));
3862 
3863   senseLength  = sizeof(smScsiRspSense_t);
3864 
3865   /* zero out the data area */
3866   for (i=0;i< senseLength;i++)
3867   {
3868     ((bit8*)pSense)[i] = 0;
3869   }
3870 
3871   /*
3872    * SCSI Sense Data part of response data
3873    */
3874   pSense->snsRespCode  = 0x70;    /*  0xC0 == vendor specific */
3875                                       /*  0x70 == standard current error */
3876   pSense->senseKey     = SnsKey;
3877   /*
3878    * Put sense info in scsi order format
3879    */
3880   pSense->info[0]      = (bit8)((SnsInfo >> 24) & 0xff);
3881   pSense->info[1]      = (bit8)((SnsInfo >> 16) & 0xff);
3882   pSense->info[2]      = (bit8)((SnsInfo >> 8) & 0xff);
3883   pSense->info[3]      = (bit8)((SnsInfo) & 0xff);
3884   pSense->addSenseLen  = 11;          /* fixed size of sense data = 18 */
3885   pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
3886   pSense->senseQual    = (bit8)(SnsCode & 0xFF);
3887   /*
3888    * Set pointer in scsi status
3889    */
3890   switch(SnsKey)
3891   {
3892     /*
3893      * set illegal request sense key specific error in cdb, no bit pointer
3894      */
3895     case SCSI_SNSKEY_ILLEGAL_REQUEST:
3896       pSense->skeySpecific[0] = 0xC8;
3897       break;
3898 
3899     default:
3900       break;
3901   }
3902   /* setting sense data length */
3903   if (satIOContext != agNULL)
3904   {
3905     satIOContext->pSmSenseData->senseLen = 18;
3906   }
3907   else
3908   {
3909     SM_DBG1(("smsatSetSensePayload: satIOContext is NULL!!!\n"));
3910   }
3911 
3912   /* Only for SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE */
3913   if (SnsCode == SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE)
3914   {
3915     /* filling in COMMAND-SPECIFIC INFORMATION */
3916     tmp = satIOContext->extend << 7 | satIOContext->Sector_Cnt_Upper_Nonzero << 6 | satIOContext->LBA_Upper_Nonzero << 5;
3917     SM_DBG3(("smsatSetSensePayload: extend 0x%x Sector_Cnt_Upper_Nonzero 0x%x LBA_Upper_Nonzero 0x%x\n",
3918     satIOContext->extend, satIOContext->Sector_Cnt_Upper_Nonzero, satIOContext->LBA_Upper_Nonzero));
3919     SM_DBG3(("smsatSetSensePayload: tmp 0x%x\n", tmp));
3920     pSense->cmdSpecific[0]      = tmp;
3921     pSense->cmdSpecific[1]      = satIOContext->LBAHigh07;
3922     pSense->cmdSpecific[2]      = satIOContext->LBAMid07;
3923     pSense->cmdSpecific[3]      = satIOContext->LBALow07;
3924 //    smhexdump("smsatSetSensePayload: cmdSpecific",(bit8 *)pSense->cmdSpecific, 4);
3925 //    smhexdump("smsatSetSensePayload: info",(bit8 *)pSense->info, 4);
3926 
3927   }
3928   return;
3929 }
3930 
3931 /*****************************************************************************
3932 *! \brief  smsatDecodeSATADeviceType
3933 *
3934 *   This routine decodes ATA signature
3935 *
3936 *  \param   pSignature:       ATA signature
3937 *
3938 *
3939 *  \return:
3940 *          TRUE if ATA signature
3941 *          FALSE otherwise
3942 *
3943 *****************************************************************************/
3944 /*
3945   ATA p65
3946   PM p65
3947   SATAII p79, p80
3948  */
3949 GLOBAL bit32
3950 smsatDecodeSATADeviceType(
3951                          bit8  *pSignature
3952                          )
3953 {
3954   bit32 deviceType = UNKNOWN_DEVICE;
3955 
3956   if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3957        && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00
3958        && (pSignature)[4] == 0xA0 )    /* this is the signature of a Hitachi SATA HDD*/
3959   {
3960     deviceType = SATA_ATA_DEVICE;
3961   }
3962   else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3963       && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00
3964       && (pSignature)[4] == 0x00 )
3965   {
3966     deviceType = SATA_ATA_DEVICE;
3967   }
3968   else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3969           && (pSignature)[2] == 0x14 && (pSignature)[3] == 0xEB
3970           && ( (pSignature)[4] == 0x00 || (pSignature)[4] == 0x10) )
3971   {
3972     deviceType = SATA_ATAPI_DEVICE;
3973   }
3974   else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3975           && (pSignature)[2] == 0x69 && (pSignature)[3] == 0x96
3976           && (pSignature)[4] == 0x00 )
3977   {
3978     deviceType = SATA_PM_DEVICE;
3979   }
3980   else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3981           && (pSignature)[2] == 0x3C && (pSignature)[3] == 0xC3
3982           && (pSignature)[4] == 0x00 )
3983   {
3984     deviceType = SATA_SEMB_DEVICE;
3985   }
3986   else if ( (pSignature)[0] == 0xFF && (pSignature)[1] == 0xFF
3987           && (pSignature)[2] == 0xFF && (pSignature)[3] == 0xFF
3988           && (pSignature)[4] == 0xFF )
3989   {
3990     deviceType = SATA_SEMB_WO_SEP_DEVICE;
3991   }
3992 
3993   return deviceType;
3994 }
3995 
3996 
3997 /*****************************************************************************/
3998 /*! \brief SAT implementation for ATAPI Packet Command.
3999  *
4000  *  SAT implementation for ATAPI Packet and send FIS request to LL layer.
4001  *
4002  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4003  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4004  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4005  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4006  *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4007  *
4008  *  \return If command is started successfully
4009  *    - \e smIOSuccess:     I/O request successfully initiated.
4010  *    - \e smIOBusy:        No resources available, try again later.
4011  *    - \e smIONoDevice:  Invalid device handle.
4012  *    - \e smIOError:       Other errors.
4013  */
4014 /*****************************************************************************/
4015 osGLOBAL bit32
4016 smsatPacket(
4017           smRoot_t                  *smRoot,
4018           smIORequest_t             *smIORequest,
4019           smDeviceHandle_t          *smDeviceHandle,
4020           smScsiInitiatorRequest_t  *smScsiRequest,
4021           smSatIOContext_t            *satIOContext
4022   )
4023 {
4024   bit32                     status;
4025   bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4026   smDeviceData_t            *pSatDevData;
4027   smIniScsiCmnd_t           *scsiCmnd;
4028   agsaFisRegHostToDevice_t  *fis;
4029 
4030   pSatDevData   = satIOContext->pSatDevData;
4031   scsiCmnd      = &smScsiRequest->scsiCmnd;
4032   fis           = satIOContext->pFis;
4033 
4034   SM_DBG3(("smsatPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
4035            scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
4036            scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
4037            scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
4038 
4039   fis->h.fisType        = 0x27;                   /* Reg host to device */
4040   fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
4041   fis->h.command        = SAT_PACKET;             /* 0xA0 */
4042   if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
4043   {
4044      fis->h.features    = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
4045   }
4046   else
4047   {
4048      fis->h.features    = 0;                      /* FIS reserve */
4049   }
4050 
4051   if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4052   {
4053      /*DMA transfer mode*/
4054      fis->h.features |= 0x01;
4055   }
4056   else
4057   {
4058      /*PIO transfer mode*/
4059      fis->h.features |= 0x0;
4060   }
4061   /* Byte count low and byte count high */
4062   if ( scsiCmnd->expDataLength > 0xFFFF )
4063   {
4064      fis->d.lbaMid = 0xFF;                                 /* FIS LBA (15:8 ) */
4065      fis->d.lbaHigh = 0xFF;                                /* FIS LBA (23:16) */
4066   }
4067   else
4068   {
4069      fis->d.lbaMid = (bit8)scsiCmnd->expDataLength;        /* FIS LBA (15:8 ) */
4070      fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8);  /* FIS LBA (23:16) */
4071   }
4072 
4073   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
4074   fis->d.device         = 0;                      /* FIS LBA (27:24) and FIS LBA mode  */
4075   fis->d.lbaLowExp      = 0;
4076   fis->d.lbaMidExp      = 0;
4077   fis->d.lbaHighExp     = 0;
4078   fis->d.featuresExp    = 0;
4079   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
4080   fis->d.sectorCountExp = 0;
4081   fis->d.reserved4      = 0;
4082   fis->d.control        = 0;                      /* FIS HOB bit clear */
4083   fis->d.reserved5      = 0;
4084 
4085   satIOContext->ATACmd = SAT_PACKET;
4086 
4087   if (smScsiRequest->dataDirection == smDirectionIn)
4088   {
4089       agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4090   }
4091   else
4092   {
4093       agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
4094   }
4095 
4096   satIOContext->satCompleteCB = &smsatPacketCB;
4097 
4098   /*
4099    * Prepare SGL and send FIS to LL layer.
4100    */
4101   satIOContext->reqType = agRequestType;       /* Save it */
4102 
4103   status = smsataLLIOStart(smRoot,
4104                           smIORequest,
4105                           smDeviceHandle,
4106                           smScsiRequest,
4107                           satIOContext);
4108 
4109   SM_DBG3(("smsatPacket: return\n"));
4110   return (status);
4111 }
4112 
4113 /*****************************************************************************/
4114 /*! \brief SAT implementation for smsatSetFeaturePIO.
4115  *
4116  *  This function creates Set Features fis and sends the request to LL layer
4117  *
4118  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4119  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4120  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4121  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4122  *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4123  *
4124  *  \return If command is started successfully
4125  *    - \e smIOSuccess:     I/O request successfully initiated.
4126  *    - \e smIOBusy:        No resources available, try again later.
4127  *    - \e smIONoDevice:  Invalid device handle.
4128  *    - \e smIOError:       Other errors.
4129  */
4130 /*****************************************************************************/
4131 osGLOBAL bit32
4132 smsatSetFeaturesPIO(
4133   smRoot_t                  *smRoot,
4134   smIORequest_t             *smIORequest,
4135   smDeviceHandle_t          *smDeviceHandle,
4136   smScsiInitiatorRequest_t  *smScsiRequest,
4137   smSatIOContext_t          *satIOContext
4138   )
4139 {
4140   bit32                     status = SM_RC_FAILURE;
4141   bit32                     agRequestType;
4142   agsaFisRegHostToDevice_t *fis;
4143 
4144   fis           = satIOContext->pFis;
4145   SM_DBG2(("smsatSetFeaturesPIO: start\n"));
4146   /*
4147    * Send the Set Features command.
4148    */
4149   fis->h.fisType        = 0x27;                   /* Reg host to device */
4150   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4151   fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
4152   fis->h.features       = 0x03;                   /* set transfer mode */
4153   fis->d.lbaLow         = 0;
4154   fis->d.lbaMid         = 0;
4155   fis->d.lbaHigh        = 0;
4156   fis->d.device         = 0;
4157   fis->d.lbaLowExp      = 0;
4158   fis->d.lbaMidExp      = 0;
4159   fis->d.lbaHighExp     = 0;
4160   fis->d.featuresExp    = 0;
4161   fis->d.sectorCountExp = 0;
4162   fis->d.reserved4      = 0;
4163   fis->d.control        = 0;                      /* FIS HOB bit clear */
4164   fis->d.reserved5      = 0;
4165 
4166   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
4167 
4168   /* Initialize CB for SATA completion.
4169    */
4170   fis->d.sectorCount = 0x0C;                     /*enable PIO transfer mode */
4171   satIOContext->satCompleteCB = &smsatSetFeaturesPIOCB;
4172 
4173   /*
4174    * Prepare SGL and send FIS to LL layer.
4175    */
4176   satIOContext->reqType = agRequestType;       /* Save it */
4177 
4178   status = smsataLLIOStart( smRoot,
4179                           smIORequest,
4180                           smDeviceHandle,
4181                           smScsiRequest,
4182                           satIOContext);
4183 
4184   SM_DBG2(("smsatSetFeaturesPIO: return\n"));
4185   /* debugging code */
4186   if (smIORequest->tdData == smIORequest->smData)
4187   {
4188     SM_DBG1(("smsatSetFeaturesPIO: incorrect smIORequest\n"));
4189   }
4190 
4191   return status;
4192 }
4193 /*****************************************************************************/
4194 /*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device.
4195  *
4196  *  SAT implementation for SCSI REQUEST SENSE.
4197  *
4198  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4199  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4200  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4201  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4202  *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4203  *
4204  *  \return If command is started successfully
4205  *    - \e smIOSuccess:     I/O request successfully initiated.
4206  *    - \e smIOBusy:        No resources available, try again later.
4207  *    - \e smIONoDevice:  Invalid device handle.
4208  *    - \e smIOError:       Other errors.
4209  */
4210 /*****************************************************************************/
4211 osGLOBAL bit32
4212 smsatRequestSenseForATAPI(
4213   smRoot_t                  *smRoot,
4214   smIORequest_t             *smIORequest,
4215   smDeviceHandle_t          *smDeviceHandle,
4216   smScsiInitiatorRequest_t  *smScsiRequest,
4217   smSatIOContext_t            *satIOContext
4218   )
4219 {
4220   bit32                     status;
4221   bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4222   smDeviceData_t            *pSatDevData;
4223   smIniScsiCmnd_t           *scsiCmnd;
4224   agsaFisRegHostToDevice_t  *fis;
4225 
4226   pSatDevData   = satIOContext->pSatDevData;
4227   scsiCmnd      = &smScsiRequest->scsiCmnd;
4228   fis           = satIOContext->pFis;
4229 
4230   scsiCmnd->cdb[0]   = SCSIOPC_REQUEST_SENSE;
4231   scsiCmnd->cdb[1]   = 0;
4232   scsiCmnd->cdb[2]   = 0;
4233   scsiCmnd->cdb[3]   = 0;
4234   scsiCmnd->cdb[4]   = (bit8)scsiCmnd->expDataLength;
4235   scsiCmnd->cdb[5]   = 0;
4236   SM_DBG3(("smsatRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
4237            scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
4238            scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
4239            scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
4240 
4241   fis->h.fisType        = 0x27;                   /* Reg host to device */
4242   fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
4243   fis->h.command        = SAT_PACKET;             /* 0xA0 */
4244   if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
4245   {
4246      fis->h.features    = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
4247   }
4248   else
4249   {
4250      fis->h.features    = 0;                      /* FIS reserve */
4251   }
4252 
4253   if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4254   {
4255      fis->h.features |= 0x01;
4256   }
4257   else
4258   {
4259      fis->h.features |= 0x0;
4260   }
4261 
4262   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
4263   fis->d.lbaMid         = (bit8)scsiCmnd->expDataLength;        /* FIS LBA (15:8 ) */
4264   fis->d.lbaHigh        = (bit8)(scsiCmnd->expDataLength>>8);  /* FIS LBA (23:16) */
4265   fis->d.device         = 0;                      /* FIS LBA (27:24) and FIS LBA mode  */
4266   fis->d.lbaLowExp      = 0;
4267   fis->d.lbaMidExp      = 0;
4268   fis->d.lbaHighExp     = 0;
4269   fis->d.featuresExp    = 0;
4270   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
4271   fis->d.sectorCountExp = 0;
4272   fis->d.reserved4      = 0;
4273   fis->d.control        = 0;                      /* FIS HOB bit clear */
4274   fis->d.reserved5      = 0;
4275 
4276   satIOContext->ATACmd = SAT_PACKET;
4277 
4278   agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4279 
4280 
4281   satIOContext->satCompleteCB = &smsatRequestSenseForATAPICB;
4282 
4283   /*
4284    * Prepare SGL and send FIS to LL layer.
4285    */
4286   satIOContext->reqType = agRequestType;       /* Save it */
4287 
4288   status = smsataLLIOStart( smRoot,
4289                           smIORequest,
4290                           smDeviceHandle,
4291                           smScsiRequest,
4292                           satIOContext);
4293 
4294   SM_DBG3(("smsatRequestSenseForATAPI: return\n"));
4295   return (status);
4296 }
4297 /*****************************************************************************/
4298 /*! \brief SAT implementation for smsatDeviceReset.
4299  *
4300  *  This function creates DEVICE RESET fis and sends the request to LL layer
4301  *
4302  *  \param   smRoot:           Pointer to TISA initiator driver/port instance.
4303  *  \param   smIORequest:      Pointer to TISA I/O request context for this I/O.
4304  *  \param   smDeviceHandle:   Pointer to TISA device handle for this I/O.
4305  *  \param   smScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4306  *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4307  *
4308  *  \return If command is started successfully
4309  *    - \e smIOSuccess:     I/O request successfully initiated.
4310  *    - \e smIOBusy:        No resources available, try again later.
4311  *    - \e smIONoDevice:  Invalid device handle.
4312  *    - \e smIOError:       Other errors.
4313  */
4314 /*****************************************************************************/
4315 osGLOBAL bit32
4316 smsatDeviceReset(
4317   smRoot_t                  *smRoot,
4318   smIORequest_t             *smIORequest,
4319   smDeviceHandle_t          *smDeviceHandle,
4320   smScsiInitiatorRequest_t  *smScsiRequest,
4321   smSatIOContext_t            *satIOContext
4322   )
4323 {
4324   bit32                     status;
4325   bit32                     agRequestType;
4326   agsaFisRegHostToDevice_t *fis;
4327 
4328   fis           = satIOContext->pFis;
4329   SM_DBG3(("smsatDeviceReset: start\n"));
4330   /*
4331    * Send the  Execute Device Diagnostic command.
4332    */
4333   fis->h.fisType        = 0x27;                   /* Reg host to device */
4334   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4335   fis->h.command        = SAT_DEVICE_RESET;       /* 0x08 */
4336   fis->h.features       = 0;
4337   fis->d.lbaLow         = 0;
4338   fis->d.lbaMid         = 0;
4339   fis->d.lbaHigh        = 0;
4340   fis->d.device         = 0;
4341   fis->d.lbaLowExp      = 0;
4342   fis->d.lbaMidExp      = 0;
4343   fis->d.lbaHighExp     = 0;
4344   fis->d.featuresExp    = 0;
4345   fis->d.sectorCount    = 0;
4346   fis->d.sectorCountExp = 0;
4347   fis->d.reserved4      = 0;
4348   fis->d.control        = 0;                      /* FIS HOB bit clear */
4349   fis->d.reserved5      = 0;
4350 
4351   agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
4352 
4353   /* Initialize CB for SATA completion.
4354    */
4355   satIOContext->satCompleteCB = &smsatDeviceResetCB;
4356 
4357   /*
4358    * Prepare SGL and send FIS to LL layer.
4359    */
4360   satIOContext->reqType = agRequestType;       /* Save it */
4361 
4362   status = smsataLLIOStart( smRoot,
4363                           smIORequest,
4364                           smDeviceHandle,
4365                           smScsiRequest,
4366                           satIOContext);
4367 
4368   SM_DBG3(("smsatDeviceReset: return\n"));
4369 
4370   return status;
4371 }
4372 
4373 
4374 /*****************************************************************************/
4375 /*! \brief SAT implementation for smsatExecuteDeviceDiagnostic.
4376  *
4377  *  This function creates Execute Device Diagnostic fis and sends the request to LL layer
4378  *
4379  *  \param   smRoot:           Pointer to TISA initiator driver/port instance.
4380  *  \param   smIORequest:      Pointer to TISA I/O request context for this I/O.
4381  *  \param   smDeviceHandle:   Pointer to TISA device handle for this I/O.
4382  *  \param   smScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4383  *  \param   smSatIOContext_t:   Pointer to the SAT IO Context
4384  *
4385  *  \return If command is started successfully
4386  *    - \e smIOSuccess:     I/O request successfully initiated.
4387  *    - \e smIOBusy:        No resources available, try again later.
4388  *    - \e smIONoDevice:  Invalid device handle.
4389  *    - \e smIOError:       Other errors.
4390  */
4391 /*****************************************************************************/
4392 osGLOBAL bit32
4393 smsatExecuteDeviceDiagnostic(
4394   smRoot_t                  *smRoot,
4395   smIORequest_t             *smIORequest,
4396   smDeviceHandle_t          *smDeviceHandle,
4397   smScsiInitiatorRequest_t  *smScsiRequest,
4398   smSatIOContext_t            *satIOContext
4399   )
4400 {
4401   bit32                     status;
4402   bit32                     agRequestType;
4403   agsaFisRegHostToDevice_t *fis;
4404 
4405   fis           = satIOContext->pFis;
4406   SM_DBG3(("smsatExecuteDeviceDiagnostic: start\n"));
4407   /*
4408    * Send the  Execute Device Diagnostic command.
4409    */
4410   fis->h.fisType        = 0x27;                   /* Reg host to device */
4411   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4412   fis->h.command        = SAT_EXECUTE_DEVICE_DIAGNOSTIC;   /* 0x90 */
4413   fis->h.features       = 0;
4414   fis->d.lbaLow         = 0;
4415   fis->d.lbaMid         = 0;
4416   fis->d.lbaHigh        = 0;
4417   fis->d.device         = 0;
4418   fis->d.lbaLowExp      = 0;
4419   fis->d.lbaMidExp      = 0;
4420   fis->d.lbaHighExp     = 0;
4421   fis->d.featuresExp    = 0;
4422   fis->d.sectorCount    = 0;
4423   fis->d.sectorCountExp = 0;
4424   fis->d.reserved4      = 0;
4425   fis->d.control        = 0;                      /* FIS HOB bit clear */
4426   fis->d.reserved5      = 0;
4427 
4428   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
4429 
4430   /* Initialize CB for SATA completion.
4431    */
4432   satIOContext->satCompleteCB = &smsatExecuteDeviceDiagnosticCB;
4433 
4434   /*
4435    * Prepare SGL and send FIS to LL layer.
4436    */
4437   satIOContext->reqType = agRequestType;       /* Save it */
4438 
4439   status = smsataLLIOStart( smRoot,
4440                           smIORequest,
4441                           smDeviceHandle,
4442                           smScsiRequest,
4443                           satIOContext);
4444 
4445   SM_DBG3(("smsatExecuteDeviceDiagnostic: return\n"));
4446 
4447   return status;
4448 }
4449 
4450 
4451 osGLOBAL void
4452 smsatSetDeferredSensePayload(
4453                              smScsiRspSense_t *pSense,
4454                              bit8             SnsKey,
4455                              bit32            SnsInfo,
4456                              bit16            SnsCode,
4457                              smSatIOContext_t   *satIOContext
4458                             )
4459 {
4460   SM_DBG2(("smsatSetDeferredSensePayload: start\n"));
4461   return;
4462 }
4463 
4464 
4465 GLOBAL bit32
4466 smsatRead6(
4467            smRoot_t                  *smRoot,
4468            smIORequest_t             *smIORequest,
4469            smDeviceHandle_t          *smDeviceHandle,
4470            smScsiInitiatorRequest_t  *smScsiRequest,
4471            smSatIOContext_t            *satIOContext
4472     )
4473 {
4474   bit32                     status;
4475   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4476   smDeviceData_t            *pSatDevData;
4477   smScsiRspSense_t          *pSense;
4478   smIniScsiCmnd_t           *scsiCmnd;
4479   agsaFisRegHostToDevice_t  *fis;
4480   bit32                     lba = 0;
4481   bit16                     tl = 0;
4482 
4483   pSense        = satIOContext->pSense;
4484   pSatDevData   = satIOContext->pSatDevData;
4485   scsiCmnd      = &smScsiRequest->scsiCmnd;
4486   fis           = satIOContext->pFis;
4487 
4488   SM_DBG2(("smsatRead6: start\n"));
4489 
4490   /* no FUA checking since read6 */
4491 
4492 
4493   /* checking CONTROL */
4494   /* NACA == 1 or LINK == 1*/
4495   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
4496   {
4497     smsatSetSensePayload( pSense,
4498                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4499                           0,
4500                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4501                           satIOContext);
4502 
4503     /*smEnqueueIO(smRoot, satIOContext);*/
4504 
4505     tdsmIOCompletedCB( smRoot,
4506                        smIORequest,
4507                        smIOSuccess,
4508                        SCSI_STAT_CHECK_CONDITION,
4509                        satIOContext->pSmSenseData,
4510                        satIOContext->interruptContext );
4511 
4512     SM_DBG1(("smsatRead6: return control!!!\n"));
4513     return SM_RC_SUCCESS;
4514   }
4515 
4516   /* cbd6; computing LBA and transfer length */
4517   lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
4518     + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
4519   tl = scsiCmnd->cdb[4];
4520 
4521   /* Table 34, 9.1, p 46 */
4522   /*
4523     note: As of 2/10/2006, no support for DMA QUEUED
4524    */
4525 
4526   /*
4527     Table 34, 9.1, p 46, b
4528     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4529     return check condition
4530   */
4531   if (pSatDevData->satNCQ != agTRUE &&
4532       pSatDevData->sat48BitSupport != agTRUE
4533       )
4534   {
4535     if (lba > SAT_TR_LBA_LIMIT - 1)
4536     {
4537       smsatSetSensePayload( pSense,
4538                             SCSI_SNSKEY_ILLEGAL_REQUEST,
4539                             0,
4540                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4541                             satIOContext);
4542 
4543       /*smEnqueueIO(smRoot, satIOContext);*/
4544 
4545       tdsmIOCompletedCB( smRoot,
4546                          smIORequest,
4547                          smIOSuccess,
4548                          SCSI_STAT_CHECK_CONDITION,
4549                          satIOContext->pSmSenseData,
4550                          satIOContext->interruptContext );
4551 
4552     SM_DBG1(("smsatRead6: return LBA out of range!!!\n"));
4553     return SM_RC_SUCCESS;
4554     }
4555   }
4556 
4557   /* case 1 and 2 */
4558   if (lba + tl <= SAT_TR_LBA_LIMIT)
4559   {
4560     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4561     {
4562       /* case 2 */
4563       /* READ DMA*/
4564       SM_DBG5(("smsatRead6: case 2\n"));
4565 
4566 
4567       fis->h.fisType        = 0x27;                   /* Reg host to device */
4568       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4569       fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
4570       fis->h.features       = 0;                      /* FIS reserve */
4571       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4572       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4573       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4574       fis->d.device         = 0x40;                   /* FIS LBA mode  */
4575       fis->d.lbaLowExp      = 0;
4576       fis->d.lbaMidExp      = 0;
4577       fis->d.lbaHighExp     = 0;
4578       fis->d.featuresExp    = 0;
4579       if (tl == 0)
4580       {
4581         /* temporary fix */
4582         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4583       }
4584       else
4585       {
4586         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4587       }
4588       fis->d.sectorCountExp = 0;
4589       fis->d.reserved4      = 0;
4590       fis->d.control        = 0;                      /* FIS HOB bit clear */
4591       fis->d.reserved5      = 0;
4592 
4593       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4594     }
4595     else
4596     {
4597       /* case 1 */
4598       /* READ SECTORS for easier implemetation */
4599       SM_DBG5(("smsatRead6: case 1\n"));
4600 
4601       fis->h.fisType        = 0x27;                   /* Reg host to device */
4602       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4603       fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
4604       fis->h.features       = 0;                      /* FIS reserve */
4605       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4606       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4607       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4608       fis->d.device         = 0x40;                   /* FIS LBA mode  */
4609       fis->d.lbaLowExp      = 0;
4610       fis->d.lbaMidExp      = 0;
4611       fis->d.lbaHighExp     = 0;
4612       fis->d.featuresExp    = 0;
4613       if (tl == 0)
4614       {
4615         /* temporary fix */
4616         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4617       }
4618       else
4619       {
4620         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4621       }
4622       fis->d.sectorCountExp = 0;
4623       fis->d.reserved4      = 0;
4624       fis->d.control        = 0;                      /* FIS HOB bit clear */
4625       fis->d.reserved5      = 0;
4626 
4627       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
4628 
4629     }
4630   }
4631 
4632   /* case 3 and 4 */
4633   if (pSatDevData->sat48BitSupport == agTRUE)
4634   {
4635     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4636     {
4637       /* case 3 */
4638       /* READ DMA EXT only */
4639       SM_DBG5(("smsatRead6: case 3\n"));
4640       fis->h.fisType        = 0x27;                   /* Reg host to device */
4641       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4642       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
4643       fis->h.features       = 0;                      /* FIS reserve */
4644       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4645       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4646       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4647       fis->d.device         = 0x40;                   /* FIS LBA mode set */
4648       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4649       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4650       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4651       fis->d.featuresExp    = 0;                      /* FIS reserve */
4652       if (tl == 0)
4653       {
4654         /* sector count is 256, 0x100*/
4655         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4656         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4657       }
4658       else
4659       {
4660         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4661         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4662       }
4663       fis->d.reserved4      = 0;
4664       fis->d.control        = 0;                      /* FIS HOB bit clear */
4665       fis->d.reserved5      = 0;
4666 
4667       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4668     }
4669     else
4670     {
4671       /* case 4 */
4672       /* READ SECTORS EXT for easier implemetation */
4673       SM_DBG5(("smsatRead6: case 4\n"));
4674 
4675       fis->h.fisType        = 0x27;                   /* Reg host to device */
4676       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4677       fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
4678       fis->h.features       = 0;                      /* FIS reserve */
4679       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4680       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4681       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4682       fis->d.device         = 0x40;                   /* FIS LBA mode set */
4683       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4684       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4685       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4686       fis->d.featuresExp    = 0;                      /* FIS reserve */
4687       if (tl == 0)
4688       {
4689         /* sector count is 256, 0x100*/
4690         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4691         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4692       }
4693       else
4694       {
4695         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4696         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4697       }
4698       fis->d.reserved4      = 0;
4699       fis->d.control        = 0;                      /* FIS HOB bit clear */
4700       fis->d.reserved5      = 0;
4701 
4702       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
4703     }
4704   }
4705 
4706   /* case 5 */
4707   if (pSatDevData->satNCQ == agTRUE)
4708   {
4709     /* READ FPDMA QUEUED */
4710     if (pSatDevData->sat48BitSupport != agTRUE)
4711     {
4712       /* sanity check */
4713       SM_DBG1(("smsatRead6: case 5 !!! error NCQ but 28 bit address support!!!\n"));
4714       smsatSetSensePayload( pSense,
4715                             SCSI_SNSKEY_ILLEGAL_REQUEST,
4716                             0,
4717                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4718                             satIOContext);
4719 
4720       /*smEnqueueIO(smRoot, satIOContext);*/
4721 
4722       tdsmIOCompletedCB( smRoot,
4723                          smIORequest,
4724                          smIOSuccess,
4725                          SCSI_STAT_CHECK_CONDITION,
4726                          satIOContext->pSmSenseData,
4727                          satIOContext->interruptContext );
4728       return SM_RC_SUCCESS;
4729     }
4730     SM_DBG5(("smsatRead6: case 5\n"));
4731 
4732     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
4733 
4734     fis->h.fisType        = 0x27;                   /* Reg host to device */
4735     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4736     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
4737     fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4738     fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4739     fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4740     fis->d.device         = 0x40;                   /* FIS FUA clear */
4741     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4742     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4743     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4744     if (tl == 0)
4745     {
4746       /* sector count is 256, 0x100*/
4747       fis->h.features       = 0;                         /* FIS sector count (7:0) */
4748       fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
4749     }
4750     else
4751     {
4752       fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4753       fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
4754     }
4755     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4756     fis->d.sectorCountExp = 0;
4757     fis->d.reserved4      = 0;
4758     fis->d.control        = 0;                      /* FIS HOB bit clear */
4759     fis->d.reserved5      = 0;
4760 
4761     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
4762   }
4763 
4764    /* Initialize CB for SATA completion.
4765    */
4766   satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
4767 
4768   /*
4769    * Prepare SGL and send FIS to LL layer.
4770    */
4771   satIOContext->reqType = agRequestType;       /* Save it */
4772 
4773   status = smsataLLIOStart( smRoot,
4774                             smIORequest,
4775                             smDeviceHandle,
4776                             smScsiRequest,
4777                             satIOContext);
4778   return (status);
4779 
4780 }
4781 
4782 osGLOBAL FORCEINLINE bit32
4783 smsatRead10(
4784             smRoot_t                  *smRoot,
4785             smIORequest_t             *smIORequest,
4786             smDeviceHandle_t          *smDeviceHandle,
4787             smScsiInitiatorRequest_t  *smScsiRequest,
4788             smSatIOContext_t            *satIOContext
4789      )
4790 {
4791   smDeviceData_t            *pSatDevData = satIOContext->pSatDevData;
4792   smScsiRspSense_t          *pSense      = satIOContext->pSense;
4793   smIniScsiCmnd_t           *scsiCmnd    = &smScsiRequest->scsiCmnd;
4794   agsaFisRegHostToDevice_t  *fis         = satIOContext->pFis;
4795 
4796   bit32                     status;
4797   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4798   bit32                     lba = 0;
4799   bit32                     tl = 0;
4800   bit32                     LoopNum = 1;
4801   bit8                      LBA[8];
4802   bit8                      TL[8];
4803   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
4804 
4805   SM_DBG2(("smsatRead10: start\n"));
4806   SM_DBG2(("smsatRead10: pSatDevData did=%d\n", pSatDevData->id));
4807   //  smhexdump("smsatRead10", (bit8 *)scsiCmnd->cdb, 10);
4808 
4809   /* checking FUA_NV */
4810   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
4811   {
4812     smsatSetSensePayload( pSense,
4813                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4814                           0,
4815                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4816                           satIOContext);
4817 
4818     /*smEnqueueIO(smRoot, satIOContext);*/
4819 
4820     tdsmIOCompletedCB( smRoot,
4821                        smIORequest,
4822                        smIOSuccess,
4823                        SCSI_STAT_CHECK_CONDITION,
4824                        satIOContext->pSmSenseData,
4825                        satIOContext->interruptContext );
4826 
4827     SM_DBG1(("smsatRead10: return FUA_NV!!!\n"));
4828     return SM_RC_SUCCESS;
4829 
4830   }
4831 
4832   /* checking CONTROL */
4833   /* NACA == 1 or LINK == 1*/
4834   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
4835   {
4836     smsatSetSensePayload( pSense,
4837                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4838                           0,
4839                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4840                           satIOContext);
4841 
4842     /*smEnqueueIO(smRoot, satIOContext);*/
4843 
4844     tdsmIOCompletedCB( smRoot,
4845                        smIORequest,
4846                        smIOSuccess,
4847                        SCSI_STAT_CHECK_CONDITION,
4848                        satIOContext->pSmSenseData,
4849                        satIOContext->interruptContext );
4850 
4851     SM_DBG1(("smsatRead10: return control!!!\n"));
4852     return SM_RC_SUCCESS;
4853   }
4854   /*
4855   sm_memset(LBA, 0, sizeof(LBA));
4856   sm_memset(TL, 0, sizeof(TL));
4857   */
4858   /* do not use memcpy due to indexing in LBA and TL */
4859   LBA[0] = 0;                  /* MSB */
4860   LBA[1] = 0;
4861   LBA[2] = 0;
4862   LBA[3] = 0;
4863   LBA[4] = scsiCmnd->cdb[2];
4864   LBA[5] = scsiCmnd->cdb[3];
4865   LBA[6] = scsiCmnd->cdb[4];
4866   LBA[7] = scsiCmnd->cdb[5];   /* LSB */
4867 
4868   TL[0] = 0;
4869   TL[1] = 0;
4870   TL[2] = 0;
4871   TL[3] = 0;
4872   TL[4] = 0;
4873   TL[5] = 0;
4874   TL[6] = scsiCmnd->cdb[7];
4875   TL[7] = scsiCmnd->cdb[8];    /* LSB */
4876 
4877 
4878   /* cbd10; computing LBA and transfer length */
4879   lba = (scsiCmnd->cdb[2] << 24) + (scsiCmnd->cdb[3] << 16)
4880         + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
4881   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
4882 
4883 
4884   SM_DBG5(("smsatRead10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext)));
4885   SM_DBG5(("smsatRead10: lba 0x%x functioned lba 0x%x\n", lba, smsatComputeCDB10LBA(satIOContext)));
4886   SM_DBG5(("smsatRead10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext)));
4887 
4888   /* Table 34, 9.1, p 46 */
4889   /*
4890     note: As of 2/10/2006, no support for DMA QUEUED
4891    */
4892 
4893   /*
4894     Table 34, 9.1, p 46, b
4895     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4896     return check condition
4897   */
4898 
4899   if (pSatDevData->satNCQ != agTRUE &&
4900       pSatDevData->sat48BitSupport != agTRUE
4901       )
4902   {
4903     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
4904     if (AllChk)
4905     {
4906       SM_DBG1(("smsatRead10: return LBA out of range, not EXT!!!\n"));
4907       smsatSetSensePayload( pSense,
4908                             SCSI_SNSKEY_ILLEGAL_REQUEST,
4909                             0,
4910                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4911                             satIOContext);
4912 
4913       /*smEnqueueIO(smRoot, satIOContext);*/
4914 
4915       tdsmIOCompletedCB( smRoot,
4916                          smIORequest,
4917                          smIOSuccess,
4918                          SCSI_STAT_CHECK_CONDITION,
4919                          satIOContext->pSmSenseData,
4920                          satIOContext->interruptContext );
4921 
4922       return SM_RC_SUCCESS;
4923     }
4924   }
4925   else
4926   {
4927     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
4928     if (AllChk)
4929     {
4930       SM_DBG1(("smsatRead10: return LBA out of range, EXT!!!\n"));
4931       smsatSetSensePayload( pSense,
4932                             SCSI_SNSKEY_ILLEGAL_REQUEST,
4933                             0,
4934                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4935                             satIOContext);
4936 
4937       /*smEnqueueIO(smRoot, satIOContext);*/
4938 
4939       tdsmIOCompletedCB( smRoot,
4940                          smIORequest,
4941                          smIOSuccess,
4942                          SCSI_STAT_CHECK_CONDITION,
4943                          satIOContext->pSmSenseData,
4944                          satIOContext->interruptContext );
4945 
4946     return SM_RC_SUCCESS;
4947     }
4948   }
4949     /* case 5 */
4950   if (pSatDevData->satNCQ == agTRUE)
4951   {
4952     /* READ FPDMA QUEUED */
4953     if (pSatDevData->sat48BitSupport != agTRUE)
4954     {
4955       SM_DBG1(("smsatRead10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
4956       smsatSetSensePayload( pSense,
4957                             SCSI_SNSKEY_ILLEGAL_REQUEST,
4958                             0,
4959                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4960                             satIOContext);
4961 
4962       /*smEnqueueIO(smRoot, satIOContext);*/
4963 
4964       tdsmIOCompletedCB( smRoot,
4965                          smIORequest,
4966                          smIOSuccess,
4967                          SCSI_STAT_CHECK_CONDITION,
4968                          satIOContext->pSmSenseData,
4969                          satIOContext->interruptContext );
4970       return SM_RC_SUCCESS;
4971     }
4972 
4973     SM_DBG6(("smsatRead10: case 5\n"));
4974 
4975     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
4976 
4977     fis->h.fisType        = 0x27;                   /* Reg host to device */
4978     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4979     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
4980     fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4981     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4982     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4983     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4984 
4985     /* Check FUA bit */
4986     if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
4987       fis->d.device       = 0xC0;                   /* FIS FUA set */
4988     else
4989       fis->d.device       = 0x40;                   /* FIS FUA clear */
4990 
4991     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4992     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4993     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4994     fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4995     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4996     fis->d.sectorCountExp = 0;
4997     fis->d.reserved4      = 0;
4998     fis->d.control        = 0;                      /* FIS HOB bit clear */
4999     fis->d.reserved5      = 0;
5000 
5001     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
5002     satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
5003   }
5004   else if (pSatDevData->sat48BitSupport == agTRUE) /* case 3 and 4 */
5005   {
5006     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5007     {
5008       /* case 3 */
5009       /* READ DMA EXT */
5010       SM_DBG5(("smsatRead10: case 3\n"));
5011       fis->h.fisType        = 0x27;                   /* Reg host to device */
5012 
5013       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5014       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
5015       fis->h.features       = 0;                      /* FIS reserve */
5016       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5017       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5018       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5019       fis->d.device         = 0x40;                   /* FIS LBA mode set */
5020       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5021       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5022       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5023       fis->d.featuresExp    = 0;                      /* FIS reserve */
5024       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5025       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
5026       fis->d.reserved4      = 0;
5027       fis->d.control        = 0;                      /* FIS HOB bit clear */
5028       fis->d.reserved5      = 0;
5029 
5030       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5031       satIOContext->ATACmd = SAT_READ_DMA_EXT;
5032 
5033     }
5034     else
5035     {
5036       /* case 4 */
5037       /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5038       /* READ SECTORS EXT for easier implemetation */
5039       SM_DBG5(("smsatRead10: case 4\n"));
5040       fis->h.fisType        = 0x27;                   /* Reg host to device */
5041       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5042 
5043       /* Check FUA bit */
5044       if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
5045       {
5046 
5047         /* for now, no support for FUA */
5048         smsatSetSensePayload( pSense,
5049                               SCSI_SNSKEY_ILLEGAL_REQUEST,
5050                               0,
5051                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5052                               satIOContext);
5053 
5054         /*smEnqueueIO(smRoot, satIOContext);*/
5055 
5056         tdsmIOCompletedCB( smRoot,
5057                            smIORequest,
5058                            smIOSuccess,
5059                            SCSI_STAT_CHECK_CONDITION,
5060                            satIOContext->pSmSenseData,
5061                            satIOContext->interruptContext );
5062         return SM_RC_SUCCESS;
5063       }
5064 
5065       fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
5066 
5067       fis->h.features       = 0;                      /* FIS reserve */
5068       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5069       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5070       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5071       fis->d.device         = 0x40;                   /* FIS LBA mode set */
5072       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5073       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5074       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5075       fis->d.featuresExp    = 0;                      /* FIS reserve */
5076       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5077       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
5078       fis->d.reserved4      = 0;
5079       fis->d.control        = 0;                      /* FIS HOB bit clear */
5080       fis->d.reserved5      = 0;
5081 
5082       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5083       satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
5084     }
5085   }
5086   else/* case 1 and 2 */
5087   {
5088       if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5089       {
5090         /* case 2 */
5091         /* READ DMA*/
5092         /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */
5093         SM_DBG5(("smsatRead10: case 2\n"));
5094 
5095 
5096         fis->h.fisType        = 0x27;                   /* Reg host to device */
5097         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5098         fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
5099         fis->h.features       = 0;                      /* FIS reserve */
5100         fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5101         fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5102         fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5103         fis->d.device         =
5104           (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5105         fis->d.lbaLowExp      = 0;
5106         fis->d.lbaMidExp      = 0;
5107         fis->d.lbaHighExp     = 0;
5108         fis->d.featuresExp    = 0;
5109         fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5110         fis->d.sectorCountExp = 0;
5111         fis->d.reserved4      = 0;
5112         fis->d.control        = 0;                      /* FIS HOB bit clear */
5113         fis->d.reserved5      = 0;
5114 
5115 
5116         agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5117         satIOContext->ATACmd = SAT_READ_DMA;
5118       }
5119       else
5120       {
5121         /* case 1 */
5122         /* READ MULTIPLE or READ SECTOR(S) */
5123         /* READ SECTORS for easier implemetation */
5124         /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */
5125         SM_DBG5(("smsatRead10: case 1\n"));
5126 
5127         fis->h.fisType        = 0x27;                   /* Reg host to device */
5128         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5129         fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
5130         fis->h.features       = 0;                      /* FIS reserve */
5131         fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5132         fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5133         fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5134         fis->d.device         =
5135           (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5136         fis->d.lbaLowExp      = 0;
5137         fis->d.lbaMidExp      = 0;
5138         fis->d.lbaHighExp     = 0;
5139         fis->d.featuresExp    = 0;
5140         fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
5141         fis->d.sectorCountExp = 0;
5142         fis->d.reserved4      = 0;
5143         fis->d.control        = 0;                      /* FIS HOB bit clear */
5144         fis->d.reserved5      = 0;
5145 
5146 
5147         agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5148         satIOContext->ATACmd = SAT_READ_SECTORS;
5149     }
5150   }
5151   //  smhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
5152 
5153   /* saves the current LBA and orginal TL */
5154   satIOContext->currentLBA = lba;
5155   satIOContext->OrgTL = tl;
5156 
5157  /*
5158     computing number of loop and remainder for tl
5159     0xFF in case not ext
5160     0xFFFF in case EXT
5161   */
5162   if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5163   {
5164     LoopNum = smsatComputeLoopNum(tl, 0x100);
5165   }
5166   else
5167   {
5168      /* SAT_READ_FPDMA_QUEUED */
5169      /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5170      LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5171   }
5172 
5173   satIOContext->LoopNum = LoopNum;
5174 
5175   /* Initialize CB for SATA completion.
5176    */
5177   if (LoopNum == 1)
5178   {
5179     SM_DBG5(("smsatRead10: NON CHAINED data\n"));
5180     satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
5181   }
5182   else
5183   {
5184     SM_DBG2(("smsatRead10: CHAINED data!!!\n"));
5185 
5186     /* re-setting tl */
5187     if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5188     {
5189       fis->d.sectorCount    = 0x0;
5190       smsatSplitSGL(smRoot,
5191                     smIORequest,
5192                     smDeviceHandle,
5193                     smScsiRequest,
5194                     satIOContext,
5195                     NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */
5196                     (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5197                     agTRUE);
5198     }
5199     else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5200     {
5201       /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5202       fis->d.sectorCount    = 0xFF;
5203       fis->d.sectorCountExp = 0xFF;
5204       smsatSplitSGL(smRoot,
5205                     smIORequest,
5206                     smDeviceHandle,
5207                     smScsiRequest,
5208                     satIOContext,
5209                     BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
5210                     (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5211                     agTRUE);
5212     }
5213     else
5214     {
5215       /* SAT_READ_FPDMA_QUEUED */
5216       fis->h.features       = 0xFF;
5217       fis->d.featuresExp    = 0xFF;
5218       smsatSplitSGL(smRoot,
5219                     smIORequest,
5220                     smDeviceHandle,
5221                     smScsiRequest,
5222                     satIOContext,
5223                     BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
5224                     (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5225                     agTRUE);
5226     }
5227 
5228     /* chained data */
5229     satIOContext->satCompleteCB = &smsatChainedDataIOCB;
5230 
5231   }
5232 
5233   /*
5234    * Prepare SGL and send FIS to LL layer.
5235    */
5236   satIOContext->reqType = agRequestType;       /* Save it */
5237 
5238   status = smsataLLIOStart( smRoot,
5239                             smIORequest,
5240                             smDeviceHandle,
5241                             smScsiRequest,
5242                             satIOContext);
5243 
5244   SM_DBG5(("smsatRead10: return\n"));
5245   return (status);
5246 
5247 }
5248 
5249 osGLOBAL bit32
5250 smsatRead12(
5251             smRoot_t                  *smRoot,
5252             smIORequest_t             *smIORequest,
5253             smDeviceHandle_t          *smDeviceHandle,
5254             smScsiInitiatorRequest_t  *smScsiRequest,
5255             smSatIOContext_t            *satIOContext
5256      )
5257 {
5258   bit32                     status;
5259   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5260   smDeviceData_t            *pSatDevData;
5261   smScsiRspSense_t          *pSense;
5262   smIniScsiCmnd_t           *scsiCmnd;
5263   agsaFisRegHostToDevice_t  *fis;
5264   bit32                     lba = 0;
5265   bit32                     tl = 0;
5266   bit32                     LoopNum = 1;
5267   bit8                      LBA[8];
5268   bit8                      TL[8];
5269   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
5270 
5271   pSense        = satIOContext->pSense;
5272   pSatDevData   = satIOContext->pSatDevData;
5273   scsiCmnd      = &smScsiRequest->scsiCmnd;
5274   fis           = satIOContext->pFis;
5275 
5276   SM_DBG5(("smsatRead12: start\n"));
5277 
5278   /* checking FUA_NV */
5279   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
5280   {
5281     smsatSetSensePayload( pSense,
5282                           SCSI_SNSKEY_ILLEGAL_REQUEST,
5283                           0,
5284                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5285                           satIOContext);
5286 
5287     /*smEnqueueIO(smRoot, satIOContext);*/
5288 
5289     tdsmIOCompletedCB( smRoot,
5290                        smIORequest,
5291                        smIOSuccess,
5292                        SCSI_STAT_CHECK_CONDITION,
5293                        satIOContext->pSmSenseData,
5294                        satIOContext->interruptContext );
5295 
5296     SM_DBG1(("smsatRead12: return FUA_NV!!!\n"));
5297     return SM_RC_SUCCESS;
5298 
5299   }
5300 
5301   /* checking CONTROL */
5302   /* NACA == 1 or LINK == 1*/
5303   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
5304   {
5305     smsatSetSensePayload( pSense,
5306                           SCSI_SNSKEY_ILLEGAL_REQUEST,
5307                           0,
5308                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5309                           satIOContext);
5310 
5311     /*smEnqueueIO(smRoot, satIOContext);*/
5312 
5313     tdsmIOCompletedCB( smRoot,
5314                        smIORequest,
5315                        smIOSuccess,
5316                        SCSI_STAT_CHECK_CONDITION,
5317                        satIOContext->pSmSenseData,
5318                        satIOContext->interruptContext );
5319 
5320     SM_DBG1(("smsatRead12: return control!!!\n"));
5321     return SM_RC_SUCCESS;
5322   }
5323 
5324   sm_memset(LBA, 0, sizeof(LBA));
5325   sm_memset(TL, 0, sizeof(TL));
5326 
5327   /* do not use memcpy due to indexing in LBA and TL */
5328   LBA[0] = 0;                  /* MSB */
5329   LBA[1] = 0;
5330   LBA[2] = 0;
5331   LBA[3] = 0;
5332   LBA[4] = scsiCmnd->cdb[2];
5333   LBA[5] = scsiCmnd->cdb[3];
5334   LBA[6] = scsiCmnd->cdb[4];
5335   LBA[7] = scsiCmnd->cdb[5];   /* LSB */
5336 
5337   TL[0] = 0;                   /* MSB */
5338   TL[1] = 0;
5339   TL[2] = 0;
5340   TL[3] = 0;
5341   TL[4] = scsiCmnd->cdb[6];
5342   TL[5] = scsiCmnd->cdb[7];
5343   TL[6] = scsiCmnd->cdb[8];
5344   TL[7] = scsiCmnd->cdb[9];   	/* LSB */
5345 
5346 
5347   lba = smsatComputeCDB12LBA(satIOContext);
5348   tl = smsatComputeCDB12TL(satIOContext);
5349 
5350   /* Table 34, 9.1, p 46 */
5351   /*
5352     note: As of 2/10/2006, no support for DMA QUEUED
5353    */
5354 
5355   /*
5356     Table 34, 9.1, p 46, b
5357     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
5358     return check condition
5359   */
5360   if (pSatDevData->satNCQ != agTRUE &&
5361       pSatDevData->sat48BitSupport != agTRUE
5362       )
5363   {
5364 
5365     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
5366     if (AllChk)
5367     {
5368       SM_DBG1(("smsatRead12: return LBA out of range, not EXT!!!\n"));
5369       smsatSetSensePayload( pSense,
5370                             SCSI_SNSKEY_ILLEGAL_REQUEST,
5371                             0,
5372                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5373                             satIOContext);
5374 
5375       /*smEnqueueIO(smRoot, satIOContext);*/
5376 
5377       tdsmIOCompletedCB( smRoot,
5378                          smIORequest,
5379                          smIOSuccess,
5380                          SCSI_STAT_CHECK_CONDITION,
5381                          satIOContext->pSmSenseData,
5382                          satIOContext->interruptContext );
5383 
5384     return SM_RC_SUCCESS;
5385     }
5386   }
5387   else
5388   {
5389     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
5390     if (AllChk)
5391     {
5392       SM_DBG1(("smsatRead12: return LBA out of range, EXT!!!\n"));
5393       smsatSetSensePayload( pSense,
5394                             SCSI_SNSKEY_ILLEGAL_REQUEST,
5395                             0,
5396                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5397                             satIOContext);
5398 
5399       /*smEnqueueIO(smRoot, satIOContext);*/
5400 
5401       tdsmIOCompletedCB( smRoot,
5402                          smIORequest,
5403                          smIOSuccess,
5404                          SCSI_STAT_CHECK_CONDITION,
5405                          satIOContext->pSmSenseData,
5406                          satIOContext->interruptContext );
5407 
5408     return SM_RC_SUCCESS;
5409     }
5410   }
5411 
5412   /* case 1 and 2 */
5413     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5414     {
5415       /* case 2 */
5416       /* READ DMA*/
5417       /* in case that we can't fit the transfer length,
5418          we need to make it fit by sending multiple ATA cmnds */
5419       SM_DBG5(("smsatRead12: case 2\n"));
5420 
5421 
5422       fis->h.fisType        = 0x27;                   /* Reg host to device */
5423       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5424       fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
5425       fis->h.features       = 0;                      /* FIS reserve */
5426       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5427       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5428       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5429       fis->d.device         =
5430         (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5431       fis->d.lbaLowExp      = 0;
5432       fis->d.lbaMidExp      = 0;
5433       fis->d.lbaHighExp     = 0;
5434       fis->d.featuresExp    = 0;
5435       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5436       fis->d.sectorCountExp = 0;
5437       fis->d.reserved4      = 0;
5438       fis->d.control        = 0;                      /* FIS HOB bit clear */
5439       fis->d.reserved5      = 0;
5440 
5441 
5442       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5443       satIOContext->ATACmd = SAT_READ_DMA;
5444     }
5445     else
5446     {
5447       /* case 1 */
5448       /* READ MULTIPLE or READ SECTOR(S) */
5449       /* READ SECTORS for easier implemetation */
5450       /* can't fit the transfer length but need to make it fit by sending multiple*/
5451       SM_DBG5(("smsatRead12: case 1\n"));
5452 
5453       fis->h.fisType        = 0x27;                   /* Reg host to device */
5454       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5455       fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
5456       fis->h.features       = 0;                      /* FIS reserve */
5457       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5458       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5459       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5460       fis->d.device         =
5461         (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5462       fis->d.lbaLowExp      = 0;
5463       fis->d.lbaMidExp      = 0;
5464       fis->d.lbaHighExp     = 0;
5465       fis->d.featuresExp    = 0;
5466       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5467       fis->d.sectorCountExp = 0;
5468       fis->d.reserved4      = 0;
5469       fis->d.control        = 0;                      /* FIS HOB bit clear */
5470       fis->d.reserved5      = 0;
5471 
5472 
5473       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5474       satIOContext->ATACmd = SAT_READ_SECTORS;
5475   }
5476 
5477   /* case 3 and 4 */
5478   if (pSatDevData->sat48BitSupport == agTRUE)
5479   {
5480     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5481     {
5482       /* case 3 */
5483       /* READ DMA EXT */
5484       SM_DBG5(("smsatRead12: case 3\n"));
5485       fis->h.fisType        = 0x27;                   /* Reg host to device */
5486 
5487       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5488       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
5489       fis->h.features       = 0;                      /* FIS reserve */
5490       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5491       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5492       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5493       fis->d.device         = 0x40;                   /* FIS LBA mode set */
5494       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5495       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5496       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5497       fis->d.featuresExp    = 0;                      /* FIS reserve */
5498       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5499       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
5500       fis->d.reserved4      = 0;
5501       fis->d.control        = 0;                      /* FIS HOB bit clear */
5502       fis->d.reserved5      = 0;
5503 
5504       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5505       satIOContext->ATACmd = SAT_READ_DMA_EXT;
5506 
5507     }
5508     else
5509     {
5510       /* case 4 */
5511       /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5512       /* READ SECTORS EXT for easier implemetation */
5513       SM_DBG5(("smsatRead12: case 4\n"));
5514       fis->h.fisType        = 0x27;                   /* Reg host to device */
5515       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5516 
5517       /* Check FUA bit */
5518       if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
5519       {
5520 
5521         /* for now, no support for FUA */
5522         smsatSetSensePayload( pSense,
5523                               SCSI_SNSKEY_ILLEGAL_REQUEST,
5524                               0,
5525                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5526                               satIOContext);
5527 
5528         /*smEnqueueIO(smRoot, satIOContext);*/
5529 
5530         tdsmIOCompletedCB( smRoot,
5531                            smIORequest,
5532                            smIOSuccess,
5533                            SCSI_STAT_CHECK_CONDITION,
5534                            satIOContext->pSmSenseData,
5535                            satIOContext->interruptContext );
5536         return SM_RC_SUCCESS;
5537       }
5538 
5539       fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
5540 
5541       fis->h.features       = 0;                      /* FIS reserve */
5542       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5543       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5544       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5545       fis->d.device         = 0x40;                   /* FIS LBA mode set */
5546       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5547       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5548       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5549       fis->d.featuresExp    = 0;                      /* FIS reserve */
5550       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5551       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
5552       fis->d.reserved4      = 0;
5553       fis->d.control        = 0;                      /* FIS HOB bit clear */
5554       fis->d.reserved5      = 0;
5555 
5556       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5557       satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
5558     }
5559   }
5560 
5561   /* case 5 */
5562   if (pSatDevData->satNCQ == agTRUE)
5563   {
5564     /* READ FPDMA QUEUED */
5565     if (pSatDevData->sat48BitSupport != agTRUE)
5566     {
5567       SM_DBG1(("smsatRead12: case 5 !!! error NCQ but 28 bit address support!!!\n"));
5568       smsatSetSensePayload( pSense,
5569                             SCSI_SNSKEY_ILLEGAL_REQUEST,
5570                             0,
5571                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5572                             satIOContext);
5573 
5574         /*smEnqueueIO(smRoot, satIOContext);*/
5575 
5576         tdsmIOCompletedCB( smRoot,
5577                            smIORequest,
5578                            smIOSuccess,
5579                            SCSI_STAT_CHECK_CONDITION,
5580                            satIOContext->pSmSenseData,
5581                            satIOContext->interruptContext );
5582       return SM_RC_SUCCESS;
5583     }
5584 
5585     SM_DBG6(("smsatRead12: case 5\n"));
5586 
5587     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
5588 
5589     fis->h.fisType        = 0x27;                   /* Reg host to device */
5590     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5591     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
5592     fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
5593     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
5594     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
5595     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
5596 
5597     /* Check FUA bit */
5598     if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
5599       fis->d.device       = 0xC0;                   /* FIS FUA set */
5600     else
5601       fis->d.device       = 0x40;                   /* FIS FUA clear */
5602 
5603     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
5604     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5605     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5606     fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
5607     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
5608     fis->d.sectorCountExp = 0;
5609     fis->d.reserved4      = 0;
5610     fis->d.control        = 0;                      /* FIS HOB bit clear */
5611     fis->d.reserved5      = 0;
5612 
5613     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
5614     satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
5615   }
5616 
5617   /* saves the current LBA and orginal TL */
5618   satIOContext->currentLBA = lba;
5619   satIOContext->OrgTL = tl;
5620 
5621   /*
5622     computing number of loop and remainder for tl
5623     0xFF in case not ext
5624     0xFFFF in case EXT
5625   */
5626   if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5627   {
5628     LoopNum = smsatComputeLoopNum(tl, 0xFF);
5629   }
5630   else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5631   {
5632     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5633     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5634   }
5635   else
5636   {
5637     /* SAT_READ_FPDMA_QUEUEDK */
5638     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5639   }
5640 
5641   satIOContext->LoopNum = LoopNum;
5642 
5643   if (LoopNum == 1)
5644   {
5645     SM_DBG5(("smsatRead12: NON CHAINED data\n"));
5646     satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
5647   }
5648   else
5649   {
5650     SM_DBG1(("smsatRead12: CHAINED data\n"));
5651     /* re-setting tl */
5652     if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5653     {
5654        fis->d.sectorCount    = 0xFF;
5655     }
5656     else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5657     {
5658       /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5659       fis->d.sectorCount    = 0xFF;
5660       fis->d.sectorCountExp = 0xFF;
5661     }
5662     else
5663     {
5664       /* SAT_READ_FPDMA_QUEUED */
5665       fis->h.features       = 0xFF;
5666       fis->d.featuresExp    = 0xFF;
5667     }
5668 
5669     /* chained data */
5670     satIOContext->satCompleteCB = &smsatChainedDataIOCB;
5671   }
5672 
5673   /*
5674    * Prepare SGL and send FIS to LL layer.
5675    */
5676   satIOContext->reqType = agRequestType;       /* Save it */
5677 
5678   status = smsataLLIOStart( smRoot,
5679                             smIORequest,
5680                             smDeviceHandle,
5681                             smScsiRequest,
5682                             satIOContext);
5683 
5684   SM_DBG5(("smsatRead12: return\n"));
5685   return (status);
5686 }
5687 
5688 osGLOBAL bit32
5689 smsatRead16(
5690             smRoot_t                  *smRoot,
5691             smIORequest_t             *smIORequest,
5692             smDeviceHandle_t          *smDeviceHandle,
5693             smScsiInitiatorRequest_t  *smScsiRequest,
5694             smSatIOContext_t            *satIOContext
5695      )
5696 {
5697   bit32                     status;
5698   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5699   smDeviceData_t            *pSatDevData;
5700   smScsiRspSense_t          *pSense;
5701   smIniScsiCmnd_t           *scsiCmnd;
5702   agsaFisRegHostToDevice_t  *fis;
5703   bit32                     lba = 0;
5704   bit32                     tl = 0;
5705   bit32                     LoopNum = 1;
5706   bit8                      LBA[8];
5707   bit8                      TL[8];
5708   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
5709 //  bit32                     limitExtChk = agFALSE; /* lba limit check for bit48 addressing check */
5710 
5711   pSense        = satIOContext->pSense;
5712   pSatDevData   = satIOContext->pSatDevData;
5713   scsiCmnd      = &smScsiRequest->scsiCmnd;
5714   fis           = satIOContext->pFis;
5715 
5716   SM_DBG5(("smsatRead16: start\n"));
5717 
5718   /* checking FUA_NV */
5719   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
5720   {
5721     smsatSetSensePayload( pSense,
5722                           SCSI_SNSKEY_ILLEGAL_REQUEST,
5723                           0,
5724                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5725                           satIOContext);
5726 
5727     /*smEnqueueIO(smRoot, satIOContext);*/
5728 
5729     tdsmIOCompletedCB( smRoot,
5730                        smIORequest,
5731                        smIOSuccess,
5732                        SCSI_STAT_CHECK_CONDITION,
5733                        satIOContext->pSmSenseData,
5734                        satIOContext->interruptContext );
5735 
5736     SM_DBG1(("smsatRead16: return FUA_NV!!!\n"));
5737     return SM_RC_SUCCESS;
5738 
5739   }
5740 
5741   /* checking CONTROL */
5742   /* NACA == 1 or LINK == 1*/
5743   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
5744   {
5745     smsatSetSensePayload( pSense,
5746                           SCSI_SNSKEY_ILLEGAL_REQUEST,
5747                           0,
5748                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5749                           satIOContext);
5750 
5751     /*smEnqueueIO(smRoot, satIOContext);*/
5752 
5753     tdsmIOCompletedCB( smRoot,
5754                        smIORequest,
5755                        smIOSuccess,
5756                        SCSI_STAT_CHECK_CONDITION,
5757                        satIOContext->pSmSenseData,
5758                        satIOContext->interruptContext );
5759 
5760     SM_DBG1(("smsatRead16: return control!!!\n"));
5761     return SM_RC_SUCCESS;
5762   }
5763 
5764 
5765   sm_memset(LBA, 0, sizeof(LBA));
5766   sm_memset(TL, 0, sizeof(TL));
5767 
5768 
5769   /* do not use memcpy due to indexing in LBA and TL */
5770   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
5771   LBA[1] = scsiCmnd->cdb[3];
5772   LBA[2] = scsiCmnd->cdb[4];
5773   LBA[3] = scsiCmnd->cdb[5];
5774   LBA[4] = scsiCmnd->cdb[6];
5775   LBA[5] = scsiCmnd->cdb[7];
5776   LBA[6] = scsiCmnd->cdb[8];
5777   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
5778 
5779   TL[0] = 0;
5780   TL[1] = 0;
5781   TL[2] = 0;
5782   TL[3] = 0;
5783   TL[4] = scsiCmnd->cdb[10];   /* MSB */
5784   TL[5] = scsiCmnd->cdb[11];
5785   TL[6] = scsiCmnd->cdb[12];
5786   TL[7] = scsiCmnd->cdb[13];   /* LSB */
5787 
5788 
5789 
5790 
5791  lba = smsatComputeCDB16LBA(satIOContext);
5792  tl = smsatComputeCDB16TL(satIOContext);
5793 
5794 
5795   /* Table 34, 9.1, p 46 */
5796   /*
5797     note: As of 2/10/2006, no support for DMA QUEUED
5798    */
5799 
5800   /*
5801     Table 34, 9.1, p 46, b
5802     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
5803     return check condition
5804   */
5805   if (pSatDevData->satNCQ != agTRUE &&
5806       pSatDevData->sat48BitSupport != agTRUE
5807       )
5808   {
5809     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
5810     if (AllChk)
5811     {
5812       SM_DBG1(("smsatRead16: return LBA out of range, not EXT!!!\n"));
5813 
5814       /*smEnqueueIO(smRoot, satIOContext);*/
5815 
5816 
5817       smsatSetSensePayload( pSense,
5818                             SCSI_SNSKEY_ILLEGAL_REQUEST,
5819                             0,
5820                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5821                             satIOContext);
5822 
5823       /*smEnqueueIO(smRoot, satIOContext);*/
5824 
5825       tdsmIOCompletedCB( smRoot,
5826                          smIORequest,
5827                          smIOSuccess,
5828                          SCSI_STAT_CHECK_CONDITION,
5829                          satIOContext->pSmSenseData,
5830                          satIOContext->interruptContext );
5831 
5832       return SM_RC_SUCCESS;
5833     }
5834   }
5835   else
5836   {
5837 //    rangeChk = smsatAddNComparebit64(LBA, TL);
5838 
5839     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
5840 
5841 
5842     if (AllChk)
5843     {
5844       SM_DBG1(("smsatRead16: return LBA out of range, EXT!!!\n"));
5845       smsatSetSensePayload( pSense,
5846                             SCSI_SNSKEY_ILLEGAL_REQUEST,
5847                             0,
5848                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5849                             satIOContext);
5850 
5851       /*smEnqueueIO(smRoot, satIOContext);*/
5852 
5853       tdsmIOCompletedCB( smRoot,
5854                          smIORequest,
5855                          smIOSuccess,
5856                          SCSI_STAT_CHECK_CONDITION,
5857                          satIOContext->pSmSenseData,
5858                          satIOContext->interruptContext );
5859 
5860       return SM_RC_SUCCESS;
5861     }
5862   }
5863 
5864   /* case 1 and 2 */
5865     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5866     {
5867       /* case 2 */
5868       /* READ DMA*/
5869       /* in case that we can't fit the transfer length,
5870          we need to make it fit by sending multiple ATA cmnds */
5871       SM_DBG5(("smsatRead16: case 2\n"));
5872 
5873 
5874       fis->h.fisType        = 0x27;                   /* Reg host to device */
5875       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5876       fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
5877       fis->h.features       = 0;                      /* FIS reserve */
5878       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5879       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5880       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5881       fis->d.device         =
5882         (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5883       fis->d.lbaLowExp      = 0;
5884       fis->d.lbaMidExp      = 0;
5885       fis->d.lbaHighExp     = 0;
5886       fis->d.featuresExp    = 0;
5887       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
5888       fis->d.sectorCountExp = 0;
5889       fis->d.reserved4      = 0;
5890       fis->d.control        = 0;                      /* FIS HOB bit clear */
5891       fis->d.reserved5      = 0;
5892 
5893 
5894       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5895       satIOContext->ATACmd = SAT_READ_DMA;
5896     }
5897     else
5898     {
5899       /* case 1 */
5900       /* READ MULTIPLE or READ SECTOR(S) */
5901       /* READ SECTORS for easier implemetation */
5902       /* can't fit the transfer length but need to make it fit by sending multiple*/
5903       SM_DBG5(("smsatRead16: case 1\n"));
5904 
5905       fis->h.fisType        = 0x27;                   /* Reg host to device */
5906       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5907       fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
5908       fis->h.features       = 0;                      /* FIS reserve */
5909       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5910       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5911       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5912       fis->d.device         =
5913         (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
5914       fis->d.lbaLowExp      = 0;
5915       fis->d.lbaMidExp      = 0;
5916       fis->d.lbaHighExp     = 0;
5917       fis->d.featuresExp    = 0;
5918       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
5919       fis->d.sectorCountExp = 0;
5920       fis->d.reserved4      = 0;
5921       fis->d.control        = 0;                      /* FIS HOB bit clear */
5922       fis->d.reserved5      = 0;
5923 
5924 
5925       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5926       satIOContext->ATACmd = SAT_READ_SECTORS;
5927   }
5928 
5929   /* case 3 and 4 */
5930   if (pSatDevData->sat48BitSupport == agTRUE)
5931   {
5932     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5933     {
5934       /* case 3 */
5935       /* READ DMA EXT */
5936       SM_DBG5(("smsatRead16: case 3\n"));
5937       fis->h.fisType        = 0x27;                   /* Reg host to device */
5938 
5939       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5940       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
5941       fis->h.features       = 0;                      /* FIS reserve */
5942       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5943       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5944       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5945       fis->d.device         = 0x40;                   /* FIS LBA mode set */
5946       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
5947       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
5948       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
5949       fis->d.featuresExp    = 0;                      /* FIS reserve */
5950       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
5951       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
5952       fis->d.reserved4      = 0;
5953       fis->d.control        = 0;                      /* FIS HOB bit clear */
5954       fis->d.reserved5      = 0;
5955 
5956       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5957       satIOContext->ATACmd = SAT_READ_DMA_EXT;
5958 
5959     }
5960     else
5961     {
5962       /* case 4 */
5963       /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5964       /* READ SECTORS EXT for easier implemetation */
5965       SM_DBG5(("smsatRead16: case 4\n"));
5966       fis->h.fisType        = 0x27;                   /* Reg host to device */
5967       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5968 
5969       /* Check FUA bit */
5970       if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
5971       {
5972         /* for now, no support for FUA */
5973         smsatSetSensePayload( pSense,
5974                               SCSI_SNSKEY_ILLEGAL_REQUEST,
5975                               0,
5976                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5977                               satIOContext);
5978 
5979         /*smEnqueueIO(smRoot, satIOContext);*/
5980 
5981         tdsmIOCompletedCB( smRoot,
5982                            smIORequest,
5983                            smIOSuccess,
5984                            SCSI_STAT_CHECK_CONDITION,
5985                            satIOContext->pSmSenseData,
5986                            satIOContext->interruptContext );
5987         return SM_RC_SUCCESS;
5988       }
5989 
5990       fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
5991 
5992       fis->h.features       = 0;                      /* FIS reserve */
5993       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
5994       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
5995       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
5996       fis->d.device         = 0x40;                   /* FIS LBA mode set */
5997       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
5998       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
5999       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
6000       fis->d.featuresExp    = 0;                      /* FIS reserve */
6001       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
6002       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
6003       fis->d.reserved4      = 0;
6004       fis->d.control        = 0;                      /* FIS HOB bit clear */
6005       fis->d.reserved5      = 0;
6006 
6007       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
6008       satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
6009     }
6010   }
6011 
6012 
6013   /* case 5 */
6014   if (pSatDevData->satNCQ == agTRUE)
6015   {
6016     /* READ FPDMA QUEUED */
6017     if (pSatDevData->sat48BitSupport != agTRUE)
6018     {
6019       SM_DBG1(("smsatRead16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6020       smsatSetSensePayload( pSense,
6021                             SCSI_SNSKEY_ILLEGAL_REQUEST,
6022                             0,
6023                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6024                             satIOContext);
6025 
6026       /*smEnqueueIO(smRoot, satIOContext);*/
6027 
6028       tdsmIOCompletedCB( smRoot,
6029                          smIORequest,
6030                          smIOSuccess,
6031                          SCSI_STAT_CHECK_CONDITION,
6032                          satIOContext->pSmSenseData,
6033                          satIOContext->interruptContext );
6034       return SM_RC_SUCCESS;
6035     }
6036 
6037     SM_DBG6(("smsatRead16: case 5\n"));
6038 
6039     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
6040 
6041     fis->h.fisType        = 0x27;                   /* Reg host to device */
6042     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6043     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
6044     fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
6045     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
6046     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
6047     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
6048 
6049     /* Check FUA bit */
6050     if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
6051       fis->d.device       = 0xC0;                   /* FIS FUA set */
6052     else
6053       fis->d.device       = 0x40;                   /* FIS FUA clear */
6054 
6055     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
6056     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
6057     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
6058     fis->d.featuresExp    = scsiCmnd->cdb[12];      /* FIS sector count (15:8) */
6059     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
6060     fis->d.sectorCountExp = 0;
6061     fis->d.reserved4      = 0;
6062     fis->d.control        = 0;                      /* FIS HOB bit clear */
6063     fis->d.reserved5      = 0;
6064 
6065     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
6066     satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
6067   }
6068 
6069   /* saves the current LBA and orginal TL */
6070   satIOContext->currentLBA = lba;
6071   satIOContext->OrgTL = tl;
6072 
6073   /*
6074     computing number of loop and remainder for tl
6075     0xFF in case not ext
6076     0xFFFF in case EXT
6077   */
6078   if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
6079   {
6080     LoopNum = smsatComputeLoopNum(tl, 0xFF);
6081   }
6082   else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
6083   {
6084     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6085     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6086   }
6087   else
6088   {
6089     /* SAT_READ_FPDMA_QUEUEDK */
6090     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6091   }
6092   satIOContext->LoopNum = LoopNum;
6093 
6094   if (LoopNum == 1)
6095   {
6096     SM_DBG5(("smsatRead16: NON CHAINED data\n"));
6097     satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6098   }
6099   else
6100   {
6101     SM_DBG1(("smsatRead16: CHAINED data!!!\n"));
6102     /* re-setting tl */
6103     if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
6104     {
6105        fis->d.sectorCount    = 0xFF;
6106     }
6107     else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
6108     {
6109       /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6110       fis->d.sectorCount    = 0xFF;
6111       fis->d.sectorCountExp = 0xFF;
6112     }
6113     else
6114     {
6115       /* SAT_READ_FPDMA_QUEUED */
6116       fis->h.features       = 0xFF;
6117       fis->d.featuresExp    = 0xFF;
6118     }
6119 
6120     /* chained data */
6121     satIOContext->satCompleteCB = &smsatChainedDataIOCB;
6122   }
6123 
6124   /*
6125    * Prepare SGL and send FIS to LL layer.
6126    */
6127   satIOContext->reqType = agRequestType;       /* Save it */
6128 
6129   status = smsataLLIOStart( smRoot,
6130                             smIORequest,
6131                             smDeviceHandle,
6132                             smScsiRequest,
6133                             satIOContext);
6134 
6135   SM_DBG5(("smsatRead16: return\n"));
6136   return (status);
6137 
6138 }
6139 
6140 osGLOBAL bit32
6141 smsatWrite6(
6142             smRoot_t                  *smRoot,
6143             smIORequest_t             *smIORequest,
6144             smDeviceHandle_t          *smDeviceHandle,
6145             smScsiInitiatorRequest_t  *smScsiRequest,
6146             smSatIOContext_t            *satIOContext
6147      )
6148 {
6149 
6150   bit32                     status;
6151   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6152   smDeviceData_t            *pSatDevData;
6153   smScsiRspSense_t          *pSense;
6154   smIniScsiCmnd_t           *scsiCmnd;
6155   agsaFisRegHostToDevice_t  *fis;
6156   bit32                     lba = 0;
6157   bit16                     tl = 0;
6158 
6159   pSense        = satIOContext->pSense;
6160   pSatDevData   = satIOContext->pSatDevData;
6161   scsiCmnd      = &smScsiRequest->scsiCmnd;
6162   fis           = satIOContext->pFis;
6163 
6164   SM_DBG5(("smsatWrite6: start\n"));
6165 
6166   /* checking CONTROL */
6167   /* NACA == 1 or LINK == 1*/
6168   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
6169   {
6170     smsatSetSensePayload( pSense,
6171                           SCSI_SNSKEY_ILLEGAL_REQUEST,
6172                           0,
6173                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6174                           satIOContext);
6175 
6176     /*smEnqueueIO(smRoot, satIOContext);*/
6177 
6178     tdsmIOCompletedCB( smRoot,
6179                        smIORequest,
6180                        smIOSuccess,
6181                        SCSI_STAT_CHECK_CONDITION,
6182                        satIOContext->pSmSenseData,
6183                        satIOContext->interruptContext );
6184 
6185     SM_DBG1(("smsatWrite6: return control!!!\n"));
6186     return SM_RC_SUCCESS;
6187   }
6188 
6189 
6190   /* cbd6; computing LBA and transfer length */
6191   lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
6192     + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
6193   tl = scsiCmnd->cdb[4];
6194 
6195 
6196   /* Table 34, 9.1, p 46 */
6197   /*
6198     note: As of 2/10/2006, no support for DMA QUEUED
6199    */
6200 
6201   /*
6202     Table 34, 9.1, p 46, b
6203     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
6204     return check condition
6205   */
6206   if (pSatDevData->satNCQ != agTRUE &&
6207       pSatDevData->sat48BitSupport != agTRUE
6208       )
6209   {
6210     if (lba > SAT_TR_LBA_LIMIT - 1)
6211     {
6212       smsatSetSensePayload( pSense,
6213                             SCSI_SNSKEY_ILLEGAL_REQUEST,
6214                             0,
6215                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6216                             satIOContext);
6217 
6218       /*smEnqueueIO(smRoot, satIOContext);*/
6219 
6220       tdsmIOCompletedCB( smRoot,
6221                          smIORequest,
6222                          smIOSuccess,
6223                          SCSI_STAT_CHECK_CONDITION,
6224                          satIOContext->pSmSenseData,
6225                          satIOContext->interruptContext );
6226 
6227     SM_DBG1(("smsatWrite6: return LBA out of range!!!\n"));
6228     return SM_RC_SUCCESS;
6229     }
6230   }
6231 
6232   /* case 1 and 2 */
6233   if (lba + tl <= SAT_TR_LBA_LIMIT)
6234   {
6235     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6236     {
6237       /* case 2 */
6238       /* WRITE DMA*/
6239       SM_DBG5(("smsatWrite6: case 2\n"));
6240 
6241 
6242       fis->h.fisType        = 0x27;                   /* Reg host to device */
6243       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6244       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
6245       fis->h.features       = 0;                      /* FIS reserve */
6246       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6247       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6248       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6249       fis->d.device         = 0x40;                   /* FIS LBA mode  */
6250       fis->d.lbaLowExp      = 0;
6251       fis->d.lbaMidExp      = 0;
6252       fis->d.lbaHighExp     = 0;
6253       fis->d.featuresExp    = 0;
6254       if (tl == 0)
6255       {
6256         /* temporary fix */
6257         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
6258       }
6259       else
6260       {
6261         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6262       }
6263       fis->d.sectorCountExp = 0;
6264       fis->d.reserved4      = 0;
6265       fis->d.control        = 0;                      /* FIS HOB bit clear */
6266       fis->d.reserved5      = 0;
6267 
6268       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6269     }
6270     else
6271     {
6272       /* case 1 */
6273       /* WRITE SECTORS for easier implemetation */
6274       SM_DBG5(("smsatWrite6: case 1\n"));
6275 
6276       fis->h.fisType        = 0x27;                   /* Reg host to device */
6277       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6278       fis->h.command        = SAT_WRITE_SECTORS;          /* 0xCA */
6279       fis->h.features       = 0;                      /* FIS reserve */
6280       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6281       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6282       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6283       fis->d.device         = 0x40;                   /* FIS LBA mode  */
6284       fis->d.lbaLowExp      = 0;
6285       fis->d.lbaMidExp      = 0;
6286       fis->d.lbaHighExp     = 0;
6287       fis->d.featuresExp    = 0;
6288       if (tl == 0)
6289       {
6290         /* temporary fix */
6291         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
6292       }
6293       else
6294       {
6295         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6296       }
6297       fis->d.sectorCountExp = 0;
6298       fis->d.reserved4      = 0;
6299       fis->d.control        = 0;                      /* FIS HOB bit clear */
6300       fis->d.reserved5      = 0;
6301 
6302       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6303 
6304     }
6305   }
6306 
6307   /* case 3 and 4 */
6308   if (pSatDevData->sat48BitSupport == agTRUE)
6309   {
6310     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6311     {
6312       /* case 3 */
6313       /* WRITE DMA EXT only */
6314       SM_DBG5(("smsatWrite6: case 3\n"));
6315       fis->h.fisType        = 0x27;                   /* Reg host to device */
6316       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6317       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
6318       fis->h.features       = 0;                      /* FIS reserve */
6319       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6320       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6321       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6322       fis->d.device         = 0x40;                   /* FIS LBA mode set */
6323       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
6324       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6325       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6326       fis->d.featuresExp    = 0;                      /* FIS reserve */
6327       if (tl == 0)
6328       {
6329         /* sector count is 256, 0x100*/
6330         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
6331         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
6332       }
6333       else
6334       {
6335         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6336         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
6337       }
6338       fis->d.reserved4      = 0;
6339       fis->d.control        = 0;                      /* FIS HOB bit clear */
6340       fis->d.reserved5      = 0;
6341 
6342       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6343     }
6344     else
6345     {
6346       /* case 4 */
6347       /* WRITE SECTORS EXT for easier implemetation */
6348       SM_DBG5(("smsatWrite6: case 4\n"));
6349 
6350       fis->h.fisType        = 0x27;                   /* Reg host to device */
6351       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6352       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
6353       fis->h.features       = 0;                      /* FIS reserve */
6354       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6355       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6356       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6357       fis->d.device         = 0x40;                   /* FIS LBA mode set */
6358       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
6359       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6360       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6361       fis->d.featuresExp    = 0;                      /* FIS reserve */
6362       if (tl == 0)
6363       {
6364         /* sector count is 256, 0x100*/
6365         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
6366         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
6367       }
6368       else
6369       {
6370         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6371         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
6372       }
6373       fis->d.reserved4      = 0;
6374       fis->d.control        = 0;                      /* FIS HOB bit clear */
6375       fis->d.reserved5      = 0;
6376 
6377       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6378     }
6379   }
6380 
6381    /* case 5 */
6382   if (pSatDevData->satNCQ == agTRUE)
6383   {
6384     /* WRITE FPDMA QUEUED */
6385     if (pSatDevData->sat48BitSupport != agTRUE)
6386     {
6387       /* sanity check */
6388       SM_DBG5(("smsatWrite6: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6389       smsatSetSensePayload( pSense,
6390                             SCSI_SNSKEY_ILLEGAL_REQUEST,
6391                             0,
6392                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6393                             satIOContext);
6394 
6395       /*smEnqueueIO(smRoot, satIOContext);*/
6396 
6397       tdsmIOCompletedCB( smRoot,
6398                          smIORequest,
6399                          smIOSuccess,
6400                          SCSI_STAT_CHECK_CONDITION,
6401                          satIOContext->pSmSenseData,
6402                          satIOContext->interruptContext );
6403       return SM_RC_SUCCESS;
6404     }
6405     SM_DBG5(("smsatWrite6: case 5\n"));
6406 
6407     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
6408 
6409     fis->h.fisType        = 0x27;                   /* Reg host to device */
6410     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6411     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
6412     fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
6413     fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
6414     fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
6415     fis->d.device         = 0x40;                   /* FIS FUA clear */
6416     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
6417     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6418     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6419     if (tl == 0)
6420     {
6421       /* sector count is 256, 0x100*/
6422       fis->h.features       = 0;                         /* FIS sector count (7:0) */
6423       fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
6424     }
6425     else
6426     {
6427       fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
6428       fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
6429     }
6430     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
6431     fis->d.sectorCountExp = 0;
6432     fis->d.reserved4      = 0;
6433     fis->d.control        = 0;                      /* FIS HOB bit clear */
6434     fis->d.reserved5      = 0;
6435 
6436     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
6437   }
6438 
6439   /* Initialize CB for SATA completion.
6440    */
6441   satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6442 
6443   /*
6444    * Prepare SGL and send FIS to LL layer.
6445    */
6446   satIOContext->reqType = agRequestType;       /* Save it */
6447 
6448   status = smsataLLIOStart( smRoot,
6449                             smIORequest,
6450                             smDeviceHandle,
6451                             smScsiRequest,
6452                             satIOContext);
6453   return (status);
6454 }
6455 
6456 osGLOBAL FORCEINLINE bit32
6457 smsatWrite10(
6458              smRoot_t                  *smRoot,
6459              smIORequest_t             *smIORequest,
6460              smDeviceHandle_t          *smDeviceHandle,
6461              smScsiInitiatorRequest_t  *smScsiRequest,
6462              smSatIOContext_t            *satIOContext
6463             )
6464 {
6465   smDeviceData_t           *pSatDevData = satIOContext->pSatDevData;
6466   smScsiRspSense_t         *pSense      = satIOContext->pSense;
6467   smIniScsiCmnd_t          *scsiCmnd    = &smScsiRequest->scsiCmnd;
6468   agsaFisRegHostToDevice_t *fis         =  satIOContext->pFis;
6469   bit32                     status      = SM_RC_FAILURE;
6470   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6471   bit32                     lba = 0;
6472   bit32                     tl = 0;
6473   bit32                     LoopNum = 1;
6474   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
6475   bit8                      LBA[8];
6476   bit8                      TL[8];
6477 
6478   SM_DBG2(("smsatWrite10: start\n"));
6479 
6480   /* checking FUA_NV */
6481   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
6482   {
6483     smsatSetSensePayload( pSense,
6484                           SCSI_SNSKEY_ILLEGAL_REQUEST,
6485                           0,
6486                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6487                           satIOContext);
6488 
6489     /*smEnqueueIO(smRoot, satIOContext);*/
6490 
6491     tdsmIOCompletedCB( smRoot,
6492                        smIORequest,
6493                        smIOSuccess,
6494                        SCSI_STAT_CHECK_CONDITION,
6495                        satIOContext->pSmSenseData,
6496                        satIOContext->interruptContext );
6497 
6498     SM_DBG1(("smsatWrite10: return FUA_NV!!!\n"));
6499     return SM_RC_SUCCESS;
6500 
6501   }
6502 
6503   /* checking CONTROL */
6504   /* NACA == 1 or LINK == 1*/
6505   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
6506   {
6507     smsatSetSensePayload( pSense,
6508                           SCSI_SNSKEY_ILLEGAL_REQUEST,
6509                           0,
6510                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6511                           satIOContext);
6512 
6513     /*smEnqueueIO(smRoot, satIOContext);*/
6514 
6515     tdsmIOCompletedCB( smRoot,
6516                        smIORequest,
6517                        smIOSuccess,
6518                        SCSI_STAT_CHECK_CONDITION,
6519                        satIOContext->pSmSenseData,
6520                        satIOContext->interruptContext );
6521 
6522     SM_DBG1(("smsatWrite10: return control!!!\n"));
6523     return SM_RC_SUCCESS;
6524   }
6525 /*
6526   sm_memset(LBA, 0, sizeof(LBA));
6527   sm_memset(TL, 0, sizeof(TL));
6528 */
6529   /* do not use memcpy due to indexing in LBA and TL */
6530   LBA[0] = 0;                  /* MSB */
6531   LBA[1] = 0;
6532   LBA[2] = 0;
6533   LBA[3] = 0;
6534   LBA[4] = scsiCmnd->cdb[2];
6535   LBA[5] = scsiCmnd->cdb[3];
6536   LBA[6] = scsiCmnd->cdb[4];
6537   LBA[7] = scsiCmnd->cdb[5];   /* LSB */
6538 
6539   TL[0] = 0;
6540   TL[1] = 0;
6541   TL[2] = 0;
6542   TL[3] = 0;
6543   TL[4] = 0;
6544   TL[5] = 0;
6545   TL[6] = scsiCmnd->cdb[7];
6546   TL[7] = scsiCmnd->cdb[8];  	/* LSB */
6547 
6548 
6549 
6550   /* cbd10; computing LBA and transfer length */
6551   lba = (scsiCmnd->cdb[2] << (24)) + (scsiCmnd->cdb[3] << (16))
6552     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
6553   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
6554 
6555   SM_DBG5(("smsatWrite10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext)));
6556   SM_DBG5(("smsatWrite10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext)));
6557 
6558   /* Table 34, 9.1, p 46 */
6559   /*
6560     note: As of 2/10/2006, no support for DMA QUEUED
6561    */
6562 
6563   /*
6564     Table 34, 9.1, p 46, b
6565     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
6566     return check condition
6567   */
6568   if (pSatDevData->satNCQ != agTRUE &&
6569       pSatDevData->sat48BitSupport != agTRUE
6570       )
6571   {
6572     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
6573     if (AllChk)
6574     {
6575      SM_DBG1(("smsatWrite10: return LBA out of range, not EXT!!!\n"));
6576      SM_DBG1(("smsatWrite10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
6577              scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
6578      SM_DBG1(("smsatWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
6579       smsatSetSensePayload( pSense,
6580                             SCSI_SNSKEY_ILLEGAL_REQUEST,
6581                             0,
6582                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6583                             satIOContext);
6584 
6585       /*smEnqueueIO(smRoot, satIOContext);*/
6586 
6587       tdsmIOCompletedCB( smRoot,
6588                          smIORequest,
6589                          smIOSuccess,
6590                          SCSI_STAT_CHECK_CONDITION,
6591                          satIOContext->pSmSenseData,
6592                          satIOContext->interruptContext );
6593 
6594     return SM_RC_SUCCESS;
6595     }
6596   }
6597   else
6598   {
6599     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
6600     if (AllChk)
6601     {
6602       SM_DBG1(("smsatWrite10: return LBA out of range, EXT!!!\n"));
6603       smsatSetSensePayload( pSense,
6604                             SCSI_SNSKEY_ILLEGAL_REQUEST,
6605                             0,
6606                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6607                             satIOContext);
6608 
6609     /*smEnqueueIO(smRoot, satIOContext);*/
6610 
6611     tdsmIOCompletedCB( smRoot,
6612                        smIORequest,
6613                        smIOSuccess,
6614                        SCSI_STAT_CHECK_CONDITION,
6615                        satIOContext->pSmSenseData,
6616                        satIOContext->interruptContext );
6617 
6618     return SM_RC_SUCCESS;
6619     }
6620 
6621   }
6622 
6623   /* case 5 */
6624   if (pSatDevData->satNCQ == agTRUE)
6625   {
6626     /* WRITE FPDMA QUEUED */
6627     if (pSatDevData->sat48BitSupport != agTRUE)
6628     {
6629       SM_DBG1(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6630       smsatSetSensePayload( pSense,
6631                             SCSI_SNSKEY_ILLEGAL_REQUEST,
6632                             0,
6633                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6634                             satIOContext);
6635 
6636       /*smEnqueueIO(smRoot, satIOContext);*/
6637 
6638       tdsmIOCompletedCB( smRoot,
6639                          smIORequest,
6640                          smIOSuccess,
6641                          SCSI_STAT_CHECK_CONDITION,
6642                          satIOContext->pSmSenseData,
6643                          satIOContext->interruptContext );
6644       return SM_RC_SUCCESS;
6645     }
6646     SM_DBG6(("smsatWrite10: case 5\n"));
6647 
6648     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
6649 
6650     fis->h.fisType        = 0x27;                   /* Reg host to device */
6651     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6652     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
6653     fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6654     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6655     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6656     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6657 
6658     /* Check FUA bit */
6659     if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
6660       fis->d.device       = 0xC0;                   /* FIS FUA set */
6661     else
6662       fis->d.device       = 0x40;                   /* FIS FUA clear */
6663 
6664     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
6665     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6666     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6667     fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
6668     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
6669     fis->d.sectorCountExp = 0;
6670     fis->d.reserved4      = 0;
6671     fis->d.control        = 0;                      /* FIS HOB bit clear */
6672     fis->d.reserved5      = 0;
6673 
6674     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
6675     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
6676   }
6677   /* case 3 and 4 */
6678   else if (pSatDevData->sat48BitSupport == agTRUE)
6679   {
6680     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6681     {
6682       /* case 3 */
6683       /* WRITE DMA EXT or WRITE DMA FUA EXT */
6684       SM_DBG5(("smsatWrite10: case 3\n"));
6685       fis->h.fisType        = 0x27;                   /* Reg host to device */
6686       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6687 
6688       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
6689       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
6690       satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
6691 
6692       fis->h.features       = 0;                      /* FIS reserve */
6693       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6694       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6695       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6696       fis->d.device         = 0x40;                   /* FIS LBA mode set */
6697       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
6698       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6699       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6700       fis->d.featuresExp    = 0;                      /* FIS reserve */
6701       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6702       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
6703       fis->d.reserved4      = 0;
6704       fis->d.control        = 0;                      /* FIS HOB bit clear */
6705       fis->d.reserved5      = 0;
6706 
6707       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6708     }
6709     else
6710     {
6711       /* case 4 */
6712       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
6713       /* WRITE SECTORS EXT for easier implemetation */
6714       SM_DBG5(("smsatWrite10: case 4\n"));
6715       fis->h.fisType        = 0x27;                   /* Reg host to device */
6716       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
6717       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
6718 
6719       fis->h.features       = 0;                      /* FIS reserve */
6720       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6721       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6722       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6723       fis->d.device         = 0x40;                   /* FIS LBA mode set */
6724       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
6725       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
6726       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
6727       fis->d.featuresExp    = 0;                      /* FIS reserve */
6728       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6729       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
6730       fis->d.reserved4      = 0;
6731       fis->d.control        = 0;                      /* FIS HOB bit clear */
6732       fis->d.reserved5      = 0;
6733 
6734       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6735       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
6736     }
6737   }
6738   else /* case 1 and 2 */
6739   {
6740     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6741     {
6742       /* case 2 */
6743       /* WRITE DMA*/
6744       /* can't fit the transfer length */
6745       SM_DBG5(("smsatWrite10: case 2\n"));
6746       fis->h.fisType        = 0x27;                   /* Reg host to device */
6747       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
6748       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
6749       fis->h.features       = 0;                      /* FIS reserve */
6750       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6751       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6752       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6753 
6754       /* FIS LBA mode set LBA (27:24) */
6755       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
6756 
6757       fis->d.lbaLowExp      = 0;
6758       fis->d.lbaMidExp      = 0;
6759       fis->d.lbaHighExp     = 0;
6760       fis->d.featuresExp    = 0;
6761       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6762       fis->d.sectorCountExp = 0;
6763       fis->d.reserved4      = 0;
6764       fis->d.control        = 0;                      /* FIS HOB bit clear */
6765       fis->d.reserved5      = 0;
6766 
6767       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6768       satIOContext->ATACmd = SAT_WRITE_DMA;
6769     }
6770     else
6771     {
6772       /* case 1 */
6773       /* WRITE MULTIPLE or WRITE SECTOR(S) */
6774       /* WRITE SECTORS for easier implemetation */
6775       /* can't fit the transfer length */
6776       SM_DBG5(("smsatWrite10: case 1\n"));
6777       fis->h.fisType        = 0x27;                   /* Reg host to device */
6778       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
6779       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
6780       fis->h.features       = 0;                      /* FIS reserve */
6781       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
6782       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
6783       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
6784 
6785       /* FIS LBA mode set LBA (27:24) */
6786       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
6787 
6788       fis->d.lbaLowExp      = 0;
6789       fis->d.lbaMidExp      = 0;
6790       fis->d.lbaHighExp     = 0;
6791       fis->d.featuresExp    = 0;
6792       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
6793       fis->d.sectorCountExp = 0;
6794       fis->d.reserved4      = 0;
6795       fis->d.control        = 0;                      /* FIS HOB bit clear */
6796       fis->d.reserved5      = 0;
6797 
6798       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6799       satIOContext->ATACmd = SAT_WRITE_SECTORS;
6800     }
6801   }
6802 
6803   //  smhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
6804 
6805   satIOContext->currentLBA = lba;
6806   satIOContext->OrgTL = tl;
6807 
6808   /*
6809     computing number of loop and remainder for tl
6810     0xFF in case not ext
6811     0xFFFF in case EXT
6812   */
6813   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
6814   {
6815     LoopNum = smsatComputeLoopNum(tl, 0x100);
6816   }
6817   else
6818   {
6819     /* SAT_WRITE_FPDMA_QUEUEDK */
6820     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6821     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6822   }
6823 
6824   satIOContext->LoopNum = LoopNum;
6825 
6826 
6827   if (LoopNum == 1)
6828   {
6829     SM_DBG5(("smsatWrite10: NON CHAINED data\n"));
6830     /* Initialize CB for SATA completion.
6831      */
6832     satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6833   }
6834   else
6835   {
6836     SM_DBG2(("smsatWrite10: CHAINED data!!!\n"));
6837     /* re-setting tl */
6838     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
6839     {
6840       fis->d.sectorCount    = 0x0;
6841       smsatSplitSGL(smRoot,
6842                     smIORequest,
6843                     smDeviceHandle,
6844                     smScsiRequest,
6845                     satIOContext,
6846                     NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */
6847                     (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6848                     agTRUE);
6849     }
6850     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
6851              fis->h.command == SAT_WRITE_DMA_EXT ||
6852              fis->h.command == SAT_WRITE_DMA_FUA_EXT
6853              )
6854     {
6855       fis->d.sectorCount    = 0xFF;
6856       fis->d.sectorCountExp = 0xFF;
6857       smsatSplitSGL(smRoot,
6858                     smIORequest,
6859                     smDeviceHandle,
6860                     smScsiRequest,
6861                     satIOContext,
6862                     BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
6863                     (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6864                     agTRUE);
6865     }
6866     else
6867     {
6868       /* SAT_WRITE_FPDMA_QUEUED */
6869       fis->h.features       = 0xFF;
6870       fis->d.featuresExp    = 0xFF;
6871       smsatSplitSGL(smRoot,
6872                     smIORequest,
6873                     smDeviceHandle,
6874                     smScsiRequest,
6875                     satIOContext,
6876                     BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
6877                     (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6878                     agTRUE);
6879     }
6880 
6881     /* Initialize CB for SATA completion.
6882      */
6883     satIOContext->satCompleteCB = &smsatChainedDataIOCB;
6884   }
6885 
6886 
6887   /*
6888    * Prepare SGL and send FIS to LL layer.
6889    */
6890   satIOContext->reqType = agRequestType;       /* Save it */
6891 
6892   status = smsataLLIOStart( smRoot,
6893                             smIORequest,
6894                             smDeviceHandle,
6895                             smScsiRequest,
6896                             satIOContext);
6897   return (status);
6898 }
6899 
6900 osGLOBAL bit32
6901 smsatWrite12(
6902              smRoot_t                  *smRoot,
6903              smIORequest_t             *smIORequest,
6904              smDeviceHandle_t          *smDeviceHandle,
6905              smScsiInitiatorRequest_t  *smScsiRequest,
6906              smSatIOContext_t            *satIOContext
6907             )
6908 {
6909   bit32                     status;
6910   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6911   smDeviceData_t            *pSatDevData;
6912   smScsiRspSense_t          *pSense;
6913   smIniScsiCmnd_t           *scsiCmnd;
6914   agsaFisRegHostToDevice_t  *fis;
6915   bit32                     lba = 0;
6916   bit32                     tl = 0;
6917   bit32                     LoopNum = 1;
6918   bit8                      LBA[8];
6919   bit8                      TL[8];
6920   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
6921 
6922   pSense        = satIOContext->pSense;
6923   pSatDevData   = satIOContext->pSatDevData;
6924   scsiCmnd      = &smScsiRequest->scsiCmnd;
6925   fis           = satIOContext->pFis;
6926 
6927   SM_DBG5(("smsatWrite12: start\n"));
6928 
6929   /* checking FUA_NV */
6930   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
6931   {
6932     smsatSetSensePayload( pSense,
6933                           SCSI_SNSKEY_ILLEGAL_REQUEST,
6934                           0,
6935                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6936                           satIOContext);
6937 
6938     /*smEnqueueIO(smRoot, satIOContext);*/
6939 
6940     tdsmIOCompletedCB( smRoot,
6941                        smIORequest,
6942                        smIOSuccess,
6943                        SCSI_STAT_CHECK_CONDITION,
6944                        satIOContext->pSmSenseData,
6945                        satIOContext->interruptContext );
6946 
6947     SM_DBG1(("smsatWrite12: return FUA_NV!!!\n"));
6948     return SM_RC_SUCCESS;
6949 
6950   }
6951 
6952 
6953   /* checking CONTROL */
6954   /* NACA == 1 or LINK == 1*/
6955   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
6956   {
6957     smsatSetSensePayload( pSense,
6958                           SCSI_SNSKEY_ILLEGAL_REQUEST,
6959                           0,
6960                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6961                           satIOContext);
6962 
6963     /*smEnqueueIO(smRoot, satIOContext);*/
6964 
6965     tdsmIOCompletedCB( smRoot,
6966                        smIORequest,
6967                        smIOSuccess,
6968                        SCSI_STAT_CHECK_CONDITION,
6969                        satIOContext->pSmSenseData,
6970                        satIOContext->interruptContext );
6971 
6972     SM_DBG1(("smsatWrite10: return control!!!\n"));
6973     return SM_RC_SUCCESS;
6974   }
6975 
6976 
6977   sm_memset(LBA, 0, sizeof(LBA));
6978   sm_memset(TL, 0, sizeof(TL));
6979 
6980   /* do not use memcpy due to indexing in LBA and TL */
6981   LBA[0] = 0;                  /* MSB */
6982   LBA[1] = 0;
6983   LBA[2] = 0;
6984   LBA[3] = 0;
6985   LBA[4] = scsiCmnd->cdb[2];
6986   LBA[5] = scsiCmnd->cdb[3];
6987   LBA[6] = scsiCmnd->cdb[4];
6988   LBA[7] = scsiCmnd->cdb[5];  	/* LSB */
6989 
6990   TL[0] = 0;                    /* MSB */
6991   TL[1] = 0;
6992   TL[2] = 0;
6993   TL[3] = 0;
6994   TL[4] = scsiCmnd->cdb[6];
6995   TL[5] = scsiCmnd->cdb[7];
6996   TL[6] = scsiCmnd->cdb[8];
6997   TL[7] = scsiCmnd->cdb[9];   	/* LSB */
6998 
6999 
7000   lba = smsatComputeCDB12LBA(satIOContext);
7001   tl = smsatComputeCDB12TL(satIOContext);
7002 
7003 
7004   /* Table 34, 9.1, p 46 */
7005   /*
7006     note: As of 2/10/2006, no support for DMA QUEUED
7007    */
7008 
7009   /*
7010     Table 34, 9.1, p 46, b
7011     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
7012     return check condition
7013   */
7014   if (pSatDevData->satNCQ != agTRUE &&
7015       pSatDevData->sat48BitSupport != agTRUE
7016       )
7017   {
7018     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7019 
7020       /*smEnqueueIO(smRoot, satIOContext);*/
7021 
7022 
7023 
7024     if (AllChk)
7025     {
7026       SM_DBG1(("smsatWrite12: return LBA out of range, not EXT!!!\n"));
7027       smsatSetSensePayload( pSense,
7028                             SCSI_SNSKEY_ILLEGAL_REQUEST,
7029                             0,
7030                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7031                             satIOContext);
7032 
7033       /*smEnqueueIO(smRoot, satIOContext);*/
7034 
7035       tdsmIOCompletedCB( smRoot,
7036                          smIORequest,
7037                          smIOSuccess,
7038                          SCSI_STAT_CHECK_CONDITION,
7039                          satIOContext->pSmSenseData,
7040                          satIOContext->interruptContext );
7041 
7042       return SM_RC_SUCCESS;
7043     }
7044   }
7045   else
7046   {
7047     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7048     if (AllChk)
7049     {
7050       SM_DBG1(("smsatWrite12: return LBA out of range, EXT!!!\n"));
7051       smsatSetSensePayload( pSense,
7052                             SCSI_SNSKEY_ILLEGAL_REQUEST,
7053                             0,
7054                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7055                             satIOContext);
7056       tdsmIOCompletedCB( smRoot,
7057                          smIORequest,
7058                          smIOSuccess,
7059                          SCSI_STAT_CHECK_CONDITION,
7060                          satIOContext->pSmSenseData,
7061                          satIOContext->interruptContext );
7062       return SM_RC_SUCCESS;
7063     }
7064   }
7065     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7066     {
7067       /* case 2 */
7068       /* WRITE DMA*/
7069       /* In case that we can't fit the transfer length, we loop */
7070       SM_DBG5(("smsatWrite10: case 2\n"));
7071       fis->h.fisType        = 0x27;                   /* Reg host to device */
7072       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7073       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
7074       fis->h.features       = 0;                      /* FIS reserve */
7075       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7076       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7077       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7078 
7079       /* FIS LBA mode set LBA (27:24) */
7080       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7081 
7082       fis->d.lbaLowExp      = 0;
7083       fis->d.lbaMidExp      = 0;
7084       fis->d.lbaHighExp     = 0;
7085       fis->d.featuresExp    = 0;
7086       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7087       fis->d.sectorCountExp = 0;
7088       fis->d.reserved4      = 0;
7089       fis->d.control        = 0;                      /* FIS HOB bit clear */
7090       fis->d.reserved5      = 0;
7091 
7092       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7093       satIOContext->ATACmd = SAT_WRITE_DMA;
7094     }
7095     else
7096     {
7097       /* case 1 */
7098       /* WRITE MULTIPLE or WRITE SECTOR(S) */
7099       /* WRITE SECTORS for easier implemetation */
7100       /* In case that we can't fit the transfer length, we loop */
7101       SM_DBG5(("smsatWrite10: case 1\n"));
7102       fis->h.fisType        = 0x27;                   /* Reg host to device */
7103       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7104       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
7105       fis->h.features       = 0;                      /* FIS reserve */
7106       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7107       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7108       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7109 
7110       /* FIS LBA mode set LBA (27:24) */
7111       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7112 
7113       fis->d.lbaLowExp      = 0;
7114       fis->d.lbaMidExp      = 0;
7115       fis->d.lbaHighExp     = 0;
7116       fis->d.featuresExp    = 0;
7117       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7118       fis->d.sectorCountExp = 0;
7119       fis->d.reserved4      = 0;
7120       fis->d.control        = 0;                      /* FIS HOB bit clear */
7121       fis->d.reserved5      = 0;
7122 
7123       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7124       satIOContext->ATACmd = SAT_WRITE_SECTORS;
7125   }
7126 
7127   /* case 3 and 4 */
7128   if (pSatDevData->sat48BitSupport == agTRUE)
7129   {
7130     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7131     {
7132       /* case 3 */
7133       /* WRITE DMA EXT or WRITE DMA FUA EXT */
7134       SM_DBG5(("smsatWrite10: case 3\n"));
7135       fis->h.fisType        = 0x27;                   /* Reg host to device */
7136       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7137 
7138       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
7139       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
7140 
7141       fis->h.features       = 0;                      /* FIS reserve */
7142       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7143       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7144       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7145       fis->d.device         = 0x40;                   /* FIS LBA mode set */
7146       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7147       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7148       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7149       fis->d.featuresExp    = 0;                      /* FIS reserve */
7150       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7151       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
7152       fis->d.reserved4      = 0;
7153       fis->d.control        = 0;                      /* FIS HOB bit clear */
7154       fis->d.reserved5      = 0;
7155 
7156       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7157       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
7158     }
7159     else
7160     {
7161       /* case 4 */
7162       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
7163       /* WRITE SECTORS EXT for easier implemetation */
7164       SM_DBG5(("smsatWrite10: case 4\n"));
7165       fis->h.fisType        = 0x27;                   /* Reg host to device */
7166       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7167       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
7168 
7169       fis->h.features       = 0;                      /* FIS reserve */
7170       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7171       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7172       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7173       fis->d.device         = 0x40;                   /* FIS LBA mode set */
7174       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7175       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7176       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7177       fis->d.featuresExp    = 0;                      /* FIS reserve */
7178       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7179       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
7180       fis->d.reserved4      = 0;
7181       fis->d.control        = 0;                      /* FIS HOB bit clear */
7182       fis->d.reserved5      = 0;
7183 
7184       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7185       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
7186     }
7187   }
7188 
7189   /* case 5 */
7190   if (pSatDevData->satNCQ == agTRUE)
7191   {
7192     /* WRITE FPDMA QUEUED */
7193     if (pSatDevData->sat48BitSupport != agTRUE)
7194     {
7195        SM_DBG5(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
7196        smsatSetSensePayload( pSense,
7197                              SCSI_SNSKEY_ILLEGAL_REQUEST,
7198                              0,
7199                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7200                              satIOContext);
7201 
7202        /*smEnqueueIO(smRoot, satIOContext);*/
7203 
7204        tdsmIOCompletedCB( smRoot,
7205                           smIORequest,
7206                           smIOSuccess,
7207                           SCSI_STAT_CHECK_CONDITION,
7208                           satIOContext->pSmSenseData,
7209                           satIOContext->interruptContext );
7210       return SM_RC_SUCCESS;
7211     }
7212     SM_DBG6(("smsatWrite10: case 5\n"));
7213 
7214     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
7215 
7216     fis->h.fisType        = 0x27;                   /* Reg host to device */
7217     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7218     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
7219     fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
7220     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7221     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7222     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7223 
7224     /* Check FUA bit */
7225     if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
7226       fis->d.device       = 0xC0;                   /* FIS FUA set */
7227     else
7228       fis->d.device       = 0x40;                   /* FIS FUA clear */
7229 
7230     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7231     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7232     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7233     fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
7234     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
7235     fis->d.sectorCountExp = 0;
7236     fis->d.reserved4      = 0;
7237     fis->d.control        = 0;                      /* FIS HOB bit clear */
7238     fis->d.reserved5      = 0;
7239 
7240     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
7241     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
7242   }
7243 
7244   satIOContext->currentLBA = lba;
7245   satIOContext->OrgTL = tl;
7246 
7247   /*
7248     computing number of loop and remainder for tl
7249     0xFF in case not ext
7250     0xFFFF in case EXT
7251   */
7252   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7253   {
7254     LoopNum = smsatComputeLoopNum(tl, 0xFF);
7255   }
7256   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7257            fis->h.command == SAT_WRITE_DMA_EXT     ||
7258            fis->h.command == SAT_WRITE_DMA_FUA_EXT
7259            )
7260   {
7261     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7262     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7263   }
7264   else
7265   {
7266     /* SAT_WRITE_FPDMA_QUEUEDK */
7267     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7268   }
7269 
7270   satIOContext->LoopNum = LoopNum;
7271 
7272 
7273   if (LoopNum == 1)
7274   {
7275     SM_DBG5(("smsatWrite10: NON CHAINED data\n"));
7276     /* Initialize CB for SATA completion.
7277      */
7278     satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
7279   }
7280   else
7281   {
7282     SM_DBG1(("smsatWrite10: CHAINED data\n"));
7283     /* re-setting tl */
7284     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7285     {
7286        fis->d.sectorCount    = 0xFF;
7287     }
7288     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7289              fis->h.command == SAT_WRITE_DMA_EXT ||
7290              fis->h.command == SAT_WRITE_DMA_FUA_EXT
7291              )
7292     {
7293       fis->d.sectorCount    = 0xFF;
7294       fis->d.sectorCountExp = 0xFF;
7295     }
7296     else
7297     {
7298       /* SAT_WRITE_FPDMA_QUEUED */
7299       fis->h.features       = 0xFF;
7300       fis->d.featuresExp    = 0xFF;
7301     }
7302 
7303     /* Initialize CB for SATA completion.
7304      */
7305     satIOContext->satCompleteCB = &smsatChainedDataIOCB;
7306   }
7307 
7308 
7309   /*
7310    * Prepare SGL and send FIS to LL layer.
7311    */
7312   satIOContext->reqType = agRequestType;       /* Save it */
7313 
7314   status = smsataLLIOStart( smRoot,
7315                             smIORequest,
7316                             smDeviceHandle,
7317                             smScsiRequest,
7318                             satIOContext);
7319   return (status);
7320 }
7321 
7322 osGLOBAL bit32
7323 smsatWrite16(
7324              smRoot_t                  *smRoot,
7325              smIORequest_t             *smIORequest,
7326              smDeviceHandle_t          *smDeviceHandle,
7327              smScsiInitiatorRequest_t  *smScsiRequest,
7328              smSatIOContext_t            *satIOContext
7329             )
7330 {
7331   bit32                     status;
7332   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7333   smDeviceData_t            *pSatDevData;
7334   smScsiRspSense_t          *pSense;
7335   smIniScsiCmnd_t           *scsiCmnd;
7336   agsaFisRegHostToDevice_t  *fis;
7337   bit32                     lba = 0;
7338   bit32                     tl = 0;
7339   bit32                     LoopNum = 1;
7340   bit8                      LBA[8];
7341   bit8                      TL[8];
7342   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
7343 
7344   pSense        = satIOContext->pSense;
7345   pSatDevData   = satIOContext->pSatDevData;
7346   scsiCmnd      = &smScsiRequest->scsiCmnd;
7347   fis           = satIOContext->pFis;
7348 
7349   SM_DBG5(("smsatWrite16: start\n"));
7350 
7351   /* checking FUA_NV */
7352   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
7353   {
7354     smsatSetSensePayload( pSense,
7355                           SCSI_SNSKEY_ILLEGAL_REQUEST,
7356                           0,
7357                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7358                           satIOContext);
7359 
7360     /*smEnqueueIO(smRoot, satIOContext);*/
7361 
7362     tdsmIOCompletedCB( smRoot,
7363                        smIORequest,
7364                        smIOSuccess,
7365                        SCSI_STAT_CHECK_CONDITION,
7366                        satIOContext->pSmSenseData,
7367                        satIOContext->interruptContext );
7368 
7369     SM_DBG1(("smsatWrite16: return FUA_NV!!!\n"));
7370     return SM_RC_SUCCESS;
7371 
7372   }
7373 
7374   /* checking CONTROL */
7375   /* NACA == 1 or LINK == 1*/
7376   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
7377   {
7378     smsatSetSensePayload( pSense,
7379                           SCSI_SNSKEY_ILLEGAL_REQUEST,
7380                           0,
7381                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7382                           satIOContext);
7383 
7384     /*smEnqueueIO(smRoot, satIOContext);*/
7385 
7386     tdsmIOCompletedCB( smRoot,
7387                        smIORequest,
7388                        smIOSuccess,
7389                        SCSI_STAT_CHECK_CONDITION,
7390                        satIOContext->pSmSenseData,
7391                        satIOContext->interruptContext );
7392 
7393     SM_DBG1(("smsatWrite16: return control!!!\n"));
7394     return SM_RC_SUCCESS;
7395   }
7396 
7397 
7398   sm_memset(LBA, 0, sizeof(LBA));
7399   sm_memset(TL, 0, sizeof(TL));
7400 
7401 
7402   /* do not use memcpy due to indexing in LBA and TL */
7403   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
7404   LBA[1] = scsiCmnd->cdb[3];
7405   LBA[2] = scsiCmnd->cdb[4];
7406   LBA[3] = scsiCmnd->cdb[5];
7407   LBA[4] = scsiCmnd->cdb[6];
7408   LBA[5] = scsiCmnd->cdb[7];
7409   LBA[6] = scsiCmnd->cdb[8];
7410   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
7411 
7412   TL[0] = 0;
7413   TL[1] = 0;
7414   TL[2] = 0;
7415   TL[3] = 0;
7416   TL[4] = scsiCmnd->cdb[10];   /* MSB */
7417   TL[5] = scsiCmnd->cdb[11];
7418   TL[6] = scsiCmnd->cdb[12];
7419   TL[7] = scsiCmnd->cdb[13];   /* LSB */
7420 
7421 
7422 
7423   lba = smsatComputeCDB16LBA(satIOContext);
7424   tl = smsatComputeCDB16TL(satIOContext);
7425 
7426 
7427 
7428   /* Table 34, 9.1, p 46 */
7429   /*
7430     note: As of 2/10/2006, no support for DMA QUEUED
7431   */
7432 
7433   /*
7434     Table 34, 9.1, p 46, b
7435     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
7436     return check condition
7437   */
7438   if (pSatDevData->satNCQ != agTRUE &&
7439       pSatDevData->sat48BitSupport != agTRUE
7440      )
7441   {
7442     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7443     if (AllChk)
7444     {
7445       SM_DBG1(("smsatWrite16: return LBA out of range, not EXT!!!\n"));
7446       smsatSetSensePayload( pSense,
7447                             SCSI_SNSKEY_ILLEGAL_REQUEST,
7448                             0,
7449                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7450                             satIOContext);
7451 
7452       /*smEnqueueIO(smRoot, satIOContext);*/
7453 
7454       tdsmIOCompletedCB( smRoot,
7455                          smIORequest,
7456                          smIOSuccess,
7457                          SCSI_STAT_CHECK_CONDITION,
7458                          satIOContext->pSmSenseData,
7459                          satIOContext->interruptContext );
7460 
7461     return SM_RC_SUCCESS;
7462     }
7463   }
7464   else
7465   {
7466     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7467     if (AllChk)
7468     {
7469       SM_DBG1(("smsatWrite16: return LBA out of range, EXT!!!\n"));
7470       smsatSetSensePayload( pSense,
7471                             SCSI_SNSKEY_ILLEGAL_REQUEST,
7472                             0,
7473                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7474                             satIOContext);
7475 
7476       /*smEnqueueIO(smRoot, satIOContext);*/
7477 
7478       tdsmIOCompletedCB( smRoot,
7479                          smIORequest,
7480                          smIOSuccess,
7481                          SCSI_STAT_CHECK_CONDITION,
7482                          satIOContext->pSmSenseData,
7483                          satIOContext->interruptContext );
7484 
7485     return SM_RC_SUCCESS;
7486     }
7487   }
7488 
7489   /* case 1 and 2 */
7490     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7491     {
7492       /* case 2 */
7493       /* WRITE DMA*/
7494       /* In case that we can't fit the transfer length, we loop */
7495       SM_DBG5(("smsatWrite16: case 2\n"));
7496       fis->h.fisType        = 0x27;                   /* Reg host to device */
7497       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7498       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
7499       fis->h.features       = 0;                      /* FIS reserve */
7500       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7501       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7502       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7503 
7504       /* FIS LBA mode set LBA (27:24) */
7505       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
7506 
7507       fis->d.lbaLowExp      = 0;
7508       fis->d.lbaMidExp      = 0;
7509       fis->d.lbaHighExp     = 0;
7510       fis->d.featuresExp    = 0;
7511       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7512       fis->d.sectorCountExp = 0;
7513       fis->d.reserved4      = 0;
7514       fis->d.control        = 0;                      /* FIS HOB bit clear */
7515       fis->d.reserved5      = 0;
7516 
7517       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7518       satIOContext->ATACmd = SAT_WRITE_DMA;
7519     }
7520     else
7521     {
7522       /* case 1 */
7523       /* WRITE MULTIPLE or WRITE SECTOR(S) */
7524       /* WRITE SECTORS for easier implemetation */
7525       /* In case that we can't fit the transfer length, we loop */
7526       SM_DBG5(("smsatWrite16: case 1\n"));
7527       fis->h.fisType        = 0x27;                   /* Reg host to device */
7528       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7529       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
7530       fis->h.features       = 0;                      /* FIS reserve */
7531       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7532       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7533       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7534 
7535       /* FIS LBA mode set LBA (27:24) */
7536       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
7537 
7538       fis->d.lbaLowExp      = 0;
7539       fis->d.lbaMidExp      = 0;
7540       fis->d.lbaHighExp     = 0;
7541       fis->d.featuresExp    = 0;
7542       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7543       fis->d.sectorCountExp = 0;
7544       fis->d.reserved4      = 0;
7545       fis->d.control        = 0;                      /* FIS HOB bit clear */
7546       fis->d.reserved5      = 0;
7547 
7548       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7549       satIOContext->ATACmd = SAT_WRITE_SECTORS;
7550   }
7551 
7552   /* case 3 and 4 */
7553   if (pSatDevData->sat48BitSupport == agTRUE)
7554   {
7555     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7556     {
7557       /* case 3 */
7558       /* WRITE DMA EXT or WRITE DMA FUA EXT */
7559       SM_DBG5(("smsatWrite16: case 3\n"));
7560       fis->h.fisType        = 0x27;                   /* Reg host to device */
7561       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7562 
7563       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
7564       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
7565 
7566       fis->h.features       = 0;                      /* FIS reserve */
7567       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7568       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7569       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7570       fis->d.device         = 0x40;                   /* FIS LBA mode set */
7571       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
7572       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
7573       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
7574       fis->d.featuresExp    = 0;                      /* FIS reserve */
7575       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7576       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
7577       fis->d.reserved4      = 0;
7578       fis->d.control        = 0;                      /* FIS HOB bit clear */
7579       fis->d.reserved5      = 0;
7580 
7581       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7582       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
7583     }
7584     else
7585     {
7586       /* case 4 */
7587       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
7588       /* WRITE SECTORS EXT for easier implemetation */
7589       SM_DBG5(("smsatWrite16: case 4\n"));
7590       fis->h.fisType        = 0x27;                   /* Reg host to device */
7591       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7592       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
7593 
7594       fis->h.features       = 0;                      /* FIS reserve */
7595       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7596       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7597       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7598       fis->d.device         = 0x40;                   /* FIS LBA mode set */
7599       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
7600       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
7601       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
7602       fis->d.featuresExp    = 0;                      /* FIS reserve */
7603       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7604       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
7605       fis->d.reserved4      = 0;
7606       fis->d.control        = 0;                      /* FIS HOB bit clear */
7607       fis->d.reserved5      = 0;
7608 
7609       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7610       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
7611     }
7612   }
7613 
7614   /* case 5 */
7615   if (pSatDevData->satNCQ == agTRUE)
7616   {
7617     /* WRITE FPDMA QUEUED */
7618     if (pSatDevData->sat48BitSupport != agTRUE)
7619     {
7620       SM_DBG5(("smsatWrite16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
7621       smsatSetSensePayload( pSense,
7622                             SCSI_SNSKEY_ILLEGAL_REQUEST,
7623                             0,
7624                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7625                             satIOContext);
7626 
7627       /*smEnqueueIO(smRoot, satIOContext);*/
7628 
7629       tdsmIOCompletedCB( smRoot,
7630                          smIORequest,
7631                          smIOSuccess,
7632                          SCSI_STAT_CHECK_CONDITION,
7633                          satIOContext->pSmSenseData,
7634                          satIOContext->interruptContext );
7635       return SM_RC_SUCCESS;
7636     }
7637     SM_DBG6(("smsatWrite16: case 5\n"));
7638 
7639     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
7640 
7641     fis->h.fisType        = 0x27;                   /* Reg host to device */
7642     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7643     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
7644     fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
7645     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
7646     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
7647     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
7648 
7649     /* Check FUA bit */
7650     if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
7651       fis->d.device       = 0xC0;                   /* FIS FUA set */
7652     else
7653       fis->d.device       = 0x40;                   /* FIS FUA clear */
7654 
7655     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
7656     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
7657     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
7658     fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
7659     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
7660     fis->d.sectorCountExp = 0;
7661     fis->d.reserved4      = 0;
7662     fis->d.control        = 0;                      /* FIS HOB bit clear */
7663     fis->d.reserved5      = 0;
7664 
7665     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
7666     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
7667   }
7668 
7669   satIOContext->currentLBA = lba;
7670   satIOContext->OrgTL = tl;
7671 
7672   /*
7673     computing number of loop and remainder for tl
7674     0xFF in case not ext
7675     0xFFFF in case EXT
7676   */
7677   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7678   {
7679     LoopNum = smsatComputeLoopNum(tl, 0xFF);
7680   }
7681   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7682            fis->h.command == SAT_WRITE_DMA_EXT     ||
7683            fis->h.command == SAT_WRITE_DMA_FUA_EXT
7684            )
7685   {
7686     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7687     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7688   }
7689   else
7690   {
7691     /* SAT_WRITE_FPDMA_QUEUEDK */
7692     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7693   }
7694 
7695   satIOContext->LoopNum = LoopNum;
7696 
7697 
7698   if (LoopNum == 1)
7699   {
7700     SM_DBG5(("smsatWrite16: NON CHAINED data\n"));
7701     /* Initialize CB for SATA completion.
7702      */
7703     satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
7704   }
7705   else
7706   {
7707     SM_DBG1(("smsatWrite16: CHAINED data!!!\n"));
7708     /* re-setting tl */
7709     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7710     {
7711        fis->d.sectorCount    = 0xFF;
7712     }
7713     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7714              fis->h.command == SAT_WRITE_DMA_EXT ||
7715              fis->h.command == SAT_WRITE_DMA_FUA_EXT
7716              )
7717     {
7718       fis->d.sectorCount    = 0xFF;
7719       fis->d.sectorCountExp = 0xFF;
7720     }
7721     else
7722     {
7723       /* SAT_WRITE_FPDMA_QUEUED */
7724       fis->h.features       = 0xFF;
7725       fis->d.featuresExp    = 0xFF;
7726     }
7727 
7728     /* Initialize CB for SATA completion.
7729      */
7730     satIOContext->satCompleteCB = &smsatChainedDataIOCB;
7731   }
7732 
7733 
7734   /*
7735    * Prepare SGL and send FIS to LL layer.
7736    */
7737   satIOContext->reqType = agRequestType;       /* Save it */
7738 
7739   status = smsataLLIOStart( smRoot,
7740                             smIORequest,
7741                             smDeviceHandle,
7742                             smScsiRequest,
7743                             satIOContext);
7744   return (status);
7745 }
7746 
7747 
7748 osGLOBAL bit32
7749 smsatVerify10(
7750               smRoot_t                  *smRoot,
7751               smIORequest_t             *smIORequest,
7752               smDeviceHandle_t          *smDeviceHandle,
7753               smScsiInitiatorRequest_t  *smScsiRequest,
7754               smSatIOContext_t            *satIOContext
7755              )
7756 {
7757   /*
7758     For simple implementation,
7759     no byte comparison supported as of 4/5/06
7760   */
7761   smScsiRspSense_t          *pSense;
7762   smIniScsiCmnd_t           *scsiCmnd;
7763   smDeviceData_t            *pSatDevData;
7764   agsaFisRegHostToDevice_t  *fis;
7765   bit32                     status;
7766   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7767   bit32                     lba = 0;
7768   bit32                     tl = 0;
7769   bit32                     LoopNum = 1;
7770   bit8                      LBA[8];
7771   bit8                      TL[8];
7772   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
7773 
7774   pSense            = satIOContext->pSense;
7775   scsiCmnd          = &smScsiRequest->scsiCmnd;
7776   pSatDevData       = satIOContext->pSatDevData;
7777   fis               = satIOContext->pFis;
7778   SM_DBG5(("smsatVerify10: start\n"));
7779   /* checking BYTCHK */
7780   if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
7781   {
7782     /*
7783       should do the byte check
7784       but not supported in this version
7785      */
7786     smsatSetSensePayload( pSense,
7787                           SCSI_SNSKEY_ILLEGAL_REQUEST,
7788                           0,
7789                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7790                           satIOContext);
7791     /*smEnqueueIO(smRoot, satIOContext);*/
7792     tdsmIOCompletedCB( smRoot,
7793                        smIORequest,
7794                        smIOSuccess,
7795                        SCSI_STAT_CHECK_CONDITION,
7796                        satIOContext->pSmSenseData,
7797                        satIOContext->interruptContext );
7798 
7799     SM_DBG1(("smsatVerify10: no byte checking!!!\n"));
7800     return SM_RC_SUCCESS;
7801   }
7802 
7803   /* checking CONTROL */
7804   /* NACA == 1 or LINK == 1*/
7805   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
7806   {
7807     smsatSetSensePayload( pSense,
7808                           SCSI_SNSKEY_ILLEGAL_REQUEST,
7809                           0,
7810                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7811                           satIOContext);
7812 
7813     /*smEnqueueIO(smRoot, satIOContext);*/
7814 
7815     tdsmIOCompletedCB( smRoot,
7816                        smIORequest,
7817                        smIOSuccess,
7818                        SCSI_STAT_CHECK_CONDITION,
7819                        satIOContext->pSmSenseData,
7820                        satIOContext->interruptContext );
7821 
7822     SM_DBG1(("smsatVerify10: return control!!!\n"));
7823     return SM_RC_SUCCESS;
7824   }
7825 
7826 
7827   sm_memset(LBA, 0, sizeof(LBA));
7828   sm_memset(TL, 0, sizeof(TL));
7829 
7830   /* do not use memcpy due to indexing in LBA and TL */
7831   LBA[0] = 0;                  /* MSB */
7832   LBA[1] = 0;
7833   LBA[2] = 0;
7834   LBA[3] = 0;
7835   LBA[4] = scsiCmnd->cdb[2];
7836   LBA[5] = scsiCmnd->cdb[3];
7837   LBA[6] = scsiCmnd->cdb[4];
7838   LBA[7] = scsiCmnd->cdb[5];  	/* LSB */
7839 
7840   TL[0] = 0;
7841   TL[1] = 0;
7842   TL[2] = 0;
7843   TL[3] = 0;
7844   TL[4] = 0;
7845   TL[5] = 0;
7846   TL[6] = scsiCmnd->cdb[7];
7847   TL[7] = scsiCmnd->cdb[8];  	/* LSB */
7848 
7849 
7850   /* cbd10; computing LBA and transfer length */
7851   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
7852     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
7853   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7854 
7855   if (pSatDevData->satNCQ != agTRUE &&
7856       pSatDevData->sat48BitSupport != agTRUE
7857       )
7858   {
7859     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7860     if (AllChk)
7861     {
7862       SM_DBG1(("smsatVerify10: return LBA out of range, not EXT!!!\n"));
7863       SM_DBG1(("smsatVerify10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
7864              scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
7865       SM_DBG1(("smsatVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
7866       smsatSetSensePayload( pSense,
7867                             SCSI_SNSKEY_ILLEGAL_REQUEST,
7868                             0,
7869                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7870                             satIOContext);
7871 
7872       /*smEnqueueIO(smRoot, satIOContext);*/
7873 
7874       tdsmIOCompletedCB( smRoot,
7875                          smIORequest,
7876                          smIOSuccess,
7877                          SCSI_STAT_CHECK_CONDITION,
7878                          satIOContext->pSmSenseData,
7879                          satIOContext->interruptContext );
7880 
7881     return SM_RC_SUCCESS;
7882     }
7883   }
7884   else
7885   {
7886     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7887     if (AllChk)
7888     {
7889       SM_DBG1(("smsatVerify10: return LBA out of range, EXT!!!\n"));
7890       smsatSetSensePayload( pSense,
7891                             SCSI_SNSKEY_ILLEGAL_REQUEST,
7892                             0,
7893                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7894                             satIOContext);
7895 
7896       /*smEnqueueIO(smRoot, satIOContext);*/
7897 
7898       tdsmIOCompletedCB( smRoot,
7899                          smIORequest,
7900                          smIOSuccess,
7901                          SCSI_STAT_CHECK_CONDITION,
7902                          satIOContext->pSmSenseData,
7903                          satIOContext->interruptContext );
7904 
7905     return SM_RC_SUCCESS;
7906     }
7907   }
7908 
7909   if (pSatDevData->sat48BitSupport == agTRUE)
7910   {
7911     SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS_EXT\n"));
7912     fis->h.fisType        = 0x27;                   /* Reg host to device */
7913     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7914 
7915     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
7916     fis->h.features       = 0;                      /* FIS reserve */
7917     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7918     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7919     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7920     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
7921     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7922     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7923     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7924     fis->d.featuresExp    = 0;                      /* FIS reserve */
7925     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7926     fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
7927 
7928     fis->d.reserved4      = 0;
7929     fis->d.control        = 0;                      /* FIS HOB bit clear */
7930     fis->d.reserved5      = 0;
7931 
7932     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7933     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
7934   }
7935   else
7936   {
7937     SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS\n"));
7938     fis->h.fisType        = 0x27;                   /* Reg host to device */
7939     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7940     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
7941     fis->h.features       = 0;                      /* FIS reserve */
7942     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7943     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7944     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7945       /* FIS LBA mode set LBA (27:24) */
7946     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7947     fis->d.lbaLowExp      = 0;
7948     fis->d.lbaMidExp      = 0;
7949     fis->d.lbaHighExp     = 0;
7950     fis->d.featuresExp    = 0;
7951     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7952     fis->d.sectorCountExp = 0;
7953     fis->d.reserved4      = 0;
7954     fis->d.control        = 0;                      /* FIS HOB bit clear */
7955     fis->d.reserved5      = 0;
7956 
7957     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7958     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
7959 
7960  }
7961 
7962   satIOContext->currentLBA = lba;
7963   satIOContext->OrgTL = tl;
7964 
7965   /*
7966     computing number of loop and remainder for tl
7967     0xFF in case not ext
7968     0xFFFF in case EXT
7969   */
7970   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7971   {
7972     LoopNum = smsatComputeLoopNum(tl, 0xFF);
7973   }
7974   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
7975   {
7976     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7977     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7978   }
7979   else
7980   {
7981     SM_DBG1(("smsatVerify10: error case 1!!!\n"));
7982     LoopNum = 1;
7983   }
7984 
7985   satIOContext->LoopNum = LoopNum;
7986 
7987   if (LoopNum == 1)
7988   {
7989     SM_DBG5(("smsatVerify10: NON CHAINED data\n"));
7990     /* Initialize CB for SATA completion.
7991      */
7992     satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
7993   }
7994   else
7995   {
7996     SM_DBG1(("smsatVerify10: CHAINED data!!!\n"));
7997     /* re-setting tl */
7998     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7999     {
8000        fis->d.sectorCount    = 0xFF;
8001     }
8002     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8003     {
8004       fis->d.sectorCount    = 0xFF;
8005       fis->d.sectorCountExp = 0xFF;
8006     }
8007     else
8008     {
8009       SM_DBG1(("smsatVerify10: error case 2!!!\n"));
8010     }
8011 
8012     /* Initialize CB for SATA completion.
8013      */
8014     satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8015   }
8016 
8017 
8018   /*
8019    * Prepare SGL and send FIS to LL layer.
8020    */
8021   satIOContext->reqType = agRequestType;       /* Save it */
8022 
8023   status = smsataLLIOStart( smRoot,
8024                             smIORequest,
8025                             smDeviceHandle,
8026                             smScsiRequest,
8027                             satIOContext);
8028   return (status);
8029 }
8030 
8031 osGLOBAL bit32
8032 smsatVerify12(
8033               smRoot_t                  *smRoot,
8034               smIORequest_t             *smIORequest,
8035               smDeviceHandle_t          *smDeviceHandle,
8036               smScsiInitiatorRequest_t  *smScsiRequest,
8037               smSatIOContext_t            *satIOContext
8038              )
8039 {
8040   /*
8041     For simple implementation,
8042     no byte comparison supported as of 4/5/06
8043   */
8044   smScsiRspSense_t          *pSense;
8045   smIniScsiCmnd_t           *scsiCmnd;
8046   smDeviceData_t            *pSatDevData;
8047   agsaFisRegHostToDevice_t  *fis;
8048   bit32                     status;
8049   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8050   bit32                     lba = 0;
8051   bit32                     tl = 0;
8052   bit32                     LoopNum = 1;
8053   bit8                      LBA[8];
8054   bit8                      TL[8];
8055   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
8056 
8057   pSense            = satIOContext->pSense;
8058   scsiCmnd          = &smScsiRequest->scsiCmnd;
8059   pSatDevData       = satIOContext->pSatDevData;
8060   fis               = satIOContext->pFis;
8061   SM_DBG5(("smsatVerify12: start\n"));
8062   /* checking BYTCHK */
8063   if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8064   {
8065     /*
8066       should do the byte check
8067       but not supported in this version
8068      */
8069     smsatSetSensePayload( pSense,
8070                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8071                           0,
8072                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8073                           satIOContext);
8074 
8075     /*smEnqueueIO(smRoot, satIOContext);*/
8076 
8077     tdsmIOCompletedCB( smRoot,
8078                        smIORequest,
8079                        smIOSuccess,
8080                        SCSI_STAT_CHECK_CONDITION,
8081                        satIOContext->pSmSenseData,
8082                        satIOContext->interruptContext );
8083 
8084     SM_DBG1(("smsatVerify12: no byte checking!!!\n"));
8085     return SM_RC_SUCCESS;
8086   }
8087 
8088   /* checking CONTROL */
8089   /* NACA == 1 or LINK == 1*/
8090   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
8091   {
8092     smsatSetSensePayload( pSense,
8093                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8094                           0,
8095                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8096                           satIOContext);
8097 
8098     /*smEnqueueIO(smRoot, satIOContext);*/
8099 
8100     tdsmIOCompletedCB( smRoot,
8101                        smIORequest,
8102                        smIOSuccess,
8103                        SCSI_STAT_CHECK_CONDITION,
8104                        satIOContext->pSmSenseData,
8105                        satIOContext->interruptContext );
8106 
8107     SM_DBG1(("smsatVerify12: return control!!!\n"));
8108     return SM_RC_SUCCESS;
8109   }
8110 
8111   sm_memset(LBA, 0, sizeof(LBA));
8112   sm_memset(TL, 0, sizeof(TL));
8113 
8114   /* do not use memcpy due to indexing in LBA and TL */
8115   LBA[0] = 0;                  /* MSB */
8116   LBA[1] = 0;
8117   LBA[2] = 0;
8118   LBA[3] = 0;
8119   LBA[4] = scsiCmnd->cdb[2];
8120   LBA[5] = scsiCmnd->cdb[3];
8121   LBA[6] = scsiCmnd->cdb[4];
8122   LBA[7] = scsiCmnd->cdb[5];  	/* LSB */
8123 
8124   TL[0] = 0;                    /* MSB */
8125   TL[1] = 0;
8126   TL[2] = 0;
8127   TL[3] = 0;
8128   TL[4] = scsiCmnd->cdb[6];
8129   TL[5] = scsiCmnd->cdb[7];
8130   TL[6] = scsiCmnd->cdb[8];
8131   TL[7] = scsiCmnd->cdb[9];   	/* LSB */
8132 
8133 
8134   lba = smsatComputeCDB12LBA(satIOContext);
8135   tl = smsatComputeCDB12TL(satIOContext);
8136 
8137   if (pSatDevData->satNCQ != agTRUE &&
8138       pSatDevData->sat48BitSupport != agTRUE
8139       )
8140   {
8141     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
8142     if (AllChk)
8143     {
8144       SM_DBG1(("smsatVerify12: return LBA out of range, not EXT!!!\n"));
8145       SM_DBG1(("smsatVerify12: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
8146              scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
8147       SM_DBG1(("smsatVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
8148       smsatSetSensePayload( pSense,
8149                             SCSI_SNSKEY_ILLEGAL_REQUEST,
8150                             0,
8151                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8152                             satIOContext);
8153 
8154       /*smEnqueueIO(smRoot, satIOContext);*/
8155 
8156       tdsmIOCompletedCB( smRoot,
8157                          smIORequest,
8158                          smIOSuccess,
8159                          SCSI_STAT_CHECK_CONDITION,
8160                          satIOContext->pSmSenseData,
8161                          satIOContext->interruptContext );
8162 
8163     return SM_RC_SUCCESS;
8164     }
8165   }
8166   else
8167   {
8168     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
8169     if (AllChk)
8170     {
8171       SM_DBG1(("smsatVerify12: return LBA out of range, EXT!!!\n"));
8172       smsatSetSensePayload( pSense,
8173                             SCSI_SNSKEY_ILLEGAL_REQUEST,
8174                             0,
8175                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8176                             satIOContext);
8177 
8178       /*smEnqueueIO(smRoot, satIOContext);*/
8179 
8180       tdsmIOCompletedCB( smRoot,
8181                          smIORequest,
8182                          smIOSuccess,
8183                          SCSI_STAT_CHECK_CONDITION,
8184                          satIOContext->pSmSenseData,
8185                          satIOContext->interruptContext );
8186 
8187     return SM_RC_SUCCESS;
8188     }
8189   }
8190 
8191   if (pSatDevData->sat48BitSupport == agTRUE)
8192   {
8193     SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS_EXT\n"));
8194     fis->h.fisType        = 0x27;                   /* Reg host to device */
8195     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8196 
8197     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8198     fis->h.features       = 0;                      /* FIS reserve */
8199     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8200     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8201     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8202     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8203     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
8204     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
8205     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
8206     fis->d.featuresExp    = 0;                      /* FIS reserve */
8207     fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8208     fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
8209 
8210     fis->d.reserved4      = 0;
8211     fis->d.control        = 0;                      /* FIS HOB bit clear */
8212     fis->d.reserved5      = 0;
8213 
8214     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8215     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8216   }
8217   else
8218   {
8219     SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS\n"));
8220     fis->h.fisType        = 0x27;                   /* Reg host to device */
8221     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8222     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8223     fis->h.features       = 0;                      /* FIS reserve */
8224     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8225     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8226     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8227       /* FIS LBA mode set LBA (27:24) */
8228     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
8229     fis->d.lbaLowExp      = 0;
8230     fis->d.lbaMidExp      = 0;
8231     fis->d.lbaHighExp     = 0;
8232     fis->d.featuresExp    = 0;
8233     fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8234     fis->d.sectorCountExp = 0;
8235     fis->d.reserved4      = 0;
8236     fis->d.control        = 0;                      /* FIS HOB bit clear */
8237     fis->d.reserved5      = 0;
8238 
8239     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8240     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8241 
8242  }
8243 
8244   satIOContext->currentLBA = lba;
8245   satIOContext->OrgTL = tl;
8246 
8247   /*
8248     computing number of loop and remainder for tl
8249     0xFF in case not ext
8250     0xFFFF in case EXT
8251   */
8252   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8253   {
8254     LoopNum = smsatComputeLoopNum(tl, 0xFF);
8255   }
8256   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8257   {
8258     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8259     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
8260   }
8261   else
8262   {
8263     SM_DBG1(("smsatVerify12: error case 1!!!\n"));
8264     LoopNum = 1;
8265   }
8266 
8267   satIOContext->LoopNum = LoopNum;
8268 
8269   if (LoopNum == 1)
8270   {
8271     SM_DBG5(("smsatVerify12: NON CHAINED data\n"));
8272     /* Initialize CB for SATA completion.
8273      */
8274     satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
8275   }
8276   else
8277   {
8278     SM_DBG1(("smsatVerify12: CHAINED data!!!\n"));
8279     /* re-setting tl */
8280     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8281     {
8282        fis->d.sectorCount    = 0xFF;
8283     }
8284     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8285     {
8286       fis->d.sectorCount    = 0xFF;
8287       fis->d.sectorCountExp = 0xFF;
8288     }
8289     else
8290     {
8291       SM_DBG1(("smsatVerify12: error case 2!!!\n"));
8292     }
8293 
8294     /* Initialize CB for SATA completion.
8295      */
8296     satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8297   }
8298 
8299 
8300   /*
8301    * Prepare SGL and send FIS to LL layer.
8302    */
8303   satIOContext->reqType = agRequestType;       /* Save it */
8304 
8305   status = smsataLLIOStart( smRoot,
8306                             smIORequest,
8307                             smDeviceHandle,
8308                             smScsiRequest,
8309                             satIOContext);
8310   return (status);
8311 }
8312 
8313 osGLOBAL bit32
8314 smsatVerify16(
8315               smRoot_t                  *smRoot,
8316               smIORequest_t             *smIORequest,
8317               smDeviceHandle_t          *smDeviceHandle,
8318               smScsiInitiatorRequest_t  *smScsiRequest,
8319               smSatIOContext_t            *satIOContext
8320              )
8321 {
8322   /*
8323     For simple implementation,
8324     no byte comparison supported as of 4/5/06
8325   */
8326   smScsiRspSense_t          *pSense;
8327   smIniScsiCmnd_t           *scsiCmnd;
8328   smDeviceData_t            *pSatDevData;
8329   agsaFisRegHostToDevice_t  *fis;
8330   bit32                     status;
8331   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8332   bit32                     lba = 0;
8333   bit32                     tl = 0;
8334   bit32                     LoopNum = 1;
8335   bit8                      LBA[8];
8336   bit8                      TL[8];
8337   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
8338 
8339   pSense            = satIOContext->pSense;
8340   scsiCmnd          = &smScsiRequest->scsiCmnd;
8341   pSatDevData       = satIOContext->pSatDevData;
8342   fis               = satIOContext->pFis;
8343   SM_DBG5(("smsatVerify16: start\n"));
8344   /* checking BYTCHK */
8345   if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8346   {
8347     /*
8348       should do the byte check
8349       but not supported in this version
8350      */
8351     smsatSetSensePayload( pSense,
8352                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8353                           0,
8354                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8355                           satIOContext);
8356     /*smEnqueueIO(smRoot, satIOContext);*/
8357     tdsmIOCompletedCB( smRoot,
8358                        smIORequest,
8359                        smIOSuccess,
8360                        SCSI_STAT_CHECK_CONDITION,
8361                        satIOContext->pSmSenseData,
8362                        satIOContext->interruptContext );
8363     SM_DBG1(("smsatVerify16: no byte checking!!!\n"));
8364     return SM_RC_SUCCESS;
8365   }
8366   /* checking CONTROL */
8367   /* NACA == 1 or LINK == 1*/
8368   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
8369   {
8370     smsatSetSensePayload( pSense,
8371                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8372                           0,
8373                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8374                           satIOContext);
8375     /*smEnqueueIO(smRoot, satIOContext);*/
8376     tdsmIOCompletedCB( smRoot,
8377                        smIORequest,
8378                        smIOSuccess,
8379                        SCSI_STAT_CHECK_CONDITION,
8380                        satIOContext->pSmSenseData,
8381                        satIOContext->interruptContext );
8382     SM_DBG1(("smsatVerify16: return control!!!\n"));
8383     return SM_RC_SUCCESS;
8384   }
8385   sm_memset(LBA, 0, sizeof(LBA));
8386   sm_memset(TL, 0, sizeof(TL));
8387 
8388   /* do not use memcpy due to indexing in LBA and TL */
8389   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
8390   LBA[1] = scsiCmnd->cdb[3];
8391   LBA[2] = scsiCmnd->cdb[4];
8392   LBA[3] = scsiCmnd->cdb[5];
8393   LBA[4] = scsiCmnd->cdb[6];
8394   LBA[5] = scsiCmnd->cdb[7];
8395   LBA[6] = scsiCmnd->cdb[8];
8396   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
8397 
8398   TL[0] = 0;
8399   TL[1] = 0;
8400   TL[2] = 0;
8401   TL[3] = 0;
8402   TL[4] = scsiCmnd->cdb[10];   /* MSB */
8403   TL[5] = scsiCmnd->cdb[11];
8404   TL[6] = scsiCmnd->cdb[12];
8405   TL[7] = scsiCmnd->cdb[13];   /* LSB */
8406   lba = smsatComputeCDB16LBA(satIOContext);
8407   tl = smsatComputeCDB16TL(satIOContext);
8408 
8409   if (pSatDevData->satNCQ != agTRUE &&
8410      pSatDevData->sat48BitSupport != agTRUE
8411      )
8412   {
8413     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
8414     if (AllChk)
8415     {
8416       SM_DBG1(("smsatVerify16: return LBA out of range, not EXT!!!\n"));
8417       smsatSetSensePayload( pSense,
8418                             SCSI_SNSKEY_ILLEGAL_REQUEST,
8419                             0,
8420                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8421                             satIOContext);
8422      /*smEnqueueIO(smRoot, satIOContext);*/
8423      tdsmIOCompletedCB( smRoot,
8424                          smIORequest,
8425                          smIOSuccess,
8426                          SCSI_STAT_CHECK_CONDITION,
8427                          satIOContext->pSmSenseData,
8428                          satIOContext->interruptContext );
8429     return SM_RC_SUCCESS;
8430     }
8431   }
8432   else
8433   {
8434     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
8435     if (AllChk)
8436     {
8437       SM_DBG1(("smsatVerify16: return LBA out of range, EXT!!!\n"));
8438       smsatSetSensePayload( pSense,
8439                             SCSI_SNSKEY_ILLEGAL_REQUEST,
8440                             0,
8441                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8442                             satIOContext);
8443       /*smEnqueueIO(smRoot, satIOContext);*/
8444       tdsmIOCompletedCB( smRoot,
8445                          smIORequest,
8446                          smIOSuccess,
8447                          SCSI_STAT_CHECK_CONDITION,
8448                          satIOContext->pSmSenseData,
8449                          satIOContext->interruptContext );
8450     return SM_RC_SUCCESS;
8451     }
8452   }
8453 
8454   if (pSatDevData->sat48BitSupport == agTRUE)
8455   {
8456     SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS_EXT\n"));
8457     fis->h.fisType        = 0x27;                   /* Reg host to device */
8458     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8459     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8460     fis->h.features       = 0;                      /* FIS reserve */
8461     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8462     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8463     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8464     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8465     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
8466     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
8467     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
8468     fis->d.featuresExp    = 0;                      /* FIS reserve */
8469     fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8470     fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
8471 
8472     fis->d.reserved4      = 0;
8473     fis->d.control        = 0;                      /* FIS HOB bit clear */
8474     fis->d.reserved5      = 0;
8475 
8476     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8477     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8478   }
8479   else
8480   {
8481     SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS\n"));
8482     fis->h.fisType        = 0x27;                   /* Reg host to device */
8483     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8484     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8485     fis->h.features       = 0;                      /* FIS reserve */
8486     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8487     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8488     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8489       /* FIS LBA mode set LBA (27:24) */
8490     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
8491     fis->d.lbaLowExp      = 0;
8492     fis->d.lbaMidExp      = 0;
8493     fis->d.lbaHighExp     = 0;
8494     fis->d.featuresExp    = 0;
8495     fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8496     fis->d.sectorCountExp = 0;
8497     fis->d.reserved4      = 0;
8498     fis->d.control        = 0;                      /* FIS HOB bit clear */
8499     fis->d.reserved5      = 0;
8500 
8501     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8502     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8503 
8504  }
8505 
8506   satIOContext->currentLBA = lba;
8507   satIOContext->OrgTL = tl;
8508 
8509   /*
8510     computing number of loop and remainder for tl
8511     0xFF in case not ext
8512     0xFFFF in case EXT
8513   */
8514   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8515   {
8516     LoopNum = smsatComputeLoopNum(tl, 0xFF);
8517   }
8518   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8519   {
8520     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8521     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
8522   }
8523   else
8524   {
8525     SM_DBG1(("smsatVerify16: error case 1!!!\n"));
8526     LoopNum = 1;
8527   }
8528 
8529   satIOContext->LoopNum = LoopNum;
8530 
8531   if (LoopNum == 1)
8532   {
8533     SM_DBG5(("smsatVerify16: NON CHAINED data\n"));
8534     /* Initialize CB for SATA completion.
8535      */
8536     satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
8537   }
8538   else
8539   {
8540     SM_DBG1(("smsatVerify16: CHAINED data!!!\n"));
8541     /* re-setting tl */
8542     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8543     {
8544        fis->d.sectorCount    = 0xFF;
8545     }
8546     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8547     {
8548       fis->d.sectorCount    = 0xFF;
8549       fis->d.sectorCountExp = 0xFF;
8550     }
8551     else
8552     {
8553       SM_DBG1(("smsatVerify16: error case 2!!!\n"));
8554     }
8555 
8556     /* Initialize CB for SATA completion.
8557      */
8558     satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8559   }
8560 
8561 
8562   /*
8563    * Prepare SGL and send FIS to LL layer.
8564    */
8565   satIOContext->reqType = agRequestType;       /* Save it */
8566 
8567   status = smsataLLIOStart( smRoot,
8568                             smIORequest,
8569                             smDeviceHandle,
8570                             smScsiRequest,
8571                             satIOContext);
8572   return (status);
8573 }
8574 
8575 osGLOBAL bit32
8576 smsatTestUnitReady(
8577                    smRoot_t                  *smRoot,
8578                    smIORequest_t             *smIORequest,
8579                    smDeviceHandle_t          *smDeviceHandle,
8580                    smScsiInitiatorRequest_t  *smScsiRequest,
8581                    smSatIOContext_t            *satIOContext
8582                   )
8583 {
8584   bit32                     status;
8585   bit32                     agRequestType;
8586   smDeviceData_t            *pSatDevData;
8587   smScsiRspSense_t          *pSense;
8588   smIniScsiCmnd_t           *scsiCmnd;
8589   agsaFisRegHostToDevice_t  *fis;
8590 
8591   pSense        = satIOContext->pSense;
8592   pSatDevData   = satIOContext->pSatDevData;
8593   scsiCmnd      = &smScsiRequest->scsiCmnd;
8594   fis           = satIOContext->pFis;
8595 
8596   SM_DBG5(("smsatTestUnitReady: start\n"));
8597 
8598   /* checking CONTROL */
8599   /* NACA == 1 or LINK == 1*/
8600   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8601   {
8602     smsatSetSensePayload( pSense,
8603                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8604                           0,
8605                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8606                           satIOContext);
8607 
8608     /*smEnqueueIO(smRoot, satIOContext);*/
8609 
8610     tdsmIOCompletedCB( smRoot,
8611                        smIORequest,
8612                        smIOSuccess,
8613                        SCSI_STAT_CHECK_CONDITION,
8614                        satIOContext->pSmSenseData,
8615                        satIOContext->interruptContext );
8616 
8617     SM_DBG1(("smsatTestUnitReady: return control!!!\n"));
8618     return SM_RC_SUCCESS;
8619   }
8620 
8621   /* SAT revision 8, 8.11.2, p42*/
8622   if (pSatDevData->satStopState == agTRUE)
8623   {
8624     smsatSetSensePayload( pSense,
8625                           SCSI_SNSKEY_NOT_READY,
8626                           0,
8627                           SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
8628                           satIOContext);
8629 
8630     /*smEnqueueIO(smRoot, satIOContext);*/
8631 
8632     tdsmIOCompletedCB( smRoot,
8633                        smIORequest,
8634                        smIOSuccess,
8635                        SCSI_STAT_CHECK_CONDITION,
8636                        satIOContext->pSmSenseData,
8637                        satIOContext->interruptContext );
8638     SM_DBG1(("smsatTestUnitReady: stop state!!!\n"));
8639     return SM_RC_SUCCESS;
8640   }
8641 
8642   /*
8643    * Check if format is in progress
8644    */
8645   if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
8646   {
8647     SM_DBG1(("smsatTestUnitReady: FORMAT_IN_PROGRESS!!!\n"));
8648 
8649     smsatSetSensePayload( pSense,
8650                           SCSI_SNSKEY_NOT_READY,
8651                           0,
8652                           SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
8653                           satIOContext);
8654 
8655     /*smEnqueueIO(smRoot, satIOContext);*/
8656 
8657     tdsmIOCompletedCB( smRoot,
8658                        smIORequest,
8659                        smIOSuccess,
8660                        SCSI_STAT_CHECK_CONDITION,
8661                        satIOContext->pSmSenseData,
8662                        satIOContext->interruptContext );
8663     SM_DBG1(("smsatTestUnitReady: format in progress!!!\n"));
8664     return SM_RC_SUCCESS;
8665   }
8666 
8667   /*
8668     check previously issued ATA command
8669   */
8670   if (pSatDevData->satPendingIO != 0)
8671   {
8672     if (pSatDevData->satDeviceFaultState == agTRUE)
8673     {
8674       smsatSetSensePayload( pSense,
8675                             SCSI_SNSKEY_HARDWARE_ERROR,
8676                             0,
8677                             SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
8678                             satIOContext);
8679 
8680       /*smEnqueueIO(smRoot, satIOContext);*/
8681 
8682       tdsmIOCompletedCB( smRoot,
8683                          smIORequest,
8684                          smIOSuccess,
8685                          SCSI_STAT_CHECK_CONDITION,
8686                          satIOContext->pSmSenseData,
8687                          satIOContext->interruptContext );
8688       SM_DBG1(("smsatTestUnitReady: previous command ended in error!!!\n"));
8689       return SM_RC_SUCCESS;
8690     }
8691   }
8692 
8693   /*
8694     check removalbe media feature set
8695    */
8696   if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
8697   {
8698     SM_DBG5(("smsatTestUnitReady: sending get media status cmnd\n"));
8699     /* send GET MEDIA STATUS command */
8700     fis->h.fisType        = 0x27;                   /* Reg host to device */
8701     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8702     fis->h.command        = SAT_GET_MEDIA_STATUS;   /* 0xDA */
8703     fis->h.features       = 0;                      /* FIS features NA       */
8704     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
8705     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
8706     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
8707     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
8708     fis->d.lbaLowExp      = 0;
8709     fis->d.lbaMidExp      = 0;
8710     fis->d.lbaHighExp     = 0;
8711     fis->d.featuresExp    = 0;
8712     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
8713     fis->d.sectorCountExp = 0;
8714     fis->d.reserved4      = 0;
8715     fis->d.control        = 0;                      /* FIS HOB bit clear */
8716     fis->d.reserved5      = 0;
8717     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8718 
8719     /* Initialize CB for SATA completion.
8720      */
8721     satIOContext->satCompleteCB = &smsatTestUnitReadyCB;
8722 
8723     /*
8724      * Prepare SGL and send FIS to LL layer.
8725      */
8726     satIOContext->reqType = agRequestType;       /* Save it */
8727 
8728     status = smsataLLIOStart( smRoot,
8729                               smIORequest,
8730                               smDeviceHandle,
8731                               smScsiRequest,
8732                               satIOContext);
8733 
8734     return (status);
8735   }
8736   /*
8737     number 6) in SAT p42
8738     send ATA CHECK POWER MODE
8739   */
8740    SM_DBG5(("smsatTestUnitReady: sending check power mode cmnd\n"));
8741    status = smsatTestUnitReady_1( smRoot,
8742                                   smIORequest,
8743                                   smDeviceHandle,
8744                                   smScsiRequest,
8745                                   satIOContext);
8746    return (status);
8747 }
8748 
8749 osGLOBAL bit32
8750 smsatTestUnitReady_1(
8751                      smRoot_t                  *smRoot,
8752                      smIORequest_t             *smIORequest,
8753                      smDeviceHandle_t          *smDeviceHandle,
8754                      smScsiInitiatorRequest_t  *smScsiRequest,
8755                      smSatIOContext_t            *satIOContext
8756                     )
8757 {
8758   /*
8759     sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY
8760     internally generated - no directly corresponding scsi
8761     called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42
8762   */
8763   bit32                     status;
8764   bit32                     agRequestType;
8765   agsaFisRegHostToDevice_t  *fis;
8766 
8767   fis           = satIOContext->pFis;
8768   SM_DBG5(("smsatTestUnitReady_1: start\n"));
8769   /*
8770    * Send the ATA CHECK POWER MODE command.
8771    */
8772   fis->h.fisType        = 0x27;                   /* Reg host to device */
8773   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8774   fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
8775   fis->h.features       = 0;
8776   fis->d.lbaLow         = 0;
8777   fis->d.lbaMid         = 0;
8778   fis->d.lbaHigh        = 0;
8779   fis->d.device         = 0;
8780   fis->d.lbaLowExp      = 0;
8781   fis->d.lbaMidExp      = 0;
8782   fis->d.lbaHighExp     = 0;
8783   fis->d.featuresExp    = 0;
8784   fis->d.sectorCount    = 0;
8785   fis->d.sectorCountExp = 0;
8786   fis->d.reserved4      = 0;
8787   fis->d.control        = 0;                      /* FIS HOB bit clear */
8788   fis->d.reserved5      = 0;
8789 
8790   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8791 
8792   /* Initialize CB for SATA completion.
8793    */
8794   satIOContext->satCompleteCB = &smsatTestUnitReadyCB;
8795 
8796   /*
8797    * Prepare SGL and send FIS to LL layer.
8798    */
8799   satIOContext->reqType = agRequestType;       /* Save it */
8800 
8801   status = smsataLLIOStart( smRoot,
8802                             smIORequest,
8803                             smDeviceHandle,
8804                             smScsiRequest,
8805                             satIOContext);
8806 
8807   SM_DBG5(("smsatTestUnitReady_1: return\n"));
8808 
8809   return status;
8810 }
8811 
8812 osGLOBAL bit32
8813 smsatInquiry(
8814              smRoot_t                  *smRoot,
8815              smIORequest_t             *smIORequest,
8816              smDeviceHandle_t          *smDeviceHandle,
8817              smScsiInitiatorRequest_t  *smScsiRequest,
8818              smSatIOContext_t            *satIOContext
8819             )
8820 {
8821   /*
8822     CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8
8823   */
8824   smScsiRspSense_t          *pSense;
8825   smIniScsiCmnd_t           *scsiCmnd;
8826   smDeviceData_t            *pSatDevData;
8827   bit32                      status;
8828 
8829   pSense      = satIOContext->pSense;
8830   scsiCmnd    = &smScsiRequest->scsiCmnd;
8831   pSatDevData = satIOContext->pSatDevData;
8832   SM_DBG5(("smsatInquiry: start\n"));
8833   SM_DBG5(("smsatInquiry: pSatDevData did %d\n", pSatDevData->id));
8834   //smhexdump("smsatInquiry", (bit8 *)scsiCmnd->cdb, 6);
8835   /* checking CONTROL */
8836   /* NACA == 1 or LINK == 1*/
8837   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8838   {
8839     smsatSetSensePayload( pSense,
8840                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8841                           0,
8842                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8843                           satIOContext);
8844     /*smEnqueueIO(smRoot, satIOContext);*/
8845     tdsmIOCompletedCB( smRoot,
8846                        smIORequest,
8847                        smIOSuccess,
8848                        SCSI_STAT_CHECK_CONDITION,
8849                        satIOContext->pSmSenseData,
8850                        satIOContext->interruptContext );
8851     SM_DBG1(("smsatInquiry: return control!!!\n"));
8852     return SM_RC_SUCCESS;
8853   }
8854 
8855   /* checking EVPD and Allocation Length */
8856   /* SPC-4 spec 6.4 p141 */
8857   /* EVPD bit == 0 && PAGE CODE != 0 */
8858   if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
8859        (scsiCmnd->cdb[2] != 0)
8860        )
8861   {
8862     smsatSetSensePayload( pSense,
8863                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8864                           0,
8865                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8866                           satIOContext);
8867     /*smEnqueueIO(smRoot, satIOContext);*/
8868     tdsmIOCompletedCB( smRoot,
8869                        smIORequest,
8870                        smIOSuccess,
8871                        SCSI_STAT_CHECK_CONDITION,
8872                        satIOContext->pSmSenseData,
8873                        satIOContext->interruptContext );
8874     SM_DBG1(("smsatInquiry: return EVPD and PAGE CODE!!!\n"));
8875     return SM_RC_SUCCESS;
8876   }
8877   SM_DBG6(("smsatInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4]));
8878   /* convert OS IO to TD internal IO */
8879   if ( pSatDevData->IDDeviceValid == agFALSE)
8880   {
8881     status = smsatStartIDDev(
8882                              smRoot,
8883                              smIORequest,
8884                              smDeviceHandle,
8885                              smScsiRequest,
8886                              satIOContext
8887                             );
8888     SM_DBG6(("smsatInquiry: end status %d\n", status));
8889     return status;
8890   }
8891   else
8892   {
8893     SM_DBG6(("smsatInquiry: calling satInquiryIntCB\n"));
8894     smsatInquiryIntCB(
8895                       smRoot,
8896                       smIORequest,
8897                       smDeviceHandle,
8898                       smScsiRequest,
8899                       satIOContext
8900                      );
8901     /*smEnqueueIO(smRoot, satIOContext);*/
8902     return SM_RC_SUCCESS;
8903   }
8904 }
8905 
8906 
8907 osGLOBAL bit32
8908 smsatStartIDDev(
8909                 smRoot_t                  *smRoot,
8910                 smIORequest_t             *smIORequest,
8911                 smDeviceHandle_t          *smDeviceHandle,
8912                 smScsiInitiatorRequest_t  *smScsiRequest,
8913                 smSatIOContext_t            *satIOContext
8914                )
8915 {
8916   smSatInternalIo_t        *satIntIo = agNULL;
8917   smDeviceData_t           *satDevData = agNULL;
8918   smIORequestBody_t        *smIORequestBody;
8919   smSatIOContext_t         *satNewIOContext;
8920   bit32                     status;
8921 
8922   SM_DBG5(("smsatStartIDDev: start\n"));
8923 
8924   satDevData = satIOContext->pSatDevData;
8925 
8926   SM_DBG6(("smsatStartIDDev: before alloc\n"));
8927 
8928   /* allocate identify device command */
8929   satIntIo = smsatAllocIntIoResource( smRoot,
8930                                       smIORequest,
8931                                       satDevData,
8932                                       sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
8933                                       satIntIo);
8934 
8935   SM_DBG6(("smsatStartIDDev: before after\n"));
8936 
8937   if (satIntIo == agNULL)
8938   {
8939     SM_DBG1(("smsatStartIDDev: can't alloacate!!!\n"));
8940 
8941     /*smEnqueueIO(smRoot, satIOContext);*/
8942 
8943     return SM_RC_FAILURE;
8944   }
8945 
8946   satIntIo->satOrgSmIORequest = smIORequest; /* changed */
8947   smIORequestBody = satIntIo->satIntRequestBody;
8948   satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext);
8949 
8950   satNewIOContext->pSatDevData   = satDevData;
8951   satNewIOContext->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
8952   satNewIOContext->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
8953   satNewIOContext->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
8954   satNewIOContext->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
8955   satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */
8956   satNewIOContext->interruptContext = tiInterruptContext;
8957   satNewIOContext->satIntIoContext  = satIntIo;
8958 
8959   satNewIOContext->psmDeviceHandle = agNULL;
8960   satNewIOContext->satOrgIOContext = satIOContext; /* changed */
8961 
8962   /* this is valid only for TD layer generated (not triggered by OS at all) IO */
8963   satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg);
8964 
8965 
8966   SM_DBG6(("smsatStartIDDev: OS satIOContext %p \n", satIOContext));
8967   SM_DBG6(("smsatStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
8968   SM_DBG6(("smsatStartIDDev: OS tiScsiXchg %p \n", satIOContext->smScsiXchg));
8969   SM_DBG6(("smsatStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->smScsiXchg));
8970 
8971 
8972 
8973   SM_DBG1(("smsatStartIDDev: satNewIOContext %p smIORequestBody %p!!!\n", satNewIOContext, smIORequestBody));
8974 
8975   status = smsatSendIDDev( smRoot,
8976                            &satIntIo->satIntSmIORequest, /* New smIORequest */
8977                            smDeviceHandle,
8978                            satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
8979                            satNewIOContext);
8980 
8981   if (status != SM_RC_SUCCESS)
8982   {
8983     SM_DBG1(("smsatStartIDDev: failed in sending!!!\n"));
8984 
8985     smsatFreeIntIoResource( smRoot,
8986                             satDevData,
8987                             satIntIo);
8988     /*smEnqueueIO(smRoot, satIOContext);*/
8989 
8990     return SM_RC_FAILURE;
8991   }
8992 
8993 
8994   SM_DBG6(("smsatStartIDDev: end\n"));
8995 
8996   return status;
8997 }
8998 
8999 osGLOBAL bit32
9000 smsatSendIDDev(
9001                 smRoot_t                  *smRoot,
9002                 smIORequest_t             *smIORequest,
9003                 smDeviceHandle_t          *smDeviceHandle,
9004                 smScsiInitiatorRequest_t  *smScsiRequest,
9005                 smSatIOContext_t            *satIOContext
9006                )
9007 {
9008   bit32                     status;
9009   bit32                     agRequestType;
9010   smDeviceData_t           *pSatDevData;
9011   agsaFisRegHostToDevice_t *fis;
9012 #ifdef SM_INTERNAL_DEBUG
9013   smIORequestBody_t        *smIORequestBody;
9014   smSatInternalIo_t        *satIntIoContext;
9015 #endif
9016 
9017   pSatDevData   = satIOContext->pSatDevData;
9018   fis           = satIOContext->pFis;
9019   SM_DBG6(("smsatSendIDDev: start\n"));
9020   SM_DBG6(("smsatSendIDDev: did %d\n", pSatDevData->id));
9021 #ifdef SM_INTERNAL_DEBUG
9022   satIntIoContext = satIOContext->satIntIoContext;
9023   smIORequestBody = satIntIoContext->satIntRequestBody;
9024 #endif
9025   fis->h.fisType        = 0x27;                   /* Reg host to device */
9026   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9027   if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
9028       fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
9029   else
9030       fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
9031   fis->h.features       = 0;                      /* FIS reserve */
9032   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9033   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9034   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9035   fis->d.device         = 0;                      /* FIS LBA mode  */
9036   fis->d.lbaLowExp      = 0;
9037   fis->d.lbaMidExp      = 0;
9038   fis->d.lbaHighExp     = 0;
9039   fis->d.featuresExp    = 0;
9040   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9041   fis->d.sectorCountExp = 0;
9042   fis->d.reserved4      = 0;
9043   fis->d.control        = 0;                      /* FIS HOB bit clear */
9044   fis->d.reserved5      = 0;
9045 
9046   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
9047 
9048   /* Initialize CB for SATA completion.
9049    */
9050   satIOContext->satCompleteCB = &smsatInquiryCB;
9051 
9052   /*
9053    * Prepare SGL and send FIS to LL layer.
9054    */
9055   satIOContext->reqType = agRequestType;       /* Save it */
9056 
9057 #ifdef SM_INTERNAL_DEBUG
9058   smhexdump("smsatSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
9059   smhexdump("smsatSendIDDev LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
9060 #endif
9061   status = smsataLLIOStart( smRoot,
9062                             smIORequest,
9063                             smDeviceHandle,
9064                             smScsiRequest,
9065                             satIOContext);
9066 
9067   SM_DBG6(("smsatSendIDDev: end status %d\n", status));
9068   return status;
9069 }
9070 
9071 osGLOBAL bit32
9072 smsatRequestSense(
9073                   smRoot_t                  *smRoot,
9074                   smIORequest_t             *smIORequest,
9075                   smDeviceHandle_t          *smDeviceHandle,
9076                   smScsiInitiatorRequest_t  *smScsiRequest,
9077                   smSatIOContext_t            *satIOContext
9078                  )
9079 {
9080   /*
9081     SAT Rev 8 p38, Table25
9082     sending SMART RETURN STATUS
9083     Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB()
9084     Only fixed format sense data is support. In other words, we don't support DESC bit is set
9085     in Request Sense
9086    */
9087   bit32                     status;
9088   bit32                     agRequestType;
9089   smScsiRspSense_t          *pSense;
9090   smDeviceData_t            *pSatDevData;
9091   smIniScsiCmnd_t           *scsiCmnd;
9092   agsaFisRegHostToDevice_t  *fis;
9093   smIORequestBody_t         *smIORequestBody;
9094   smSatInternalIo_t           *satIntIo = agNULL;
9095   smSatIOContext_t            *satIOContext2;
9096   bit8                      *pDataBuffer = agNULL;
9097   bit32                     allocationLen = 0;
9098 
9099   pSense            = satIOContext->pSense;
9100   pSatDevData       = satIOContext->pSatDevData;
9101   scsiCmnd          = &smScsiRequest->scsiCmnd;
9102   fis               = satIOContext->pFis;
9103   pDataBuffer       = (bit8 *) smScsiRequest->sglVirtualAddr;
9104   allocationLen     = scsiCmnd->cdb[4];
9105   allocationLen     = MIN(allocationLen, scsiCmnd->expDataLength);
9106   SM_DBG5(("smsatRequestSense: start\n"));
9107 
9108   /* checking CONTROL */
9109   /* NACA == 1 or LINK == 1*/
9110   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9111   {
9112     smsatSetSensePayload( pSense,
9113                           SCSI_SNSKEY_ILLEGAL_REQUEST,
9114                           0,
9115                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9116                           satIOContext);
9117     sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9118 
9119     /*smEnqueueIO(smRoot, satIOContext);*/
9120 
9121     tdsmIOCompletedCB( smRoot,
9122                        smIORequest,
9123                        smIOSuccess,
9124                        SCSI_STAT_CHECK_CONDITION,
9125                        satIOContext->pSmSenseData,
9126                        satIOContext->interruptContext );
9127 
9128     SM_DBG1(("smsatRequestSense: return control!!!\n"));
9129     return SM_RC_SUCCESS;
9130   }
9131 
9132   /*
9133     Only fixed format sense data is support. In other words, we don't support DESC bit is set
9134     in Request Sense
9135    */
9136   if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
9137   {
9138     smsatSetSensePayload( pSense,
9139                           SCSI_SNSKEY_ILLEGAL_REQUEST,
9140                           0,
9141                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9142                           satIOContext);
9143     sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9144 
9145     /*smEnqueueIO(smRoot, satIOContext);*/
9146 
9147     tdsmIOCompletedCB( smRoot,
9148                        smIORequest,
9149                        smIOSuccess,
9150                        SCSI_STAT_CHECK_CONDITION,
9151                        satIOContext->pSmSenseData,
9152                        satIOContext->interruptContext );
9153 
9154     SM_DBG1(("smsatRequestSense: DESC bit is set, which we don't support!!!\n"));
9155     return SM_RC_SUCCESS;
9156   }
9157 
9158 
9159   if (pSatDevData->satSMARTEnabled == agTRUE)
9160   {
9161     /* sends SMART RETURN STATUS */
9162     fis->h.fisType        = 0x27;                   /* Reg host to device */
9163     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9164 
9165     fis->h.command        = SAT_SMART;               /* 0xB0 */
9166     fis->h.features       = SAT_SMART_RETURN_STATUS; /* FIS features */
9167     fis->d.featuresExp    = 0;                      /* FIS reserve */
9168     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9169     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9170     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9171     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9172     fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
9173     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9174     fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
9175     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9176     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
9177     fis->d.control        = 0;                      /* FIS HOB bit clear */
9178     fis->d.reserved4      = 0;
9179     fis->d.reserved5      = 0;
9180 
9181     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9182     /* Initialize CB for SATA completion.
9183      */
9184     satIOContext->satCompleteCB = &smsatRequestSenseCB;
9185 
9186     /*
9187      * Prepare SGL and send FIS to LL layer.
9188      */
9189     satIOContext->reqType = agRequestType;       /* Save it */
9190 
9191     status = smsataLLIOStart( smRoot,
9192                               smIORequest,
9193                               smDeviceHandle,
9194                               smScsiRequest,
9195                               satIOContext);
9196 
9197     SM_DBG4(("smsatRequestSense: if return, status %d\n", status));
9198     return (status);
9199   }
9200   else
9201   {
9202     /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE
9203       then call satRequestSense2 */
9204 
9205     SM_DBG4(("smsatRequestSense: before satIntIo %p\n", satIntIo));
9206     /* allocate iocontext */
9207     satIntIo = smsatAllocIntIoResource( smRoot,
9208                                         smIORequest, /* original request */
9209                                         pSatDevData,
9210                                         smScsiRequest->scsiCmnd.expDataLength,
9211                                         satIntIo);
9212 
9213     SM_DBG4(("smsatRequestSense: after satIntIo %p\n", satIntIo));
9214 
9215     if (satIntIo == agNULL)
9216     {
9217       /* failed during sending SMART RETURN STATUS */
9218       smsatSetSensePayload( pSense,
9219                             SCSI_SNSKEY_NO_SENSE,
9220                             0,
9221                             SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
9222                             satIOContext);
9223       sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9224 
9225       /*smEnqueueIO(smRoot, satIOContext);*/
9226 
9227       tdsmIOCompletedCB( smRoot,
9228                          smIORequest,
9229                          smIOSuccess,
9230                          SCSI_STAT_GOOD,
9231                          agNULL,
9232                          satIOContext->interruptContext );
9233 
9234       SM_DBG1(("smsatRequestSense: else fail 1!!!\n"));
9235       return SM_RC_SUCCESS;
9236     } /* end of memory allocation failure */
9237 
9238 
9239     /*
9240      * Need to initialize all the fields within satIOContext except
9241      * reqType and satCompleteCB which will be set depending on cmd.
9242      */
9243 
9244     if (satIntIo == agNULL)
9245     {
9246       SM_DBG4(("smsatRequestSense: satIntIo is NULL\n"));
9247     }
9248     else
9249     {
9250       SM_DBG4(("smsatRequestSense: satIntIo is NOT NULL\n"));
9251     }
9252     /* use this --- tttttthe one the same */
9253 
9254 
9255     satIntIo->satOrgSmIORequest = smIORequest;
9256     smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
9257     satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);
9258 
9259     satIOContext2->pSatDevData   = pSatDevData;
9260     satIOContext2->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
9261     satIOContext2->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
9262     satIOContext2->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
9263     satIOContext2->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
9264     satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;
9265     satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
9266     satIOContext2->interruptContext = satIOContext->interruptContext;
9267     satIOContext2->satIntIoContext  = satIntIo;
9268     satIOContext2->psmDeviceHandle = smDeviceHandle;
9269     satIOContext2->satOrgIOContext = satIOContext;
9270 
9271     SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len));
9272 
9273     SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper));
9274 
9275     SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower));
9276 
9277     SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type));
9278 
9279     status = smsatRequestSense_1( smRoot,
9280                                   &(satIntIo->satIntSmIORequest),
9281                                   smDeviceHandle,
9282                                   &(satIntIo->satIntSmScsiXchg),
9283                                   satIOContext2);
9284 
9285     if (status != SM_RC_SUCCESS)
9286     {
9287       smsatFreeIntIoResource( smRoot,
9288                               pSatDevData,
9289                               satIntIo);
9290 
9291       /* failed during sending SMART RETURN STATUS */
9292       smsatSetSensePayload( pSense,
9293                             SCSI_SNSKEY_NO_SENSE,
9294                             0,
9295                             SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
9296                             satIOContext);
9297       sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9298 
9299       /*smEnqueueIO(smRoot, satIOContext);*/
9300 
9301       tdsmIOCompletedCB( smRoot,
9302                          smIORequest,
9303                          smIOSuccess,
9304                          SCSI_STAT_CHECK_CONDITION,
9305                          agNULL,
9306                          satIOContext->interruptContext );
9307 
9308       SM_DBG1(("smsatRequestSense: else fail 2!!!\n"));
9309       return SM_RC_SUCCESS;
9310     }
9311     SM_DBG4(("smsatRequestSense: else return success\n"));
9312     return SM_RC_SUCCESS;
9313   }
9314 }
9315 
9316 osGLOBAL bit32
9317 smsatRequestSense_1(
9318                     smRoot_t                  *smRoot,
9319                     smIORequest_t             *smIORequest,
9320                     smDeviceHandle_t          *smDeviceHandle,
9321                     smScsiInitiatorRequest_t  *smScsiRequest,
9322                     smSatIOContext_t            *satIOContext
9323                    )
9324 {
9325   /*
9326     sends SAT_CHECK_POWER_MODE
9327   */
9328   bit32                     status;
9329   bit32                     agRequestType;
9330   agsaFisRegHostToDevice_t  *fis;
9331 
9332   fis               = satIOContext->pFis;
9333   SM_DBG5(("smsatRequestSense_1: start\n"));
9334   /*
9335    * Send the ATA CHECK POWER MODE command.
9336    */
9337   fis->h.fisType        = 0x27;                   /* Reg host to device */
9338   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9339   fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
9340   fis->h.features       = 0;
9341   fis->d.lbaLow         = 0;
9342   fis->d.lbaMid         = 0;
9343   fis->d.lbaHigh        = 0;
9344   fis->d.device         = 0;
9345   fis->d.lbaLowExp      = 0;
9346   fis->d.lbaMidExp      = 0;
9347   fis->d.lbaHighExp     = 0;
9348   fis->d.featuresExp    = 0;
9349   fis->d.sectorCount    = 0;
9350   fis->d.sectorCountExp = 0;
9351   fis->d.reserved4      = 0;
9352   fis->d.control        = 0;                      /* FIS HOB bit clear */
9353   fis->d.reserved5      = 0;
9354 
9355   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9356 
9357   /* Initialize CB for SATA completion.
9358    */
9359   satIOContext->satCompleteCB = &smsatRequestSenseCB;
9360 
9361   /*
9362    * Prepare SGL and send FIS to LL layer.
9363    */
9364   satIOContext->reqType = agRequestType;       /* Save it */
9365 
9366 
9367   SM_DBG4(("smsatRequestSense_1: smSgl1.len %d\n", smScsiRequest->smSgl1.len));
9368 
9369   SM_DBG4(("smsatRequestSense_1: smSgl1.upper %d\n", smScsiRequest->smSgl1.upper));
9370 
9371   SM_DBG4(("smsatRequestSense_1: smSgl1.lower %d\n", smScsiRequest->smSgl1.lower));
9372 
9373   SM_DBG4(("smsatRequestSense_1: smSgl1.type %d\n", smScsiRequest->smSgl1.type));
9374 
9375   //  smhexdump("smsatRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
9376 
9377   status = smsataLLIOStart( smRoot,
9378                             smIORequest,
9379                             smDeviceHandle,
9380                             smScsiRequest,
9381                             satIOContext);
9382 
9383 
9384 
9385   return status;
9386 }
9387 
9388 osGLOBAL bit32
9389 smsatModeSense6(
9390                 smRoot_t                  *smRoot,
9391                 smIORequest_t             *smIORequest,
9392                 smDeviceHandle_t          *smDeviceHandle,
9393                 smScsiInitiatorRequest_t  *smScsiRequest,
9394                 smSatIOContext_t            *satIOContext
9395                )
9396 {
9397   smScsiRspSense_t        *pSense;
9398   bit32                   allocationLen;
9399   smIniScsiCmnd_t         *scsiCmnd;
9400   bit32                   pageSupported;
9401   bit8                    page;
9402   bit8                    *pModeSense;    /* Mode Sense data buffer */
9403   smDeviceData_t          *pSatDevData;
9404   bit8                    PC;
9405   bit8                    AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN];
9406   bit8                    Control[MODE_SENSE6_CONTROL_PAGE_LEN];
9407   bit8                    RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN];
9408   bit8                    Caching[MODE_SENSE6_CACHING_LEN];
9409   bit8                    InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN];
9410   bit8                    lenRead = 0;
9411 
9412 
9413   pSense      = satIOContext->pSense;
9414   scsiCmnd    = &smScsiRequest->scsiCmnd;
9415   pModeSense  = (bit8 *) smScsiRequest->sglVirtualAddr;
9416   pSatDevData = satIOContext->pSatDevData;
9417 
9418   //smhexdump("smsatModeSense6", (bit8 *)scsiCmnd->cdb, 6);
9419   SM_DBG5(("smsatModeSense6: start\n"));
9420   /* checking CONTROL */
9421   /* NACA == 1 or LINK == 1*/
9422   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9423   {
9424     smsatSetSensePayload( pSense,
9425                           SCSI_SNSKEY_ILLEGAL_REQUEST,
9426                           0,
9427                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9428                           satIOContext);
9429    /*smEnqueueIO(smRoot, satIOContext);*/
9430    tdsmIOCompletedCB( smRoot,
9431                        smIORequest,
9432                        smIOSuccess,
9433                        SCSI_STAT_CHECK_CONDITION,
9434                        satIOContext->pSmSenseData,
9435                        satIOContext->interruptContext );
9436     SM_DBG1(("smsatModeSense6: return control!!!\n"));
9437     return SM_RC_SUCCESS;
9438   }
9439   /* checking PC(Page Control)
9440      SAT revion 8, 8.5.3 p33 and 10.1.2, p66
9441   */
9442   PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
9443   if (PC != 0)
9444   {
9445     smsatSetSensePayload( pSense,
9446                           SCSI_SNSKEY_ILLEGAL_REQUEST,
9447                           0,
9448                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9449                           satIOContext);
9450     /*smEnqueueIO(smRoot, satIOContext);*/
9451     tdsmIOCompletedCB( smRoot,
9452                        smIORequest,
9453                        smIOSuccess,
9454                        SCSI_STAT_CHECK_CONDITION,
9455                        satIOContext->pSmSenseData,
9456                        satIOContext->interruptContext );
9457     SM_DBG1(("smsatModeSense6: return due to PC value pc 0x%x!!!\n", PC >> 6));
9458     return SM_RC_SUCCESS;
9459   }
9460   /* reading PAGE CODE */
9461   page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
9462 
9463 
9464   SM_DBG5(("smsatModeSense6: page=0x%x\n", page));
9465 
9466   allocationLen = scsiCmnd->cdb[4];
9467   allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
9468     /*
9469     Based on page code value, returns a corresponding mode page
9470     note: no support for subpage
9471   */
9472   switch(page)
9473   {
9474     case MODESENSE_RETURN_ALL_PAGES:
9475     case MODESENSE_CONTROL_PAGE: /* control */
9476     case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
9477     case MODESENSE_CACHING: /* caching */
9478     case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
9479       pageSupported = agTRUE;
9480       break;
9481     case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
9482     default:
9483       pageSupported = agFALSE;
9484       break;
9485   }
9486 
9487   if (pageSupported == agFALSE)
9488   {
9489 
9490     SM_DBG1(("smsatModeSense6 *** ERROR *** not supported page 0x%x did %d!!!\n",
9491         page, pSatDevData->id));
9492 
9493     smsatSetSensePayload( pSense,
9494                           SCSI_SNSKEY_ILLEGAL_REQUEST,
9495                           0,
9496                           SCSI_SNSCODE_INVALID_COMMAND,
9497                           satIOContext);
9498 
9499     /*smEnqueueIO(smRoot, satIOContext);*/
9500 
9501     tdsmIOCompletedCB( smRoot,
9502                        smIORequest,
9503                        smIOSuccess,
9504                        SCSI_STAT_CHECK_CONDITION,
9505                        satIOContext->pSmSenseData,
9506                        satIOContext->interruptContext );
9507     return SM_RC_SUCCESS;
9508   }
9509 
9510   switch(page)
9511   {
9512   case MODESENSE_RETURN_ALL_PAGES:
9513     lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
9514     break;
9515   case MODESENSE_CONTROL_PAGE: /* control */
9516     lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CONTROL_PAGE_LEN);
9517     break;
9518   case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
9519     lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
9520     break;
9521   case MODESENSE_CACHING: /* caching */
9522     lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CACHING_LEN);
9523     break;
9524   case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
9525     lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
9526     break;
9527   default:
9528     SM_DBG1(("smsatModeSense6: default error page %d!!!\n", page));
9529     break;
9530   }
9531 
9532   if (page == MODESENSE_RETURN_ALL_PAGES)
9533   {
9534     SM_DBG5(("smsatModeSense6: MODESENSE_RETURN_ALL_PAGES\n"));
9535     AllPages[0] = (bit8)(lenRead - 1);
9536     AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */
9537     AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9538     AllPages[3] = 0x08; /* block descriptor length */
9539 
9540     /*
9541      * Fill-up direct-access device block-descriptor, SAT, Table 19
9542      */
9543 
9544     /* density code */
9545     AllPages[4]  = 0x04; /* density-code : reserved for direct-access */
9546     /* number of blocks */
9547     AllPages[5]  = 0x00; /* unspecified */
9548     AllPages[6]  = 0x00; /* unspecified */
9549     AllPages[7]  = 0x00; /* unspecified */
9550     /* reserved */
9551     AllPages[8]  = 0x00; /* reserved */
9552     /* Block size */
9553     AllPages[9]  = 0x00;
9554     AllPages[10] = 0x02;   /* Block size is always 512 bytes */
9555     AllPages[11] = 0x00;
9556 
9557     /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
9558     AllPages[12] = 0x01; /* page code */
9559     AllPages[13] = 0x0A; /* page length */
9560     AllPages[14] = 0x40; /* ARRE is set */
9561     AllPages[15] = 0x00;
9562     AllPages[16] = 0x00;
9563     AllPages[17] = 0x00;
9564     AllPages[18] = 0x00;
9565     AllPages[19] = 0x00;
9566     AllPages[20] = 0x00;
9567     AllPages[21] = 0x00;
9568     AllPages[22] = 0x00;
9569     AllPages[23] = 0x00;
9570     /* MODESENSE_CACHING */
9571     AllPages[24] = 0x08; /* page code */
9572     AllPages[25] = 0x12; /* page length */
9573     if (pSatDevData->satWriteCacheEnabled == agTRUE)
9574     {
9575       AllPages[26] = 0x04;/* WCE bit is set */
9576     }
9577     else
9578     {
9579       AllPages[26] = 0x00;/* WCE bit is NOT set */
9580     }
9581 
9582     AllPages[27] = 0x00;
9583     AllPages[28] = 0x00;
9584     AllPages[29] = 0x00;
9585     AllPages[30] = 0x00;
9586     AllPages[31] = 0x00;
9587     AllPages[32] = 0x00;
9588     AllPages[33] = 0x00;
9589     AllPages[34] = 0x00;
9590     AllPages[35] = 0x00;
9591     if (pSatDevData->satLookAheadEnabled == agTRUE)
9592     {
9593       AllPages[36] = 0x00;/* DRA bit is NOT set */
9594     }
9595     else
9596     {
9597       AllPages[36] = 0x20;/* DRA bit is set */
9598     }
9599     AllPages[37] = 0x00;
9600     AllPages[38] = 0x00;
9601     AllPages[39] = 0x00;
9602     AllPages[40] = 0x00;
9603     AllPages[41] = 0x00;
9604     AllPages[42] = 0x00;
9605     AllPages[43] = 0x00;
9606     /* MODESENSE_CONTROL_PAGE */
9607     AllPages[44] = 0x0A; /* page code */
9608     AllPages[45] = 0x0A; /* page length */
9609     AllPages[46] = 0x02; /* only GLTSD bit is set */
9610     if (pSatDevData->satNCQ == agTRUE)
9611     {
9612       AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
9613     }
9614     else
9615     {
9616       AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
9617     }
9618     AllPages[48] = 0x00;
9619     AllPages[49] = 0x00;
9620     AllPages[50] = 0x00; /* obsolete */
9621     AllPages[51] = 0x00; /* obsolete */
9622     AllPages[52] = 0xFF; /* Busy Timeout Period */
9623     AllPages[53] = 0xFF; /* Busy Timeout Period */
9624     AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */
9625     AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */
9626     /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
9627     AllPages[56] = 0x1C; /* page code */
9628     AllPages[57] = 0x0A; /* page length */
9629     if (pSatDevData->satSMARTEnabled == agTRUE)
9630     {
9631       AllPages[58] = 0x00;/* DEXCPT bit is NOT set */
9632     }
9633     else
9634     {
9635       AllPages[58] = 0x08;/* DEXCPT bit is set */
9636     }
9637     AllPages[59] = 0x00; /* We don't support MRIE */
9638     AllPages[60] = 0x00; /* Interval timer vendor-specific */
9639     AllPages[61] = 0x00;
9640     AllPages[62] = 0x00;
9641     AllPages[63] = 0x00;
9642     AllPages[64] = 0x00; /* REPORT-COUNT */
9643     AllPages[65] = 0x00;
9644     AllPages[66] = 0x00;
9645     AllPages[67] = 0x00;
9646 
9647     sm_memcpy(pModeSense, &AllPages, lenRead);
9648   }
9649   else if (page == MODESENSE_CONTROL_PAGE)
9650   {
9651     SM_DBG5(("smsatModeSense6: MODESENSE_CONTROL_PAGE\n"));
9652     Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1;
9653     Control[1] = 0x00; /* default medium type (currently mounted medium type) */
9654     Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9655     Control[3] = 0x08; /* block descriptor length */
9656     /*
9657      * Fill-up direct-access device block-descriptor, SAT, Table 19
9658      */
9659 
9660     /* density code */
9661     Control[4]  = 0x04; /* density-code : reserved for direct-access */
9662     /* number of blocks */
9663     Control[5]  = 0x00; /* unspecified */
9664     Control[6]  = 0x00; /* unspecified */
9665     Control[7]  = 0x00; /* unspecified */
9666     /* reserved */
9667     Control[8]  = 0x00; /* reserved */
9668     /* Block size */
9669     Control[9]  = 0x00;
9670     Control[10] = 0x02;   /* Block size is always 512 bytes */
9671     Control[11] = 0x00;
9672     /*
9673      * Fill-up control mode page, SAT, Table 65
9674      */
9675     Control[12] = 0x0A; /* page code */
9676     Control[13] = 0x0A; /* page length */
9677     Control[14] = 0x02; /* only GLTSD bit is set */
9678     if (pSatDevData->satNCQ == agTRUE)
9679     {
9680       Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
9681     }
9682     else
9683     {
9684       Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
9685     }
9686     Control[16] = 0x00;
9687     Control[17] = 0x00;
9688     Control[18] = 0x00; /* obsolete */
9689     Control[19] = 0x00; /* obsolete */
9690     Control[20] = 0xFF; /* Busy Timeout Period */
9691     Control[21] = 0xFF; /* Busy Timeout Period */
9692     Control[22] = 0x00; /* we don't support non-000b value for the self-test code */
9693     Control[23] = 0x00; /* we don't support non-000b value for the self-test code */
9694 
9695     sm_memcpy(pModeSense, &Control, lenRead);
9696 
9697   }
9698   else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
9699   {
9700     SM_DBG5(("smsatModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
9701     RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1;
9702     RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */
9703     RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9704     RWErrorRecovery[3] = 0x08; /* block descriptor length */
9705     /*
9706      * Fill-up direct-access device block-descriptor, SAT, Table 19
9707      */
9708 
9709     /* density code */
9710     RWErrorRecovery[4]  = 0x04; /* density-code : reserved for direct-access */
9711     /* number of blocks */
9712     RWErrorRecovery[5]  = 0x00; /* unspecified */
9713     RWErrorRecovery[6]  = 0x00; /* unspecified */
9714     RWErrorRecovery[7]  = 0x00; /* unspecified */
9715     /* reserved */
9716     RWErrorRecovery[8]  = 0x00; /* reserved */
9717     /* Block size */
9718     RWErrorRecovery[9]  = 0x00;
9719     RWErrorRecovery[10] = 0x02;   /* Block size is always 512 bytes */
9720     RWErrorRecovery[11] = 0x00;
9721     /*
9722      * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
9723      */
9724     RWErrorRecovery[12] = 0x01; /* page code */
9725     RWErrorRecovery[13] = 0x0A; /* page length */
9726     RWErrorRecovery[14] = 0x40; /* ARRE is set */
9727     RWErrorRecovery[15] = 0x00;
9728     RWErrorRecovery[16] = 0x00;
9729     RWErrorRecovery[17] = 0x00;
9730     RWErrorRecovery[18] = 0x00;
9731     RWErrorRecovery[19] = 0x00;
9732     RWErrorRecovery[20] = 0x00;
9733     RWErrorRecovery[21] = 0x00;
9734     RWErrorRecovery[22] = 0x00;
9735     RWErrorRecovery[23] = 0x00;
9736 
9737     sm_memcpy(pModeSense, &RWErrorRecovery, lenRead);
9738 
9739   }
9740   else if (page == MODESENSE_CACHING)
9741   {
9742     SM_DBG5(("smsatModeSense6: MODESENSE_CACHING\n"));
9743     /* special case */
9744     if (allocationLen == 4 && page == MODESENSE_CACHING)
9745     {
9746       SM_DBG5(("smsatModeSense6: linux 2.6.8.24 support\n"));
9747 
9748       Caching[0] = 0x20 - 1; /* 32 - 1 */
9749       Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
9750       Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9751       Caching[3] = 0x08; /* block descriptor length */
9752 
9753       sm_memcpy(pModeSense, &Caching, 4);
9754       /*smEnqueueIO(smRoot, satIOContext);*/
9755 
9756       tdsmIOCompletedCB( smRoot,
9757                          smIORequest,
9758                          smIOSuccess,
9759                          SCSI_STAT_GOOD,
9760                          agNULL,
9761                          satIOContext->interruptContext);
9762       return SM_RC_SUCCESS;
9763     }
9764     Caching[0] = MODE_SENSE6_CACHING_LEN - 1;
9765     Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
9766     Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9767     Caching[3] = 0x08; /* block descriptor length */
9768     /*
9769      * Fill-up direct-access device block-descriptor, SAT, Table 19
9770      */
9771 
9772     /* density code */
9773     Caching[4]  = 0x04; /* density-code : reserved for direct-access */
9774     /* number of blocks */
9775     Caching[5]  = 0x00; /* unspecified */
9776     Caching[6]  = 0x00; /* unspecified */
9777     Caching[7]  = 0x00; /* unspecified */
9778     /* reserved */
9779     Caching[8]  = 0x00; /* reserved */
9780     /* Block size */
9781     Caching[9]  = 0x00;
9782     Caching[10] = 0x02;   /* Block size is always 512 bytes */
9783     Caching[11] = 0x00;
9784     /*
9785      * Fill-up Caching mode page, SAT, Table 67
9786      */
9787     /* length 20 */
9788     Caching[12] = 0x08; /* page code */
9789     Caching[13] = 0x12; /* page length */
9790     if (pSatDevData->satWriteCacheEnabled == agTRUE)
9791     {
9792       Caching[14] = 0x04;/* WCE bit is set */
9793     }
9794     else
9795     {
9796       Caching[14] = 0x00;/* WCE bit is NOT set */
9797     }
9798 
9799     Caching[15] = 0x00;
9800     Caching[16] = 0x00;
9801     Caching[17] = 0x00;
9802     Caching[18] = 0x00;
9803     Caching[19] = 0x00;
9804     Caching[20] = 0x00;
9805     Caching[21] = 0x00;
9806     Caching[22] = 0x00;
9807     Caching[23] = 0x00;
9808     if (pSatDevData->satLookAheadEnabled == agTRUE)
9809     {
9810       Caching[24] = 0x00;/* DRA bit is NOT set */
9811     }
9812     else
9813     {
9814       Caching[24] = 0x20;/* DRA bit is set */
9815     }
9816     Caching[25] = 0x00;
9817     Caching[26] = 0x00;
9818     Caching[27] = 0x00;
9819     Caching[28] = 0x00;
9820     Caching[29] = 0x00;
9821     Caching[30] = 0x00;
9822     Caching[31] = 0x00;
9823 
9824     sm_memcpy(pModeSense, &Caching, lenRead);
9825 
9826   }
9827   else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
9828   {
9829     SM_DBG5(("smsatModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
9830     InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1;
9831     InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */
9832     InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9833     InfoExceptionCtrl[3] = 0x08; /* block descriptor length */
9834     /*
9835      * Fill-up direct-access device block-descriptor, SAT, Table 19
9836      */
9837 
9838     /* density code */
9839     InfoExceptionCtrl[4]  = 0x04; /* density-code : reserved for direct-access */
9840     /* number of blocks */
9841     InfoExceptionCtrl[5]  = 0x00; /* unspecified */
9842     InfoExceptionCtrl[6]  = 0x00; /* unspecified */
9843     InfoExceptionCtrl[7]  = 0x00; /* unspecified */
9844     /* reserved */
9845     InfoExceptionCtrl[8]  = 0x00; /* reserved */
9846     /* Block size */
9847     InfoExceptionCtrl[9]  = 0x00;
9848     InfoExceptionCtrl[10] = 0x02;   /* Block size is always 512 bytes */
9849     InfoExceptionCtrl[11] = 0x00;
9850     /*
9851      * Fill-up informational-exceptions control mode page, SAT, Table 68
9852      */
9853     InfoExceptionCtrl[12] = 0x1C; /* page code */
9854     InfoExceptionCtrl[13] = 0x0A; /* page length */
9855      if (pSatDevData->satSMARTEnabled == agTRUE)
9856     {
9857       InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */
9858     }
9859     else
9860     {
9861       InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */
9862     }
9863     InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */
9864     InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */
9865     InfoExceptionCtrl[17] = 0x00;
9866     InfoExceptionCtrl[18] = 0x00;
9867     InfoExceptionCtrl[19] = 0x00;
9868     InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */
9869     InfoExceptionCtrl[21] = 0x00;
9870     InfoExceptionCtrl[22] = 0x00;
9871     InfoExceptionCtrl[23] = 0x00;
9872     sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
9873 
9874   }
9875   else
9876   {
9877     /* Error */
9878     SM_DBG1(("smsatModeSense6: Error page %d!!!\n", page));
9879     smsatSetSensePayload( pSense,
9880                           SCSI_SNSKEY_ILLEGAL_REQUEST,
9881                           0,
9882                           SCSI_SNSCODE_INVALID_COMMAND,
9883                           satIOContext);
9884 
9885     /*smEnqueueIO(smRoot, satIOContext);*/
9886 
9887     tdsmIOCompletedCB( smRoot,
9888                        smIORequest,
9889                        smIOSuccess,
9890                        SCSI_STAT_CHECK_CONDITION,
9891                        satIOContext->pSmSenseData,
9892                        satIOContext->interruptContext );
9893     return SM_RC_SUCCESS;
9894   }
9895 
9896   /* there can be only underrun not overrun in error case */
9897   if (allocationLen > lenRead)
9898   {
9899     SM_DBG6(("smsatModeSense6 reporting underrun lenRead=0x%x allocationLen=0x%x\n", lenRead, allocationLen));
9900 
9901     /*smEnqueueIO(smRoot, satIOContext);*/
9902 
9903     tdsmIOCompletedCB( smRoot,
9904                        smIORequest,
9905                        smIOUnderRun,
9906                        allocationLen - lenRead,
9907                        agNULL,
9908                        satIOContext->interruptContext );
9909 
9910 
9911   }
9912   else
9913   {
9914     /*smEnqueueIO(smRoot, satIOContext);*/
9915 
9916     tdsmIOCompletedCB( smRoot,
9917                        smIORequest,
9918                        smIOSuccess,
9919                        SCSI_STAT_GOOD,
9920                        agNULL,
9921                        satIOContext->interruptContext);
9922   }
9923 
9924   return SM_RC_SUCCESS;
9925 
9926 }
9927 
9928 osGLOBAL bit32
9929 smsatModeSense10(
9930                   smRoot_t                  *smRoot,
9931                   smIORequest_t             *smIORequest,
9932                   smDeviceHandle_t          *smDeviceHandle,
9933                   smScsiInitiatorRequest_t  *smScsiRequest,
9934                   smSatIOContext_t            *satIOContext
9935                  )
9936 {
9937   smScsiRspSense_t        *pSense;
9938   bit32                   allocationLen;
9939   smIniScsiCmnd_t         *scsiCmnd;
9940   bit32                   pageSupported;
9941   bit8                    page;
9942   bit8                    *pModeSense;    /* Mode Sense data buffer */
9943   smDeviceData_t          *pSatDevData;
9944   bit8                    PC; /* page control */
9945   bit8                    LLBAA; /* Long LBA Accepted */
9946   bit32                   index;
9947   bit8                    AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN];
9948   bit8                    Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN];
9949   bit8                    RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN];
9950   bit8                    Caching[MODE_SENSE10_CACHING_LLBAA_LEN];
9951   bit8                    InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN];
9952   bit8                    lenRead = 0;
9953 
9954   pSense      = satIOContext->pSense;
9955   scsiCmnd    = &smScsiRequest->scsiCmnd;
9956   pModeSense  = (bit8 *) smScsiRequest->sglVirtualAddr;
9957   pSatDevData = satIOContext->pSatDevData;
9958   SM_DBG5(("smsatModeSense10: start\n"));
9959   /* checking CONTROL */
9960   /* NACA == 1 or LINK == 1*/
9961   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
9962   {
9963     smsatSetSensePayload( pSense,
9964                           SCSI_SNSKEY_ILLEGAL_REQUEST,
9965                           0,
9966                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9967                           satIOContext);
9968 
9969     /*smEnqueueIO(smRoot, satIOContext);*/
9970 
9971     tdsmIOCompletedCB( smRoot,
9972                        smIORequest,
9973                        smIOSuccess,
9974                        SCSI_STAT_CHECK_CONDITION,
9975                        satIOContext->pSmSenseData,
9976                        satIOContext->interruptContext );
9977 
9978     SM_DBG1(("smsatModeSense10: return control!!!\n"));
9979     return SM_RC_SUCCESS;
9980   }
9981 
9982   /* checking PC(Page Control)
9983      SAT revion 8, 8.5.3 p33 and 10.1.2, p66
9984   */
9985   PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
9986   if (PC != 0)
9987   {
9988     smsatSetSensePayload( pSense,
9989                           SCSI_SNSKEY_ILLEGAL_REQUEST,
9990                           0,
9991                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9992                           satIOContext);
9993 
9994     /*smEnqueueIO(smRoot, satIOContext);*/
9995 
9996     tdsmIOCompletedCB( smRoot,
9997                        smIORequest,
9998                        smIOSuccess,
9999                        SCSI_STAT_CHECK_CONDITION,
10000                        satIOContext->pSmSenseData,
10001                        satIOContext->interruptContext );
10002 
10003     SM_DBG1(("smsatModeSense10: return due to PC value pc 0x%x!!!\n", PC));
10004     return SM_RC_SUCCESS;
10005   }
10006 
10007   /* finding LLBAA bit */
10008   LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
10009 
10010   /* reading PAGE CODE */
10011   page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
10012   SM_DBG5(("smsatModeSense10: page=0x%x, did %d\n", page, pSatDevData->id));
10013   allocationLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
10014   allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
10015 
10016   /*
10017     Based on page code value, returns a corresponding mode page
10018     note: no support for subpage
10019   */
10020   switch(page)
10021   {
10022     case MODESENSE_RETURN_ALL_PAGES: /* return all pages */
10023     case MODESENSE_CONTROL_PAGE: /* control */
10024     case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
10025     case MODESENSE_CACHING: /* caching */
10026     case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
10027       pageSupported = agTRUE;
10028       break;
10029     case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
10030     default:
10031       pageSupported = agFALSE;
10032       break;
10033   }
10034   if (pageSupported == agFALSE)
10035   {
10036     SM_DBG1(("smsatModeSense10 *** ERROR *** not supported page 0x%x did %d!!!\n", page, pSatDevData->id));
10037 
10038     smsatSetSensePayload( pSense,
10039                           SCSI_SNSKEY_ILLEGAL_REQUEST,
10040                           0,
10041                           SCSI_SNSCODE_INVALID_COMMAND,
10042                           satIOContext);
10043     /*smEnqueueIO(smRoot, satIOContext);*/
10044     tdsmIOCompletedCB( smRoot,
10045                        smIORequest,
10046                        smIOSuccess,
10047                        SCSI_STAT_CHECK_CONDITION,
10048                        satIOContext->pSmSenseData,
10049                        satIOContext->interruptContext );
10050     return SM_RC_SUCCESS;
10051   }
10052   switch(page)
10053   {
10054   case MODESENSE_RETURN_ALL_PAGES:
10055     if (LLBAA)
10056     {
10057       lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
10058     }
10059     else
10060     {
10061       lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
10062     }
10063     break;
10064   case MODESENSE_CONTROL_PAGE: /* control */
10065     if (LLBAA)
10066     {
10067       lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
10068     }
10069     else
10070     {
10071       lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LEN);
10072     }
10073     break;
10074   case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
10075     if (LLBAA)
10076     {
10077       lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
10078     }
10079     else
10080     {
10081       lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
10082     }
10083     break;
10084   case MODESENSE_CACHING: /* caching */
10085     if (LLBAA)
10086     {
10087       lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LLBAA_LEN);
10088     }
10089     else
10090     {
10091       lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LEN);
10092     }
10093     break;
10094   case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
10095     if (LLBAA)
10096     {
10097       lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
10098     }
10099     else
10100     {
10101       lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
10102     }
10103     break;
10104   default:
10105     SM_DBG1(("smsatModeSense10: default error page %d!!!\n", page));
10106     break;
10107   }
10108 
10109   if (page == MODESENSE_RETURN_ALL_PAGES)
10110   {
10111     SM_DBG5(("smsatModeSense10: MODESENSE_RETURN_ALL_PAGES\n"));
10112     AllPages[0] = 0;
10113     AllPages[1] = (bit8)(lenRead - 2);
10114     AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10115     AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10116     if (LLBAA)
10117     {
10118       AllPages[4] = 0x00; /* reserved and LONGLBA */
10119       AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */
10120     }
10121     else
10122     {
10123       AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10124     }
10125     AllPages[5] = 0x00; /* reserved */
10126     AllPages[6] = 0x00; /* block descriptot length */
10127     if (LLBAA)
10128     {
10129       AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10130     }
10131     else
10132     {
10133       AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10134     }
10135 
10136     /*
10137      * Fill-up direct-access device block-descriptor, SAT, Table 19
10138      */
10139 
10140     if (LLBAA)
10141     {
10142       /* density code */
10143       AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
10144       /* number of blocks */
10145       AllPages[9]   = 0x00; /* unspecified */
10146       AllPages[10]  = 0x00; /* unspecified */
10147       AllPages[11]  = 0x00; /* unspecified */
10148       AllPages[12]  = 0x00; /* unspecified */
10149       AllPages[13]  = 0x00; /* unspecified */
10150       AllPages[14]  = 0x00; /* unspecified */
10151       AllPages[15]  = 0x00; /* unspecified */
10152       /* reserved */
10153       AllPages[16]  = 0x00; /* reserved */
10154       AllPages[17]  = 0x00; /* reserved */
10155       AllPages[18]  = 0x00; /* reserved */
10156       AllPages[19]  = 0x00; /* reserved */
10157       /* Block size */
10158       AllPages[20]  = 0x00;
10159       AllPages[21]  = 0x00;
10160       AllPages[22]  = 0x02;   /* Block size is always 512 bytes */
10161       AllPages[23]  = 0x00;
10162     }
10163     else
10164     {
10165       /* density code */
10166       AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
10167       /* number of blocks */
10168       AllPages[9]   = 0x00; /* unspecified */
10169       AllPages[10]  = 0x00; /* unspecified */
10170       AllPages[11]  = 0x00; /* unspecified */
10171       /* reserved */
10172       AllPages[12]  = 0x00; /* reserved */
10173       /* Block size */
10174       AllPages[13]  = 0x00;
10175       AllPages[14]  = 0x02;   /* Block size is always 512 bytes */
10176       AllPages[15]  = 0x00;
10177     }
10178 
10179     if (LLBAA)
10180     {
10181       index = 24;
10182     }
10183     else
10184     {
10185       index = 16;
10186     }
10187     /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
10188     AllPages[index+0] = 0x01; /* page code */
10189     AllPages[index+1] = 0x0A; /* page length */
10190     AllPages[index+2] = 0x40; /* ARRE is set */
10191     AllPages[index+3] = 0x00;
10192     AllPages[index+4] = 0x00;
10193     AllPages[index+5] = 0x00;
10194     AllPages[index+6] = 0x00;
10195     AllPages[index+7] = 0x00;
10196     AllPages[index+8] = 0x00;
10197     AllPages[index+9] = 0x00;
10198     AllPages[index+10] = 0x00;
10199     AllPages[index+11] = 0x00;
10200 
10201     /* MODESENSE_CACHING */
10202     /*
10203      * Fill-up Caching mode page, SAT, Table 67
10204      */
10205     /* length 20 */
10206     AllPages[index+12] = 0x08; /* page code */
10207     AllPages[index+13] = 0x12; /* page length */
10208     if (pSatDevData->satWriteCacheEnabled == agTRUE)
10209     {
10210       AllPages[index+14] = 0x04;/* WCE bit is set */
10211     }
10212     else
10213     {
10214       AllPages[index+14] = 0x00;/* WCE bit is NOT set */
10215     }
10216 
10217     AllPages[index+15] = 0x00;
10218     AllPages[index+16] = 0x00;
10219     AllPages[index+17] = 0x00;
10220     AllPages[index+18] = 0x00;
10221     AllPages[index+19] = 0x00;
10222     AllPages[index+20] = 0x00;
10223     AllPages[index+21] = 0x00;
10224     AllPages[index+22] = 0x00;
10225     AllPages[index+23] = 0x00;
10226     if (pSatDevData->satLookAheadEnabled == agTRUE)
10227     {
10228       AllPages[index+24] = 0x00;/* DRA bit is NOT set */
10229     }
10230     else
10231     {
10232       AllPages[index+24] = 0x20;/* DRA bit is set */
10233     }
10234     AllPages[index+25] = 0x00;
10235     AllPages[index+26] = 0x00;
10236     AllPages[index+27] = 0x00;
10237     AllPages[index+28] = 0x00;
10238     AllPages[index+29] = 0x00;
10239     AllPages[index+30] = 0x00;
10240     AllPages[index+31] = 0x00;
10241 
10242     /* MODESENSE_CONTROL_PAGE */
10243     /*
10244      * Fill-up control mode page, SAT, Table 65
10245      */
10246     AllPages[index+32] = 0x0A; /* page code */
10247     AllPages[index+33] = 0x0A; /* page length */
10248     AllPages[index+34] = 0x02; /* only GLTSD bit is set */
10249     if (pSatDevData->satNCQ == agTRUE)
10250     {
10251       AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
10252     }
10253     else
10254     {
10255       AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
10256     }
10257     AllPages[index+36] = 0x00;
10258     AllPages[index+37] = 0x00;
10259     AllPages[index+38] = 0x00; /* obsolete */
10260     AllPages[index+39] = 0x00; /* obsolete */
10261     AllPages[index+40] = 0xFF; /* Busy Timeout Period */
10262     AllPages[index+41] = 0xFF; /* Busy Timeout Period */
10263     AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */
10264     AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */
10265 
10266     /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
10267     /*
10268      * Fill-up informational-exceptions control mode page, SAT, Table 68
10269      */
10270     AllPages[index+44] = 0x1C; /* page code */
10271     AllPages[index+45] = 0x0A; /* page length */
10272      if (pSatDevData->satSMARTEnabled == agTRUE)
10273     {
10274       AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */
10275     }
10276     else
10277     {
10278       AllPages[index+46] = 0x08;/* DEXCPT bit is set */
10279     }
10280     AllPages[index+47] = 0x00; /* We don't support MRIE */
10281     AllPages[index+48] = 0x00; /* Interval timer vendor-specific */
10282     AllPages[index+49] = 0x00;
10283     AllPages[index+50] = 0x00;
10284     AllPages[index+51] = 0x00;
10285     AllPages[index+52] = 0x00; /* REPORT-COUNT */
10286     AllPages[index+53] = 0x00;
10287     AllPages[index+54] = 0x00;
10288     AllPages[index+55] = 0x00;
10289 
10290     sm_memcpy(pModeSense, &AllPages, lenRead);
10291   }
10292   else if (page == MODESENSE_CONTROL_PAGE)
10293   {
10294     SM_DBG5(("smsatModeSense10: MODESENSE_CONTROL_PAGE\n"));
10295     Control[0] = 0;
10296     Control[1] = (bit8)(lenRead - 2);
10297     Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10298     Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10299     if (LLBAA)
10300     {
10301       Control[4] = 0x00; /* reserved and LONGLBA */
10302       Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */
10303     }
10304     else
10305     {
10306       Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10307     }
10308     Control[5] = 0x00; /* reserved */
10309     Control[6] = 0x00; /* block descriptot length */
10310     if (LLBAA)
10311     {
10312       Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10313     }
10314     else
10315     {
10316       Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10317     }
10318 
10319     /*
10320      * Fill-up direct-access device block-descriptor, SAT, Table 19
10321      */
10322 
10323     if (LLBAA)
10324     {
10325       /* density code */
10326       Control[8]   = 0x04; /* density-code : reserved for direct-access */
10327       /* number of blocks */
10328       Control[9]   = 0x00; /* unspecified */
10329       Control[10]  = 0x00; /* unspecified */
10330       Control[11]  = 0x00; /* unspecified */
10331       Control[12]  = 0x00; /* unspecified */
10332       Control[13]  = 0x00; /* unspecified */
10333       Control[14]  = 0x00; /* unspecified */
10334       Control[15]  = 0x00; /* unspecified */
10335       /* reserved */
10336       Control[16]  = 0x00; /* reserved */
10337       Control[17]  = 0x00; /* reserved */
10338       Control[18]  = 0x00; /* reserved */
10339       Control[19]  = 0x00; /* reserved */
10340       /* Block size */
10341       Control[20]  = 0x00;
10342       Control[21]  = 0x00;
10343       Control[22]  = 0x02;   /* Block size is always 512 bytes */
10344       Control[23]  = 0x00;
10345     }
10346     else
10347     {
10348       /* density code */
10349       Control[8]   = 0x04; /* density-code : reserved for direct-access */
10350       /* number of blocks */
10351       Control[9]   = 0x00; /* unspecified */
10352       Control[10]  = 0x00; /* unspecified */
10353       Control[11]  = 0x00; /* unspecified */
10354       /* reserved */
10355       Control[12]  = 0x00; /* reserved */
10356       /* Block size */
10357       Control[13]  = 0x00;
10358       Control[14]  = 0x02;   /* Block size is always 512 bytes */
10359       Control[15]  = 0x00;
10360     }
10361 
10362     if (LLBAA)
10363     {
10364       index = 24;
10365     }
10366     else
10367     {
10368       index = 16;
10369     }
10370     /*
10371      * Fill-up control mode page, SAT, Table 65
10372      */
10373     Control[index+0] = 0x0A; /* page code */
10374     Control[index+1] = 0x0A; /* page length */
10375     Control[index+2] = 0x02; /* only GLTSD bit is set */
10376     if (pSatDevData->satNCQ == agTRUE)
10377     {
10378       Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
10379     }
10380     else
10381     {
10382       Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
10383     }
10384     Control[index+4] = 0x00;
10385     Control[index+5] = 0x00;
10386     Control[index+6] = 0x00; /* obsolete */
10387     Control[index+7] = 0x00; /* obsolete */
10388     Control[index+8] = 0xFF; /* Busy Timeout Period */
10389     Control[index+9] = 0xFF; /* Busy Timeout Period */
10390     Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */
10391     Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */
10392 
10393     sm_memcpy(pModeSense, &Control, lenRead);
10394   }
10395   else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
10396   {
10397     SM_DBG5(("smsatModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
10398     RWErrorRecovery[0] = 0;
10399     RWErrorRecovery[1] = (bit8)(lenRead - 2);
10400     RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10401     RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10402     if (LLBAA)
10403     {
10404       RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */
10405       RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */
10406     }
10407     else
10408     {
10409       RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10410     }
10411     RWErrorRecovery[5] = 0x00; /* reserved */
10412     RWErrorRecovery[6] = 0x00; /* block descriptot length */
10413     if (LLBAA)
10414     {
10415       RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10416     }
10417     else
10418     {
10419       RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10420     }
10421 
10422     /*
10423      * Fill-up direct-access device block-descriptor, SAT, Table 19
10424      */
10425 
10426     if (LLBAA)
10427     {
10428       /* density code */
10429       RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
10430       /* number of blocks */
10431       RWErrorRecovery[9]   = 0x00; /* unspecified */
10432       RWErrorRecovery[10]  = 0x00; /* unspecified */
10433       RWErrorRecovery[11]  = 0x00; /* unspecified */
10434       RWErrorRecovery[12]  = 0x00; /* unspecified */
10435       RWErrorRecovery[13]  = 0x00; /* unspecified */
10436       RWErrorRecovery[14]  = 0x00; /* unspecified */
10437       RWErrorRecovery[15]  = 0x00; /* unspecified */
10438       /* reserved */
10439       RWErrorRecovery[16]  = 0x00; /* reserved */
10440       RWErrorRecovery[17]  = 0x00; /* reserved */
10441       RWErrorRecovery[18]  = 0x00; /* reserved */
10442       RWErrorRecovery[19]  = 0x00; /* reserved */
10443       /* Block size */
10444       RWErrorRecovery[20]  = 0x00;
10445       RWErrorRecovery[21]  = 0x00;
10446       RWErrorRecovery[22]  = 0x02;   /* Block size is always 512 bytes */
10447       RWErrorRecovery[23]  = 0x00;
10448     }
10449     else
10450     {
10451       /* density code */
10452       RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
10453       /* number of blocks */
10454       RWErrorRecovery[9]   = 0x00; /* unspecified */
10455       RWErrorRecovery[10]  = 0x00; /* unspecified */
10456       RWErrorRecovery[11]  = 0x00; /* unspecified */
10457       /* reserved */
10458       RWErrorRecovery[12]  = 0x00; /* reserved */
10459       /* Block size */
10460       RWErrorRecovery[13]  = 0x00;
10461       RWErrorRecovery[14]  = 0x02;   /* Block size is always 512 bytes */
10462       RWErrorRecovery[15]  = 0x00;
10463     }
10464 
10465     if (LLBAA)
10466     {
10467       index = 24;
10468     }
10469     else
10470     {
10471       index = 16;
10472     }
10473     /*
10474      * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
10475      */
10476     RWErrorRecovery[index+0] = 0x01; /* page code */
10477     RWErrorRecovery[index+1] = 0x0A; /* page length */
10478     RWErrorRecovery[index+2] = 0x40; /* ARRE is set */
10479     RWErrorRecovery[index+3] = 0x00;
10480     RWErrorRecovery[index+4] = 0x00;
10481     RWErrorRecovery[index+5] = 0x00;
10482     RWErrorRecovery[index+6] = 0x00;
10483     RWErrorRecovery[index+7] = 0x00;
10484     RWErrorRecovery[index+8] = 0x00;
10485     RWErrorRecovery[index+9] = 0x00;
10486     RWErrorRecovery[index+10] = 0x00;
10487     RWErrorRecovery[index+11] = 0x00;
10488 
10489     sm_memcpy(pModeSense, &RWErrorRecovery, lenRead);
10490   }
10491   else if (page == MODESENSE_CACHING)
10492   {
10493     SM_DBG5(("smsatModeSense10: MODESENSE_CACHING\n"));
10494     Caching[0] = 0;
10495     Caching[1] = (bit8)(lenRead - 2);
10496     Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10497     Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10498     if (LLBAA)
10499     {
10500       Caching[4] = 0x00; /* reserved and LONGLBA */
10501       Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */
10502     }
10503     else
10504     {
10505       Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10506     }
10507     Caching[5] = 0x00; /* reserved */
10508     Caching[6] = 0x00; /* block descriptot length */
10509     if (LLBAA)
10510     {
10511       Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10512     }
10513     else
10514     {
10515       Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10516     }
10517 
10518     /*
10519      * Fill-up direct-access device block-descriptor, SAT, Table 19
10520      */
10521 
10522     if (LLBAA)
10523     {
10524       /* density code */
10525       Caching[8]   = 0x04; /* density-code : reserved for direct-access */
10526       /* number of blocks */
10527       Caching[9]   = 0x00; /* unspecified */
10528       Caching[10]  = 0x00; /* unspecified */
10529       Caching[11]  = 0x00; /* unspecified */
10530       Caching[12]  = 0x00; /* unspecified */
10531       Caching[13]  = 0x00; /* unspecified */
10532       Caching[14]  = 0x00; /* unspecified */
10533       Caching[15]  = 0x00; /* unspecified */
10534       /* reserved */
10535       Caching[16]  = 0x00; /* reserved */
10536       Caching[17]  = 0x00; /* reserved */
10537       Caching[18]  = 0x00; /* reserved */
10538       Caching[19]  = 0x00; /* reserved */
10539       /* Block size */
10540       Caching[20]  = 0x00;
10541       Caching[21]  = 0x00;
10542       Caching[22]  = 0x02;   /* Block size is always 512 bytes */
10543       Caching[23]  = 0x00;
10544     }
10545     else
10546     {
10547       /* density code */
10548       Caching[8]   = 0x04; /* density-code : reserved for direct-access */
10549       /* number of blocks */
10550       Caching[9]   = 0x00; /* unspecified */
10551       Caching[10]  = 0x00; /* unspecified */
10552       Caching[11]  = 0x00; /* unspecified */
10553       /* reserved */
10554       Caching[12]  = 0x00; /* reserved */
10555       /* Block size */
10556       Caching[13]  = 0x00;
10557       Caching[14]  = 0x02;   /* Block size is always 512 bytes */
10558       Caching[15]  = 0x00;
10559     }
10560 
10561     if (LLBAA)
10562     {
10563       index = 24;
10564     }
10565     else
10566     {
10567       index = 16;
10568     }
10569     /*
10570      * Fill-up Caching mode page, SAT, Table 67
10571      */
10572     /* length 20 */
10573     Caching[index+0] = 0x08; /* page code */
10574     Caching[index+1] = 0x12; /* page length */
10575     if (pSatDevData->satWriteCacheEnabled == agTRUE)
10576     {
10577       Caching[index+2] = 0x04;/* WCE bit is set */
10578     }
10579     else
10580     {
10581       Caching[index+2] = 0x00;/* WCE bit is NOT set */
10582     }
10583 
10584     Caching[index+3] = 0x00;
10585     Caching[index+4] = 0x00;
10586     Caching[index+5] = 0x00;
10587     Caching[index+6] = 0x00;
10588     Caching[index+7] = 0x00;
10589     Caching[index+8] = 0x00;
10590     Caching[index+9] = 0x00;
10591     Caching[index+10] = 0x00;
10592     Caching[index+11] = 0x00;
10593     if (pSatDevData->satLookAheadEnabled == agTRUE)
10594     {
10595       Caching[index+12] = 0x00;/* DRA bit is NOT set */
10596     }
10597     else
10598     {
10599       Caching[index+12] = 0x20;/* DRA bit is set */
10600     }
10601     Caching[index+13] = 0x00;
10602     Caching[index+14] = 0x00;
10603     Caching[index+15] = 0x00;
10604     Caching[index+16] = 0x00;
10605     Caching[index+17] = 0x00;
10606     Caching[index+18] = 0x00;
10607     Caching[index+19] = 0x00;
10608     sm_memcpy(pModeSense, &Caching, lenRead);
10609 
10610   }
10611   else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
10612   {
10613     SM_DBG5(("smsatModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
10614     InfoExceptionCtrl[0] = 0;
10615     InfoExceptionCtrl[1] = (bit8)(lenRead - 2);
10616     InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10617     InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10618     if (LLBAA)
10619     {
10620       InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */
10621       InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */
10622     }
10623     else
10624     {
10625       InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10626     }
10627     InfoExceptionCtrl[5] = 0x00; /* reserved */
10628     InfoExceptionCtrl[6] = 0x00; /* block descriptot length */
10629     if (LLBAA)
10630     {
10631       InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10632     }
10633     else
10634     {
10635       InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10636     }
10637 
10638     /*
10639      * Fill-up direct-access device block-descriptor, SAT, Table 19
10640      */
10641 
10642     if (LLBAA)
10643     {
10644       /* density code */
10645       InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
10646       /* number of blocks */
10647       InfoExceptionCtrl[9]   = 0x00; /* unspecified */
10648       InfoExceptionCtrl[10]  = 0x00; /* unspecified */
10649       InfoExceptionCtrl[11]  = 0x00; /* unspecified */
10650       InfoExceptionCtrl[12]  = 0x00; /* unspecified */
10651       InfoExceptionCtrl[13]  = 0x00; /* unspecified */
10652       InfoExceptionCtrl[14]  = 0x00; /* unspecified */
10653       InfoExceptionCtrl[15]  = 0x00; /* unspecified */
10654       /* reserved */
10655       InfoExceptionCtrl[16]  = 0x00; /* reserved */
10656       InfoExceptionCtrl[17]  = 0x00; /* reserved */
10657       InfoExceptionCtrl[18]  = 0x00; /* reserved */
10658       InfoExceptionCtrl[19]  = 0x00; /* reserved */
10659       /* Block size */
10660       InfoExceptionCtrl[20]  = 0x00;
10661       InfoExceptionCtrl[21]  = 0x00;
10662       InfoExceptionCtrl[22]  = 0x02;   /* Block size is always 512 bytes */
10663       InfoExceptionCtrl[23]  = 0x00;
10664     }
10665     else
10666     {
10667       /* density code */
10668       InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
10669       /* number of blocks */
10670       InfoExceptionCtrl[9]   = 0x00; /* unspecified */
10671       InfoExceptionCtrl[10]  = 0x00; /* unspecified */
10672       InfoExceptionCtrl[11]  = 0x00; /* unspecified */
10673       /* reserved */
10674       InfoExceptionCtrl[12]  = 0x00; /* reserved */
10675       /* Block size */
10676       InfoExceptionCtrl[13]  = 0x00;
10677       InfoExceptionCtrl[14]  = 0x02;   /* Block size is always 512 bytes */
10678       InfoExceptionCtrl[15]  = 0x00;
10679     }
10680 
10681     if (LLBAA)
10682     {
10683       index = 24;
10684     }
10685     else
10686     {
10687       index = 16;
10688     }
10689     /*
10690      * Fill-up informational-exceptions control mode page, SAT, Table 68
10691      */
10692     InfoExceptionCtrl[index+0] = 0x1C; /* page code */
10693     InfoExceptionCtrl[index+1] = 0x0A; /* page length */
10694      if (pSatDevData->satSMARTEnabled == agTRUE)
10695     {
10696       InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */
10697     }
10698     else
10699     {
10700       InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */
10701     }
10702     InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */
10703     InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */
10704     InfoExceptionCtrl[index+5] = 0x00;
10705     InfoExceptionCtrl[index+6] = 0x00;
10706     InfoExceptionCtrl[index+7] = 0x00;
10707     InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */
10708     InfoExceptionCtrl[index+9] = 0x00;
10709     InfoExceptionCtrl[index+10] = 0x00;
10710     InfoExceptionCtrl[index+11] = 0x00;
10711     sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
10712 
10713   }
10714   else
10715   {
10716     /* Error */
10717     SM_DBG1(("smsatModeSense10: Error page %d!!!\n", page));
10718     smsatSetSensePayload( pSense,
10719                           SCSI_SNSKEY_ILLEGAL_REQUEST,
10720                           0,
10721                           SCSI_SNSCODE_INVALID_COMMAND,
10722                           satIOContext);
10723 
10724     /*smEnqueueIO(smRoot, satIOContext);*/
10725 
10726     tdsmIOCompletedCB( smRoot,
10727                        smIORequest,
10728                        smIOSuccess,
10729                        SCSI_STAT_CHECK_CONDITION,
10730                        satIOContext->pSmSenseData,
10731                        satIOContext->interruptContext );
10732     return SM_RC_SUCCESS;
10733   }
10734 
10735   if (allocationLen > lenRead)
10736   {
10737     SM_DBG1(("smsatModeSense10: reporting underrun lenRead=0x%x allocationLen=0x%x smIORequest=%p\n", lenRead, allocationLen, smIORequest));
10738 
10739     /*smEnqueueIO(smRoot, satIOContext);*/
10740 
10741     tdsmIOCompletedCB( smRoot,
10742                        smIORequest,
10743                        smIOUnderRun,
10744                        allocationLen - lenRead,
10745                        agNULL,
10746                        satIOContext->interruptContext );
10747 
10748 
10749   }
10750   else
10751   {
10752     /*smEnqueueIO(smRoot, satIOContext);*/
10753 
10754     tdsmIOCompletedCB( smRoot,
10755                        smIORequest,
10756                        smIOSuccess,
10757                        SCSI_STAT_GOOD,
10758                        agNULL,
10759                        satIOContext->interruptContext);
10760   }
10761 
10762   return SM_RC_SUCCESS;
10763 }
10764 
10765 osGLOBAL bit32
10766 smsatReadCapacity10(
10767                     smRoot_t                  *smRoot,
10768                     smIORequest_t             *smIORequest,
10769                     smDeviceHandle_t          *smDeviceHandle,
10770                     smScsiInitiatorRequest_t  *smScsiRequest,
10771                     smSatIOContext_t            *satIOContext
10772                    )
10773 {
10774   smScsiRspSense_t        *pSense;
10775   smIniScsiCmnd_t         *scsiCmnd;
10776   bit8                    dataBuffer[8] = {0};
10777   bit32                   allocationLen;
10778   bit8  	              *pVirtAddr = agNULL;
10779   smDeviceData_t          *pSatDevData;
10780   agsaSATAIdentifyData_t  *pSATAIdData;
10781   bit32                   lastLba;
10782   bit32                   word117_118;
10783   bit32                   word117;
10784   bit32                   word118;
10785 
10786   pSense      = satIOContext->pSense;
10787   pVirtAddr   = (bit8 *) smScsiRequest->sglVirtualAddr;
10788   scsiCmnd    = &smScsiRequest->scsiCmnd;
10789   pSatDevData = satIOContext->pSatDevData;
10790   pSATAIdData = &pSatDevData->satIdentifyData;
10791   allocationLen = scsiCmnd->expDataLength;
10792 
10793   SM_DBG5(("smsatReadCapacity10: start\n"));
10794 
10795   /* checking CONTROL */
10796   /* NACA == 1 or LINK == 1*/
10797   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
10798   {
10799     smsatSetSensePayload( pSense,
10800                           SCSI_SNSKEY_ILLEGAL_REQUEST,
10801                           0,
10802                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10803                           satIOContext);
10804 
10805     /*smEnqueueIO(smRoot, satIOContext);*/
10806 
10807     tdsmIOCompletedCB( smRoot,
10808                        smIORequest,
10809                        smIOSuccess,
10810                        SCSI_STAT_CHECK_CONDITION,
10811                        satIOContext->pSmSenseData,
10812                        satIOContext->interruptContext );
10813 
10814     SM_DBG1(("smsatReadCapacity10: return control!!!\n"));
10815     return SM_RC_SUCCESS;
10816   }
10817 
10818 
10819   /*
10820    * If Logical block address is not set to zero, return error
10821    */
10822   if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
10823   {
10824     SM_DBG1(("smsatReadCapacity10: *** ERROR *** logical address non zero, did %d!!!\n",
10825         pSatDevData->id));
10826 
10827     smsatSetSensePayload( pSense,
10828                           SCSI_SNSKEY_ILLEGAL_REQUEST,
10829                           0,
10830                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10831                           satIOContext);
10832 
10833     /*smEnqueueIO(smRoot, satIOContext);*/
10834 
10835     tdsmIOCompletedCB( smRoot,
10836                        smIORequest,
10837                        smIOSuccess,
10838                        SCSI_STAT_CHECK_CONDITION,
10839                        satIOContext->pSmSenseData,
10840                        satIOContext->interruptContext );
10841     return SM_RC_SUCCESS;
10842 
10843   }
10844 
10845   /*
10846    * If PMI bit is not zero, return error
10847    */
10848   if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
10849   {
10850     SM_DBG1(("smsatReadCapacity10: *** ERROR *** PMI is not zero, did %d\n",
10851         pSatDevData->id));
10852 
10853     smsatSetSensePayload( pSense,
10854                           SCSI_SNSKEY_ILLEGAL_REQUEST,
10855                           0,
10856                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10857                           satIOContext);
10858 
10859     /*smEnqueueIO(smRoot, satIOContext);*/
10860 
10861     tdsmIOCompletedCB( smRoot,
10862                        smIORequest,
10863                        smIOSuccess,
10864                        SCSI_STAT_CHECK_CONDITION,
10865                        satIOContext->pSmSenseData,
10866                        satIOContext->interruptContext );
10867     return SM_RC_SUCCESS;
10868 
10869   }
10870 
10871   /*
10872     filling in Read Capacity parameter data
10873     saved identify device has been already flipped
10874     See ATA spec p125 and p136 and SBC spec p54
10875   */
10876   /*
10877    * If 48-bit addressing is supported, set capacity information from Identify
10878    * Device Word 100-103.
10879    */
10880   if (pSatDevData->sat48BitSupport == agTRUE)
10881   {
10882     /*
10883      * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data:
10884      * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL
10885      * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL
10886      * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would
10887      * then issue a READ CAPACITY(16) command.
10888      */
10889     /* ATA Identify Device information word 100 - 103 */
10890     if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
10891     {
10892       dataBuffer[0] = 0xFF;        /* MSB number of block */
10893       dataBuffer[1] = 0xFF;
10894       dataBuffer[2] = 0xFF;
10895       dataBuffer[3] = 0xFF;        /* LSB number of block */
10896       SM_DBG1(("smsatReadCapacity10: returns 0xFFFFFFFF!!!\n"));
10897     }
10898     else  /* Fit the Readcapacity10 4-bytes response length */
10899     {
10900       lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
10901                   (pSATAIdData->maxLBA0_15);
10902       lastLba = lastLba - 1;      /* LBA starts from zero */
10903 
10904       /*
10905         for testing
10906       lastLba = lastLba - (512*10) - 1;
10907       */
10908 
10909 
10910       dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
10911       dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF);
10912       dataBuffer[2] = (bit8)((lastLba >> 8)  & 0xFF);
10913       dataBuffer[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
10914 
10915       SM_DBG3(("smsatReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
10916       SM_DBG3(("smsatReadCapacity10: LBA 0 is 0x%x %d\n", dataBuffer[0], dataBuffer[0]));
10917       SM_DBG3(("smsatReadCapacity10: LBA 1 is 0x%x %d\n", dataBuffer[1], dataBuffer[1]));
10918       SM_DBG3(("smsatReadCapacity10: LBA 2 is 0x%x %d\n", dataBuffer[2], dataBuffer[2]));
10919       SM_DBG3(("smsatReadCapacity10: LBA 3 is 0x%x %d\n", dataBuffer[3], dataBuffer[3]));
10920 
10921     }
10922   }
10923 
10924   /*
10925    * For 28-bit addressing, set capacity information from Identify
10926    * Device Word 60-61.
10927    */
10928   else
10929   {
10930     /* ATA Identify Device information word 60 - 61 */
10931     lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
10932                 (pSATAIdData->numOfUserAddressableSectorsLo);
10933     lastLba = lastLba - 1;      /* LBA starts from zero */
10934 
10935     dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
10936     dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF);
10937     dataBuffer[2] = (bit8)((lastLba >> 8)  & 0xFF);
10938     dataBuffer[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
10939   }
10940   /* SAT Rev 8d */
10941   if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
10942   {
10943     SM_DBG5(("smsatReadCapacity10: Default Block Length is 512\n"));
10944     /*
10945      * Set the block size, fixed at 512 bytes.
10946      */
10947     dataBuffer[4] = 0x00;        /* MSB block size in bytes */
10948     dataBuffer[5] = 0x00;
10949     dataBuffer[6] = 0x02;
10950     dataBuffer[7] = 0x00;        /* LSB block size in bytes */
10951   }
10952   else
10953   {
10954     word118 = pSATAIdData->word112_126[6];
10955     word117 = pSATAIdData->word112_126[5];
10956 
10957     word117_118 = (word118 << 16) + word117;
10958     word117_118 = word117_118 * 2;
10959     dataBuffer[4] = (bit8)((word117_118 >> 24) & 0xFF);        /* MSB block size in bytes */
10960     dataBuffer[5] = (bit8)((word117_118 >> 16) & 0xFF);
10961     dataBuffer[6] = (bit8)((word117_118 >> 8) & 0xFF);
10962     dataBuffer[7] = (bit8)(word117_118 & 0xFF);                /* LSB block size in bytes */
10963 
10964     SM_DBG1(("smsatReadCapacity10: Nondefault word118 %d 0x%x !!!\n", word118, word118));
10965     SM_DBG1(("smsatReadCapacity10: Nondefault word117 %d 0x%x !!!\n", word117, word117));
10966     SM_DBG1(("smsatReadCapacity10: Nondefault Block Length is %d 0x%x !!!\n",word117_118, word117_118));
10967 
10968   }
10969 
10970   /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
10971   pSatDevData->satMaxLBA[0] = 0;            /* MSB */
10972   pSatDevData->satMaxLBA[1] = 0;
10973   pSatDevData->satMaxLBA[2] = 0;
10974   pSatDevData->satMaxLBA[3] = 0;
10975   pSatDevData->satMaxLBA[4] = dataBuffer[0];
10976   pSatDevData->satMaxLBA[5] = dataBuffer[1];
10977   pSatDevData->satMaxLBA[6] = dataBuffer[2];
10978   pSatDevData->satMaxLBA[7] = dataBuffer[3]; /* LSB */
10979 
10980 
10981   SM_DBG4(("smsatReadCapacity10: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , did %d\n",
10982         dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3],
10983         dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7],
10984         pSatDevData->id));
10985 
10986   sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, 8));
10987 
10988   /*
10989    * Send the completion response now.
10990    */
10991   /*smEnqueueIO(smRoot, satIOContext);*/
10992 
10993   tdsmIOCompletedCB( smRoot,
10994                      smIORequest,
10995                      smIOSuccess,
10996                      SCSI_STAT_GOOD,
10997                      agNULL,
10998                      satIOContext->interruptContext);
10999   return SM_RC_SUCCESS;
11000 }
11001 
11002 osGLOBAL bit32
11003 smsatReadCapacity16(
11004                     smRoot_t                  *smRoot,
11005                     smIORequest_t             *smIORequest,
11006                     smDeviceHandle_t          *smDeviceHandle,
11007                     smScsiInitiatorRequest_t  *smScsiRequest,
11008                     smSatIOContext_t            *satIOContext
11009                    )
11010 {
11011   smScsiRspSense_t        *pSense;
11012   smIniScsiCmnd_t         *scsiCmnd;
11013   bit8                    dataBuffer[32] = {0};
11014   bit8  	              *pVirtAddr = agNULL;
11015   smDeviceData_t          *pSatDevData;
11016   agsaSATAIdentifyData_t  *pSATAIdData;
11017   bit32                   lastLbaLo;
11018   bit32                   allocationLen;
11019   bit32                   readCapacityLen  = 32;
11020   bit32                   i = 0;
11021 
11022   pSense      = satIOContext->pSense;
11023   pVirtAddr   = (bit8 *) smScsiRequest->sglVirtualAddr;
11024   scsiCmnd    = &smScsiRequest->scsiCmnd;
11025   pSatDevData = satIOContext->pSatDevData;
11026   pSATAIdData = &pSatDevData->satIdentifyData;
11027 
11028   SM_DBG5(("smsatReadCapacity16: start\n"));
11029 
11030   /* Find the buffer size allocated by Initiator */
11031   allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
11032                   (((bit32)scsiCmnd->cdb[11]) << 16) |
11033                   (((bit32)scsiCmnd->cdb[12]) << 8 ) |
11034                   (((bit32)scsiCmnd->cdb[13])      );
11035   allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
11036 
11037 #ifdef REMOVED
11038   if (allocationLen < readCapacityLen)
11039   {
11040     SM_DBG1(("smsatReadCapacity16: *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x!!!\n", allocationLen, readCapacityLen));
11041 
11042     smsatSetSensePayload( pSense,
11043                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11044                           0,
11045                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11046                           satIOContext);
11047 
11048     /*smEnqueueIO(smRoot, satIOContext);*/
11049 
11050     tdsmIOCompletedCB( smRoot,
11051                        smIORequest,
11052                        smIOSuccess,
11053                        SCSI_STAT_CHECK_CONDITION,
11054                        satIOContext->pSmSenseData,
11055                        satIOContext->interruptContext );
11056     return SM_RC_SUCCESS;
11057 
11058   }
11059 #endif
11060 
11061   /* checking CONTROL */
11062   /* NACA == 1 or LINK == 1*/
11063   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
11064   {
11065     smsatSetSensePayload( pSense,
11066                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11067                           0,
11068                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11069                           satIOContext);
11070 
11071     /*smEnqueueIO(smRoot, satIOContext);*/
11072 
11073     tdsmIOCompletedCB( smRoot,
11074                        smIORequest,
11075                        smIOSuccess,
11076                        SCSI_STAT_CHECK_CONDITION,
11077                        satIOContext->pSmSenseData,
11078                        satIOContext->interruptContext );
11079 
11080     SM_DBG1(("smsatReadCapacity16: return control!!!\n"));
11081     return SM_RC_SUCCESS;
11082   }
11083 
11084   /*
11085    * If Logical blcok address is not set to zero, return error
11086    */
11087   if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) ||
11088       (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9])  )
11089   {
11090     SM_DBG1(("smsatReadCapacity16: *** ERROR *** logical address non zero, did %d\n",
11091         pSatDevData->id));
11092 
11093     smsatSetSensePayload( pSense,
11094                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11095                           0,
11096                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11097                           satIOContext);
11098 
11099     /*smEnqueueIO(smRoot, satIOContext);*/
11100 
11101     tdsmIOCompletedCB( smRoot,
11102                        smIORequest,
11103                        smIOSuccess,
11104                        SCSI_STAT_CHECK_CONDITION,
11105                        satIOContext->pSmSenseData,
11106                        satIOContext->interruptContext );
11107     return SM_RC_SUCCESS;
11108 
11109   }
11110 
11111   /*
11112    * If PMI bit is not zero, return error
11113    */
11114   if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
11115   {
11116     SM_DBG1(("smsatReadCapacity16: *** ERROR *** PMI is not zero, did %d\n",
11117         pSatDevData->id));
11118 
11119     smsatSetSensePayload( pSense,
11120                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11121                           0,
11122                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11123                           satIOContext);
11124 
11125     /*smEnqueueIO(smRoot, satIOContext);*/
11126 
11127     tdsmIOCompletedCB( smRoot,
11128                        smIORequest,
11129                        smIOSuccess,
11130                        SCSI_STAT_CHECK_CONDITION,
11131                        satIOContext->pSmSenseData,
11132                        satIOContext->interruptContext );
11133     return SM_RC_SUCCESS;
11134 
11135   }
11136 
11137   /*
11138     filling in Read Capacity parameter data
11139   */
11140 
11141   /*
11142    * If 48-bit addressing is supported, set capacity information from Identify
11143    * Device Word 100-103.
11144    */
11145   if (pSatDevData->sat48BitSupport == agTRUE)
11146   {
11147     dataBuffer[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff);  /* MSB */
11148     dataBuffer[1] = (bit8)((pSATAIdData->maxLBA48_63)        & 0xff);
11149     dataBuffer[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
11150     dataBuffer[3] = (bit8)((pSATAIdData->maxLBA32_47)        & 0xff);
11151 
11152     lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
11153     lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
11154 
11155     dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
11156     dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
11157     dataBuffer[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
11158     dataBuffer[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
11159 
11160   }
11161 
11162   /*
11163    * For 28-bit addressing, set capacity information from Identify
11164    * Device Word 60-61.
11165    */
11166   else
11167   {
11168     dataBuffer[0] = 0;       /* MSB */
11169     dataBuffer[1] = 0;
11170     dataBuffer[2] = 0;
11171     dataBuffer[3] = 0;
11172 
11173     lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
11174                   (pSATAIdData->numOfUserAddressableSectorsLo);
11175     lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
11176 
11177     dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
11178     dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
11179     dataBuffer[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
11180     dataBuffer[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
11181 
11182   }
11183 
11184   /*
11185    * Set the block size, fixed at 512 bytes.
11186    */
11187   dataBuffer[8]  = 0x00;        /* MSB block size in bytes */
11188   dataBuffer[9]  = 0x00;
11189   dataBuffer[10] = 0x02;
11190   dataBuffer[11] = 0x00;        /* LSB block size in bytes */
11191 
11192 
11193   /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
11194   pSatDevData->satMaxLBA[0] = dataBuffer[0];            /* MSB */
11195   pSatDevData->satMaxLBA[1] = dataBuffer[1];
11196   pSatDevData->satMaxLBA[2] = dataBuffer[2];
11197   pSatDevData->satMaxLBA[3] = dataBuffer[3];
11198   pSatDevData->satMaxLBA[4] = dataBuffer[4];
11199   pSatDevData->satMaxLBA[5] = dataBuffer[5];
11200   pSatDevData->satMaxLBA[6] = dataBuffer[6];
11201   pSatDevData->satMaxLBA[7] = dataBuffer[7];             /* LSB */
11202 
11203   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",
11204         dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3],
11205         dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7],
11206         dataBuffer[8], dataBuffer[9], dataBuffer[10], dataBuffer[11],
11207         pSatDevData->id));
11208 
11209   if (allocationLen > 0xC) /* 0xc = 12 */
11210   {
11211     for(i=12;i<=31;i++)
11212     {
11213       dataBuffer[i] = 0x00;
11214     }
11215   }
11216 
11217   sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, readCapacityLen));
11218   /*
11219    * Send the completion response now.
11220    */
11221   if (allocationLen > readCapacityLen)
11222   {
11223     /* underrun */
11224     SM_DBG1(("smsatReadCapacity16: reporting underrun readCapacityLen=0x%x allocationLen=0x%x !!!\n", readCapacityLen, allocationLen));
11225 
11226     /*smEnqueueIO(smRoot, satIOContext);*/
11227 
11228     tdsmIOCompletedCB( smRoot,
11229                        smIORequest,
11230                        smIOUnderRun,
11231                        allocationLen - readCapacityLen,
11232                        agNULL,
11233                        satIOContext->interruptContext );
11234 
11235 
11236   }
11237   else
11238   {
11239     /*smEnqueueIO(smRoot, satIOContext);*/
11240 
11241     tdsmIOCompletedCB( smRoot,
11242                        smIORequest,
11243                        smIOSuccess,
11244                        SCSI_STAT_GOOD,
11245                        agNULL,
11246                        satIOContext->interruptContext);
11247   }
11248   return SM_RC_SUCCESS;
11249 }
11250 
11251 osGLOBAL bit32
11252 smsatReportLun(
11253                smRoot_t                  *smRoot,
11254                smIORequest_t             *smIORequest,
11255                smDeviceHandle_t          *smDeviceHandle,
11256                smScsiInitiatorRequest_t  *smScsiRequest,
11257                smSatIOContext_t            *satIOContext
11258               )
11259 {
11260   smScsiRspSense_t      *pSense;
11261   bit8                  dataBuffer[16] = {0};
11262   bit32                 allocationLen;
11263   bit32                 reportLunLen;
11264   smScsiReportLun_t     *pReportLun;
11265   smIniScsiCmnd_t       *scsiCmnd;
11266 #ifdef  TD_DEBUG_ENABLE
11267   smDeviceData_t        *pSatDevData;
11268 #endif
11269 
11270   pSense     = satIOContext->pSense;
11271   pReportLun = (smScsiReportLun_t *) dataBuffer;
11272   scsiCmnd   = &smScsiRequest->scsiCmnd;
11273 #ifdef  TD_DEBUG_ENABLE
11274   pSatDevData = satIOContext->pSatDevData;
11275 #endif
11276   SM_DBG5(("smsatReportLun: start\n"));
11277 //  smhexdump("smsatReportLun: cdb", (bit8 *)scsiCmnd, 16);
11278   /* Find the buffer size allocated by Initiator */
11279   allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
11280                   (((bit32)scsiCmnd->cdb[7]) << 16) |
11281                   (((bit32)scsiCmnd->cdb[8]) << 8 ) |
11282                   (((bit32)scsiCmnd->cdb[9])      );
11283   allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
11284   reportLunLen  = 16;     /* 8 byte header and 8 bytes of LUN0 */
11285   if (allocationLen < reportLunLen)
11286   {
11287     SM_DBG1(("smsatReportLun: *** ERROR *** insufficient len=0x%x did %d\n",
11288         reportLunLen, pSatDevData->id));
11289     smsatSetSensePayload( pSense,
11290                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11291                           0,
11292                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11293                           satIOContext);
11294     /*smEnqueueIO(smRoot, satIOContext);*/
11295     tdsmIOCompletedCB( smRoot,
11296                        smIORequest,
11297                        smIOSuccess,
11298                        SCSI_STAT_CHECK_CONDITION,
11299                        satIOContext->pSmSenseData,
11300                        satIOContext->interruptContext );
11301     return SM_RC_SUCCESS;
11302   }
11303   /* Set length to one entry */
11304   pReportLun->len[0] = 0;
11305   pReportLun->len[1] = 0;
11306   pReportLun->len[2] = 0;
11307   pReportLun->len[3] = sizeof (tiLUN_t);
11308   pReportLun->reserved = 0;
11309   /* Set to LUN 0:
11310    * - address method to 0x00: Peripheral device addressing method,
11311    * - bus identifier to 0
11312    */
11313   pReportLun->lunList[0].lun[0] = 0;
11314   pReportLun->lunList[0].lun[1] = 0;
11315   pReportLun->lunList[0].lun[2] = 0;
11316   pReportLun->lunList[0].lun[3] = 0;
11317   pReportLun->lunList[0].lun[4] = 0;
11318   pReportLun->lunList[0].lun[5] = 0;
11319   pReportLun->lunList[0].lun[6] = 0;
11320   pReportLun->lunList[0].lun[7] = 0;
11321 
11322   sm_memcpy(smScsiRequest->sglVirtualAddr, dataBuffer, MIN(allocationLen, reportLunLen));
11323   if (allocationLen > reportLunLen)
11324   {
11325     /* underrun */
11326     SM_DBG1(("smsatReportLun: reporting underrun reportLunLen=0x%x allocationLen=0x%x !!!\n", reportLunLen, allocationLen));
11327 
11328     /*smEnqueueIO(smRoot, satIOContext);*/
11329 
11330     tdsmIOCompletedCB( smRoot,
11331                        smIORequest,
11332                        smIOUnderRun,
11333                        allocationLen - reportLunLen,
11334                        agNULL,
11335                        satIOContext->interruptContext );
11336 
11337 
11338   }
11339   else
11340   {
11341     /*smEnqueueIO(smRoot, satIOContext);*/
11342 
11343     tdsmIOCompletedCB( smRoot,
11344                        smIORequest,
11345                        smIOSuccess,
11346                        SCSI_STAT_GOOD,
11347                        agNULL,
11348                        satIOContext->interruptContext);
11349   }
11350   return SM_RC_SUCCESS;
11351 }
11352 
11353 osGLOBAL bit32
11354 smsatFormatUnit(
11355                 smRoot_t                  *smRoot,
11356                 smIORequest_t             *smIORequest,
11357                 smDeviceHandle_t          *smDeviceHandle,
11358                 smScsiInitiatorRequest_t  *smScsiRequest,
11359                 smSatIOContext_t            *satIOContext
11360                )
11361 {
11362   /*
11363     note: we don't support media certification in this version and IP bit
11364     satDevData->satFormatState will be agFalse since SAT does not actually sends
11365     any ATA command
11366    */
11367 
11368   smScsiRspSense_t        *pSense;
11369   smIniScsiCmnd_t         *scsiCmnd;
11370   bit32                    index = 0;
11371 
11372   pSense        = satIOContext->pSense;
11373   scsiCmnd      = &smScsiRequest->scsiCmnd;
11374   SM_DBG5(("smsatFormatUnit: start\n"));
11375   /*
11376     checking opcode
11377     1. FMTDATA bit == 0(no defect list header)
11378     2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided
11379     with DCRT bit set)
11380   */
11381   if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) ||
11382        ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
11383         (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK))
11384        )
11385   {
11386     /*smEnqueueIO(smRoot, satIOContext);*/
11387 
11388     tdsmIOCompletedCB( smRoot,
11389                        smIORequest,
11390                        smIOSuccess,
11391                        SCSI_STAT_GOOD,
11392                        agNULL,
11393                        satIOContext->interruptContext);
11394 
11395     SM_DBG1(("smsatFormatUnit: return opcode!!!\n"));
11396     return SM_RC_SUCCESS;
11397   }
11398 
11399   /*
11400     checking DEFECT LIST FORMAT and defect list length
11401   */
11402   if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) ||
11403         ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) )
11404   {
11405     /* short parameter header */
11406     if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00)
11407     {
11408       index = 8;
11409     }
11410     /* long parameter header */
11411     if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01)
11412     {
11413       index = 10;
11414     }
11415     /* defect list length */
11416     if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0))
11417     {
11418       smsatSetSensePayload( pSense,
11419                             SCSI_SNSKEY_ILLEGAL_REQUEST,
11420                             0,
11421                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11422                             satIOContext);
11423 
11424       /*smEnqueueIO(smRoot, satIOContext);*/
11425 
11426       tdsmIOCompletedCB( smRoot,
11427                          smIORequest,
11428                          smIOSuccess,
11429                          SCSI_STAT_CHECK_CONDITION,
11430                          satIOContext->pSmSenseData,
11431                          satIOContext->interruptContext );
11432 
11433       SM_DBG1(("smsatFormatUnit: return defect list format!!!\n"));
11434       return SM_RC_SUCCESS;
11435     }
11436   }
11437 
11438   if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
11439        (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
11440   {
11441     smsatSetSensePayload( pSense,
11442                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11443                           0,
11444                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11445                           satIOContext);
11446 
11447     /*smEnqueueIO(smRoot, satIOContext);*/
11448 
11449     tdsmIOCompletedCB( smRoot,
11450                        smIORequest,
11451                        smIOSuccess,
11452                        SCSI_STAT_CHECK_CONDITION,
11453                        satIOContext->pSmSenseData,
11454                        satIOContext->interruptContext );
11455 
11456     SM_DBG1(("smsatFormatUnit: return cmplist!!!\n"));
11457     return SM_RC_SUCCESS;
11458 
11459   }
11460 
11461   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
11462   {
11463     smsatSetSensePayload( pSense,
11464                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11465                           0,
11466                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11467                           satIOContext);
11468 
11469     /*smEnqueueIO(smRoot, satIOContext);*/
11470 
11471     tdsmIOCompletedCB( smRoot,
11472                        smIORequest,
11473                        smIOSuccess,
11474                        SCSI_STAT_CHECK_CONDITION,
11475                        satIOContext->pSmSenseData,
11476                        satIOContext->interruptContext );
11477 
11478     SM_DBG1(("smsatFormatUnit: return control!!!\n"));
11479     return SM_RC_SUCCESS;
11480   }
11481 
11482   /* defect list header filed, if exists, SAT rev8, Table 37, p48 */
11483   if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK)
11484   {
11485     /* case 1,2,3 */
11486     /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */
11487     if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) ||
11488          ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) ||
11489          ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11490            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11491            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK))
11492          )
11493     {
11494       /*smEnqueueIO(smRoot, satIOContext);*/
11495 
11496       tdsmIOCompletedCB( smRoot,
11497                          smIORequest,
11498                          smIOSuccess,
11499                          SCSI_STAT_GOOD,
11500                          agNULL,
11501                          satIOContext->interruptContext);
11502 
11503       SM_DBG5(("smsatFormatUnit: return defect list case 1\n"));
11504       return SM_RC_SUCCESS;
11505     }
11506     /* case 4,5,6 */
11507     /*
11508         1. IMMED 0, FOV 1, DCRT 0, IP 0
11509         2. IMMED 0, FOV 1, DCRT 0, IP 1
11510         3. IMMED 0, FOV 1, DCRT 1, IP 1
11511       */
11512 
11513     if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11514             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11515            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11516            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11517          ||
11518          ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11519             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11520            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11521             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11522          ||
11523          ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11524             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11525             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11526             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11527          )
11528     {
11529 
11530       smsatSetSensePayload( pSense,
11531                             SCSI_SNSKEY_ILLEGAL_REQUEST,
11532                             0,
11533                             SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
11534                             satIOContext);
11535 
11536       /*smEnqueueIO(smRoot, satIOContext);*/
11537 
11538       tdsmIOCompletedCB( smRoot,
11539                          smIORequest,
11540                          smIOSuccess,
11541                          SCSI_STAT_CHECK_CONDITION,
11542                          satIOContext->pSmSenseData,
11543                          satIOContext->interruptContext );
11544 
11545       SM_DBG5(("smsatFormatUnit: return defect list case 2\n"));
11546       return SM_RC_SUCCESS;
11547 
11548     }
11549   }
11550 
11551 
11552   /*
11553    * Send the completion response now.
11554    */
11555   /*smEnqueueIO(smRoot, satIOContext);*/
11556 
11557   tdsmIOCompletedCB( smRoot,
11558                      smIORequest,
11559                      smIOSuccess,
11560                      SCSI_STAT_GOOD,
11561                      agNULL,
11562                      satIOContext->interruptContext);
11563 
11564   SM_DBG5(("smsatFormatUnit: return last\n"));
11565   return SM_RC_SUCCESS;
11566 }
11567 
11568 osGLOBAL bit32
11569 smsatSendDiagnostic(
11570                     smRoot_t                  *smRoot,
11571                     smIORequest_t             *smIORequest,
11572                     smDeviceHandle_t          *smDeviceHandle,
11573                     smScsiInitiatorRequest_t  *smScsiRequest,
11574                     smSatIOContext_t            *satIOContext
11575                    )
11576 {
11577   bit32                     status;
11578   bit32                     agRequestType;
11579   smDeviceData_t            *pSatDevData;
11580   smScsiRspSense_t          *pSense;
11581   smIniScsiCmnd_t           *scsiCmnd;
11582   agsaFisRegHostToDevice_t  *fis;
11583   bit32                     parmLen;
11584 
11585   pSense        = satIOContext->pSense;
11586   pSatDevData   = satIOContext->pSatDevData;
11587   scsiCmnd      = &smScsiRequest->scsiCmnd;
11588   fis           = satIOContext->pFis;
11589 
11590   SM_DBG5(("smsatSendDiagnostic: start\n"));
11591 
11592   /* reset satVerifyState */
11593   pSatDevData->satVerifyState = 0;
11594   /* no pending diagnostic in background */
11595   pSatDevData->satBGPendingDiag = agFALSE;
11596 
11597   /* table 27, 8.10 p39 SAT Rev8 */
11598   /*
11599     1. checking PF == 1
11600     2. checking DEVOFFL == 1
11601     3. checking UNITOFFL == 1
11602     4. checking PARAMETER LIST LENGTH != 0
11603 
11604   */
11605   if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) ||
11606        (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) ||
11607        (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) ||
11608        ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) )
11609        )
11610   {
11611     smsatSetSensePayload( pSense,
11612                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11613                           0,
11614                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11615                           satIOContext);
11616 
11617     /*smEnqueueIO(smRoot, satIOContext);*/
11618 
11619     tdsmIOCompletedCB( smRoot,
11620                        smIORequest,
11621                        smIOSuccess,
11622                        SCSI_STAT_CHECK_CONDITION,
11623                        satIOContext->pSmSenseData,
11624                        satIOContext->interruptContext );
11625 
11626     SM_DBG1(("smsatSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST!!!\n"));
11627     return SM_RC_SUCCESS;
11628   }
11629 
11630   /* checking CONTROL */
11631   /* NACA == 1 or LINK == 1*/
11632   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
11633   {
11634     smsatSetSensePayload( pSense,
11635                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11636                           0,
11637                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11638                           satIOContext);
11639 
11640     /*smEnqueueIO(smRoot, satIOContext);*/
11641 
11642     tdsmIOCompletedCB( smRoot,
11643                        smIORequest,
11644                        smIOSuccess,
11645                        SCSI_STAT_CHECK_CONDITION,
11646                        satIOContext->pSmSenseData,
11647                        satIOContext->interruptContext );
11648 
11649     SM_DBG1(("smsatSendDiagnostic: return control!!!\n"));
11650     return SM_RC_SUCCESS;
11651   }
11652 
11653   parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
11654 
11655   /* checking SELFTEST bit*/
11656   /* table 29, 8.10.3, p41 SAT Rev8 */
11657   /* case 1 */
11658   if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11659        (pSatDevData->satSMARTSelfTest == agFALSE)
11660        )
11661   {
11662     smsatSetSensePayload( pSense,
11663                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11664                           0,
11665                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11666                           satIOContext);
11667 
11668     /*smEnqueueIO(smRoot, satIOContext);*/
11669 
11670     tdsmIOCompletedCB( smRoot,
11671                        smIORequest,
11672                        smIOSuccess,
11673                        SCSI_STAT_CHECK_CONDITION,
11674                        satIOContext->pSmSenseData,
11675                        satIOContext->interruptContext );
11676 
11677     SM_DBG1(("smsatSendDiagnostic: return Table 29 case 1!!!\n"));
11678     return SM_RC_SUCCESS;
11679   }
11680 
11681   /* case 2 */
11682   if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11683        (pSatDevData->satSMARTSelfTest == agTRUE) &&
11684        (pSatDevData->satSMARTEnabled == agFALSE)
11685        )
11686   {
11687     smsatSetSensePayload( pSense,
11688                           SCSI_SNSKEY_ABORTED_COMMAND,
11689                           0,
11690                           SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
11691                           satIOContext);
11692 
11693     /*smEnqueueIO(smRoot, satIOContext);*/
11694 
11695     tdsmIOCompletedCB( smRoot,
11696                        smIORequest,
11697                        smIOSuccess,
11698                        SCSI_STAT_CHECK_CONDITION,
11699                        satIOContext->pSmSenseData,
11700                        satIOContext->interruptContext );
11701 
11702     SM_DBG5(("smsatSendDiagnostic: return Table 29 case 2\n"));
11703     return SM_RC_SUCCESS;
11704   }
11705   /*
11706     case 3
11707      see SELF TEST CODE later
11708   */
11709 
11710 
11711 
11712   /* case 4 */
11713 
11714   /*
11715     sends three ATA verify commands
11716 
11717   */
11718   if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11719         (pSatDevData->satSMARTSelfTest == agFALSE))
11720        ||
11721        ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11722         (pSatDevData->satSMARTSelfTest == agTRUE) &&
11723         (pSatDevData->satSMARTEnabled == agFALSE))
11724        )
11725   {
11726     /*
11727       sector count 1, LBA 0
11728       sector count 1, LBA MAX
11729       sector count 1, LBA random
11730     */
11731     if (pSatDevData->sat48BitSupport == agTRUE)
11732     {
11733       /* sends READ VERIFY SECTOR(S) EXT*/
11734       fis->h.fisType        = 0x27;                   /* Reg host to device */
11735       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11736       fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
11737       fis->h.features       = 0;                      /* FIS reserve */
11738       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
11739       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
11740       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
11741       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
11742       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
11743       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
11744       fis->d.featuresExp    = 0;                      /* FIS reserve */
11745       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
11746       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
11747       fis->d.reserved4      = 0;
11748       fis->d.device         = 0x40;                   /* 01000000 */
11749       fis->d.control        = 0;                      /* FIS HOB bit clear */
11750       fis->d.reserved5      = 0;
11751 
11752       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11753     }
11754     else
11755     {
11756       /* READ VERIFY SECTOR(S)*/
11757       fis->h.fisType        = 0x27;                   /* Reg host to device */
11758       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11759       fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
11760       fis->h.features       = 0;                      /* FIS features NA       */
11761       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
11762       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
11763       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
11764       fis->d.lbaLowExp      = 0;
11765       fis->d.lbaMidExp      = 0;
11766       fis->d.lbaHighExp     = 0;
11767       fis->d.featuresExp    = 0;
11768       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
11769       fis->d.sectorCountExp = 0;
11770       fis->d.reserved4      = 0;
11771       fis->d.device         = 0x40;                   /* 01000000 */
11772       fis->d.control        = 0;                      /* FIS HOB bit clear */
11773       fis->d.reserved5      = 0;
11774 
11775       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11776     }
11777 
11778     /* Initialize CB for SATA completion.
11779      */
11780     satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11781 
11782     /*
11783      * Prepare SGL and send FIS to LL layer.
11784      */
11785     satIOContext->reqType = agRequestType;       /* Save it */
11786 
11787     status = smsataLLIOStart( smRoot,
11788                               smIORequest,
11789                               smDeviceHandle,
11790                               smScsiRequest,
11791                               satIOContext);
11792 
11793 
11794     SM_DBG5(("smsatSendDiagnostic: return Table 29 case 4\n"));
11795     return (status);
11796   }
11797   /* case 5 */
11798   if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11799        (pSatDevData->satSMARTSelfTest == agTRUE) &&
11800        (pSatDevData->satSMARTEnabled == agTRUE)
11801        )
11802   {
11803     /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
11804     fis->h.fisType        = 0x27;                   /* Reg host to device */
11805     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11806     fis->h.command        = SAT_SMART;               /* 0xB0 */
11807     fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
11808     fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
11809     fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11810     fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11811     fis->d.lbaLowExp      = 0;
11812     fis->d.lbaMidExp      = 0;
11813     fis->d.lbaHighExp     = 0;
11814     fis->d.featuresExp    = 0;
11815     fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11816     fis->d.sectorCountExp = 0;
11817     fis->d.reserved4      = 0;
11818     fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
11819     fis->d.control        = 0;                         /* FIS HOB bit clear */
11820     fis->d.reserved5      = 0;
11821 
11822     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11823 
11824     /* Initialize CB for SATA completion.
11825      */
11826     satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11827 
11828     /*
11829      * Prepare SGL and send FIS to LL layer.
11830      */
11831     satIOContext->reqType = agRequestType;       /* Save it */
11832 
11833     status = smsataLLIOStart( smRoot,
11834                               smIORequest,
11835                               smDeviceHandle,
11836                               smScsiRequest,
11837                               satIOContext);
11838 
11839 
11840     SM_DBG5(("smsatSendDiagnostic: return Table 29 case 5\n"));
11841     return (status);
11842   }
11843 
11844 
11845 
11846 
11847   /* SAT rev8 Table29 p41 case 3*/
11848   /* checking SELF TEST CODE*/
11849   if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11850        (pSatDevData->satSMARTSelfTest == agTRUE) &&
11851        (pSatDevData->satSMARTEnabled == agTRUE)
11852        )
11853   {
11854     /* SAT rev8 Table28 p40 */
11855     /* finding self-test code */
11856     switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5)
11857     {
11858     case 1:
11859       pSatDevData->satBGPendingDiag = agTRUE;
11860 
11861       tdsmIOCompletedCB( smRoot,
11862                          smIORequest,
11863                          smIOSuccess,
11864                          SCSI_STAT_GOOD,
11865                          agNULL,
11866                          satIOContext->interruptContext );
11867       /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
11868       fis->h.fisType        = 0x27;                   /* Reg host to device */
11869       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11870       fis->h.command        = SAT_SMART;              /* 0x40 */
11871       fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;  /* FIS features NA       */
11872       fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
11873       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11874       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11875 
11876       fis->d.lbaLowExp      = 0;
11877       fis->d.lbaMidExp      = 0;
11878       fis->d.lbaHighExp     = 0;
11879       fis->d.featuresExp    = 0;
11880       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11881       fis->d.sectorCountExp = 0;
11882       fis->d.reserved4      = 0;
11883       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
11884       fis->d.control        = 0;                         /* FIS HOB bit clear */
11885       fis->d.reserved5      = 0;
11886 
11887       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11888 
11889       /* Initialize CB for SATA completion.
11890        */
11891       satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11892 
11893       /*
11894        * Prepare SGL and send FIS to LL layer.
11895        */
11896       satIOContext->reqType = agRequestType;       /* Save it */
11897 
11898       status = smsataLLIOStart( smRoot,
11899                                 smIORequest,
11900                                 smDeviceHandle,
11901                                 smScsiRequest,
11902                                 satIOContext);
11903 
11904 
11905       SM_DBG5(("smsatSendDiagnostic: return Table 28 case 1\n"));
11906       return (status);
11907     case 2:
11908       pSatDevData->satBGPendingDiag = agTRUE;
11909 
11910       tdsmIOCompletedCB( smRoot,
11911                          smIORequest,
11912                          smIOSuccess,
11913                          SCSI_STAT_GOOD,
11914                          agNULL,
11915                          satIOContext->interruptContext );
11916 
11917 
11918       /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
11919       fis->h.fisType        = 0x27;                   /* Reg host to device */
11920       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11921       fis->h.command        = SAT_SMART;              /* 0x40 */
11922       fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
11923       fis->d.lbaLow         = 0x02;                      /* FIS LBA (7 :0 ) */
11924       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11925       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11926       fis->d.lbaLowExp      = 0;
11927       fis->d.lbaMidExp      = 0;
11928       fis->d.lbaHighExp     = 0;
11929       fis->d.featuresExp    = 0;
11930       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11931       fis->d.sectorCountExp = 0;
11932       fis->d.reserved4      = 0;
11933       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
11934       fis->d.control        = 0;                         /* FIS HOB bit clear */
11935       fis->d.reserved5      = 0;
11936 
11937       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11938 
11939       /* Initialize CB for SATA completion.
11940        */
11941       satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11942 
11943       /*
11944        * Prepare SGL and send FIS to LL layer.
11945        */
11946       satIOContext->reqType = agRequestType;       /* Save it */
11947 
11948       status = smsataLLIOStart( smRoot,
11949                                 smIORequest,
11950                                 smDeviceHandle,
11951                                 smScsiRequest,
11952                                 satIOContext);
11953 
11954 
11955       SM_DBG5(("smsatSendDiagnostic: return Table 28 case 2\n"));
11956       return (status);
11957     case 4:
11958 
11959       if (parmLen != 0)
11960       {
11961         /* check condition */
11962         smsatSetSensePayload( pSense,
11963                               SCSI_SNSKEY_ILLEGAL_REQUEST,
11964                               0,
11965                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11966                               satIOContext);
11967 
11968         /*smEnqueueIO(smRoot, satIOContext);*/
11969 
11970         tdsmIOCompletedCB( smRoot,
11971                            smIORequest,
11972                            smIOSuccess,
11973                            SCSI_STAT_CHECK_CONDITION,
11974                            satIOContext->pSmSenseData,
11975                            satIOContext->interruptContext );
11976 
11977         SM_DBG1(("smsatSendDiagnostic: case 4, non zero ParmLen %d!!!\n", parmLen));
11978         return SM_RC_SUCCESS;
11979       }
11980       if (pSatDevData->satBGPendingDiag == agTRUE)
11981       {
11982         /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */
11983         fis->h.fisType        = 0x27;                   /* Reg host to device */
11984         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11985         fis->h.command        = SAT_SMART;              /* 0x40 */
11986         fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
11987         fis->d.lbaLow         = 0x7F;                      /* FIS LBA (7 :0 ) */
11988         fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
11989         fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
11990 
11991         fis->d.lbaLowExp      = 0;
11992         fis->d.lbaMidExp      = 0;
11993         fis->d.lbaHighExp     = 0;
11994         fis->d.featuresExp    = 0;
11995         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
11996         fis->d.sectorCountExp = 0;
11997         fis->d.reserved4      = 0;
11998         fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
11999         fis->d.control        = 0;                         /* FIS HOB bit clear */
12000         fis->d.reserved5      = 0;
12001 
12002         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12003 
12004         /* Initialize CB for SATA completion.
12005          */
12006         satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12007 
12008         /*
12009          * Prepare SGL and send FIS to LL layer.
12010          */
12011         satIOContext->reqType = agRequestType;       /* Save it */
12012 
12013         status = smsataLLIOStart( smRoot,
12014                                   smIORequest,
12015                                   smDeviceHandle,
12016                                   smScsiRequest,
12017                                   satIOContext);
12018 
12019 
12020         SM_DBG5(("smsatSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
12021         SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n"));
12022         return (status);
12023       }
12024       else
12025       {
12026         /* check condition */
12027         smsatSetSensePayload( pSense,
12028                               SCSI_SNSKEY_ILLEGAL_REQUEST,
12029                               0,
12030                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12031                               satIOContext);
12032 
12033         /*smEnqueueIO(smRoot, satIOContext);*/
12034 
12035         tdsmIOCompletedCB( smRoot,
12036                            smIORequest,
12037                            smIOSuccess,
12038                            SCSI_STAT_CHECK_CONDITION,
12039                            satIOContext->pSmSenseData,
12040                            satIOContext->interruptContext );
12041 
12042         SM_DBG1(("smsatSendDiagnostic: case 4, no pending diagnostic in background!!!\n"));
12043         SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n"));
12044         return SM_RC_SUCCESS;
12045       }
12046       break;
12047     case 5:
12048       /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
12049       fis->h.fisType        = 0x27;                   /* Reg host to device */
12050       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12051       fis->h.command        = SAT_SMART;              /* 0x40 */
12052       fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
12053       fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
12054       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
12055       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
12056       fis->d.lbaLowExp      = 0;
12057       fis->d.lbaMidExp      = 0;
12058       fis->d.lbaHighExp     = 0;
12059       fis->d.featuresExp    = 0;
12060       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
12061       fis->d.sectorCountExp = 0;
12062       fis->d.reserved4      = 0;
12063       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
12064       fis->d.control        = 0;                         /* FIS HOB bit clear */
12065       fis->d.reserved5      = 0;
12066 
12067       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12068 
12069       /* Initialize CB for SATA completion.
12070        */
12071       satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12072 
12073       /*
12074        * Prepare SGL and send FIS to LL layer.
12075        */
12076       satIOContext->reqType = agRequestType;       /* Save it */
12077 
12078       status = smsataLLIOStart( smRoot,
12079                                 smIORequest,
12080                                 smDeviceHandle,
12081                                 smScsiRequest,
12082                                 satIOContext);
12083 
12084 
12085       SM_DBG5(("smsatSendDiagnostic: return Table 28 case 5\n"));
12086       return (status);
12087     case 6:
12088       /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
12089       fis->h.fisType        = 0x27;                   /* Reg host to device */
12090       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12091       fis->h.command        = SAT_SMART;              /* 0x40 */
12092       fis->h.features       = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA       */
12093       fis->d.lbaLow         = 0x82;                      /* FIS LBA (7 :0 ) */
12094       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
12095       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
12096       fis->d.lbaLowExp      = 0;
12097       fis->d.lbaMidExp      = 0;
12098       fis->d.lbaHighExp     = 0;
12099       fis->d.featuresExp    = 0;
12100       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
12101       fis->d.sectorCountExp = 0;
12102       fis->d.reserved4      = 0;
12103       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
12104       fis->d.control        = 0;                         /* FIS HOB bit clear */
12105       fis->d.reserved5      = 0;
12106 
12107       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12108 
12109       /* Initialize CB for SATA completion.
12110        */
12111       satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12112 
12113       /*
12114        * Prepare SGL and send FIS to LL layer.
12115        */
12116       satIOContext->reqType = agRequestType;       /* Save it */
12117 
12118       status = smsataLLIOStart( smRoot,
12119                                 smIORequest,
12120                                 smDeviceHandle,
12121                                 smScsiRequest,
12122                                 satIOContext);
12123 
12124 
12125       SM_DBG5(("smsatSendDiagnostic: return Table 28 case 6\n"));
12126       return (status);
12127     case 0:
12128     case 3: /* fall through */
12129     case 7: /* fall through */
12130     default:
12131       break;
12132     }/* switch */
12133 
12134     /* returns the results of default self-testing, which is good */
12135     /*smEnqueueIO(smRoot, satIOContext);*/
12136 
12137     tdsmIOCompletedCB( smRoot,
12138                        smIORequest,
12139                        smIOSuccess,
12140                        SCSI_STAT_GOOD,
12141                        agNULL,
12142                        satIOContext->interruptContext );
12143 
12144     SM_DBG5(("smsatSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
12145     return SM_RC_SUCCESS;
12146   }
12147 
12148 
12149   /*smEnqueueIO(smRoot, satIOContext);*/
12150 
12151   tdsmIOCompletedCB( smRoot,
12152                      smIORequest,
12153                      smIOSuccess,
12154                      SCSI_STAT_GOOD,
12155                      agNULL,
12156                      satIOContext->interruptContext );
12157 
12158 
12159   SM_DBG5(("smsatSendDiagnostic: return last\n"));
12160   return SM_RC_SUCCESS;
12161 
12162 }
12163 
12164 osGLOBAL bit32
12165 smsatStartStopUnit(
12166                    smRoot_t                  *smRoot,
12167                    smIORequest_t             *smIORequest,
12168                    smDeviceHandle_t          *smDeviceHandle,
12169                    smScsiInitiatorRequest_t  *smScsiRequest,
12170                    smSatIOContext_t            *satIOContext
12171                   )
12172 {
12173   bit32                     status;
12174   bit32                     agRequestType;
12175   smDeviceData_t            *pSatDevData;
12176   smScsiRspSense_t          *pSense;
12177   smIniScsiCmnd_t           *scsiCmnd;
12178   agsaFisRegHostToDevice_t  *fis;
12179 
12180   pSense        = satIOContext->pSense;
12181   pSatDevData   = satIOContext->pSatDevData;
12182   scsiCmnd      = &smScsiRequest->scsiCmnd;
12183   fis           = satIOContext->pFis;
12184 
12185   SM_DBG5(("smsatStartStopUnit: start\n"));
12186 
12187   /* checking CONTROL */
12188   /* NACA == 1 or LINK == 1*/
12189   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
12190   {
12191     smsatSetSensePayload( pSense,
12192                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12193                           0,
12194                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12195                           satIOContext);
12196 
12197     /*smEnqueueIO(smRoot, satIOContext);*/
12198 
12199     tdsmIOCompletedCB( smRoot,
12200                        smIORequest,
12201                        smIOSuccess,
12202                        SCSI_STAT_CHECK_CONDITION,
12203                        satIOContext->pSmSenseData,
12204                        satIOContext->interruptContext );
12205 
12206     SM_DBG1(("smsatStartStopUnit: return control!!!\n"));
12207     return SM_RC_SUCCESS;
12208   }
12209 
12210   /* Spec p55, Table 48 checking START and LOEJ bit */
12211   /* case 1 */
12212   if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12213   {
12214     if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12215     {
12216       /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12217       /*smEnqueueIO(smRoot, satIOContext);*/
12218 
12219       tdsmIOCompletedCB( smRoot,
12220                          smIORequest,
12221                          smIOSuccess,
12222                          SCSI_STAT_GOOD,
12223                          agNULL,
12224                          satIOContext->interruptContext );
12225       SM_DBG5(("smsatStartStopUnit: return table48 case 1-1\n"));
12226       return SM_RC_SUCCESS;
12227     }
12228     /* sends FLUSH CACHE or FLUSH CACHE EXT */
12229     if (pSatDevData->sat48BitSupport == agTRUE)
12230     {
12231       /* FLUSH CACHE EXT */
12232       fis->h.fisType        = 0x27;                   /* Reg host to device */
12233       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12234 
12235       fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
12236       fis->h.features       = 0;                      /* FIS reserve */
12237       fis->d.featuresExp    = 0;                      /* FIS reserve */
12238       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
12239       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12240       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
12241       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
12242       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
12243       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12244       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
12245       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12246       fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
12247       fis->d.control        = 0;                      /* FIS HOB bit clear */
12248       fis->d.reserved4      = 0;
12249       fis->d.reserved5      = 0;
12250 
12251       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12252     }
12253     else
12254     {
12255       /* FLUSH CACHE */
12256       fis->h.fisType        = 0x27;                   /* Reg host to device */
12257       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12258 
12259       fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
12260       fis->h.features       = 0;                      /* FIS features NA       */
12261       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
12262       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
12263       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
12264       fis->d.lbaLowExp      = 0;
12265       fis->d.lbaMidExp      = 0;
12266       fis->d.lbaHighExp     = 0;
12267       fis->d.featuresExp    = 0;
12268       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
12269       fis->d.sectorCountExp = 0;
12270       fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
12271       fis->d.control        = 0;                      /* FIS HOB bit clear */
12272       fis->d.reserved4      = 0;
12273       fis->d.reserved5      = 0;
12274 
12275       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12276     }
12277 
12278     /* Initialize CB for SATA completion.
12279      */
12280     satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12281 
12282     /*
12283      * Prepare SGL and send FIS to LL layer.
12284      */
12285     satIOContext->reqType = agRequestType;       /* Save it */
12286 
12287     status = smsataLLIOStart( smRoot,
12288                               smIORequest,
12289                               smDeviceHandle,
12290                               smScsiRequest,
12291                               satIOContext);
12292 
12293 
12294     SM_DBG5(("smsatStartStopUnit: return table48 case 1\n"));
12295     return (status);
12296   }
12297   /* case 2 */
12298   else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12299   {
12300     /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12301     if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12302     {
12303       /*smEnqueueIO(smRoot, satIOContext);*/
12304 
12305       tdsmIOCompletedCB( smRoot,
12306                          smIORequest,
12307                          smIOSuccess,
12308                          SCSI_STAT_GOOD,
12309                          agNULL,
12310                          satIOContext->interruptContext );
12311 
12312       SM_DBG5(("smsatStartStopUnit: return table48 case 2 1\n"));
12313       return SM_RC_SUCCESS;
12314     }
12315     /*
12316       sends READ_VERIFY_SECTORS(_EXT)
12317       sector count 1, any LBA between zero to Maximum
12318     */
12319     if (pSatDevData->sat48BitSupport == agTRUE)
12320     {
12321       /* READ VERIFY SECTOR(S) EXT*/
12322       fis->h.fisType        = 0x27;                   /* Reg host to device */
12323       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12324 
12325       fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
12326       fis->h.features       = 0;                      /* FIS reserve */
12327       fis->d.lbaLow         = 0x01;                   /* FIS LBA (7 :0 ) */
12328       fis->d.lbaMid         = 0x00;                   /* FIS LBA (15:8 ) */
12329       fis->d.lbaHigh        = 0x00;                   /* FIS LBA (23:16) */
12330       fis->d.lbaLowExp      = 0x00;                   /* FIS LBA (31:24) */
12331       fis->d.lbaMidExp      = 0x00;                   /* FIS LBA (39:32) */
12332       fis->d.lbaHighExp     = 0x00;                   /* FIS LBA (47:40) */
12333       fis->d.featuresExp    = 0;                      /* FIS reserve */
12334       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12335       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12336       fis->d.reserved4      = 0;
12337       fis->d.device         = 0x40;                   /* 01000000 */
12338       fis->d.control        = 0;                      /* FIS HOB bit clear */
12339       fis->d.reserved5      = 0;
12340 
12341     }
12342     else
12343     {
12344       /* READ VERIFY SECTOR(S)*/
12345       fis->h.fisType        = 0x27;                   /* Reg host to device */
12346       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12347 
12348       fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
12349       fis->h.features       = 0;                      /* FIS features NA       */
12350       fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
12351       fis->d.lbaMid         = 0x00;                      /* FIS LBA (15:8 ) */
12352       fis->d.lbaHigh        = 0x00;                      /* FIS LBA (23:16) */
12353       fis->d.lbaLowExp      = 0;
12354       fis->d.lbaMidExp      = 0;
12355       fis->d.lbaHighExp     = 0;
12356       fis->d.featuresExp    = 0;
12357       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12358       fis->d.sectorCountExp = 0;
12359       fis->d.reserved4      = 0;
12360       fis->d.device         = 0x40;                   /* 01000000 */
12361       fis->d.control        = 0;                      /* FIS HOB bit clear */
12362       fis->d.reserved5      = 0;
12363 
12364     }
12365 
12366     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12367 
12368     /* Initialize CB for SATA completion.
12369      */
12370     satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12371 
12372     /*
12373      * Prepare SGL and send FIS to LL layer.
12374      */
12375     satIOContext->reqType = agRequestType;       /* Save it */
12376 
12377     status = smsataLLIOStart( smRoot,
12378                               smIORequest,
12379                               smDeviceHandle,
12380                               smScsiRequest,
12381                               satIOContext);
12382 
12383     SM_DBG5(("smsatStartStopUnit: return table48 case 2 2\n"));
12384     return status;
12385   }
12386   /* case 3 */
12387   else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12388   {
12389     if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
12390     {
12391       /* support for removal media */
12392       /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12393       if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12394       {
12395         /*smEnqueueIO(smRoot, satIOContext);*/
12396 
12397         tdsmIOCompletedCB( smRoot,
12398                            smIORequest,
12399                            smIOSuccess,
12400                            SCSI_STAT_GOOD,
12401                            agNULL,
12402                            satIOContext->interruptContext );
12403 
12404         SM_DBG5(("smsatStartStopUnit: return table48 case 3 1\n"));
12405         return SM_RC_SUCCESS;
12406       }
12407       /*
12408         sends MEDIA EJECT
12409       */
12410       /* Media Eject fis */
12411       fis->h.fisType        = 0x27;                   /* Reg host to device */
12412       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12413 
12414       fis->h.command        = SAT_MEDIA_EJECT;        /* 0xED */
12415       fis->h.features       = 0;                      /* FIS features NA       */
12416       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
12417       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
12418       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
12419       fis->d.lbaLowExp      = 0;
12420       fis->d.lbaMidExp      = 0;
12421       fis->d.lbaHighExp     = 0;
12422       fis->d.featuresExp    = 0;
12423       /* sector count zero */
12424       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
12425       fis->d.sectorCountExp = 0;
12426       fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
12427       fis->d.control        = 0;                      /* FIS HOB bit clear */
12428       fis->d.reserved4      = 0;
12429       fis->d.reserved5      = 0;
12430 
12431       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12432 
12433       /* Initialize CB for SATA completion.
12434        */
12435       satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12436 
12437       /*
12438        * Prepare SGL and send FIS to LL layer.
12439        */
12440       satIOContext->reqType = agRequestType;       /* Save it */
12441 
12442       status = smsataLLIOStart( smRoot,
12443                                 smIORequest,
12444                                 smDeviceHandle,
12445                                 smScsiRequest,
12446                                 satIOContext);
12447 
12448       return status;
12449     }
12450     else
12451     {
12452       /* no support for removal media */
12453       smsatSetSensePayload( pSense,
12454                             SCSI_SNSKEY_ILLEGAL_REQUEST,
12455                             0,
12456                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12457                             satIOContext);
12458 
12459       /*smEnqueueIO(smRoot, satIOContext);*/
12460 
12461       tdsmIOCompletedCB( smRoot,
12462                          smIORequest,
12463                          smIOSuccess,
12464                          SCSI_STAT_CHECK_CONDITION,
12465                          satIOContext->pSmSenseData,
12466                          satIOContext->interruptContext );
12467 
12468       SM_DBG5(("smsatStartStopUnit: return Table 29 case 3 2\n"));
12469       return SM_RC_SUCCESS;
12470     }
12471 
12472   }
12473   /* case 4 */
12474   else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */
12475   {
12476     smsatSetSensePayload( pSense,
12477                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12478                           0,
12479                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12480                           satIOContext);
12481 
12482     /*smEnqueueIO(smRoot, satIOContext);*/
12483 
12484     tdsmIOCompletedCB( smRoot,
12485                        smIORequest,
12486                        smIOSuccess,
12487                        SCSI_STAT_CHECK_CONDITION,
12488                        satIOContext->pSmSenseData,
12489                        satIOContext->interruptContext );
12490 
12491     SM_DBG5(("smsatStartStopUnit: return Table 29 case 4\n"));
12492     return SM_RC_SUCCESS;
12493   }
12494 }
12495 
12496 osGLOBAL bit32
12497 smsatWriteSame10(
12498                   smRoot_t                  *smRoot,
12499                   smIORequest_t             *smIORequest,
12500                   smDeviceHandle_t          *smDeviceHandle,
12501                   smScsiInitiatorRequest_t  *smScsiRequest,
12502                   smSatIOContext_t            *satIOContext
12503                  )
12504 {
12505 
12506   bit32                     status;
12507   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
12508   smDeviceData_t            *pSatDevData;
12509   smScsiRspSense_t          *pSense;
12510   smIniScsiCmnd_t           *scsiCmnd;
12511   agsaFisRegHostToDevice_t  *fis;
12512   bit32                     lba = 0;
12513   bit32                     tl = 0;
12514 
12515   pSense        = satIOContext->pSense;
12516   pSatDevData   = satIOContext->pSatDevData;
12517   scsiCmnd      = &smScsiRequest->scsiCmnd;
12518   fis           = satIOContext->pFis;
12519 
12520   SM_DBG5(("smsatWriteSame10: start\n"));
12521 
12522   /* checking CONTROL */
12523     /* NACA == 1 or LINK == 1*/
12524   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
12525   {
12526     smsatSetSensePayload( pSense,
12527                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12528                           0,
12529                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12530                           satIOContext);
12531 
12532     /*smEnqueueIO(smRoot, satIOContext);*/
12533 
12534     tdsmIOCompletedCB( smRoot,
12535                        smIORequest,
12536                        smIOSuccess,
12537                        SCSI_STAT_CHECK_CONDITION,
12538                        satIOContext->pSmSenseData,
12539                        satIOContext->interruptContext );
12540 
12541     SM_DBG1(("smsatWriteSame10: return control!!!\n"));
12542     return SM_RC_SUCCESS;
12543   }
12544 
12545 
12546   /* checking LBDATA and PBDATA */
12547   /* case 1 */
12548   if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12549        !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12550   {
12551     SM_DBG5(("smsatWriteSame10: case 1\n"));
12552     /* spec 9.26.2, Table 62, p64, case 1*/
12553     /*
12554       normal case
12555       just like write in 9.17.1
12556     */
12557 
12558     if ( pSatDevData->sat48BitSupport != agTRUE )
12559     {
12560       /*
12561         writeSame10 but no support for 48 bit addressing
12562         -> problem in transfer length. Therefore, return check condition
12563       */
12564       smsatSetSensePayload( pSense,
12565                             SCSI_SNSKEY_ILLEGAL_REQUEST,
12566                             0,
12567                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12568                             satIOContext);
12569 
12570       /*smEnqueueIO(smRoot, satIOContext);*/
12571 
12572       tdsmIOCompletedCB( smRoot,
12573                          smIORequest,
12574                          smIOSuccess,
12575                          SCSI_STAT_CHECK_CONDITION,
12576                          satIOContext->pSmSenseData,
12577                          satIOContext->interruptContext );
12578 
12579       SM_DBG1(("smsatWriteSame10: return internal checking!!!\n"));
12580       return SM_RC_SUCCESS;
12581     }
12582 
12583     /* cdb10; computing LBA and transfer length */
12584     lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
12585       + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
12586     tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
12587 
12588 
12589     /* Table 34, 9.1, p 46 */
12590     /*
12591       note: As of 2/10/2006, no support for DMA QUEUED
12592     */
12593 
12594     /*
12595       Table 34, 9.1, p 46, b (footnote)
12596       When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
12597       return check condition
12598     */
12599     if (pSatDevData->satNCQ != agTRUE &&
12600         pSatDevData->sat48BitSupport != agTRUE
12601           )
12602     {
12603       if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */
12604       {
12605         smsatSetSensePayload( pSense,
12606                               SCSI_SNSKEY_ILLEGAL_REQUEST,
12607                               0,
12608                               SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
12609                               satIOContext);
12610 
12611         /*smEnqueueIO(smRoot, satIOContext);*/
12612 
12613         tdsmIOCompletedCB( smRoot,
12614                            smIORequest,
12615                            smIOSuccess,
12616                            SCSI_STAT_CHECK_CONDITION,
12617                            satIOContext->pSmSenseData,
12618                            satIOContext->interruptContext );
12619 
12620         SM_DBG1(("smsatWriteSame10: return LBA out of range!!!\n"));
12621         return SM_RC_SUCCESS;
12622       }
12623     }
12624 
12625 
12626     if (lba + tl <= SAT_TR_LBA_LIMIT)
12627     {
12628       if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
12629       {
12630         /* case 2 */
12631         /* WRITE DMA */
12632         /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
12633         SM_DBG1(("smsatWriteSame10: case 1-2 !!! error due to writesame10!!!\n"));
12634         smsatSetSensePayload( pSense,
12635                               SCSI_SNSKEY_ILLEGAL_REQUEST,
12636                               0,
12637                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12638                               satIOContext);
12639 
12640         /*smEnqueueIO(smRoot, satIOContext);*/
12641 
12642         tdsmIOCompletedCB( smRoot,
12643                            smIORequest,
12644                            smIOSuccess,
12645                            SCSI_STAT_CHECK_CONDITION,
12646                            satIOContext->pSmSenseData,
12647                            satIOContext->interruptContext );
12648         return SM_RC_SUCCESS;
12649       }
12650       else
12651       {
12652         /* case 1 */
12653         /* WRITE MULTIPLE or WRITE SECTOR(S) */
12654         /* WRITE SECTORS is chosen for easier implemetation */
12655         /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
12656         SM_DBG1(("smsatWriteSame10: case 1-1 !!! error due to writesame10!!!\n"));
12657         smsatSetSensePayload( pSense,
12658                               SCSI_SNSKEY_ILLEGAL_REQUEST,
12659                               0,
12660                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12661                               satIOContext);
12662 
12663         /*smEnqueueIO(smRoot, satIOContext);*/
12664 
12665         tdsmIOCompletedCB( smRoot,
12666                            smIORequest,
12667                            smIOSuccess,
12668                            SCSI_STAT_CHECK_CONDITION,
12669                            satIOContext->pSmSenseData,
12670                            satIOContext->interruptContext );
12671         return SM_RC_SUCCESS;
12672       }
12673     } /* end of case 1 and 2 */
12674 
12675     /* case 3 and 4 */
12676     if (pSatDevData->sat48BitSupport == agTRUE)
12677     {
12678       if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
12679       {
12680         /* case 3 */
12681         /* WRITE DMA EXT or WRITE DMA FUA EXT */
12682         /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */
12683         SM_DBG5(("smsatWriteSame10: case 1-3\n"));
12684         fis->h.fisType        = 0x27;                   /* Reg host to device */
12685         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12686 
12687         fis->h.command        = SAT_WRITE_DMA_EXT;          /* 0x35 */
12688 
12689         fis->h.features       = 0;                      /* FIS reserve */
12690         fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
12691         fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
12692         fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
12693         fis->d.device         = 0x40;                   /* FIS LBA mode set */
12694         fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
12695         fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12696         fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12697         fis->d.featuresExp    = 0;                      /* FIS reserve */
12698         if (tl == 0)
12699         {
12700           /* error check
12701              ATA spec, p125, 6.17.29
12702              pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12703              and allowed value is 0x0FFFFFFF - 1
12704           */
12705           if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12706           {
12707             SM_DBG1(("smsatWriteSame10: case 3 !!! warning can't fit sectors!!!\n"));
12708             smsatSetSensePayload( pSense,
12709                                   SCSI_SNSKEY_ILLEGAL_REQUEST,
12710                                   0,
12711                                   SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12712                                   satIOContext);
12713 
12714             /*smEnqueueIO(smRoot, satIOContext);*/
12715 
12716             tdsmIOCompletedCB( smRoot,
12717                                smIORequest,
12718                                smIOSuccess,
12719                                SCSI_STAT_CHECK_CONDITION,
12720                                satIOContext->pSmSenseData,
12721                                satIOContext->interruptContext );
12722             return SM_RC_SUCCESS;
12723           }
12724         }
12725         /* one sector at a time */
12726         fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12727         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12728         fis->d.reserved4      = 0;
12729         fis->d.control        = 0;                      /* FIS HOB bit clear */
12730         fis->d.reserved5      = 0;
12731 
12732         agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
12733       }
12734       else
12735       {
12736         /* case 4 */
12737         /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
12738         /* WRITE SECTORS EXT is chosen for easier implemetation */
12739         SM_DBG5(("smsatWriteSame10: case 1-4\n"));
12740         fis->h.fisType        = 0x27;                   /* Reg host to device */
12741         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12742 
12743         fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
12744         fis->h.features       = 0;                      /* FIS reserve */
12745         fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
12746         fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
12747         fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
12748         fis->d.device         = 0x40;                   /* FIS LBA mode set */
12749         fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
12750         fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12751         fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12752         fis->d.featuresExp    = 0;                      /* FIS reserve */
12753         if (tl == 0)
12754         {
12755           /* error check
12756              ATA spec, p125, 6.17.29
12757              pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12758              and allowed value is 0x0FFFFFFF - 1
12759           */
12760           if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12761           {
12762             SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n"));
12763             smsatSetSensePayload( pSense,
12764                                   SCSI_SNSKEY_ILLEGAL_REQUEST,
12765                                   0,
12766                                   SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12767                                   satIOContext);
12768 
12769             /*smEnqueueIO(smRoot, satIOContext);*/
12770 
12771             tdsmIOCompletedCB( smRoot,
12772                                smIORequest,
12773                                smIOSuccess,
12774                                SCSI_STAT_CHECK_CONDITION,
12775                                satIOContext->pSmSenseData,
12776                                satIOContext->interruptContext );
12777             return SM_RC_SUCCESS;
12778           }
12779         }
12780         /* one sector at a time */
12781         fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
12782         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
12783         fis->d.reserved4      = 0;
12784         fis->d.control        = 0;                      /* FIS HOB bit clear */
12785         fis->d.reserved5      = 0;
12786 
12787         agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
12788       }
12789     }
12790 
12791     /* case 5 */
12792     if (pSatDevData->satNCQ == agTRUE)
12793     {
12794       /* WRITE FPDMA QUEUED */
12795       if (pSatDevData->sat48BitSupport != agTRUE)
12796       {
12797         SM_DBG1(("smsatWriteSame10: case 1-5 !!! error NCQ but 28 bit address support!!!\n"));
12798         smsatSetSensePayload( pSense,
12799                               SCSI_SNSKEY_ILLEGAL_REQUEST,
12800                               0,
12801                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12802                               satIOContext);
12803 
12804         /*smEnqueueIO(smRoot, satIOContext);*/
12805 
12806         tdsmIOCompletedCB( smRoot,
12807                            smIORequest,
12808                            smIOSuccess,
12809                            SCSI_STAT_CHECK_CONDITION,
12810                            satIOContext->pSmSenseData,
12811                            satIOContext->interruptContext );
12812         return SM_RC_SUCCESS;
12813       }
12814       SM_DBG5(("smsatWriteSame10: case 1-5\n"));
12815 
12816       /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
12817 
12818       fis->h.fisType        = 0x27;                   /* Reg host to device */
12819       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12820       fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
12821 
12822       if (tl == 0)
12823       {
12824         /* error check
12825            ATA spec, p125, 6.17.29
12826            pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12827            and allowed value is 0x0FFFFFFF - 1
12828         */
12829         if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12830         {
12831           SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n"));
12832           smsatSetSensePayload( pSense,
12833                                 SCSI_SNSKEY_ILLEGAL_REQUEST,
12834                                 0,
12835                                 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12836                                 satIOContext);
12837 
12838           /*smEnqueueIO(smRoot, satIOContext);*/
12839 
12840           tdsmIOCompletedCB( smRoot,
12841                              smIORequest,
12842                              smIOSuccess,
12843                              SCSI_STAT_CHECK_CONDITION,
12844                              satIOContext->pSmSenseData,
12845                              satIOContext->interruptContext );
12846           return SM_RC_SUCCESS;
12847         }
12848       }
12849       /* one sector at a time */
12850       fis->h.features       = 1;            /* FIS sector count (7:0) */
12851       fis->d.featuresExp    = 0;            /* FIS sector count (15:8) */
12852 
12853 
12854       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
12855       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
12856       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
12857 
12858       /* NO FUA bit in the WRITE SAME 10 */
12859       fis->d.device       = 0x40;                     /* FIS FUA clear */
12860 
12861       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
12862       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
12863       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
12864       fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
12865       fis->d.sectorCountExp = 0;
12866       fis->d.reserved4      = 0;
12867       fis->d.control        = 0;                      /* FIS HOB bit clear */
12868       fis->d.reserved5      = 0;
12869 
12870       agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
12871     }
12872     /* Initialize CB for SATA completion.
12873      */
12874     satIOContext->satCompleteCB = &smsatWriteSame10CB;
12875 
12876     /*
12877      * Prepare SGL and send FIS to LL layer.
12878      */
12879     satIOContext->reqType = agRequestType;       /* Save it */
12880 
12881     status = smsataLLIOStart( smRoot,
12882                               smIORequest,
12883                               smDeviceHandle,
12884                               smScsiRequest,
12885                               satIOContext);
12886     return (status);
12887 
12888 
12889   } /* end of case 1 */
12890   else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12891              (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12892   {
12893     /* spec 9.26.2, Table 62, p64, case 2*/
12894     smsatSetSensePayload( pSense,
12895                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12896                           0,
12897                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12898                           satIOContext);
12899 
12900     /*smEnqueueIO(smRoot, satIOContext);*/
12901 
12902     tdsmIOCompletedCB( smRoot,
12903                        smIORequest,
12904                        smIOSuccess,
12905                        SCSI_STAT_CHECK_CONDITION,
12906                        satIOContext->pSmSenseData,
12907                        satIOContext->interruptContext );
12908 
12909     SM_DBG5(("smsatWriteSame10: return Table 62 case 2\n"));
12910     return SM_RC_SUCCESS;
12911   }
12912   else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12913            !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12914   {
12915     SM_DBG5(("smsatWriteSame10: Table 62 case 3\n"));
12916 
12917   }
12918   else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12919             (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */
12920   {
12921 
12922     /* spec 9.26.2, Table 62, p64, case 4*/
12923     smsatSetSensePayload( pSense,
12924                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12925                           0,
12926                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12927                           satIOContext);
12928 
12929     /*smEnqueueIO(smRoot, satIOContext);*/
12930 
12931     tdsmIOCompletedCB( smRoot,
12932                        smIORequest,
12933                        smIOSuccess,
12934                        SCSI_STAT_CHECK_CONDITION,
12935                        satIOContext->pSmSenseData,
12936                        satIOContext->interruptContext );
12937 
12938     SM_DBG5(("smsatWriteSame10: return Table 62 case 4\n"));
12939     return SM_RC_SUCCESS;
12940   }
12941 
12942 
12943   return SM_RC_SUCCESS;
12944 }
12945 
12946 osGLOBAL bit32
12947 smsatWriteSame16(
12948                   smRoot_t                  *smRoot,
12949                   smIORequest_t             *smIORequest,
12950                   smDeviceHandle_t          *smDeviceHandle,
12951                   smScsiInitiatorRequest_t  *smScsiRequest,
12952                   smSatIOContext_t            *satIOContext
12953                  )
12954 {
12955   smScsiRspSense_t          *pSense;
12956 
12957   pSense        = satIOContext->pSense;
12958 
12959   SM_DBG5(("smsatWriteSame16: start\n"));
12960 
12961 
12962   smsatSetSensePayload( pSense,
12963                         SCSI_SNSKEY_NO_SENSE,
12964                         0,
12965                         SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12966                         satIOContext);
12967 
12968   /*smEnqueueIO(smRoot, satIOContext);*/
12969 
12970   tdsmIOCompletedCB( smRoot,
12971                      smIORequest, /* == &satIntIo->satOrgSmIORequest */
12972                      smIOSuccess,
12973                      SCSI_STAT_CHECK_CONDITION,
12974                      satIOContext->pSmSenseData,
12975                      satIOContext->interruptContext );
12976   SM_DBG1(("smsatWriteSame16: return internal checking!!!\n"));
12977   return SM_RC_SUCCESS;
12978 }
12979 
12980 osGLOBAL bit32
12981 smsatLogSense(
12982               smRoot_t                  *smRoot,
12983               smIORequest_t             *smIORequest,
12984               smDeviceHandle_t          *smDeviceHandle,
12985               smScsiInitiatorRequest_t  *smScsiRequest,
12986               smSatIOContext_t            *satIOContext
12987              )
12988 {
12989   bit32                     status;
12990   bit32                     agRequestType;
12991   smDeviceData_t            *pSatDevData;
12992   smScsiRspSense_t          *pSense;
12993   smIniScsiCmnd_t           *scsiCmnd;
12994   agsaFisRegHostToDevice_t  *fis;
12995   bit8                      *pLogPage;    /* Log Page data buffer */
12996   bit32                     flag = 0;
12997   bit16                     AllocLen = 0;       /* allocation length */
12998   bit8                      AllLogPages[8];
12999   bit16                     lenRead = 0;
13000 
13001   pSense        = satIOContext->pSense;
13002   pSatDevData   = satIOContext->pSatDevData;
13003   scsiCmnd      = &smScsiRequest->scsiCmnd;
13004   fis           = satIOContext->pFis;
13005   pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
13006 
13007   SM_DBG5(("smsatLogSense: start\n"));
13008 
13009   sm_memset(&AllLogPages, 0, 8);
13010   /* checking CONTROL */
13011   /* NACA == 1 or LINK == 1*/
13012   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13013   {
13014     smsatSetSensePayload( pSense,
13015                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13016                           0,
13017                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13018                           satIOContext);
13019 
13020     /*smEnqueueIO(smRoot, satIOContext);*/
13021 
13022     tdsmIOCompletedCB( smRoot,
13023                        smIORequest,
13024                        smIOSuccess,
13025                        SCSI_STAT_CHECK_CONDITION,
13026                        satIOContext->pSmSenseData,
13027                        satIOContext->interruptContext );
13028 
13029     SM_DBG1(("smsatLogSense: return control!!!\n"));
13030     return SM_RC_SUCCESS;
13031   }
13032 
13033 
13034   AllocLen = ((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
13035   AllocLen = MIN(AllocLen, scsiCmnd->expDataLength);
13036 
13037   /* checking PC (Page Control) */
13038   /* nothing */
13039 
13040   /* special cases */
13041   if (AllocLen == 4)
13042   {
13043     SM_DBG1(("smsatLogSense: AllocLen is 4!!!\n"));
13044     switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
13045     {
13046       case LOGSENSE_SUPPORTED_LOG_PAGES:
13047         SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13048 
13049         if (pSatDevData->satSMARTFeatureSet == agTRUE)
13050         {
13051           /* add informational exception log */
13052           flag = 1;
13053           if (pSatDevData->satSMARTSelfTest == agTRUE)
13054           {
13055             /* add Self-Test results log page */
13056             flag = 2;
13057           }
13058         }
13059         else
13060         {
13061           /* only supported, no informational exception log, no  Self-Test results log page */
13062           flag = 0;
13063         }
13064         lenRead = 4;
13065         AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES;          /* page code */
13066         AllLogPages[1] = 0;          /* reserved  */
13067         switch (flag)
13068         {
13069           case 0:
13070             /* only supported */
13071             AllLogPages[2] = 0;          /* page length */
13072             AllLogPages[3] = 1;          /* page length */
13073             break;
13074           case 1:
13075             /* supported and informational exception log */
13076             AllLogPages[2] = 0;          /* page length */
13077             AllLogPages[3] = 2;          /* page length */
13078             break;
13079           case 2:
13080             /* supported and informational exception log */
13081             AllLogPages[2] = 0;          /* page length */
13082             AllLogPages[3] = 3;          /* page length */
13083             break;
13084           default:
13085             SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag));
13086             break;
13087         }
13088         sm_memcpy(pLogPage, &AllLogPages, lenRead);
13089         break;
13090       case LOGSENSE_SELFTEST_RESULTS_PAGE:
13091         SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13092         lenRead = 4;
13093         AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE;          /* page code */
13094         AllLogPages[1] = 0;          /* reserved  */
13095         /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */
13096         AllLogPages[2] = 0x01;
13097         AllLogPages[3] = 0x90;       /* page length */
13098         sm_memcpy(pLogPage, &AllLogPages, lenRead);
13099 
13100         break;
13101       case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
13102         SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13103         lenRead = 4;
13104         AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE;          /* page code */
13105         AllLogPages[1] = 0;          /* reserved  */
13106         AllLogPages[2] = 0;          /* page length */
13107         AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3;       /* page length */
13108         sm_memcpy(pLogPage, &AllLogPages, lenRead);
13109         break;
13110       default:
13111         SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
13112         smsatSetSensePayload( pSense,
13113                               SCSI_SNSKEY_ILLEGAL_REQUEST,
13114                               0,
13115                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13116                               satIOContext);
13117 
13118         /*smEnqueueIO(smRoot, satIOContext);*/
13119 
13120         tdsmIOCompletedCB( smRoot,
13121                            smIORequest,
13122                            smIOSuccess,
13123                            SCSI_STAT_CHECK_CONDITION,
13124                            satIOContext->pSmSenseData,
13125                            satIOContext->interruptContext );
13126         return SM_RC_SUCCESS;
13127     }
13128     /*smEnqueueIO(smRoot, satIOContext);*/
13129 
13130     tdsmIOCompletedCB( smRoot,
13131                        smIORequest,
13132                        smIOSuccess,
13133                        SCSI_STAT_GOOD,
13134                        agNULL,
13135                        satIOContext->interruptContext);
13136     return SM_RC_SUCCESS;
13137 
13138   } /* if */
13139 
13140   /* SAT rev8 Table 11  p30*/
13141   /* checking Page Code */
13142   switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
13143   {
13144     case LOGSENSE_SUPPORTED_LOG_PAGES:
13145       SM_DBG5(("smsatLogSense: case 1\n"));
13146 
13147       if (pSatDevData->satSMARTFeatureSet == agTRUE)
13148       {
13149         /* add informational exception log */
13150         flag = 1;
13151         if (pSatDevData->satSMARTSelfTest == agTRUE)
13152         {
13153           /* add Self-Test results log page */
13154           flag = 2;
13155         }
13156       }
13157       else
13158       {
13159         /* only supported, no informational exception log, no  Self-Test results log page */
13160         flag = 0;
13161       }
13162       AllLogPages[0] = 0;          /* page code */
13163       AllLogPages[1] = 0;          /* reserved  */
13164       switch (flag)
13165       {
13166       case 0:
13167         /* only supported */
13168         AllLogPages[2] = 0;          /* page length */
13169         AllLogPages[3] = 1;          /* page length */
13170         AllLogPages[4] = 0x00;       /* supported page list */
13171         lenRead = (bit8)(MIN(AllocLen, 5));
13172         break;
13173       case 1:
13174         /* supported and informational exception log */
13175         AllLogPages[2] = 0;          /* page length */
13176         AllLogPages[3] = 2;          /* page length */
13177         AllLogPages[4] = 0x00;       /* supported page list */
13178         AllLogPages[5] = 0x10;       /* supported page list */
13179         lenRead = (bit8)(MIN(AllocLen, 6));
13180         break;
13181       case 2:
13182         /* supported and informational exception log */
13183         AllLogPages[2] = 0;          /* page length */
13184         AllLogPages[3] = 3;          /* page length */
13185         AllLogPages[4] = 0x00;       /* supported page list */
13186         AllLogPages[5] = 0x10;       /* supported page list */
13187         AllLogPages[6] = 0x2F;       /* supported page list */
13188        lenRead = (bit8)(MIN(AllocLen, 7));
13189        break;
13190       default:
13191         SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag));
13192         break;
13193       }
13194 
13195       sm_memcpy(pLogPage, &AllLogPages, lenRead);
13196       /* comparing allocation length to Log Page byte size */
13197       /* SPC-4, 4.3.4.6, p28 */
13198       if (AllocLen > lenRead )
13199       {
13200         SM_DBG1(("smsatLogSense: reporting underrun lenRead=0x%x AllocLen=0x%x!!!\n", lenRead, AllocLen));
13201         /*smEnqueueIO(smRoot, satIOContext);*/
13202 
13203         tdsmIOCompletedCB( smRoot,
13204                            smIORequest,
13205                            smIOUnderRun,
13206                            AllocLen - lenRead,
13207                            agNULL,
13208                            satIOContext->interruptContext );
13209       }
13210       else
13211       {
13212         /*smEnqueueIO(smRoot, satIOContext);*/
13213         tdsmIOCompletedCB( smRoot,
13214                            smIORequest,
13215                            smIOSuccess,
13216                            SCSI_STAT_GOOD,
13217                            agNULL,
13218                            satIOContext->interruptContext);
13219       }
13220       break;
13221     case LOGSENSE_SELFTEST_RESULTS_PAGE:
13222       SM_DBG5(("smsatLogSense: case 2\n"));
13223       /* checking SMART self-test */
13224       if (pSatDevData->satSMARTSelfTest == agFALSE)
13225       {
13226         SM_DBG5(("smsatLogSense: case 2 no SMART Self Test\n"));
13227         smsatSetSensePayload( pSense,
13228                               SCSI_SNSKEY_ILLEGAL_REQUEST,
13229                               0,
13230                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13231                               satIOContext);
13232 
13233         /*smEnqueueIO(smRoot, satIOContext);*/
13234 
13235         tdsmIOCompletedCB( smRoot,
13236                            smIORequest,
13237                            smIOSuccess,
13238                            SCSI_STAT_CHECK_CONDITION,
13239                            satIOContext->pSmSenseData,
13240                            satIOContext->interruptContext );
13241       }
13242       else
13243       {
13244         /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */
13245         if (pSatDevData->satSMARTEnabled == agFALSE)
13246         {
13247           SM_DBG5(("smsatLogSense: case 2 calling satSMARTEnable\n"));
13248           status = smsatLogSenseAllocate(smRoot,
13249                                          smIORequest,
13250                                          smDeviceHandle,
13251                                          smScsiRequest,
13252                                          satIOContext,
13253                                          0,
13254                                          LOG_SENSE_0
13255                                          );
13256 
13257           return status;
13258 
13259         }
13260         else
13261         {
13262         /* SAT Rev 8, 10.2.4 p74 */
13263         if ( pSatDevData->sat48BitSupport == agTRUE )
13264         {
13265           SM_DBG5(("smsatLogSense: case 2-1 sends READ LOG EXT\n"));
13266           status = smsatLogSenseAllocate(smRoot,
13267                                          smIORequest,
13268                                          smDeviceHandle,
13269                                          smScsiRequest,
13270                                          satIOContext,
13271                                          512,
13272                                          LOG_SENSE_1
13273                                          );
13274 
13275           return status;
13276         }
13277         else
13278         {
13279           SM_DBG5(("smsatLogSense: case 2-2 sends SMART READ LOG\n"));
13280           status = smsatLogSenseAllocate(smRoot,
13281                                          smIORequest,
13282                                          smDeviceHandle,
13283                                          smScsiRequest,
13284                                          satIOContext,
13285                                          512,
13286                                          LOG_SENSE_2
13287                                          );
13288 
13289           return status;
13290         }
13291       }
13292       }
13293       break;
13294     case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
13295       SM_DBG5(("smsatLogSense: case 3\n"));
13296       /* checking SMART feature set */
13297       if (pSatDevData->satSMARTFeatureSet == agFALSE)
13298       {
13299         smsatSetSensePayload( pSense,
13300                               SCSI_SNSKEY_ILLEGAL_REQUEST,
13301                               0,
13302                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13303                               satIOContext);
13304 
13305         /*smEnqueueIO(smRoot, satIOContext);*/
13306 
13307         tdsmIOCompletedCB( smRoot,
13308                            smIORequest,
13309                            smIOSuccess,
13310                            SCSI_STAT_CHECK_CONDITION,
13311                            satIOContext->pSmSenseData,
13312                            satIOContext->interruptContext );
13313       }
13314       else
13315       {
13316         /* checking SMART feature enabled */
13317         if (pSatDevData->satSMARTEnabled == agFALSE)
13318         {
13319           smsatSetSensePayload( pSense,
13320                                 SCSI_SNSKEY_ABORTED_COMMAND,
13321                                 0,
13322                                 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
13323                                 satIOContext);
13324 
13325           /*smEnqueueIO(smRoot, satIOContext);*/
13326 
13327           tdsmIOCompletedCB( smRoot,
13328                              smIORequest,
13329                              smIOSuccess,
13330                              SCSI_STAT_CHECK_CONDITION,
13331                              satIOContext->pSmSenseData,
13332                              satIOContext->interruptContext );
13333         }
13334         else
13335         {
13336           /* SAT Rev 8, 10.2.3 p72 */
13337           SM_DBG5(("smsatLogSense: case 3 sends SMART RETURN STATUS\n"));
13338 
13339           /* sends SMART RETURN STATUS */
13340           fis->h.fisType        = 0x27;                   /* Reg host to device */
13341           fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13342 
13343           fis->h.command        = SAT_SMART;              /* 0xB0 */
13344           fis->h.features       = SAT_SMART_RETURN_STATUS;/* FIS features */
13345           fis->d.featuresExp    = 0;                      /* FIS reserve */
13346           fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13347           fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
13348           fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13349           fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
13350           fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
13351           fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13352           fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
13353           fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13354           fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13355           fis->d.control        = 0;                      /* FIS HOB bit clear */
13356           fis->d.reserved4      = 0;
13357           fis->d.reserved5      = 0;
13358 
13359           agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13360           /* Initialize CB for SATA completion.
13361            */
13362           satIOContext->satCompleteCB = &smsatLogSenseCB;
13363 
13364           /*
13365            * Prepare SGL and send FIS to LL layer.
13366            */
13367           satIOContext->reqType = agRequestType;       /* Save it */
13368 
13369           status = smsataLLIOStart( smRoot,
13370                                     smIORequest,
13371                                     smDeviceHandle,
13372                                     smScsiRequest,
13373                                     satIOContext);
13374 
13375 
13376           return status;
13377         }
13378       }
13379       break;
13380     default:
13381       SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
13382       smsatSetSensePayload( pSense,
13383                             SCSI_SNSKEY_ILLEGAL_REQUEST,
13384                             0,
13385                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13386                             satIOContext);
13387 
13388       /*smEnqueueIO(smRoot, satIOContext);*/
13389 
13390       tdsmIOCompletedCB( smRoot,
13391                          smIORequest,
13392                          smIOSuccess,
13393                          SCSI_STAT_CHECK_CONDITION,
13394                          satIOContext->pSmSenseData,
13395                          satIOContext->interruptContext );
13396 
13397       break;
13398   } /* end switch */
13399 
13400   return SM_RC_SUCCESS;
13401 }
13402 
13403 osGLOBAL bit32
13404 smsatLogSenseAllocate(
13405                       smRoot_t                  *smRoot,
13406                       smIORequest_t             *smIORequest,
13407                       smDeviceHandle_t          *smDeviceHandle,
13408                       smScsiInitiatorRequest_t  *smSCSIRequest,
13409                       smSatIOContext_t            *satIOContext,
13410                       bit32                     payloadSize,
13411                       bit32                     flag
13412                      )
13413 {
13414   smDeviceData_t            *pSatDevData;
13415   smIORequestBody_t         *smIORequestBody;
13416   smSatInternalIo_t           *satIntIo = agNULL;
13417   smSatIOContext_t            *satIOContext2;
13418   bit32                     status;
13419 
13420   SM_DBG5(("smsatLogSenseAllocate: start\n"));
13421 
13422   pSatDevData       = satIOContext->pSatDevData;
13423 
13424   /* create internal satIOContext */
13425   satIntIo = smsatAllocIntIoResource( smRoot,
13426                                       smIORequest, /* original request */
13427                                       pSatDevData,
13428                                       payloadSize,
13429                                       satIntIo);
13430 
13431   if (satIntIo == agNULL)
13432   {
13433     /*smEnqueueIO(smRoot, satIOContext);*/
13434 
13435     tdsmIOCompletedCB( smRoot,
13436                        smIORequest,
13437                        smIOFailed,
13438                        smDetailOtherError,
13439                        agNULL,
13440                        satIOContext->interruptContext );
13441 
13442     SM_DBG1(("smsatLogSenseAllocate: fail in allocation!!!\n"));
13443     return SM_RC_SUCCESS;
13444   } /* end of memory allocation failure */
13445 
13446   satIntIo->satOrgSmIORequest = smIORequest;
13447   smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
13448   satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);
13449 
13450   satIOContext2->pSatDevData   = pSatDevData;
13451   satIOContext2->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
13452   satIOContext2->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
13453   satIOContext2->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
13454   satIOContext2->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
13455   satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;
13456   satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
13457   satIOContext2->interruptContext = satIOContext->interruptContext;
13458   satIOContext2->satIntIoContext  = satIntIo;
13459   satIOContext2->psmDeviceHandle = smDeviceHandle;
13460   satIOContext2->satOrgIOContext = satIOContext;
13461 
13462   if (flag == LOG_SENSE_0)
13463   {
13464     /* SAT_SMART_ENABLE_OPERATIONS */
13465     status = smsatSMARTEnable( smRoot,
13466                                &(satIntIo->satIntSmIORequest),
13467                                smDeviceHandle,
13468                                &(satIntIo->satIntSmScsiXchg),
13469                                satIOContext2);
13470   }
13471   else if (flag == LOG_SENSE_1)
13472   {
13473     /* SAT_READ_LOG_EXT */
13474     status = smsatLogSense_2( smRoot,
13475                               &(satIntIo->satIntSmIORequest),
13476                               smDeviceHandle,
13477                               &(satIntIo->satIntSmScsiXchg),
13478                               satIOContext2);
13479   }
13480   else
13481   {
13482     /* SAT_SMART_READ_LOG */
13483     /* SAT_READ_LOG_EXT */
13484     status = smsatLogSense_3( smRoot,
13485                               &(satIntIo->satIntSmIORequest),
13486                               smDeviceHandle,
13487                               &(satIntIo->satIntSmScsiXchg),
13488                               satIOContext2);
13489 
13490   }
13491   if (status != SM_RC_SUCCESS)
13492   {
13493     smsatFreeIntIoResource( smRoot,
13494                             pSatDevData,
13495                             satIntIo);
13496 
13497     /*smEnqueueIO(smRoot, satIOContext);*/
13498 
13499     tdsmIOCompletedCB( smRoot,
13500                        smIORequest,
13501                        smIOFailed,
13502                        smDetailOtherError,
13503                        agNULL,
13504                        satIOContext->interruptContext );
13505     return SM_RC_SUCCESS;
13506   }
13507 
13508 
13509   return SM_RC_SUCCESS;
13510 }
13511 
13512 osGLOBAL bit32
13513 smsatSMARTEnable(
13514                  smRoot_t                  *smRoot,
13515                  smIORequest_t             *smIORequest,
13516                  smDeviceHandle_t          *smDeviceHandle,
13517                  smScsiInitiatorRequest_t  *smScsiRequest,
13518                  smSatIOContext_t            *satIOContext
13519                )
13520 {
13521   bit32                     status;
13522   bit32                     agRequestType;
13523   agsaFisRegHostToDevice_t  *fis;
13524 
13525   fis               = satIOContext->pFis;
13526   SM_DBG5(("smsatSMARTEnable: start\n"));
13527   /*
13528    * Send the SAT_SMART_ENABLE_OPERATIONS command.
13529    */
13530   fis->h.fisType        = 0x27;                   /* Reg host to device */
13531   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13532   fis->h.command        = SAT_SMART;              /* 0xB0 */
13533   fis->h.features       = SAT_SMART_ENABLE_OPERATIONS;
13534   fis->d.lbaLow         = 0;
13535   fis->d.lbaMid         = 0x4F;
13536   fis->d.lbaHigh        = 0xC2;
13537   fis->d.device         = 0;
13538   fis->d.lbaLowExp      = 0;
13539   fis->d.lbaMidExp      = 0;
13540   fis->d.lbaHighExp     = 0;
13541   fis->d.featuresExp    = 0;
13542   fis->d.sectorCount    = 0;
13543   fis->d.sectorCountExp = 0;
13544   fis->d.reserved4      = 0;
13545   fis->d.control        = 0;                      /* FIS HOB bit clear */
13546   fis->d.reserved5      = 0;
13547 
13548   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13549 
13550   /* Initialize CB for SATA completion.
13551    */
13552   satIOContext->satCompleteCB = &smsatSMARTEnableCB;
13553 
13554   /*
13555    * Prepare SGL and send FIS to LL layer.
13556    */
13557   satIOContext->reqType = agRequestType;       /* Save it */
13558 
13559   status = smsataLLIOStart( smRoot,
13560                             smIORequest,
13561                             smDeviceHandle,
13562                             smScsiRequest,
13563                             satIOContext);
13564 
13565 
13566   return status;
13567 }
13568 
13569 osGLOBAL bit32
13570 smsatLogSense_2(
13571                 smRoot_t                  *smRoot,
13572                 smIORequest_t             *smIORequest,
13573                 smDeviceHandle_t          *smDeviceHandle,
13574                 smScsiInitiatorRequest_t  *smScsiRequest,
13575                 smSatIOContext_t            *satIOContext
13576                )
13577 {
13578   bit32                     status;
13579   bit32                     agRequestType;
13580   agsaFisRegHostToDevice_t  *fis;
13581 
13582   fis               = satIOContext->pFis;
13583   SM_DBG5(("smsatLogSense_2: start\n"));
13584 
13585   /* sends READ LOG EXT */
13586   fis->h.fisType        = 0x27;                   /* Reg host to device */
13587   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13588 
13589   fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
13590   fis->h.features       = 0;                      /* FIS reserve */
13591   fis->d.lbaLow         = 0x07;                   /* 0x07 */
13592   fis->d.lbaMid         = 0;                      /*  */
13593   fis->d.lbaHigh        = 0;                      /*  */
13594   fis->d.device         = 0;                      /*  */
13595   fis->d.lbaLowExp      = 0;                      /*  */
13596   fis->d.lbaMidExp      = 0;                      /*  */
13597   fis->d.lbaHighExp     = 0;                      /*  */
13598   fis->d.featuresExp    = 0;                      /* FIS reserve */
13599   fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
13600   fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
13601   fis->d.reserved4      = 0;
13602   fis->d.control        = 0;                      /* FIS HOB bit clear */
13603   fis->d.reserved5      = 0;
13604 
13605   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
13606 
13607   /* Initialize CB for SATA completion.
13608    */
13609   satIOContext->satCompleteCB = &smsatLogSenseCB;
13610 
13611   /*
13612    * Prepare SGL and send FIS to LL layer.
13613    */
13614   satIOContext->reqType = agRequestType;       /* Save it */
13615 
13616   status = smsataLLIOStart( smRoot,
13617                             smIORequest,
13618                             smDeviceHandle,
13619                             smScsiRequest,
13620                             satIOContext);
13621   return status;
13622 }
13623 
13624 osGLOBAL bit32
13625 smsatLogSense_3(
13626                 smRoot_t                  *smRoot,
13627                 smIORequest_t             *smIORequest,
13628                 smDeviceHandle_t          *smDeviceHandle,
13629                 smScsiInitiatorRequest_t  *smScsiRequest,
13630                 smSatIOContext_t            *satIOContext
13631                )
13632 {
13633   bit32                     status;
13634   bit32                     agRequestType;
13635   agsaFisRegHostToDevice_t  *fis;
13636 
13637   fis               = satIOContext->pFis;
13638   SM_DBG5(("smsatLogSense_3: start\n"));
13639   /* sends READ LOG EXT */
13640   fis->h.fisType        = 0x27;                   /* Reg host to device */
13641   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13642   fis->h.command        = SAT_SMART;              /* 0x2F */
13643   fis->h.features       = SAT_SMART_READ_LOG;     /* 0xd5 */
13644   fis->d.lbaLow         = 0x06;                   /* 0x06 */
13645   fis->d.lbaMid         = 0x4F;                   /* 0x4f */
13646   fis->d.lbaHigh        = 0xC2;                   /* 0xc2 */
13647   fis->d.device         = 0;                      /*  */
13648   fis->d.lbaLowExp      = 0;                      /*  */
13649   fis->d.lbaMidExp      = 0;                      /*  */
13650   fis->d.lbaHighExp     = 0;                      /*  */
13651   fis->d.featuresExp    = 0;                      /* FIS reserve */
13652   fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
13653   fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
13654   fis->d.reserved4      = 0;
13655   fis->d.control        = 0;                      /* FIS HOB bit clear */
13656   fis->d.reserved5      = 0;
13657   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
13658   /* Initialize CB for SATA completion.
13659    */
13660   satIOContext->satCompleteCB = &smsatLogSenseCB;
13661   /*
13662    * Prepare SGL and send FIS to LL layer.
13663    */
13664   satIOContext->reqType = agRequestType;       /* Save it */
13665   status = smsataLLIOStart( smRoot,
13666                             smIORequest,
13667                             smDeviceHandle,
13668                             smScsiRequest,
13669                             satIOContext);
13670   return status;
13671 }
13672 
13673 
13674 osGLOBAL bit32
13675 smsatModeSelect6(
13676                  smRoot_t                  *smRoot,
13677                  smIORequest_t             *smIORequest,
13678                  smDeviceHandle_t          *smDeviceHandle,
13679                  smScsiInitiatorRequest_t  *smScsiRequest,
13680                  smSatIOContext_t            *satIOContext
13681                 )
13682 {
13683   bit32                     status;
13684   bit32                     agRequestType;
13685   smDeviceData_t            *pSatDevData;
13686   smScsiRspSense_t          *pSense;
13687   smIniScsiCmnd_t           *scsiCmnd;
13688   agsaFisRegHostToDevice_t  *fis;
13689   bit8                      *pLogPage;    /* Log Page data buffer */
13690   bit32                     StartingIndex = 0;
13691   bit8                      PageCode = 0;
13692   bit32                     chkCnd = agFALSE;
13693   bit32                     parameterListLen = 0;
13694 
13695   pSense        = satIOContext->pSense;
13696   pSatDevData   = satIOContext->pSatDevData;
13697   scsiCmnd      = &smScsiRequest->scsiCmnd;
13698   fis           = satIOContext->pFis;
13699   pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
13700 
13701   SM_DBG5(("smsatModeSelect6: start\n"));
13702 
13703   /* checking CONTROL */
13704   /* NACA == 1 or LINK == 1*/
13705   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
13706   {
13707     smsatSetSensePayload( pSense,
13708                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13709                           0,
13710                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13711                           satIOContext);
13712 
13713     /*smEnqueueIO(smRoot, satIOContext);*/
13714 
13715     tdsmIOCompletedCB( smRoot,
13716                        smIORequest,
13717                        smIOSuccess,
13718                        SCSI_STAT_CHECK_CONDITION,
13719                        satIOContext->pSmSenseData,
13720                        satIOContext->interruptContext );
13721 
13722     SM_DBG1(("smsatModeSelect6: return control!!!\n"));
13723     return SM_RC_SUCCESS;
13724   }
13725 
13726   /* checking PF bit */
13727   if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
13728   {
13729     smsatSetSensePayload( pSense,
13730                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13731                           0,
13732                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13733                           satIOContext);
13734 
13735     /*smEnqueueIO(smRoot, satIOContext);*/
13736 
13737     tdsmIOCompletedCB( smRoot,
13738                        smIORequest,
13739                        smIOSuccess,
13740                        SCSI_STAT_CHECK_CONDITION,
13741                        satIOContext->pSmSenseData,
13742                        satIOContext->interruptContext );
13743 
13744     SM_DBG1(("smsatModeSelect6: PF bit check!!!\n"));
13745     return SM_RC_SUCCESS;
13746   }
13747 
13748   parameterListLen = scsiCmnd->cdb[4];
13749   parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength);
13750   if ((0 == parameterListLen) || (agNULL == pLogPage))
13751   {
13752     tdsmIOCompletedCB( smRoot,
13753                        smIORequest,
13754                        smIOSuccess,
13755                        SCSI_STAT_GOOD,
13756                        agNULL,
13757                        satIOContext->interruptContext);
13758     return SM_RC_SUCCESS;
13759   }
13760 
13761   /* checking Block Descriptor Length on Mode parameter header(6)*/
13762   if (pLogPage[3] == 8)
13763   {
13764     /* mode parameter block descriptor exists */
13765     PageCode = (bit8)(pLogPage[12] & 0x3F);   /* page code and index is 4 + 8 */
13766     StartingIndex = 12;
13767   }
13768   else if (pLogPage[3] == 0)
13769   {
13770     /* mode parameter block descriptor does not exist */
13771     PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */
13772     StartingIndex = 4;
13773     /*smEnqueueIO(smRoot, satIOContext);*/
13774 
13775     tdsmIOCompletedCB( smRoot,
13776                        smIORequest,
13777                        smIOSuccess,
13778                        SCSI_STAT_GOOD,
13779                        agNULL,
13780                        satIOContext->interruptContext);
13781     return SM_RC_SUCCESS;
13782   }
13783   else
13784   {
13785     SM_DBG1(("smsatModeSelect6: return mode parameter block descriptor 0x%x!!!\n", pLogPage[3]));
13786 
13787     smsatSetSensePayload( pSense,
13788                           SCSI_SNSKEY_NO_SENSE,
13789                           0,
13790                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
13791                           satIOContext);
13792 
13793     /*smEnqueueIO(smRoot, satIOContext);*/
13794 
13795     tdsmIOCompletedCB( smRoot,
13796                        smIORequest,
13797                        smIOSuccess,
13798                        SCSI_STAT_CHECK_CONDITION,
13799                        satIOContext->pSmSenseData,
13800                        satIOContext->interruptContext );
13801     return SM_RC_SUCCESS;
13802   }
13803 
13804 
13805 
13806   switch (PageCode) /* page code */
13807   {
13808   case MODESELECT_CONTROL_PAGE:
13809     SM_DBG1(("smsatModeSelect6: Control mode page!!!\n"));
13810 
13811     if ( pLogPage[StartingIndex+1] != 0x0A ||
13812          pLogPage[StartingIndex+2] != 0x02 ||
13813          (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
13814          (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
13815          (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
13816          (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
13817          (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
13818 
13819          (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
13820          (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
13821          (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
13822          (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
13823 
13824          pLogPage[StartingIndex+8] != 0xFF ||
13825          pLogPage[StartingIndex+9] != 0xFF ||
13826          pLogPage[StartingIndex+10] != 0x00 ||
13827          pLogPage[StartingIndex+11] != 0x00
13828        )
13829     {
13830       chkCnd = agTRUE;
13831     }
13832     if (chkCnd == agTRUE)
13833     {
13834       smsatSetSensePayload( pSense,
13835                             SCSI_SNSKEY_ILLEGAL_REQUEST,
13836                             0,
13837                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13838                             satIOContext);
13839 
13840       /*smEnqueueIO(smRoot, satIOContext);*/
13841 
13842       tdsmIOCompletedCB( smRoot,
13843                          smIORequest,
13844                          smIOSuccess,
13845                          SCSI_STAT_CHECK_CONDITION,
13846                          satIOContext->pSmSenseData,
13847                          satIOContext->interruptContext );
13848 
13849       SM_DBG1(("smsatModeSelect6: unexpected values!!!\n"));
13850     }
13851     else
13852     {
13853       /*smEnqueueIO(smRoot, satIOContext);*/
13854 
13855       tdsmIOCompletedCB( smRoot,
13856                          smIORequest,
13857                          smIOSuccess,
13858                          SCSI_STAT_GOOD,
13859                          agNULL,
13860                          satIOContext->interruptContext);
13861     }
13862     return SM_RC_SUCCESS;
13863     break;
13864   case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
13865     SM_DBG1(("smsatModeSelect6: Read-Write Error Recovery mode page!!!\n"));
13866 
13867     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) ||
13868          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) ||
13869          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) ||
13870          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) ||
13871          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) ||
13872          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) ||
13873          (pLogPage[StartingIndex + 10]) ||
13874          (pLogPage[StartingIndex + 11])
13875          )
13876     {
13877       SM_DBG5(("smsatModeSelect6: return check condition\n"));
13878 
13879       smsatSetSensePayload( pSense,
13880                             SCSI_SNSKEY_ILLEGAL_REQUEST,
13881                             0,
13882                             SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13883                             satIOContext);
13884 
13885       /*smEnqueueIO(smRoot, satIOContext);*/
13886 
13887       tdsmIOCompletedCB( smRoot,
13888                          smIORequest,
13889                          smIOSuccess,
13890                          SCSI_STAT_CHECK_CONDITION,
13891                          satIOContext->pSmSenseData,
13892                          satIOContext->interruptContext );
13893       return SM_RC_SUCCESS;
13894     }
13895     else
13896     {
13897       SM_DBG5(("smsatModeSelect6: return GOOD \n"));
13898       /*smEnqueueIO(smRoot, satIOContext);*/
13899 
13900       tdsmIOCompletedCB( smRoot,
13901                          smIORequest,
13902                          smIOSuccess,
13903                          SCSI_STAT_GOOD,
13904                          agNULL,
13905                          satIOContext->interruptContext);
13906       return SM_RC_SUCCESS;
13907     }
13908 
13909     break;
13910   case MODESELECT_CACHING:
13911     /* SAT rev8 Table67, p69*/
13912     SM_DBG5(("smsatModeSelect6: Caching mode page\n"));
13913     if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
13914          (pLogPage[StartingIndex + 3]) ||
13915          (pLogPage[StartingIndex + 4]) ||
13916          (pLogPage[StartingIndex + 5]) ||
13917          (pLogPage[StartingIndex + 6]) ||
13918          (pLogPage[StartingIndex + 7]) ||
13919          (pLogPage[StartingIndex + 8]) ||
13920          (pLogPage[StartingIndex + 9]) ||
13921          (pLogPage[StartingIndex + 10]) ||
13922          (pLogPage[StartingIndex + 11]) ||
13923 
13924          (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
13925          (pLogPage[StartingIndex + 13]) ||
13926          (pLogPage[StartingIndex + 14]) ||
13927          (pLogPage[StartingIndex + 15])
13928          )
13929     {
13930       SM_DBG1(("smsatModeSelect6: return check condition!!!\n"));
13931 
13932       smsatSetSensePayload( pSense,
13933                             SCSI_SNSKEY_ILLEGAL_REQUEST,
13934                             0,
13935                             SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13936                             satIOContext);
13937 
13938       /*smEnqueueIO(smRoot, satIOContext);*/
13939 
13940       tdsmIOCompletedCB( smRoot,
13941                          smIORequest,
13942                          smIOSuccess,
13943                          SCSI_STAT_CHECK_CONDITION,
13944                          satIOContext->pSmSenseData,
13945                          satIOContext->interruptContext );
13946       return SM_RC_SUCCESS;
13947 
13948     }
13949     else
13950     {
13951       /* sends ATA SET FEATURES based on WCE bit */
13952       if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
13953       {
13954         SM_DBG5(("smsatModeSelect6: disable write cache\n"));
13955         /* sends SET FEATURES */
13956         fis->h.fisType        = 0x27;                   /* Reg host to device */
13957         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13958 
13959         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
13960         fis->h.features       = 0x82;                   /* disable write cache */
13961         fis->d.lbaLow         = 0;                      /* */
13962         fis->d.lbaMid         = 0;                      /* */
13963         fis->d.lbaHigh        = 0;                      /* */
13964         fis->d.device         = 0;                      /* */
13965         fis->d.lbaLowExp      = 0;                      /* */
13966         fis->d.lbaMidExp      = 0;                      /* */
13967         fis->d.lbaHighExp     = 0;                      /* */
13968         fis->d.featuresExp    = 0;                      /* */
13969         fis->d.sectorCount    = 0;                      /* */
13970         fis->d.sectorCountExp = 0;                      /* */
13971         fis->d.reserved4      = 0;
13972         fis->d.control        = 0;                      /* FIS HOB bit clear */
13973         fis->d.reserved5      = 0;
13974 
13975         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13976 
13977         /* Initialize CB for SATA completion.
13978          */
13979         satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
13980 
13981         /*
13982          * Prepare SGL and send FIS to LL layer.
13983          */
13984         satIOContext->reqType = agRequestType;       /* Save it */
13985 
13986         status = smsataLLIOStart( smRoot,
13987                                   smIORequest,
13988                                   smDeviceHandle,
13989                                   smScsiRequest,
13990                                   satIOContext);
13991         return status;
13992       }
13993       else
13994       {
13995         SM_DBG5(("smsatModeSelect6: enable write cache\n"));
13996         /* sends SET FEATURES */
13997         fis->h.fisType        = 0x27;                   /* Reg host to device */
13998         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13999 
14000         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
14001         fis->h.features       = 0x02;                   /* enable write cache */
14002         fis->d.lbaLow         = 0;                      /* */
14003         fis->d.lbaMid         = 0;                      /* */
14004         fis->d.lbaHigh        = 0;                      /* */
14005         fis->d.device         = 0;                      /* */
14006         fis->d.lbaLowExp      = 0;                      /* */
14007         fis->d.lbaMidExp      = 0;                      /* */
14008         fis->d.lbaHighExp     = 0;                      /* */
14009         fis->d.featuresExp    = 0;                      /* */
14010         fis->d.sectorCount    = 0;                      /* */
14011         fis->d.sectorCountExp = 0;                      /* */
14012         fis->d.reserved4      = 0;
14013         fis->d.control        = 0;                      /* FIS HOB bit clear */
14014         fis->d.reserved5      = 0;
14015 
14016         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14017 
14018         /* Initialize CB for SATA completion.
14019          */
14020         satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14021 
14022         /*
14023          * Prepare SGL and send FIS to LL layer.
14024          */
14025         satIOContext->reqType = agRequestType;       /* Save it */
14026 
14027         status = smsataLLIOStart( smRoot,
14028                                   smIORequest,
14029                                   smDeviceHandle,
14030                                   smScsiRequest,
14031                                   satIOContext);
14032         return status;
14033 
14034       }
14035     }
14036     break;
14037   case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
14038     SM_DBG5(("smsatModeSelect6: Informational Exception Control mode page\n"));
14039 
14040     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
14041          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
14042          )
14043     {
14044       SM_DBG1(("smsatModeSelect6: return check condition!!! \n"));
14045 
14046       smsatSetSensePayload( pSense,
14047                             SCSI_SNSKEY_ILLEGAL_REQUEST,
14048                             0,
14049                             SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14050                             satIOContext);
14051 
14052       /*smEnqueueIO(smRoot, satIOContext);*/
14053 
14054       tdsmIOCompletedCB( smRoot,
14055                          smIORequest,
14056                          smIOSuccess,
14057                          SCSI_STAT_CHECK_CONDITION,
14058                          satIOContext->pSmSenseData,
14059                          satIOContext->interruptContext );
14060       return SM_RC_SUCCESS;
14061     }
14062     else
14063     {
14064       /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
14065       if ( !(pLogPage[StartingIndex + 2] & 0x08) )
14066       {
14067         SM_DBG5(("smsatModeSelect6: enable information exceptions reporting\n"));
14068         /* sends SMART ENABLE OPERATIONS */
14069         fis->h.fisType        = 0x27;                   /* Reg host to device */
14070         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14071 
14072         fis->h.command        = SAT_SMART;              /* 0xB0 */
14073         fis->h.features       = SAT_SMART_ENABLE_OPERATIONS;       /* enable */
14074         fis->d.lbaLow         = 0;                      /* */
14075         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14076         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14077         fis->d.device         = 0;                      /* */
14078         fis->d.lbaLowExp      = 0;                      /* */
14079         fis->d.lbaMidExp      = 0;                      /* */
14080         fis->d.lbaHighExp     = 0;                      /* */
14081         fis->d.featuresExp    = 0;                      /* */
14082         fis->d.sectorCount    = 0;                      /* */
14083         fis->d.sectorCountExp = 0;                      /* */
14084         fis->d.reserved4      = 0;
14085         fis->d.control        = 0;                      /* FIS HOB bit clear */
14086         fis->d.reserved5      = 0;
14087 
14088         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14089 
14090         /* Initialize CB for SATA completion.
14091          */
14092         satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14093 
14094         /*
14095          * Prepare SGL and send FIS to LL layer.
14096          */
14097         satIOContext->reqType = agRequestType;       /* Save it */
14098 
14099         status = smsataLLIOStart( smRoot,
14100                                   smIORequest,
14101                                   smDeviceHandle,
14102                                   smScsiRequest,
14103                                   satIOContext);
14104         return status;
14105       }
14106       else
14107       {
14108         SM_DBG5(("smsatModeSelect6: disable information exceptions reporting\n"));
14109         /* sends SMART DISABLE OPERATIONS */
14110         fis->h.fisType        = 0x27;                   /* Reg host to device */
14111         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14112 
14113         fis->h.command        = SAT_SMART;              /* 0xB0 */
14114         fis->h.features       = SAT_SMART_DISABLE_OPERATIONS; /* disable */
14115         fis->d.lbaLow         = 0;                      /* */
14116         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14117         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14118         fis->d.device         = 0;                      /* */
14119         fis->d.lbaLowExp      = 0;                      /* */
14120         fis->d.lbaMidExp      = 0;                      /* */
14121         fis->d.lbaHighExp     = 0;                      /* */
14122         fis->d.featuresExp    = 0;                      /* */
14123         fis->d.sectorCount    = 0;                      /* */
14124         fis->d.sectorCountExp = 0;                      /* */
14125         fis->d.reserved4      = 0;
14126         fis->d.control        = 0;                      /* FIS HOB bit clear */
14127         fis->d.reserved5      = 0;
14128 
14129         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14130 
14131         /* Initialize CB for SATA completion.
14132          */
14133         satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14134 
14135         /*
14136          * Prepare SGL and send FIS to LL layer.
14137          */
14138         satIOContext->reqType = agRequestType;       /* Save it */
14139 
14140         status = smsataLLIOStart( smRoot,
14141                                   smIORequest,
14142                                   smDeviceHandle,
14143                                   smScsiRequest,
14144                                   satIOContext);
14145         return status;
14146 
14147       }
14148     }
14149     break;
14150   default:
14151     SM_DBG1(("smsatModeSelect6: Error unknown page code 0x%x!!!\n", pLogPage[12]));
14152     smsatSetSensePayload( pSense,
14153                           SCSI_SNSKEY_NO_SENSE,
14154                           0,
14155                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14156                           satIOContext);
14157 
14158     /*smEnqueueIO(smRoot, satIOContext);*/
14159 
14160     tdsmIOCompletedCB( smRoot,
14161                        smIORequest,
14162                        smIOSuccess,
14163                        SCSI_STAT_CHECK_CONDITION,
14164                        satIOContext->pSmSenseData,
14165                        satIOContext->interruptContext );
14166     return SM_RC_SUCCESS;
14167   }
14168 }
14169 
14170 
14171 osGLOBAL bit32
14172 smsatModeSelect10(
14173                   smRoot_t                  *smRoot,
14174                   smIORequest_t             *smIORequest,
14175                   smDeviceHandle_t          *smDeviceHandle,
14176                   smScsiInitiatorRequest_t  *smScsiRequest,
14177                   smSatIOContext_t            *satIOContext
14178                  )
14179 {
14180   bit32                     status;
14181   bit32                     agRequestType;
14182   smDeviceData_t            *pSatDevData;
14183   smScsiRspSense_t          *pSense;
14184   smIniScsiCmnd_t           *scsiCmnd;
14185   agsaFisRegHostToDevice_t  *fis;
14186   bit8                      *pLogPage;    /* Log Page data buffer */
14187   bit16                     BlkDescLen = 0;     /* Block Descriptor Length */
14188   bit32                     StartingIndex = 0;
14189   bit8                      PageCode = 0;
14190   bit32                     chkCnd = agFALSE;
14191   bit32                     parameterListLen = 0;
14192 
14193   pSense        = satIOContext->pSense;
14194   pSatDevData   = satIOContext->pSatDevData;
14195   scsiCmnd      = &smScsiRequest->scsiCmnd;
14196   fis           = satIOContext->pFis;
14197   pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
14198 
14199   SM_DBG5(("smsatModeSelect10: start\n"));
14200 
14201   /* checking CONTROL */
14202   /* NACA == 1 or LINK == 1*/
14203   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
14204   {
14205     smsatSetSensePayload( pSense,
14206                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14207                           0,
14208                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14209                           satIOContext);
14210 
14211     /*smEnqueueIO(smRoot, satIOContext);*/
14212 
14213     tdsmIOCompletedCB( smRoot,
14214                        smIORequest,
14215                        smIOSuccess,
14216                        SCSI_STAT_CHECK_CONDITION,
14217                        satIOContext->pSmSenseData,
14218                        satIOContext->interruptContext );
14219 
14220     SM_DBG1(("smsatModeSelect10: return control!!!\n"));
14221     return SM_RC_SUCCESS;
14222   }
14223 
14224   /* checking PF bit */
14225   if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
14226   {
14227     smsatSetSensePayload( pSense,
14228                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14229                           0,
14230                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14231                           satIOContext);
14232 
14233     /*smEnqueueIO(smRoot, satIOContext);*/
14234 
14235     tdsmIOCompletedCB( smRoot,
14236                        smIORequest,
14237                        smIOSuccess,
14238                        SCSI_STAT_CHECK_CONDITION,
14239                        satIOContext->pSmSenseData,
14240                        satIOContext->interruptContext );
14241 
14242     SM_DBG1(("smsatModeSelect10: PF bit check!!!\n"));
14243     return SM_RC_SUCCESS;
14244   }
14245 
14246   parameterListLen = ((scsiCmnd->cdb[7]) << 8) + scsiCmnd->cdb[8];
14247   parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength);
14248   if ((0 == parameterListLen) || (agNULL == pLogPage))
14249   {
14250     tdsmIOCompletedCB( smRoot,
14251                        smIORequest,
14252                        smIOSuccess,
14253                        SCSI_STAT_GOOD,
14254                        agNULL,
14255                        satIOContext->interruptContext);
14256     return SM_RC_SUCCESS;
14257   }
14258 
14259   BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]);
14260 
14261   /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/
14262   if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
14263   {
14264     /* mode parameter block descriptor exists and length is 8 byte */
14265     PageCode = (bit8)(pLogPage[16] & 0x3F);   /* page code and index is 8 + 8 */
14266     StartingIndex = 16;
14267   }
14268   else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
14269   {
14270     /* mode parameter block descriptor exists and length is 16 byte */
14271     PageCode = (bit8)(pLogPage[24] & 0x3F);   /* page code and index is 8 + 16 */
14272     StartingIndex = 24;
14273   }
14274   else if (BlkDescLen == 0)
14275   {
14276     PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */
14277     StartingIndex = 8;
14278     /*smEnqueueIO(smRoot, satIOContext);*/
14279 
14280     tdsmIOCompletedCB( smRoot,
14281                        smIORequest,
14282                        smIOSuccess,
14283                        SCSI_STAT_GOOD,
14284                        agNULL,
14285                        satIOContext->interruptContext);
14286     return SM_RC_SUCCESS;
14287   }
14288   else
14289   {
14290     SM_DBG1(("smsatModeSelect10: return mode parameter block descriptor 0x%x!!!\n",  BlkDescLen));
14291     /* no more than one mode parameter block descriptor shall be supported */
14292     smsatSetSensePayload( pSense,
14293                           SCSI_SNSKEY_NO_SENSE,
14294                           0,
14295                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14296                           satIOContext);
14297 
14298     /*smEnqueueIO(smRoot, satIOContext);*/
14299 
14300     tdsmIOCompletedCB( smRoot,
14301                        smIORequest,
14302                        smIOSuccess,
14303                        SCSI_STAT_CHECK_CONDITION,
14304                        satIOContext->pSmSenseData,
14305                        satIOContext->interruptContext );
14306     return SM_RC_SUCCESS;
14307   }
14308   /*
14309     for debugging only
14310   */
14311   if (StartingIndex == 8)
14312   {
14313     smhexdump("startingindex 8", (bit8 *)pLogPage, 8);
14314   }
14315   else if(StartingIndex == 16)
14316   {
14317     if (PageCode == MODESELECT_CACHING)
14318     {
14319       smhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
14320     }
14321     else
14322     {
14323       smhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
14324     }
14325   }
14326   else
14327   {
14328     if (PageCode == MODESELECT_CACHING)
14329     {
14330       smhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
14331     }
14332     else
14333     {
14334       smhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
14335     }
14336   }
14337   switch (PageCode) /* page code */
14338   {
14339   case MODESELECT_CONTROL_PAGE:
14340     SM_DBG5(("smsatModeSelect10: Control mode page\n"));
14341     /*
14342       compare pLogPage to expected value (SAT Table 65, p67)
14343       If not match, return check condition
14344      */
14345     if ( pLogPage[StartingIndex+1] != 0x0A ||
14346          pLogPage[StartingIndex+2] != 0x02 ||
14347          (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
14348          (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
14349          (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
14350          (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
14351          (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
14352 
14353          (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
14354          (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
14355          (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
14356          (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
14357 
14358          pLogPage[StartingIndex+8] != 0xFF ||
14359          pLogPage[StartingIndex+9] != 0xFF ||
14360          pLogPage[StartingIndex+10] != 0x00 ||
14361          pLogPage[StartingIndex+11] != 0x00
14362        )
14363     {
14364       chkCnd = agTRUE;
14365     }
14366     if (chkCnd == agTRUE)
14367     {
14368       smsatSetSensePayload( pSense,
14369                             SCSI_SNSKEY_ILLEGAL_REQUEST,
14370                             0,
14371                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14372                             satIOContext);
14373 
14374       /*smEnqueueIO(smRoot, satIOContext);*/
14375 
14376       tdsmIOCompletedCB( smRoot,
14377                          smIORequest,
14378                          smIOSuccess,
14379                          SCSI_STAT_CHECK_CONDITION,
14380                          satIOContext->pSmSenseData,
14381                          satIOContext->interruptContext );
14382 
14383       SM_DBG1(("smsatModeSelect10: unexpected values!!!\n"));
14384     }
14385     else
14386     {
14387       /*smEnqueueIO(smRoot, satIOContext);*/
14388 
14389       tdsmIOCompletedCB( smRoot,
14390                          smIORequest,
14391                          smIOSuccess,
14392                          SCSI_STAT_GOOD,
14393                          agNULL,
14394                          satIOContext->interruptContext);
14395     }
14396     return SM_RC_SUCCESS;
14397     break;
14398   case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
14399     SM_DBG5(("smsatModeSelect10: Read-Write Error Recovery mode page\n"));
14400 
14401     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) ||
14402          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) ||
14403          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) ||
14404          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) ||
14405          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) ||
14406          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) ||
14407          (pLogPage[StartingIndex + 10]) ||
14408          (pLogPage[StartingIndex + 11])
14409          )
14410     {
14411       SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14412 
14413       smsatSetSensePayload( pSense,
14414                             SCSI_SNSKEY_ILLEGAL_REQUEST,
14415                             0,
14416                             SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14417                             satIOContext);
14418 
14419       /*smEnqueueIO(smRoot, satIOContext);*/
14420 
14421       tdsmIOCompletedCB( smRoot,
14422                          smIORequest,
14423                          smIOSuccess,
14424                          SCSI_STAT_CHECK_CONDITION,
14425                          satIOContext->pSmSenseData,
14426                          satIOContext->interruptContext );
14427       return SM_RC_SUCCESS;
14428     }
14429     else
14430     {
14431       SM_DBG2(("smsatModeSelect10: return GOOD \n"));
14432       /*smEnqueueIO(smRoot, satIOContext);*/
14433 
14434       tdsmIOCompletedCB( smRoot,
14435                          smIORequest,
14436                          smIOSuccess,
14437                          SCSI_STAT_GOOD,
14438                          agNULL,
14439                          satIOContext->interruptContext);
14440       return SM_RC_SUCCESS;
14441     }
14442 
14443     break;
14444   case MODESELECT_CACHING:
14445     /* SAT rev8 Table67, p69*/
14446     SM_DBG5(("smsatModeSelect10: Caching mode page\n"));
14447     if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
14448          (pLogPage[StartingIndex + 3]) ||
14449          (pLogPage[StartingIndex + 4]) ||
14450          (pLogPage[StartingIndex + 5]) ||
14451          (pLogPage[StartingIndex + 6]) ||
14452          (pLogPage[StartingIndex + 7]) ||
14453          (pLogPage[StartingIndex + 8]) ||
14454          (pLogPage[StartingIndex + 9]) ||
14455          (pLogPage[StartingIndex + 10]) ||
14456          (pLogPage[StartingIndex + 11]) ||
14457 
14458          (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
14459          (pLogPage[StartingIndex + 13]) ||
14460          (pLogPage[StartingIndex + 14]) ||
14461          (pLogPage[StartingIndex + 15])
14462          )
14463     {
14464       SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14465 
14466       smsatSetSensePayload( pSense,
14467                             SCSI_SNSKEY_ILLEGAL_REQUEST,
14468                             0,
14469                             SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14470                             satIOContext);
14471 
14472       /*smEnqueueIO(smRoot, satIOContext);*/
14473 
14474       tdsmIOCompletedCB( smRoot,
14475                          smIORequest,
14476                          smIOSuccess,
14477                          SCSI_STAT_CHECK_CONDITION,
14478                          satIOContext->pSmSenseData,
14479                          satIOContext->interruptContext );
14480       return SM_RC_SUCCESS;
14481 
14482     }
14483     else
14484     {
14485       /* sends ATA SET FEATURES based on WCE bit */
14486       if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
14487       {
14488         SM_DBG5(("smsatModeSelect10: disable write cache\n"));
14489         /* sends SET FEATURES */
14490         fis->h.fisType        = 0x27;                   /* Reg host to device */
14491         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14492 
14493         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
14494         fis->h.features       = 0x82;                   /* disable write cache */
14495         fis->d.lbaLow         = 0;                      /* */
14496         fis->d.lbaMid         = 0;                      /* */
14497         fis->d.lbaHigh        = 0;                      /* */
14498         fis->d.device         = 0;                      /* */
14499         fis->d.lbaLowExp      = 0;                      /* */
14500         fis->d.lbaMidExp      = 0;                      /* */
14501         fis->d.lbaHighExp     = 0;                      /* */
14502         fis->d.featuresExp    = 0;                      /* */
14503         fis->d.sectorCount    = 0;                      /* */
14504         fis->d.sectorCountExp = 0;                      /* */
14505         fis->d.reserved4      = 0;
14506         fis->d.control        = 0;                      /* FIS HOB bit clear */
14507         fis->d.reserved5      = 0;
14508 
14509         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14510 
14511         /* Initialize CB for SATA completion.
14512          */
14513         satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14514 
14515         /*
14516          * Prepare SGL and send FIS to LL layer.
14517          */
14518         satIOContext->reqType = agRequestType;       /* Save it */
14519 
14520         status = smsataLLIOStart( smRoot,
14521                                   smIORequest,
14522                                   smDeviceHandle,
14523                                   smScsiRequest,
14524                                   satIOContext);
14525         return status;
14526       }
14527       else
14528       {
14529         SM_DBG5(("smsatModeSelect10: enable write cache\n"));
14530         /* sends SET FEATURES */
14531         fis->h.fisType        = 0x27;                   /* Reg host to device */
14532         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14533 
14534         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
14535         fis->h.features       = 0x02;                   /* enable write cache */
14536         fis->d.lbaLow         = 0;                      /* */
14537         fis->d.lbaMid         = 0;                      /* */
14538         fis->d.lbaHigh        = 0;                      /* */
14539         fis->d.device         = 0;                      /* */
14540         fis->d.lbaLowExp      = 0;                      /* */
14541         fis->d.lbaMidExp      = 0;                      /* */
14542         fis->d.lbaHighExp     = 0;                      /* */
14543         fis->d.featuresExp    = 0;                      /* */
14544         fis->d.sectorCount    = 0;                      /* */
14545         fis->d.sectorCountExp = 0;                      /* */
14546         fis->d.reserved4      = 0;
14547         fis->d.control        = 0;                      /* FIS HOB bit clear */
14548         fis->d.reserved5      = 0;
14549 
14550         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14551 
14552         /* Initialize CB for SATA completion.
14553          */
14554         satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14555 
14556         /*
14557          * Prepare SGL and send FIS to LL layer.
14558          */
14559         satIOContext->reqType = agRequestType;       /* Save it */
14560 
14561         status = smsataLLIOStart( smRoot,
14562                                   smIORequest,
14563                                   smDeviceHandle,
14564                                   smScsiRequest,
14565                                   satIOContext);
14566         return status;
14567 
14568       }
14569     }
14570     break;
14571   case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
14572     SM_DBG5(("smsatModeSelect10: Informational Exception Control mode page\n"));
14573 
14574     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
14575          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
14576          )
14577     {
14578       SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14579 
14580       smsatSetSensePayload( pSense,
14581                             SCSI_SNSKEY_ILLEGAL_REQUEST,
14582                             0,
14583                             SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14584                             satIOContext);
14585 
14586       /*smEnqueueIO(smRoot, satIOContext);*/
14587 
14588       tdsmIOCompletedCB( smRoot,
14589                          smIORequest,
14590                          smIOSuccess,
14591                          SCSI_STAT_CHECK_CONDITION,
14592                          satIOContext->pSmSenseData,
14593                          satIOContext->interruptContext );
14594       return SM_RC_SUCCESS;
14595     }
14596     else
14597     {
14598       /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
14599       if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
14600       {
14601         SM_DBG5(("smsatModeSelect10: enable information exceptions reporting\n"));
14602         /* sends SMART ENABLE OPERATIONS */
14603         fis->h.fisType        = 0x27;                   /* Reg host to device */
14604         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14605 
14606         fis->h.command        = SAT_SMART;              /* 0xB0 */
14607         fis->h.features       = SAT_SMART_ENABLE_OPERATIONS;       /* enable */
14608         fis->d.lbaLow         = 0;                      /* */
14609         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14610         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14611         fis->d.device         = 0;                      /* */
14612         fis->d.lbaLowExp      = 0;                      /* */
14613         fis->d.lbaMidExp      = 0;                      /* */
14614         fis->d.lbaHighExp     = 0;                      /* */
14615         fis->d.featuresExp    = 0;                      /* */
14616         fis->d.sectorCount    = 0;                      /* */
14617         fis->d.sectorCountExp = 0;                      /* */
14618         fis->d.reserved4      = 0;
14619         fis->d.control        = 0;                      /* FIS HOB bit clear */
14620         fis->d.reserved5      = 0;
14621 
14622         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14623 
14624         /* Initialize CB for SATA completion.
14625          */
14626         satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14627 
14628         /*
14629          * Prepare SGL and send FIS to LL layer.
14630          */
14631         satIOContext->reqType = agRequestType;       /* Save it */
14632 
14633         status = smsataLLIOStart( smRoot,
14634                                   smIORequest,
14635                                   smDeviceHandle,
14636                                   smScsiRequest,
14637                                   satIOContext);
14638         return status;
14639       }
14640       else
14641       {
14642         SM_DBG5(("smsatModeSelect10: disable information exceptions reporting\n"));
14643         /* sends SMART DISABLE OPERATIONS */
14644         fis->h.fisType        = 0x27;                   /* Reg host to device */
14645         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14646 
14647         fis->h.command        = SAT_SMART;              /* 0xB0 */
14648         fis->h.features       = SAT_SMART_DISABLE_OPERATIONS; /* disable */
14649         fis->d.lbaLow         = 0;                      /* */
14650         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
14651         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
14652         fis->d.device         = 0;                      /* */
14653         fis->d.lbaLowExp      = 0;                      /* */
14654         fis->d.lbaMidExp      = 0;                      /* */
14655         fis->d.lbaHighExp     = 0;                      /* */
14656         fis->d.featuresExp    = 0;                      /* */
14657         fis->d.sectorCount    = 0;                      /* */
14658         fis->d.sectorCountExp = 0;                      /* */
14659         fis->d.reserved4      = 0;
14660         fis->d.control        = 0;                      /* FIS HOB bit clear */
14661         fis->d.reserved5      = 0;
14662 
14663         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14664 
14665         /* Initialize CB for SATA completion.
14666          */
14667         satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14668 
14669         /*
14670          * Prepare SGL and send FIS to LL layer.
14671          */
14672         satIOContext->reqType = agRequestType;       /* Save it */
14673 
14674         status = smsataLLIOStart( smRoot,
14675                                   smIORequest,
14676                                   smDeviceHandle,
14677                                   smScsiRequest,
14678                                   satIOContext);
14679         return status;
14680 
14681       }
14682     }
14683     break;
14684   default:
14685     SM_DBG1(("smsatModeSelect10: Error unknown page code 0x%x!!!\n", pLogPage[12]));
14686     smsatSetSensePayload( pSense,
14687                           SCSI_SNSKEY_NO_SENSE,
14688                           0,
14689                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14690                           satIOContext);
14691 
14692     /*smEnqueueIO(smRoot, satIOContext);*/
14693 
14694     tdsmIOCompletedCB( smRoot,
14695                        smIORequest,
14696                        smIOSuccess,
14697                        SCSI_STAT_CHECK_CONDITION,
14698                        satIOContext->pSmSenseData,
14699                        satIOContext->interruptContext );
14700     return SM_RC_SUCCESS;
14701   }
14702 }
14703 
14704 osGLOBAL bit32
14705 smsatSynchronizeCache10(
14706                         smRoot_t                  *smRoot,
14707                         smIORequest_t             *smIORequest,
14708                         smDeviceHandle_t          *smDeviceHandle,
14709                         smScsiInitiatorRequest_t  *smScsiRequest,
14710                         smSatIOContext_t            *satIOContext
14711                        )
14712 {
14713   bit32                     status;
14714   bit32                     agRequestType;
14715   smDeviceData_t            *pSatDevData;
14716   smScsiRspSense_t          *pSense;
14717   smIniScsiCmnd_t           *scsiCmnd;
14718   agsaFisRegHostToDevice_t  *fis;
14719 
14720   pSense        = satIOContext->pSense;
14721   pSatDevData   = satIOContext->pSatDevData;
14722   scsiCmnd      = &smScsiRequest->scsiCmnd;
14723   fis           = satIOContext->pFis;
14724 
14725   SM_DBG5(("smsatSynchronizeCache10: start\n"));
14726 
14727   /* checking CONTROL */
14728   /* NACA == 1 or LINK == 1*/
14729   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
14730   {
14731     smsatSetSensePayload( pSense,
14732                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14733                           0,
14734                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14735                           satIOContext);
14736 
14737     /*smEnqueueIO(smRoot, satIOContext);*/
14738 
14739     tdsmIOCompletedCB( smRoot,
14740                        smIORequest,
14741                        smIOSuccess,
14742                        SCSI_STAT_CHECK_CONDITION,
14743                        satIOContext->pSmSenseData,
14744                        satIOContext->interruptContext );
14745 
14746     SM_DBG1(("smsatSynchronizeCache10: return control!!!\n"));
14747     return SM_RC_SUCCESS;
14748   }
14749 
14750   /* checking IMMED bit */
14751   if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
14752   {
14753     SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n"));
14754 
14755     /* return GOOD status first here */
14756     tdsmIOCompletedCB( smRoot,
14757                        smIORequest,
14758                        smIOSuccess,
14759                        SCSI_STAT_GOOD,
14760                        agNULL,
14761                        satIOContext->interruptContext);
14762   }
14763 
14764   /* sends FLUSH CACHE or FLUSH CACHE EXT */
14765   if (pSatDevData->sat48BitSupport == agTRUE)
14766   {
14767     SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n"));
14768     /* FLUSH CACHE EXT */
14769     fis->h.fisType        = 0x27;                   /* Reg host to device */
14770     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14771 
14772     fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
14773     fis->h.features       = 0;                      /* FIS reserve */
14774     fis->d.featuresExp    = 0;                      /* FIS reserve */
14775     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14776     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
14777     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14778     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
14779     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14780     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14781     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14782     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14783     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14784     fis->d.control        = 0;                      /* FIS HOB bit clear */
14785     fis->d.reserved4      = 0;
14786     fis->d.reserved5      = 0;
14787 
14788   }
14789   else
14790   {
14791     SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n"));
14792     /* FLUSH CACHE */
14793     fis->h.fisType        = 0x27;                   /* Reg host to device */
14794     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14795 
14796     fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
14797     fis->h.features       = 0;                      /* FIS features NA       */
14798     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14799     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14800     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14801     fis->d.lbaLowExp      = 0;
14802     fis->d.lbaMidExp      = 0;
14803     fis->d.lbaHighExp     = 0;
14804     fis->d.featuresExp    = 0;
14805     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14806     fis->d.sectorCountExp = 0;
14807     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14808     fis->d.control        = 0;                      /* FIS HOB bit clear */
14809     fis->d.reserved4      = 0;
14810     fis->d.reserved5      = 0;
14811 
14812   }
14813 
14814   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14815 
14816   /* Initialize CB for SATA completion.
14817    */
14818   satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB;
14819 
14820   /*
14821    * Prepare SGL and send FIS to LL layer.
14822    */
14823   satIOContext->reqType = agRequestType;       /* Save it */
14824 
14825   status = smsataLLIOStart( smRoot,
14826                             smIORequest,
14827                             smDeviceHandle,
14828                             smScsiRequest,
14829                             satIOContext);
14830 
14831 
14832   return (status);
14833 }
14834 
14835 osGLOBAL bit32
14836 smsatSynchronizeCache16(
14837                         smRoot_t                  *smRoot,
14838                         smIORequest_t             *smIORequest,
14839                         smDeviceHandle_t          *smDeviceHandle,
14840                         smScsiInitiatorRequest_t  *smScsiRequest,
14841                         smSatIOContext_t            *satIOContext
14842                        )
14843 {
14844   bit32                     status;
14845   bit32                     agRequestType;
14846   smDeviceData_t            *pSatDevData;
14847   smScsiRspSense_t          *pSense;
14848   smIniScsiCmnd_t           *scsiCmnd;
14849   agsaFisRegHostToDevice_t  *fis;
14850 
14851   pSense        = satIOContext->pSense;
14852   pSatDevData   = satIOContext->pSatDevData;
14853   scsiCmnd      = &smScsiRequest->scsiCmnd;
14854   fis           = satIOContext->pFis;
14855 
14856   SM_DBG5(("smsatSynchronizeCache10: start\n"));
14857 
14858   /* checking CONTROL */
14859   /* NACA == 1 or LINK == 1*/
14860   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
14861   {
14862     smsatSetSensePayload( pSense,
14863                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14864                           0,
14865                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14866                           satIOContext);
14867 
14868     /*smEnqueueIO(smRoot, satIOContext);*/
14869 
14870     tdsmIOCompletedCB( smRoot,
14871                        smIORequest,
14872                        smIOSuccess,
14873                        SCSI_STAT_CHECK_CONDITION,
14874                        satIOContext->pSmSenseData,
14875                        satIOContext->interruptContext );
14876 
14877     SM_DBG1(("smsatSynchronizeCache10: return control!!!\n"));
14878     return SM_RC_SUCCESS;
14879   }
14880 
14881 
14882   /* checking IMMED bit */
14883   if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
14884   {
14885     SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n"));
14886 
14887     /* return GOOD status first here */
14888     tdsmIOCompletedCB( smRoot,
14889                        smIORequest,
14890                        smIOSuccess,
14891                        SCSI_STAT_GOOD,
14892                        agNULL,
14893                        satIOContext->interruptContext);
14894   }
14895 
14896   /* sends FLUSH CACHE or FLUSH CACHE EXT */
14897   if (pSatDevData->sat48BitSupport == agTRUE)
14898   {
14899     SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n"));
14900     /* FLUSH CACHE EXT */
14901     fis->h.fisType        = 0x27;                   /* Reg host to device */
14902     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14903 
14904     fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
14905     fis->h.features       = 0;                      /* FIS reserve */
14906     fis->d.featuresExp    = 0;                      /* FIS reserve */
14907     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14908     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
14909     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14910     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
14911     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14912     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14913     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14914     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14915     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14916     fis->d.control        = 0;                      /* FIS HOB bit clear */
14917     fis->d.reserved4      = 0;
14918     fis->d.reserved5      = 0;
14919 
14920   }
14921   else
14922   {
14923     SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n"));
14924     /* FLUSH CACHE */
14925     fis->h.fisType        = 0x27;                   /* Reg host to device */
14926     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14927 
14928     fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
14929     fis->h.features       = 0;                      /* FIS features NA       */
14930     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
14931     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
14932     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
14933     fis->d.lbaLowExp      = 0;
14934     fis->d.lbaMidExp      = 0;
14935     fis->d.lbaHighExp     = 0;
14936     fis->d.featuresExp    = 0;
14937     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
14938     fis->d.sectorCountExp = 0;
14939     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
14940     fis->d.control        = 0;                      /* FIS HOB bit clear */
14941     fis->d.reserved4      = 0;
14942     fis->d.reserved5      = 0;
14943 
14944   }
14945 
14946   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14947 
14948   /* Initialize CB for SATA completion.
14949    */
14950   satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB;
14951 
14952   /*
14953    * Prepare SGL and send FIS to LL layer.
14954    */
14955   satIOContext->reqType = agRequestType;       /* Save it */
14956 
14957   status = smsataLLIOStart( smRoot,
14958                             smIORequest,
14959                             smDeviceHandle,
14960                             smScsiRequest,
14961                             satIOContext);
14962 
14963 
14964   return (status);
14965 }
14966 
14967 osGLOBAL bit32
14968 smsatWriteAndVerify10(
14969                       smRoot_t                  *smRoot,
14970                       smIORequest_t             *smIORequest,
14971                       smDeviceHandle_t          *smDeviceHandle,
14972                       smScsiInitiatorRequest_t  *smScsiRequest,
14973                       smSatIOContext_t            *satIOContext
14974                      )
14975 {
14976   /*
14977     combination of write10 and verify10
14978   */
14979 
14980   bit32                     status;
14981   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14982   smDeviceData_t            *pSatDevData;
14983   smScsiRspSense_t          *pSense;
14984   smIniScsiCmnd_t           *scsiCmnd;
14985   agsaFisRegHostToDevice_t  *fis;
14986   bit32                     lba = 0;
14987   bit32                     tl = 0;
14988   bit32                     LoopNum = 1;
14989   bit8                      LBA[8];
14990   bit8                      TL[8];
14991   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
14992 
14993   pSense        = satIOContext->pSense;
14994   pSatDevData   = satIOContext->pSatDevData;
14995   scsiCmnd      = &smScsiRequest->scsiCmnd;
14996   fis           = satIOContext->pFis;
14997 
14998   SM_DBG5(("smsatWriteAndVerify10: start\n"));
14999 
15000   /* checking BYTCHK bit */
15001   if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15002   {
15003     smsatSetSensePayload( pSense,
15004                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15005                           0,
15006                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15007                           satIOContext);
15008 
15009     /*smEnqueueIO(smRoot, satIOContext);*/
15010 
15011     tdsmIOCompletedCB( smRoot,
15012                        smIORequest,
15013                        smIOSuccess,
15014                        SCSI_STAT_CHECK_CONDITION,
15015                        satIOContext->pSmSenseData,
15016                        satIOContext->interruptContext );
15017 
15018     SM_DBG1(("smsatWriteAndVerify10: BYTCHK bit checking!!!\n"));
15019     return SM_RC_SUCCESS;
15020   }
15021 
15022 
15023   /* checking CONTROL */
15024   /* NACA == 1 or LINK == 1*/
15025   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
15026   {
15027     smsatSetSensePayload( pSense,
15028                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15029                           0,
15030                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15031                           satIOContext);
15032 
15033     /*smEnqueueIO(smRoot, satIOContext);*/
15034 
15035     tdsmIOCompletedCB( smRoot,
15036                        smIORequest,
15037                        smIOSuccess,
15038                        SCSI_STAT_CHECK_CONDITION,
15039                        satIOContext->pSmSenseData,
15040                        satIOContext->interruptContext );
15041 
15042     SM_DBG1(("smsatWriteAndVerify10: return control!!!\n"));
15043     return SM_RC_SUCCESS;
15044   }
15045 
15046   sm_memset(LBA, 0, sizeof(LBA));
15047   sm_memset(TL, 0, sizeof(TL));
15048 
15049   /* do not use memcpy due to indexing in LBA and TL */
15050   LBA[0] = 0;                  /* MSB */
15051   LBA[1] = 0;
15052   LBA[2] = 0;
15053   LBA[3] = 0;
15054   LBA[4] = scsiCmnd->cdb[2];
15055   LBA[5] = scsiCmnd->cdb[3];
15056   LBA[6] = scsiCmnd->cdb[4];
15057   LBA[7] = scsiCmnd->cdb[5];   /* LSB */
15058 
15059   TL[0] = 0;
15060   TL[1] = 0;
15061   TL[2] = 0;
15062   TL[3] = 0;
15063   TL[4] = 0;
15064   TL[5] = 0;
15065   TL[6] = scsiCmnd->cdb[7];
15066   TL[7] = scsiCmnd->cdb[8];    /* LSB */
15067 
15068 
15069   /* cbd10; computing LBA and transfer length */
15070   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
15071     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
15072   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
15073 
15074 
15075   /* Table 34, 9.1, p 46 */
15076   /*
15077     note: As of 2/10/2006, no support for DMA QUEUED
15078    */
15079 
15080   /*
15081     Table 34, 9.1, p 46, b
15082     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15083     return check condition
15084   */
15085   if (pSatDevData->satNCQ != agTRUE &&
15086       pSatDevData->sat48BitSupport != agTRUE
15087       )
15088   {
15089     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15090     if (AllChk)
15091     {
15092       SM_DBG1(("smsatWriteAndVerify10: return LBA out of range!!!\n"));
15093       smsatSetSensePayload( pSense,
15094                             SCSI_SNSKEY_ILLEGAL_REQUEST,
15095                             0,
15096                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15097                             satIOContext);
15098 
15099       /*smEnqueueIO(smRoot, satIOContext);*/
15100 
15101       tdsmIOCompletedCB( smRoot,
15102                          smIORequest,
15103                          smIOSuccess,
15104                          SCSI_STAT_CHECK_CONDITION,
15105                          satIOContext->pSmSenseData,
15106                          satIOContext->interruptContext );
15107 
15108     return SM_RC_SUCCESS;
15109     }
15110   }
15111   else
15112   {
15113     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15114     if (AllChk)
15115     {
15116       SM_DBG1(("smsatWriteAndVerify10: return LBA out of range, EXT!!!\n"));
15117       smsatSetSensePayload( pSense,
15118                             SCSI_SNSKEY_ILLEGAL_REQUEST,
15119                             0,
15120                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15121                             satIOContext);
15122 
15123       /*smEnqueueIO(smRoot, satIOContext);*/
15124 
15125       tdsmIOCompletedCB( smRoot,
15126                          smIORequest,
15127                          smIOSuccess,
15128                          SCSI_STAT_CHECK_CONDITION,
15129                          satIOContext->pSmSenseData,
15130                          satIOContext->interruptContext );
15131 
15132       return SM_RC_SUCCESS;
15133     }
15134   }
15135 
15136 
15137   /* case 1 and 2 */
15138     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15139     {
15140       /* case 2 */
15141       /* WRITE DMA*/
15142       /* can't fit the transfer length */
15143       SM_DBG5(("smsatWriteAndVerify10: case 2\n"));
15144       fis->h.fisType        = 0x27;                   /* Reg host to device */
15145       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15146       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
15147       fis->h.features       = 0;                      /* FIS reserve */
15148       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15149       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15150       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15151 
15152       /* FIS LBA mode set LBA (27:24) */
15153       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15154 
15155       fis->d.lbaLowExp      = 0;
15156       fis->d.lbaMidExp      = 0;
15157       fis->d.lbaHighExp     = 0;
15158       fis->d.featuresExp    = 0;
15159       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15160       fis->d.sectorCountExp = 0;
15161       fis->d.reserved4      = 0;
15162       fis->d.control        = 0;                      /* FIS HOB bit clear */
15163       fis->d.reserved5      = 0;
15164 
15165       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15166       satIOContext->ATACmd = SAT_WRITE_DMA;
15167     }
15168     else
15169     {
15170       /* case 1 */
15171       /* WRITE MULTIPLE or WRITE SECTOR(S) */
15172       /* WRITE SECTORS for easier implemetation */
15173       /* can't fit the transfer length */
15174       SM_DBG5(("smsatWriteAndVerify10: case 1\n"));
15175       fis->h.fisType        = 0x27;                   /* Reg host to device */
15176       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15177       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
15178       fis->h.features       = 0;                      /* FIS reserve */
15179       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15180       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15181       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15182 
15183       /* FIS LBA mode set LBA (27:24) */
15184       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15185 
15186       fis->d.lbaLowExp      = 0;
15187       fis->d.lbaMidExp      = 0;
15188       fis->d.lbaHighExp     = 0;
15189       fis->d.featuresExp    = 0;
15190       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15191       fis->d.sectorCountExp = 0;
15192       fis->d.reserved4      = 0;
15193       fis->d.control        = 0;                      /* FIS HOB bit clear */
15194       fis->d.reserved5      = 0;
15195 
15196       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15197       satIOContext->ATACmd = SAT_WRITE_SECTORS;
15198 
15199   }
15200 
15201   /* case 3 and 4 */
15202   if (pSatDevData->sat48BitSupport == agTRUE)
15203   {
15204     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15205     {
15206       /* case 3 */
15207       /* WRITE DMA EXT or WRITE DMA FUA EXT */
15208       SM_DBG5(("smsatWriteAndVerify10: case 3\n"));
15209       fis->h.fisType        = 0x27;                   /* Reg host to device */
15210       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15211 
15212       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15213       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
15214 
15215       fis->h.features       = 0;                      /* FIS reserve */
15216       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15217       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15218       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15219       fis->d.device         = 0x40;                   /* FIS LBA mode set */
15220       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15221       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15222       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15223       fis->d.featuresExp    = 0;                      /* FIS reserve */
15224       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15225       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15226       fis->d.reserved4      = 0;
15227       fis->d.control        = 0;                      /* FIS HOB bit clear */
15228       fis->d.reserved5      = 0;
15229 
15230       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15231       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15232     }
15233     else
15234     {
15235       /* case 4 */
15236       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15237       /* WRITE SECTORS EXT for easier implemetation */
15238       SM_DBG5(("smsatWriteAndVerify10: case 4\n"));
15239       fis->h.fisType        = 0x27;                   /* Reg host to device */
15240       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15241       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
15242 
15243       fis->h.features       = 0;                      /* FIS reserve */
15244       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15245       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15246       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15247       fis->d.device         = 0x40;                   /* FIS LBA mode set */
15248       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15249       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15250       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15251       fis->d.featuresExp    = 0;                      /* FIS reserve */
15252       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15253       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15254       fis->d.reserved4      = 0;
15255       fis->d.control        = 0;                      /* FIS HOB bit clear */
15256       fis->d.reserved5      = 0;
15257 
15258       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15259       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15260     }
15261   }
15262   /* case 5 */
15263   if (pSatDevData->satNCQ == agTRUE)
15264   {
15265     /* WRITE FPDMA QUEUED */
15266     if (pSatDevData->sat48BitSupport != agTRUE)
15267     {
15268       SM_DBG1(("smsatWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
15269       smsatSetSensePayload( pSense,
15270                             SCSI_SNSKEY_ILLEGAL_REQUEST,
15271                             0,
15272                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15273                             satIOContext);
15274 
15275       /*smEnqueueIO(smRoot, satIOContext);*/
15276 
15277       tdsmIOCompletedCB( smRoot,
15278                          smIORequest,
15279                          smIOSuccess,
15280                          SCSI_STAT_CHECK_CONDITION,
15281                          satIOContext->pSmSenseData,
15282                          satIOContext->interruptContext );
15283       return SM_RC_SUCCESS;
15284     }
15285     SM_DBG5(("smsatWriteAndVerify10: case 5\n"));
15286 
15287     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15288 
15289     fis->h.fisType        = 0x27;                   /* Reg host to device */
15290     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15291     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15292     fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15293     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15294     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15295     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15296 
15297     /* Check FUA bit */
15298     if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
15299       fis->d.device       = 0xC0;                   /* FIS FUA set */
15300     else
15301       fis->d.device       = 0x40;                   /* FIS FUA clear */
15302 
15303     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15304     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15305     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15306     fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15307     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15308     fis->d.sectorCountExp = 0;
15309     fis->d.reserved4      = 0;
15310     fis->d.control        = 0;                      /* FIS HOB bit clear */
15311     fis->d.reserved5      = 0;
15312 
15313     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15314     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15315   }
15316 
15317   satIOContext->currentLBA = lba;
15318   satIOContext->OrgTL = tl;
15319 
15320   /*
15321     computing number of loop and remainder for tl
15322     0xFF in case not ext
15323     0xFFFF in case EXT
15324   */
15325   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15326   {
15327     LoopNum = smsatComputeLoopNum(tl, 0xFF);
15328   }
15329   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15330            fis->h.command == SAT_WRITE_DMA_EXT     ||
15331            fis->h.command == SAT_WRITE_DMA_FUA_EXT
15332            )
15333   {
15334     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15335     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15336   }
15337   else
15338   {
15339     /* SAT_WRITE_FPDMA_QUEUED */
15340     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15341   }
15342 
15343   satIOContext->LoopNum = LoopNum;
15344 
15345 
15346   if (LoopNum == 1)
15347   {
15348     SM_DBG5(("smsatWriteAndVerify10: NON CHAINED data\n"));
15349     /* Initialize CB for SATA completion.
15350      */
15351     satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
15352   }
15353   else
15354   {
15355     SM_DBG1(("smsatWriteAndVerify10: CHAINED data!!!\n"));
15356     /* re-setting tl */
15357     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15358     {
15359        fis->d.sectorCount    = 0xFF;
15360     }
15361     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15362              fis->h.command == SAT_WRITE_DMA_EXT ||
15363              fis->h.command == SAT_WRITE_DMA_FUA_EXT
15364              )
15365     {
15366       fis->d.sectorCount    = 0xFF;
15367       fis->d.sectorCountExp = 0xFF;
15368     }
15369     else
15370     {
15371       /* SAT_WRITE_FPDMA_QUEUED */
15372       fis->h.features       = 0xFF;
15373       fis->d.featuresExp    = 0xFF;
15374     }
15375 
15376     /* Initialize CB for SATA completion.
15377      */
15378     satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
15379   }
15380 
15381 
15382   /*
15383    * Prepare SGL and send FIS to LL layer.
15384    */
15385   satIOContext->reqType = agRequestType;       /* Save it */
15386 
15387   status = smsataLLIOStart( smRoot,
15388                             smIORequest,
15389                             smDeviceHandle,
15390                             smScsiRequest,
15391                             satIOContext);
15392   return (status);
15393 
15394 }
15395 
15396 osGLOBAL bit32
15397 smsatWriteAndVerify12(
15398                       smRoot_t                  *smRoot,
15399                       smIORequest_t             *smIORequest,
15400                       smDeviceHandle_t          *smDeviceHandle,
15401                       smScsiInitiatorRequest_t  *smScsiRequest,
15402                       smSatIOContext_t            *satIOContext
15403                      )
15404 {
15405   /*
15406     combination of write12 and verify12
15407     temp: since write12 is not support (due to internal checking), no support
15408   */
15409   bit32                     status;
15410   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15411   smDeviceData_t            *pSatDevData;
15412   smScsiRspSense_t          *pSense;
15413   smIniScsiCmnd_t           *scsiCmnd;
15414   agsaFisRegHostToDevice_t  *fis;
15415   bit32                     lba = 0;
15416   bit32                     tl = 0;
15417   bit32                     LoopNum = 1;
15418   bit8                      LBA[8];
15419   bit8                      TL[8];
15420   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
15421 
15422   pSense        = satIOContext->pSense;
15423   pSatDevData   = satIOContext->pSatDevData;
15424   scsiCmnd      = &smScsiRequest->scsiCmnd;
15425   fis           = satIOContext->pFis;
15426 
15427   SM_DBG5(("smsatWriteAndVerify12: start\n"));
15428 
15429   /* checking BYTCHK bit */
15430   if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15431   {
15432     smsatSetSensePayload( pSense,
15433                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15434                           0,
15435                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15436                           satIOContext);
15437 
15438     /*smEnqueueIO(smRoot, satIOContext);*/
15439 
15440     tdsmIOCompletedCB( smRoot,
15441                        smIORequest,
15442                        smIOSuccess,
15443                        SCSI_STAT_CHECK_CONDITION,
15444                        satIOContext->pSmSenseData,
15445                        satIOContext->interruptContext );
15446 
15447     SM_DBG1(("smsatWriteAndVerify12: BYTCHK bit checking!!!\n"));
15448     return SM_RC_SUCCESS;
15449   }
15450 
15451   /* checking CONTROL */
15452   /* NACA == 1 or LINK == 1*/
15453   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
15454   {
15455     smsatSetSensePayload( pSense,
15456                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15457                           0,
15458                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15459                           satIOContext);
15460 
15461     /*smEnqueueIO(smRoot, satIOContext);*/
15462 
15463     tdsmIOCompletedCB( smRoot,
15464                        smIORequest,
15465                        smIOSuccess,
15466                        SCSI_STAT_CHECK_CONDITION,
15467                        satIOContext->pSmSenseData,
15468                        satIOContext->interruptContext );
15469 
15470     SM_DBG1(("smsatWriteAndVerify12: return control!!!\n"));
15471     return SM_RC_SUCCESS;
15472   }
15473 
15474   sm_memset(LBA, 0, sizeof(LBA));
15475   sm_memset(TL, 0, sizeof(TL));
15476 
15477   /* do not use memcpy due to indexing in LBA and TL */
15478   LBA[0] = 0;                  /* MSB */
15479   LBA[1] = 0;
15480   LBA[2] = 0;
15481   LBA[3] = 0;
15482   LBA[4] = scsiCmnd->cdb[2];
15483   LBA[5] = scsiCmnd->cdb[3];
15484   LBA[6] = scsiCmnd->cdb[4];
15485   LBA[7] = scsiCmnd->cdb[5];   /* LSB */
15486 
15487   TL[0] = 0;                   /* MSB */
15488   TL[1] = 0;
15489   TL[2] = 0;
15490   TL[3] = 0;
15491   TL[4] = scsiCmnd->cdb[6];
15492   TL[5] = scsiCmnd->cdb[7];
15493   TL[6] = scsiCmnd->cdb[8];
15494   TL[7] = scsiCmnd->cdb[9];    /* LSB */
15495 
15496 
15497   lba = smsatComputeCDB12LBA(satIOContext);
15498   tl = smsatComputeCDB12TL(satIOContext);
15499 
15500 
15501   /* Table 34, 9.1, p 46 */
15502   /*
15503     note: As of 2/10/2006, no support for DMA QUEUED
15504    */
15505 
15506   /*
15507     Table 34, 9.1, p 46, b
15508     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15509     return check condition
15510   */
15511   if (pSatDevData->satNCQ != agTRUE &&
15512       pSatDevData->sat48BitSupport != agTRUE
15513       )
15514   {
15515     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15516     if (AllChk)
15517     {
15518 
15519       /*smEnqueueIO(smRoot, satIOContext);*/
15520 
15521 
15522       SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, not EXT!!!\n"));
15523 
15524       smsatSetSensePayload( pSense,
15525                             SCSI_SNSKEY_ILLEGAL_REQUEST,
15526                             0,
15527                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15528                             satIOContext);
15529 
15530       /*smEnqueueIO(smRoot, satIOContext);*/
15531 
15532       tdsmIOCompletedCB( smRoot,
15533                          smIORequest,
15534                          smIOSuccess,
15535                          SCSI_STAT_CHECK_CONDITION,
15536                          satIOContext->pSmSenseData,
15537                          satIOContext->interruptContext );
15538 
15539     return SM_RC_SUCCESS;
15540     }
15541   }
15542   else
15543   {
15544     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15545     if (AllChk)
15546   {
15547       SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, EXT!!!\n"));
15548       smsatSetSensePayload( pSense,
15549                             SCSI_SNSKEY_ILLEGAL_REQUEST,
15550                             0,
15551                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15552                             satIOContext);
15553       tdsmIOCompletedCB( smRoot,
15554                          smIORequest,
15555                          smIOSuccess,
15556                          SCSI_STAT_CHECK_CONDITION,
15557                          satIOContext->pSmSenseData,
15558                          satIOContext->interruptContext );
15559     return SM_RC_SUCCESS;
15560     }
15561   }
15562     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15563     {
15564       /* case 2 */
15565       /* WRITE DMA*/
15566       /* In case that we can't fit the transfer length, we loop */
15567       SM_DBG5(("smsatWriteAndVerify12: case 2\n"));
15568       fis->h.fisType        = 0x27;                   /* Reg host to device */
15569       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15570       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
15571       fis->h.features       = 0;                      /* FIS reserve */
15572       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15573       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15574       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15575 
15576       /* FIS LBA mode set LBA (27:24) */
15577       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15578 
15579       fis->d.lbaLowExp      = 0;
15580       fis->d.lbaMidExp      = 0;
15581       fis->d.lbaHighExp     = 0;
15582       fis->d.featuresExp    = 0;
15583       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15584       fis->d.sectorCountExp = 0;
15585       fis->d.reserved4      = 0;
15586       fis->d.control        = 0;                      /* FIS HOB bit clear */
15587       fis->d.reserved5      = 0;
15588 
15589       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15590       satIOContext->ATACmd = SAT_WRITE_DMA;
15591     }
15592     else
15593     {
15594       /* case 1 */
15595       /* WRITE MULTIPLE or WRITE SECTOR(S) */
15596       /* WRITE SECTORS for easier implemetation */
15597       /* In case that we can't fit the transfer length, we loop */
15598       SM_DBG5(("smsatWriteAndVerify12: case 1\n"));
15599       fis->h.fisType        = 0x27;                   /* Reg host to device */
15600       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15601       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
15602       fis->h.features       = 0;                      /* FIS reserve */
15603       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15604       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15605       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15606 
15607       /* FIS LBA mode set LBA (27:24) */
15608       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15609 
15610       fis->d.lbaLowExp      = 0;
15611       fis->d.lbaMidExp      = 0;
15612       fis->d.lbaHighExp     = 0;
15613       fis->d.featuresExp    = 0;
15614       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15615       fis->d.sectorCountExp = 0;
15616       fis->d.reserved4      = 0;
15617       fis->d.control        = 0;                      /* FIS HOB bit clear */
15618       fis->d.reserved5      = 0;
15619 
15620       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15621       satIOContext->ATACmd = SAT_WRITE_SECTORS;
15622   }
15623 
15624   /* case 3 and 4 */
15625   if (pSatDevData->sat48BitSupport == agTRUE)
15626   {
15627     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15628     {
15629       /* case 3 */
15630       /* WRITE DMA EXT or WRITE DMA FUA EXT */
15631       SM_DBG5(("smsatWriteAndVerify12: case 3\n"));
15632       fis->h.fisType        = 0x27;                   /* Reg host to device */
15633       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15634 
15635       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15636       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
15637 
15638       fis->h.features       = 0;                      /* FIS reserve */
15639       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15640       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15641       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15642       fis->d.device         = 0x40;                   /* FIS LBA mode set */
15643       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15644       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15645       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15646       fis->d.featuresExp    = 0;                      /* FIS reserve */
15647       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15648       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
15649       fis->d.reserved4      = 0;
15650       fis->d.control        = 0;                      /* FIS HOB bit clear */
15651       fis->d.reserved5      = 0;
15652 
15653       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15654       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15655     }
15656     else
15657     {
15658       /* case 4 */
15659       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15660       /* WRITE SECTORS EXT for easier implemetation */
15661       SM_DBG5(("smsatWriteAndVerify12: case 4\n"));
15662       fis->h.fisType        = 0x27;                   /* Reg host to device */
15663       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15664       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
15665 
15666       fis->h.features       = 0;                      /* FIS reserve */
15667       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15668       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15669       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15670       fis->d.device         = 0x40;                   /* FIS LBA mode set */
15671       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15672       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15673       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15674       fis->d.featuresExp    = 0;                      /* FIS reserve */
15675       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15676       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
15677       fis->d.reserved4      = 0;
15678       fis->d.control        = 0;                      /* FIS HOB bit clear */
15679       fis->d.reserved5      = 0;
15680 
15681       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15682       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15683     }
15684   }
15685 
15686   /* case 5 */
15687   if (pSatDevData->satNCQ == agTRUE)
15688   {
15689     /* WRITE FPDMA QUEUED */
15690     if (pSatDevData->sat48BitSupport != agTRUE)
15691     {
15692       SM_DBG1(("smsatWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support!!!\n"));
15693       smsatSetSensePayload( pSense,
15694                             SCSI_SNSKEY_ILLEGAL_REQUEST,
15695                             0,
15696                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15697                             satIOContext);
15698 
15699       /*smEnqueueIO(smRoot, satIOContext);*/
15700 
15701       tdsmIOCompletedCB( smRoot,
15702                          smIORequest,
15703                          smIOSuccess,
15704                          SCSI_STAT_CHECK_CONDITION,
15705                          satIOContext->pSmSenseData,
15706                          satIOContext->interruptContext );
15707       return SM_RC_SUCCESS;
15708     }
15709     SM_DBG6(("smsatWriteAndVerify12: case 5\n"));
15710 
15711     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15712 
15713     fis->h.fisType        = 0x27;                   /* Reg host to device */
15714     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15715     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15716     fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
15717     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15718     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15719     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15720 
15721     /* Check FUA bit */
15722     if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
15723       fis->d.device       = 0xC0;                   /* FIS FUA set */
15724     else
15725       fis->d.device       = 0x40;                   /* FIS FUA clear */
15726 
15727     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15728     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15729     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15730     fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
15731     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15732     fis->d.sectorCountExp = 0;
15733     fis->d.reserved4      = 0;
15734     fis->d.control        = 0;                      /* FIS HOB bit clear */
15735     fis->d.reserved5      = 0;
15736 
15737     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15738     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15739   }
15740 
15741   satIOContext->currentLBA = lba;
15742 //  satIOContext->OrgLBA = lba;
15743   satIOContext->OrgTL = tl;
15744 
15745   /*
15746     computing number of loop and remainder for tl
15747     0xFF in case not ext
15748     0xFFFF in case EXT
15749   */
15750   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15751   {
15752     LoopNum = smsatComputeLoopNum(tl, 0xFF);
15753   }
15754   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15755            fis->h.command == SAT_WRITE_DMA_EXT     ||
15756            fis->h.command == SAT_WRITE_DMA_FUA_EXT
15757            )
15758   {
15759     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15760     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15761   }
15762   else
15763   {
15764     /* SAT_WRITE_FPDMA_QUEUEDK */
15765     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15766   }
15767 
15768   satIOContext->LoopNum = LoopNum;
15769   satIOContext->LoopNum2 = LoopNum;
15770 
15771 
15772   if (LoopNum == 1)
15773   {
15774     SM_DBG5(("smsatWriteAndVerify12: NON CHAINED data\n"));
15775     /* Initialize CB for SATA completion.
15776      */
15777     satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
15778   }
15779   else
15780   {
15781     SM_DBG1(("smsatWriteAndVerify12: CHAINED data!!!\n"));
15782     /* re-setting tl */
15783     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15784     {
15785        fis->d.sectorCount    = 0xFF;
15786     }
15787     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15788              fis->h.command == SAT_WRITE_DMA_EXT ||
15789              fis->h.command == SAT_WRITE_DMA_FUA_EXT
15790              )
15791     {
15792       fis->d.sectorCount    = 0xFF;
15793       fis->d.sectorCountExp = 0xFF;
15794     }
15795     else
15796     {
15797       /* SAT_WRITE_FPDMA_QUEUED */
15798       fis->h.features       = 0xFF;
15799       fis->d.featuresExp    = 0xFF;
15800     }
15801 
15802     /* Initialize CB for SATA completion.
15803      */
15804     satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
15805   }
15806 
15807 
15808   /*
15809    * Prepare SGL and send FIS to LL layer.
15810    */
15811   satIOContext->reqType = agRequestType;       /* Save it */
15812 
15813   status = smsataLLIOStart( smRoot,
15814                             smIORequest,
15815                             smDeviceHandle,
15816                             smScsiRequest,
15817                             satIOContext);
15818   return (status);
15819 }
15820 
15821 osGLOBAL bit32
15822 smsatWriteAndVerify16(
15823                       smRoot_t                  *smRoot,
15824                       smIORequest_t             *smIORequest,
15825                       smDeviceHandle_t          *smDeviceHandle,
15826                       smScsiInitiatorRequest_t  *smScsiRequest,
15827                       smSatIOContext_t            *satIOContext
15828                      )
15829 {
15830   /*
15831     combination of write16 and verify16
15832     since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support
15833   */
15834   bit32                     status;
15835   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15836   smDeviceData_t            *pSatDevData;
15837   smScsiRspSense_t          *pSense;
15838   smIniScsiCmnd_t           *scsiCmnd;
15839   agsaFisRegHostToDevice_t  *fis;
15840   bit32                     lba = 0;
15841   bit32                     tl = 0;
15842   bit32                     LoopNum = 1;
15843   bit8                      LBA[8];
15844   bit8                      TL[8];
15845   bit32                     AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
15846 
15847   pSense        = satIOContext->pSense;
15848   pSatDevData   = satIOContext->pSatDevData;
15849   scsiCmnd      = &smScsiRequest->scsiCmnd;
15850   fis           = satIOContext->pFis;
15851 
15852   SM_DBG5(("smsatWriteAndVerify16: start\n"));
15853 
15854   /* checking BYTCHK bit */
15855   if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15856   {
15857     smsatSetSensePayload( pSense,
15858                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15859                           0,
15860                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15861                           satIOContext);
15862 
15863     /*smEnqueueIO(smRoot, satIOContext);*/
15864 
15865     tdsmIOCompletedCB( smRoot,
15866                        smIORequest,
15867                        smIOSuccess,
15868                        SCSI_STAT_CHECK_CONDITION,
15869                        satIOContext->pSmSenseData,
15870                        satIOContext->interruptContext );
15871 
15872     SM_DBG1(("smsatWriteAndVerify16: BYTCHK bit checking!!!\n"));
15873     return SM_RC_SUCCESS;
15874   }
15875 
15876 
15877   /* checking CONTROL */
15878   /* NACA == 1 or LINK == 1*/
15879   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
15880   {
15881     smsatSetSensePayload( pSense,
15882                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15883                           0,
15884                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15885                           satIOContext);
15886 
15887     /*smEnqueueIO(smRoot, satIOContext);*/
15888 
15889     tdsmIOCompletedCB( smRoot,
15890                        smIORequest,
15891                        smIOSuccess,
15892                        SCSI_STAT_CHECK_CONDITION,
15893                        satIOContext->pSmSenseData,
15894                        satIOContext->interruptContext );
15895 
15896     SM_DBG1(("smsatWriteAndVerify16: return control!!!\n"));
15897     return SM_RC_SUCCESS;
15898   }
15899 
15900   sm_memset(LBA, 0, sizeof(LBA));
15901   sm_memset(TL, 0, sizeof(TL));
15902 
15903 
15904   /* do not use memcpy due to indexing in LBA and TL */
15905   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
15906   LBA[1] = scsiCmnd->cdb[3];
15907   LBA[2] = scsiCmnd->cdb[4];
15908   LBA[3] = scsiCmnd->cdb[5];
15909   LBA[4] = scsiCmnd->cdb[6];
15910   LBA[5] = scsiCmnd->cdb[7];
15911   LBA[6] = scsiCmnd->cdb[8];
15912   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
15913 
15914   TL[0] = 0;
15915   TL[1] = 0;
15916   TL[2] = 0;
15917   TL[3] = 0;
15918   TL[4] = scsiCmnd->cdb[10];   /* MSB */
15919   TL[5] = scsiCmnd->cdb[11];
15920   TL[6] = scsiCmnd->cdb[12];
15921   TL[7] = scsiCmnd->cdb[13];   /* LSB */
15922 
15923 
15924 
15925   lba = smsatComputeCDB16LBA(satIOContext);
15926   tl = smsatComputeCDB16TL(satIOContext);
15927 
15928 
15929   /* Table 34, 9.1, p 46 */
15930   /*
15931     note: As of 2/10/2006, no support for DMA QUEUED
15932   */
15933 
15934   /*
15935     Table 34, 9.1, p 46, b
15936     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15937     return check condition
15938   */
15939   if (pSatDevData->satNCQ != agTRUE &&
15940      pSatDevData->sat48BitSupport != agTRUE
15941      )
15942   {
15943     AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15944     if (AllChk)
15945     {
15946       SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, not EXT!!!\n"));
15947       smsatSetSensePayload( pSense,
15948                             SCSI_SNSKEY_ILLEGAL_REQUEST,
15949                             0,
15950                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15951                             satIOContext);
15952 
15953       /*smEnqueueIO(smRoot, satIOContext);*/
15954 
15955       tdsmIOCompletedCB( smRoot,
15956                          smIORequest,
15957                          smIOSuccess,
15958                          SCSI_STAT_CHECK_CONDITION,
15959                          satIOContext->pSmSenseData,
15960                          satIOContext->interruptContext );
15961 
15962       return SM_RC_SUCCESS;
15963     }
15964   }
15965   else
15966   {
15967     AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15968     if (AllChk)
15969     {
15970       SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, EXT!!!\n"));
15971       smsatSetSensePayload( pSense,
15972                             SCSI_SNSKEY_ILLEGAL_REQUEST,
15973                             0,
15974                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15975                             satIOContext);
15976 
15977       /*smEnqueueIO(smRoot, satIOContext);*/
15978 
15979       tdsmIOCompletedCB( smRoot,
15980                          smIORequest,
15981                          smIOSuccess,
15982                          SCSI_STAT_CHECK_CONDITION,
15983                          satIOContext->pSmSenseData,
15984                          satIOContext->interruptContext );
15985 
15986       return SM_RC_SUCCESS;
15987     }
15988   }
15989 
15990 
15991   /* case 1 and 2 */
15992     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15993     {
15994       /* case 2 */
15995       /* WRITE DMA*/
15996       /* In case that we can't fit the transfer length, we loop */
15997       SM_DBG5(("smsatWriteAndVerify16: case 2\n"));
15998       fis->h.fisType        = 0x27;                   /* Reg host to device */
15999       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16000       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
16001       fis->h.features       = 0;                      /* FIS reserve */
16002       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16003       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16004       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16005 
16006       /* FIS LBA mode set LBA (27:24) */
16007       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
16008 
16009       fis->d.lbaLowExp      = 0;
16010       fis->d.lbaMidExp      = 0;
16011       fis->d.lbaHighExp     = 0;
16012       fis->d.featuresExp    = 0;
16013       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16014       fis->d.sectorCountExp = 0;
16015       fis->d.reserved4      = 0;
16016       fis->d.control        = 0;                      /* FIS HOB bit clear */
16017       fis->d.reserved5      = 0;
16018 
16019       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16020       satIOContext->ATACmd = SAT_WRITE_DMA;
16021     }
16022     else
16023     {
16024       /* case 1 */
16025       /* WRITE MULTIPLE or WRITE SECTOR(S) */
16026       /* WRITE SECTORS for easier implemetation */
16027       /* In case that we can't fit the transfer length, we loop */
16028       SM_DBG5(("smsatWriteAndVerify16: case 1\n"));
16029       fis->h.fisType        = 0x27;                   /* Reg host to device */
16030       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16031       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
16032       fis->h.features       = 0;                      /* FIS reserve */
16033       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16034       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16035       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16036 
16037       /* FIS LBA mode set LBA (27:24) */
16038       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
16039 
16040       fis->d.lbaLowExp      = 0;
16041       fis->d.lbaMidExp      = 0;
16042       fis->d.lbaHighExp     = 0;
16043       fis->d.featuresExp    = 0;
16044       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16045       fis->d.sectorCountExp = 0;
16046       fis->d.reserved4      = 0;
16047       fis->d.control        = 0;                      /* FIS HOB bit clear */
16048       fis->d.reserved5      = 0;
16049 
16050       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16051       satIOContext->ATACmd = SAT_WRITE_SECTORS;
16052   }
16053 
16054   /* case 3 and 4 */
16055   if (pSatDevData->sat48BitSupport == agTRUE)
16056   {
16057     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16058     {
16059       /* case 3 */
16060       /* WRITE DMA EXT or WRITE DMA FUA EXT */
16061       SM_DBG5(("smsatWriteAndVerify16: case 3\n"));
16062       fis->h.fisType        = 0x27;                   /* Reg host to device */
16063       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16064 
16065       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
16066       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
16067 
16068       fis->h.features       = 0;                      /* FIS reserve */
16069       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16070       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16071       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16072       fis->d.device         = 0x40;                   /* FIS LBA mode set */
16073       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
16074       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
16075       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
16076       fis->d.featuresExp    = 0;                      /* FIS reserve */
16077       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16078       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
16079       fis->d.reserved4      = 0;
16080       fis->d.control        = 0;                      /* FIS HOB bit clear */
16081       fis->d.reserved5      = 0;
16082 
16083       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16084       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
16085     }
16086     else
16087     {
16088       /* case 4 */
16089       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
16090       /* WRITE SECTORS EXT for easier implemetation */
16091       SM_DBG5(("smsatWriteAndVerify16: case 4\n"));
16092       fis->h.fisType        = 0x27;                   /* Reg host to device */
16093       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16094       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
16095 
16096       fis->h.features       = 0;                      /* FIS reserve */
16097       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16098       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16099       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16100       fis->d.device         = 0x40;                   /* FIS LBA mode set */
16101       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
16102       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
16103       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
16104       fis->d.featuresExp    = 0;                      /* FIS reserve */
16105       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16106       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
16107       fis->d.reserved4      = 0;
16108       fis->d.control        = 0;                      /* FIS HOB bit clear */
16109       fis->d.reserved5      = 0;
16110 
16111       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16112       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
16113     }
16114   }
16115 
16116   /* case 5 */
16117   if (pSatDevData->satNCQ == agTRUE)
16118   {
16119     /* WRITE FPDMA QUEUED */
16120     if (pSatDevData->sat48BitSupport != agTRUE)
16121     {
16122       SM_DBG1(("smsatWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
16123       smsatSetSensePayload( pSense,
16124                             SCSI_SNSKEY_ILLEGAL_REQUEST,
16125                             0,
16126                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16127                             satIOContext);
16128 
16129       /*smEnqueueIO(smRoot, satIOContext);*/
16130 
16131       tdsmIOCompletedCB( smRoot,
16132                          smIORequest,
16133                          smIOSuccess,
16134                          SCSI_STAT_CHECK_CONDITION,
16135                          satIOContext->pSmSenseData,
16136                          satIOContext->interruptContext );
16137       return SM_RC_SUCCESS;
16138     }
16139     SM_DBG6(("smsatWriteAndVerify16: case 5\n"));
16140 
16141     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
16142 
16143     fis->h.fisType        = 0x27;                   /* Reg host to device */
16144     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16145     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
16146     fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
16147     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
16148     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
16149     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
16150 
16151     /* Check FUA bit */
16152     if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
16153       fis->d.device       = 0xC0;                   /* FIS FUA set */
16154     else
16155       fis->d.device       = 0x40;                   /* FIS FUA clear */
16156 
16157     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
16158     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
16159     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
16160     fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
16161     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
16162     fis->d.sectorCountExp = 0;
16163     fis->d.reserved4      = 0;
16164     fis->d.control        = 0;                      /* FIS HOB bit clear */
16165     fis->d.reserved5      = 0;
16166 
16167     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
16168     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
16169   }
16170 
16171   satIOContext->currentLBA = lba;
16172   satIOContext->OrgTL = tl;
16173 
16174   /*
16175     computing number of loop and remainder for tl
16176     0xFF in case not ext
16177     0xFFFF in case EXT
16178   */
16179   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
16180   {
16181     LoopNum = smsatComputeLoopNum(tl, 0xFF);
16182   }
16183   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
16184            fis->h.command == SAT_WRITE_DMA_EXT     ||
16185            fis->h.command == SAT_WRITE_DMA_FUA_EXT
16186            )
16187   {
16188     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
16189     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
16190   }
16191   else
16192   {
16193     /* SAT_WRITE_FPDMA_QUEUEDK */
16194     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
16195   }
16196 
16197   satIOContext->LoopNum = LoopNum;
16198 
16199 
16200   if (LoopNum == 1)
16201   {
16202     SM_DBG5(("smsatWriteAndVerify16: NON CHAINED data\n"));
16203     /* Initialize CB for SATA completion.
16204      */
16205     satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
16206   }
16207   else
16208   {
16209     SM_DBG1(("smsatWriteAndVerify16: CHAINED data!!!\n"));
16210     /* re-setting tl */
16211     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
16212     {
16213        fis->d.sectorCount    = 0xFF;
16214     }
16215     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
16216              fis->h.command == SAT_WRITE_DMA_EXT ||
16217              fis->h.command == SAT_WRITE_DMA_FUA_EXT
16218              )
16219     {
16220       fis->d.sectorCount    = 0xFF;
16221       fis->d.sectorCountExp = 0xFF;
16222     }
16223     else
16224     {
16225       /* SAT_WRITE_FPDMA_QUEUED */
16226       fis->h.features       = 0xFF;
16227       fis->d.featuresExp    = 0xFF;
16228     }
16229 
16230     /* Initialize CB for SATA completion.
16231      */
16232     satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
16233   }
16234 
16235 
16236   /*
16237    * Prepare SGL and send FIS to LL layer.
16238    */
16239   satIOContext->reqType = agRequestType;       /* Save it */
16240 
16241   status = smsataLLIOStart( smRoot,
16242                             smIORequest,
16243                             smDeviceHandle,
16244                             smScsiRequest,
16245                             satIOContext);
16246   return (status);
16247 }
16248 
16249 osGLOBAL bit32
16250 smsatReadMediaSerialNumber(
16251                            smRoot_t                  *smRoot,
16252                            smIORequest_t             *smIORequest,
16253                            smDeviceHandle_t          *smDeviceHandle,
16254                            smScsiInitiatorRequest_t  *smScsiRequest,
16255                            smSatIOContext_t            *satIOContext
16256                           )
16257 {
16258   bit32                     status;
16259   bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16260   smDeviceData_t            *pSatDevData;
16261   smScsiRspSense_t          *pSense;
16262   smIniScsiCmnd_t           *scsiCmnd;
16263   agsaFisRegHostToDevice_t  *fis;
16264   agsaSATAIdentifyData_t    *pSATAIdData;
16265   bit8                      *pSerialNumber;
16266   bit8                      MediaSerialNumber[64] = {0};
16267   bit32                     allocationLen = 0;
16268 
16269   pSense        = satIOContext->pSense;
16270   pSatDevData   = satIOContext->pSatDevData;
16271   scsiCmnd      = &smScsiRequest->scsiCmnd;
16272   fis           = satIOContext->pFis;
16273   pSATAIdData   = &(pSatDevData->satIdentifyData);
16274   pSerialNumber = (bit8 *) smScsiRequest->sglVirtualAddr;
16275 
16276   SM_DBG5(("smsatReadMediaSerialNumber: start\n"));
16277 
16278   /* checking CONTROL */
16279   /* NACA == 1 or LINK == 1*/
16280   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
16281   {
16282     smsatSetSensePayload( pSense,
16283                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16284                           0,
16285                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16286                           satIOContext);
16287 
16288     /*smEnqueueIO(smRoot, satIOContext);*/
16289 
16290     tdsmIOCompletedCB( smRoot,
16291                        smIORequest,
16292                        smIOSuccess,
16293                        SCSI_STAT_CHECK_CONDITION,
16294                        satIOContext->pSmSenseData,
16295                        satIOContext->interruptContext );
16296 
16297     SM_DBG1(("smsatReadMediaSerialNumber: return control!!!\n"));
16298     return SM_RC_SUCCESS;
16299   }
16300 
16301   allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
16302                   (((bit32)scsiCmnd->cdb[7]) << 16) |
16303                   (((bit32)scsiCmnd->cdb[8]) << 8 ) |
16304                   (((bit32)scsiCmnd->cdb[9]));
16305   allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
16306   if (allocationLen == 4)
16307   {
16308     if (pSATAIdData->commandSetFeatureDefault & 0x4)
16309     {
16310       SM_DBG1(("smsatReadMediaSerialNumber: Media serial number returning only length!!!\n"));
16311       /* SPC-3 6.16 p192; filling in length */
16312       MediaSerialNumber[0] = 0;
16313       MediaSerialNumber[1] = 0;
16314       MediaSerialNumber[2] = 0;
16315       MediaSerialNumber[3] = 0x3C;
16316     }
16317     else
16318     {
16319       /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/
16320       MediaSerialNumber[0] = 0;
16321       MediaSerialNumber[1] = 0;
16322       MediaSerialNumber[2] = 0x1;
16323       MediaSerialNumber[3] = 0xfc;
16324     }
16325 
16326     sm_memcpy(pSerialNumber, MediaSerialNumber, 4);
16327     /*smEnqueueIO(smRoot, satIOContext);*/
16328 
16329     tdsmIOCompletedCB( smRoot,
16330                        smIORequest,
16331                        smIOSuccess,
16332                        SCSI_STAT_GOOD,
16333                        agNULL,
16334                        satIOContext->interruptContext);
16335 
16336     return SM_RC_SUCCESS;
16337   }
16338 
16339   if ( pSatDevData->IDDeviceValid == agTRUE)
16340   {
16341     if (pSATAIdData->commandSetFeatureDefault & 0x4)
16342     {
16343       /* word87 bit2 Media serial number is valid */
16344       /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/
16345 #ifdef LOG_ENABLE
16346       smhexdump("ID smsatReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
16347 #endif
16348       /* SPC-3 6.16 p192; filling in length */
16349       MediaSerialNumber[0] = 0;
16350       MediaSerialNumber[1] = 0;
16351       MediaSerialNumber[2] = 0;
16352       MediaSerialNumber[3] = 0x3C;
16353       sm_memcpy(&MediaSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
16354 #ifdef LOG_ENABLE
16355       smhexdump("smsatReadMediaSerialNumber", (bit8*)MediaSerialNumber, 2*30 + 4);
16356 #endif
16357       sm_memcpy(pSerialNumber, MediaSerialNumber, MIN(allocationLen, 64));
16358       /*smEnqueueIO(smRoot, satIOContext);*/
16359 
16360       tdsmIOCompletedCB( smRoot,
16361                          smIORequest,
16362                          smIOSuccess,
16363                          SCSI_STAT_GOOD,
16364                          agNULL,
16365                          satIOContext->interruptContext);
16366       return SM_RC_SUCCESS;
16367 
16368 
16369     }
16370     else
16371     {
16372      /* word87 bit2 Media serial number is NOT valid */
16373       SM_DBG1(("smsatReadMediaSerialNumber: Media serial number is NOT valid!!!\n"));
16374 
16375       if (pSatDevData->sat48BitSupport == agTRUE)
16376       {
16377         /* READ VERIFY SECTORS EXT */
16378         fis->h.fisType        = 0x27;                   /* Reg host to device */
16379         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16380         fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
16381 
16382         fis->h.features       = 0;                      /* FIS reserve */
16383         fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16384         fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16385         fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16386         fis->d.device         = 0x40;                   /* FIS LBA mode set */
16387         fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
16388         fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
16389         fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
16390         fis->d.featuresExp    = 0;                      /* FIS reserve */
16391         fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16392         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16393         fis->d.reserved4      = 0;
16394         fis->d.control        = 0;                      /* FIS HOB bit clear */
16395         fis->d.reserved5      = 0;
16396 
16397         agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16398       }
16399       else
16400       {
16401         /* READ VERIFY SECTORS */
16402         fis->h.fisType        = 0x27;                   /* Reg host to device */
16403         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16404         fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
16405         fis->h.features       = 0;                      /* FIS reserve */
16406         fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16407         fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16408         fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16409         fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16410         fis->d.lbaLowExp      = 0;
16411         fis->d.lbaMidExp      = 0;
16412         fis->d.lbaHighExp     = 0;
16413         fis->d.featuresExp    = 0;
16414         fis->d.sectorCount    = 1;                       /* FIS sector count (7:0) */
16415         fis->d.sectorCountExp = 0;
16416         fis->d.reserved4      = 0;
16417         fis->d.control        = 0;                      /* FIS HOB bit clear */
16418         fis->d.reserved5      = 0;
16419 
16420 
16421         agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16422       }
16423       satIOContext->satCompleteCB = &smsatReadMediaSerialNumberCB;
16424       satIOContext->reqType = agRequestType;       /* Save it */
16425       status = smsataLLIOStart( smRoot,
16426                                 smIORequest,
16427                                 smDeviceHandle,
16428                                 smScsiRequest,
16429                                 satIOContext);
16430 
16431       return status;
16432     }
16433   }
16434   else
16435   {
16436 
16437     tdsmIOCompletedCB( smRoot,
16438                        smIORequest,
16439                        smIOFailed,
16440                        smDetailOtherError,
16441                        agNULL,
16442                        satIOContext->interruptContext);
16443 
16444     return SM_RC_SUCCESS;
16445 
16446   }
16447 }
16448 
16449 osGLOBAL bit32
16450 smsatReadBuffer(
16451                 smRoot_t                  *smRoot,
16452                 smIORequest_t             *smIORequest,
16453                 smDeviceHandle_t          *smDeviceHandle,
16454                 smScsiInitiatorRequest_t  *smScsiRequest,
16455                 smSatIOContext_t            *satIOContext
16456                )
16457 {
16458   bit32                      status = SM_RC_SUCCESS;
16459   bit32                      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16460   smScsiRspSense_t          *pSense;
16461   smIniScsiCmnd_t           *scsiCmnd;
16462   agsaFisRegHostToDevice_t  *fis;
16463   bit32                      bufferOffset;
16464   bit32                      tl;
16465   bit8                       mode;
16466   bit8                       bufferID;
16467   bit8                      *pBuff;
16468 
16469   pSense        = satIOContext->pSense;
16470   scsiCmnd      = &smScsiRequest->scsiCmnd;
16471   fis           = satIOContext->pFis;
16472   pBuff         = (bit8 *) smScsiRequest->sglVirtualAddr;
16473 
16474   SM_DBG5(("smsatReadBuffer: start\n"));
16475 
16476   /* checking CONTROL */
16477   /* NACA == 1 or LINK == 1*/
16478   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16479   {
16480     smsatSetSensePayload( pSense,
16481                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16482                           0,
16483                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16484                           satIOContext);
16485 
16486     /*smEnqueueIO(smRoot, satIOContext);*/
16487 
16488     tdsmIOCompletedCB( smRoot,
16489                        smIORequest,
16490                        smIOSuccess,
16491                        SCSI_STAT_CHECK_CONDITION,
16492                        satIOContext->pSmSenseData,
16493                        satIOContext->interruptContext );
16494 
16495     SM_DBG1(("smsatReadBuffer: return control!!!\n"));
16496     return SM_RC_SUCCESS;
16497   }
16498 
16499   bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16500   tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16501 
16502   mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16503   bufferID = scsiCmnd->cdb[2];
16504 
16505   if (mode == READ_BUFFER_DATA_MODE) /* 2 */
16506   {
16507     if (bufferID == 0 && bufferOffset == 0 && tl == 512)
16508     {
16509       /* send ATA READ BUFFER */
16510       fis->h.fisType        = 0x27;                   /* Reg host to device */
16511       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16512       fis->h.command        = SAT_READ_BUFFER;        /* 0xE4 */
16513       fis->h.features       = 0;                      /* FIS reserve */
16514       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16515       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16516       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16517       fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16518       fis->d.lbaLowExp      = 0;
16519       fis->d.lbaMidExp      = 0;
16520       fis->d.lbaHighExp     = 0;
16521       fis->d.featuresExp    = 0;
16522       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16523       fis->d.sectorCountExp = 0;
16524       fis->d.reserved4      = 0;
16525       fis->d.control        = 0;                      /* FIS HOB bit clear */
16526       fis->d.reserved5      = 0;
16527 
16528 
16529       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16530 
16531       satIOContext->satCompleteCB = &smsatReadBufferCB;
16532 
16533       satIOContext->reqType = agRequestType;       /* Save it */
16534 
16535       status = smsataLLIOStart( smRoot,
16536                                 smIORequest,
16537                                 smDeviceHandle,
16538                                 smScsiRequest,
16539                                 satIOContext);
16540       return status;
16541     }
16542 
16543     if (bufferID == 0 && bufferOffset == 0 && tl != 512)
16544     {
16545       smsatSetSensePayload( pSense,
16546                             SCSI_SNSKEY_ILLEGAL_REQUEST,
16547                             0,
16548                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16549                             satIOContext);
16550 
16551       /*smEnqueueIO(smRoot, satIOContext);*/
16552 
16553       tdsmIOCompletedCB( smRoot,
16554                          smIORequest,
16555                          smIOSuccess,
16556                          SCSI_STAT_CHECK_CONDITION,
16557                          satIOContext->pSmSenseData,
16558                          satIOContext->interruptContext );
16559 
16560       SM_DBG1(("smsatReadBuffer: allocation length is not 512; it is %d!!!\n", tl));
16561       return SM_RC_SUCCESS;
16562     }
16563 
16564     if (bufferID == 0 && bufferOffset != 0)
16565     {
16566       smsatSetSensePayload( pSense,
16567                             SCSI_SNSKEY_ILLEGAL_REQUEST,
16568                             0,
16569                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16570                             satIOContext);
16571 
16572       /*smEnqueueIO(smRoot, satIOContext);*/
16573 
16574       tdsmIOCompletedCB( smRoot,
16575                          smIORequest,
16576                          smIOSuccess,
16577                          SCSI_STAT_CHECK_CONDITION,
16578                          satIOContext->pSmSenseData,
16579                          satIOContext->interruptContext );
16580 
16581       SM_DBG1(("smsatReadBuffer: buffer offset is not 0; it is %d!!!\n", bufferOffset));
16582       return SM_RC_SUCCESS;
16583     }
16584     /* all other cases unsupported */
16585     SM_DBG1(("smsatReadBuffer: unsupported case 1!!!\n"));
16586     smsatSetSensePayload( pSense,
16587                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16588                           0,
16589                           SCSI_SNSCODE_INVALID_COMMAND,
16590                           satIOContext);
16591 
16592     /*smEnqueueIO(smRoot, satIOContext);*/
16593 
16594     tdsmIOCompletedCB( smRoot,
16595                        smIORequest,
16596                        smIOSuccess,
16597                        SCSI_STAT_CHECK_CONDITION,
16598                        satIOContext->pSmSenseData,
16599                        satIOContext->interruptContext );
16600 
16601     return SM_RC_SUCCESS;
16602 
16603   }
16604   else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */
16605   {
16606     if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */
16607     {
16608       smsatSetSensePayload( pSense,
16609                             SCSI_SNSKEY_ILLEGAL_REQUEST,
16610                             0,
16611                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16612                             satIOContext);
16613 
16614       /*smEnqueueIO(smRoot, satIOContext);*/
16615 
16616       tdsmIOCompletedCB( smRoot,
16617                          smIORequest,
16618                          smIOSuccess,
16619                          SCSI_STAT_CHECK_CONDITION,
16620                          satIOContext->pSmSenseData,
16621                          satIOContext->interruptContext );
16622 
16623       SM_DBG1(("smsatReadBuffer: tl < 4; tl is %d!!!\n", tl));
16624       return SM_RC_SUCCESS;
16625     }
16626     if (bufferID == 0)
16627     {
16628       /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/
16629       pBuff[0] = 0xFF;
16630       pBuff[1] = 0x00;
16631       pBuff[2] = 0x02;
16632       pBuff[3] = 0x00;
16633       if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
16634       {
16635         /* underrrun */
16636         SM_DBG1(("smsatReadBuffer: underrun tl %d data %d!!!\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
16637         /*smEnqueueIO(smRoot, satIOContext);*/
16638 
16639         tdsmIOCompletedCB( smRoot,
16640                            smIORequest,
16641                            smIOUnderRun,
16642                            tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
16643                            agNULL,
16644                            satIOContext->interruptContext );
16645 
16646         return SM_RC_SUCCESS;
16647       }
16648       else
16649       {
16650         /*smEnqueueIO(smRoot, satIOContext);*/
16651 
16652         tdsmIOCompletedCB( smRoot,
16653                            smIORequest,
16654                            smIOSuccess,
16655                            SCSI_STAT_GOOD,
16656                            agNULL,
16657                            satIOContext->interruptContext);
16658         return SM_RC_SUCCESS;
16659       }
16660     }
16661     else
16662     {
16663       /* We don't support other than bufferID 0 */
16664       smsatSetSensePayload( pSense,
16665                             SCSI_SNSKEY_ILLEGAL_REQUEST,
16666                             0,
16667                             SCSI_SNSCODE_INVALID_COMMAND,
16668                             satIOContext);
16669 
16670       /*smEnqueueIO(smRoot, satIOContext);*/
16671 
16672       tdsmIOCompletedCB( smRoot,
16673                          smIORequest,
16674                          smIOSuccess,
16675                          SCSI_STAT_CHECK_CONDITION,
16676                          satIOContext->pSmSenseData,
16677                          satIOContext->interruptContext );
16678 
16679       return SM_RC_SUCCESS;
16680     }
16681   }
16682   else
16683   {
16684     /* We don't support any other mode */
16685     SM_DBG1(("smsatReadBuffer: unsupported mode %d!!!\n", mode));
16686     smsatSetSensePayload( pSense,
16687                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16688                           0,
16689                           SCSI_SNSCODE_INVALID_COMMAND,
16690                           satIOContext);
16691 
16692     /*smEnqueueIO(smRoot, satIOContext);*/
16693 
16694     tdsmIOCompletedCB( smRoot,
16695                        smIORequest,
16696                        smIOSuccess,
16697                        SCSI_STAT_CHECK_CONDITION,
16698                        satIOContext->pSmSenseData,
16699                        satIOContext->interruptContext );
16700 
16701     return SM_RC_SUCCESS;
16702   }
16703 }
16704 
16705 osGLOBAL bit32
16706 smsatWriteBuffer(
16707                  smRoot_t                  *smRoot,
16708                  smIORequest_t             *smIORequest,
16709                  smDeviceHandle_t          *smDeviceHandle,
16710                  smScsiInitiatorRequest_t  *smScsiRequest,
16711                  smSatIOContext_t            *satIOContext
16712                 )
16713 {
16714 #ifdef NOT_YET
16715   bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16716 #endif
16717   smScsiRspSense_t          *pSense;
16718   smIniScsiCmnd_t           *scsiCmnd;
16719 #ifdef NOT_YET
16720   agsaFisRegHostToDevice_t  *fis;
16721 #endif
16722   bit32                     bufferOffset;
16723   bit32                     parmLen;
16724   bit8                      mode;
16725   bit8                      bufferID;
16726   bit8                      *pBuff;
16727 
16728   pSense        = satIOContext->pSense;
16729   scsiCmnd      = &smScsiRequest->scsiCmnd;
16730 #ifdef NOT_YET
16731   fis           = satIOContext->pFis;
16732 #endif
16733   pBuff         = (bit8 *) smScsiRequest->sglVirtualAddr;
16734 
16735   SM_DBG5(("smsatWriteBuffer: start\n"));
16736 
16737   /* checking CONTROL */
16738   /* NACA == 1 or LINK == 1*/
16739   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16740   {
16741     smsatSetSensePayload( pSense,
16742                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16743                           0,
16744                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16745                           satIOContext);
16746 
16747     /*smEnqueueIO(smRoot, satIOContext);*/
16748 
16749     tdsmIOCompletedCB( smRoot,
16750                        smIORequest,
16751                        smIOSuccess,
16752                        SCSI_STAT_CHECK_CONDITION,
16753                        satIOContext->pSmSenseData,
16754                        satIOContext->interruptContext );
16755 
16756     SM_DBG1(("smsatWriteBuffer: return control!!!\n"));
16757     return SM_RC_SUCCESS;
16758   }
16759 
16760   bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16761   parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16762 
16763   mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16764   bufferID = scsiCmnd->cdb[2];
16765 
16766   /* for debugging only */
16767   smhexdump("smsatWriteBuffer pBuff", (bit8 *)pBuff, 24);
16768 
16769   if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */
16770   {
16771     if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
16772     {
16773       SM_DBG1(("smsatWriteBuffer: sending ATA WRITE BUFFER!!!\n"));
16774       /* send ATA WRITE BUFFER */
16775 #ifdef NOT_YET
16776       fis->h.fisType        = 0x27;                   /* Reg host to device */
16777       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16778       fis->h.command        = SAT_WRITE_BUFFER;       /* 0xE8 */
16779       fis->h.features       = 0;                      /* FIS reserve */
16780       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16781       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16782       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16783       fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16784       fis->d.lbaLowExp      = 0;
16785       fis->d.lbaMidExp      = 0;
16786       fis->d.lbaHighExp     = 0;
16787       fis->d.featuresExp    = 0;
16788       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16789       fis->d.sectorCountExp = 0;
16790       fis->d.reserved4      = 0;
16791       fis->d.control        = 0;                      /* FIS HOB bit clear */
16792       fis->d.reserved5      = 0;
16793 
16794 
16795       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16796 
16797       satIOContext->satCompleteCB = &smsatWriteBufferCB;
16798 
16799       satIOContext->reqType = agRequestType;       /* Save it */
16800 
16801       status = smsataLLIOStart( smRoot,
16802                                 smIORequest,
16803                                 smDeviceHandle,
16804                                 smScsiRequest,
16805                                 satIOContext);
16806       return status;
16807 #endif
16808       /* temp */
16809       /*smEnqueueIO(smRoot, satIOContext);*/
16810 
16811       tdsmIOCompletedCB( smRoot,
16812                          smIORequest,
16813                          smIOSuccess,
16814                          SCSI_STAT_GOOD,
16815                          agNULL,
16816                          satIOContext->interruptContext);
16817       return SM_RC_SUCCESS;
16818     }
16819     if ( (bufferID == 0 && bufferOffset != 0) ||
16820          (bufferID == 0 && parmLen != 512)
16821         )
16822     {
16823       smsatSetSensePayload( pSense,
16824                             SCSI_SNSKEY_ILLEGAL_REQUEST,
16825                             0,
16826                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16827                             satIOContext);
16828 
16829       /*smEnqueueIO(smRoot, satIOContext);*/
16830 
16831       tdsmIOCompletedCB( smRoot,
16832                          smIORequest,
16833                          smIOSuccess,
16834                          SCSI_STAT_CHECK_CONDITION,
16835                          satIOContext->pSmSenseData,
16836                          satIOContext->interruptContext );
16837 
16838       SM_DBG1(("smsatWriteBuffer: wrong buffer offset %d or parameter length parmLen %d!!!\n", bufferOffset, parmLen));
16839       return SM_RC_SUCCESS;
16840     }
16841 
16842     /* all other cases unsupported */
16843     SM_DBG1(("smsatWriteBuffer: unsupported case 1!!!\n"));
16844     smsatSetSensePayload( pSense,
16845                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16846                           0,
16847                           SCSI_SNSCODE_INVALID_COMMAND,
16848                           satIOContext);
16849 
16850     /*smEnqueueIO(smRoot, satIOContext);*/
16851 
16852     tdsmIOCompletedCB( smRoot,
16853                        smIORequest,
16854                        smIOSuccess,
16855                        SCSI_STAT_CHECK_CONDITION,
16856                        satIOContext->pSmSenseData,
16857                        satIOContext->interruptContext );
16858 
16859     return SM_RC_SUCCESS;
16860 
16861   }
16862   else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */
16863   {
16864     /* temporary */
16865     SM_DBG1(("smsatWriteBuffer: not yet supported mode %d!!!\n", mode));
16866     smsatSetSensePayload( pSense,
16867                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16868                           0,
16869                           SCSI_SNSCODE_INVALID_COMMAND,
16870                           satIOContext);
16871 
16872 
16873     tdsmIOCompletedCB( smRoot,
16874                        smIORequest,
16875                        smIOSuccess,
16876                        SCSI_STAT_CHECK_CONDITION,
16877                        satIOContext->pSmSenseData,
16878                        satIOContext->interruptContext );
16879 
16880     return SM_RC_SUCCESS;
16881   }
16882   else
16883   {
16884     /* We don't support any other mode */
16885     SM_DBG1(("smsatWriteBuffer: unsupported mode %d!!!\n", mode));
16886     smsatSetSensePayload( pSense,
16887                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16888                           0,
16889                           SCSI_SNSCODE_INVALID_COMMAND,
16890                           satIOContext);
16891 
16892     /*smEnqueueIO(smRoot, satIOContext);*/
16893 
16894     tdsmIOCompletedCB( smRoot,
16895                        smIORequest,
16896                        smIOSuccess,
16897                        SCSI_STAT_CHECK_CONDITION,
16898                        satIOContext->pSmSenseData,
16899                        satIOContext->interruptContext );
16900 
16901     return SM_RC_SUCCESS;
16902   }
16903 
16904 }
16905 
16906 osGLOBAL bit32
16907 smsatReassignBlocks(
16908                     smRoot_t                  *smRoot,
16909                     smIORequest_t             *smIORequest,
16910                     smDeviceHandle_t          *smDeviceHandle,
16911                     smScsiInitiatorRequest_t  *smScsiRequest,
16912                     smSatIOContext_t            *satIOContext
16913                    )
16914 {
16915   /*
16916     assumes all LBA fits in ATA command; no boundary condition is checked here yet
16917   */
16918   bit32                     status;
16919   bit32                     agRequestType;
16920   smDeviceData_t            *pSatDevData;
16921   smScsiRspSense_t          *pSense;
16922   smIniScsiCmnd_t           *scsiCmnd;
16923   agsaFisRegHostToDevice_t  *fis;
16924   bit8                      *pParmList;    /* Log Page data buffer */
16925   bit8                      LongLBA;
16926   bit8                      LongList;
16927   bit32                     defectListLen;
16928   bit8                      LBA[8];
16929   bit32                     startingIndex;
16930 
16931   pSense        = satIOContext->pSense;
16932   pSatDevData   = satIOContext->pSatDevData;
16933   scsiCmnd      = &smScsiRequest->scsiCmnd;
16934   fis           = satIOContext->pFis;
16935   pParmList     = (bit8 *) smScsiRequest->sglVirtualAddr;
16936 
16937   SM_DBG5(("smsatReassignBlocks: start\n"));
16938 
16939   /* checking CONTROL */
16940   /* NACA == 1 or LINK == 1*/
16941   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
16942   {
16943     smsatSetSensePayload( pSense,
16944                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16945                           0,
16946                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16947                           satIOContext);
16948 
16949     /*smEnqueueIO(smRoot, satIOContext);*/
16950 
16951     tdsmIOCompletedCB( smRoot,
16952                        smIORequest,
16953                        smIOSuccess,
16954                        SCSI_STAT_CHECK_CONDITION,
16955                        satIOContext->pSmSenseData,
16956                        satIOContext->interruptContext );
16957 
16958     SM_DBG1(("smsatReassignBlocks: return control!!!\n"));
16959     return SM_RC_SUCCESS;
16960   }
16961 
16962   sm_memset(satIOContext->LBA, 0, 8);
16963   satIOContext->ParmIndex = 0;
16964   satIOContext->ParmLen = 0;
16965 
16966   LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK);
16967   LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16968   sm_memset(LBA, 0, sizeof(LBA));
16969 
16970   if (LongList == 0)
16971   {
16972     defectListLen = (pParmList[2] << 8) + pParmList[3];
16973   }
16974   else
16975   {
16976     defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2))
16977                   + (pParmList[2] << 8) + pParmList[3];
16978   }
16979   /* SBC 5.16.2, p61*/
16980   satIOContext->ParmLen = defectListLen + 4 /* header size */;
16981 
16982   startingIndex = 4;
16983 
16984   if (LongLBA == 0)
16985   {
16986     LBA[4] = pParmList[startingIndex];   /* MSB */
16987     LBA[5] = pParmList[startingIndex+1];
16988     LBA[6] = pParmList[startingIndex+2];
16989     LBA[7] = pParmList[startingIndex+3];  /* LSB */
16990     startingIndex = startingIndex + 4;
16991   }
16992   else
16993   {
16994     LBA[0] = pParmList[startingIndex];    /* MSB */
16995     LBA[1] = pParmList[startingIndex+1];
16996     LBA[2] = pParmList[startingIndex+2];
16997     LBA[3] = pParmList[startingIndex+3];
16998     LBA[4] = pParmList[startingIndex+4];
16999     LBA[5] = pParmList[startingIndex+5];
17000     LBA[6] = pParmList[startingIndex+6];
17001     LBA[7] = pParmList[startingIndex+7];  /* LSB */
17002     startingIndex = startingIndex + 8;
17003   }
17004 
17005   smhexdump("smsatReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen);
17006 
17007   if (pSatDevData->sat48BitSupport == agTRUE)
17008   {
17009     /* sends READ VERIFY SECTOR(S) EXT*/
17010     fis->h.fisType        = 0x27;                   /* Reg host to device */
17011     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17012     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17013     fis->h.features       = 0;                      /* FIS reserve */
17014     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
17015     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
17016     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
17017     fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
17018     fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
17019     fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
17020     fis->d.featuresExp    = 0;                      /* FIS reserve */
17021     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
17022     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
17023     fis->d.reserved4      = 0;
17024     fis->d.device         = 0x40;                   /* 01000000 */
17025     fis->d.control        = 0;                      /* FIS HOB bit clear */
17026     fis->d.reserved5      = 0;
17027   }
17028   else
17029   {
17030     /* READ VERIFY SECTOR(S)*/
17031     fis->h.fisType        = 0x27;                   /* Reg host to device */
17032     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17033     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
17034     fis->h.features       = 0;                      /* FIS features NA       */
17035     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
17036     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
17037     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
17038     fis->d.lbaLowExp      = 0;
17039     fis->d.lbaMidExp      = 0;
17040     fis->d.lbaHighExp     = 0;
17041     fis->d.featuresExp    = 0;
17042     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
17043     fis->d.sectorCountExp = 0;
17044     fis->d.reserved4      = 0;
17045     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
17046                             /* DEV and LBA 27:24 */
17047     fis->d.control        = 0;                      /* FIS HOB bit clear */
17048     fis->d.reserved5      = 0;
17049   }
17050 
17051   sm_memcpy(satIOContext->LBA, LBA, 8);
17052   satIOContext->ParmIndex = startingIndex;
17053 
17054   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17055 
17056   /* Initialize CB for SATA completion.
17057    */
17058   satIOContext->satCompleteCB = &smsatReassignBlocksCB;
17059 
17060   /*
17061    * Prepare SGL and send FIS to LL layer.
17062    */
17063   satIOContext->reqType = agRequestType;       /* Save it */
17064 
17065   status = smsataLLIOStart( smRoot,
17066                             smIORequest,
17067                             smDeviceHandle,
17068                             smScsiRequest,
17069                             satIOContext);
17070 
17071   return status;
17072 }
17073 
17074 osGLOBAL bit32
17075 smsatRead_1(
17076             smRoot_t                  *smRoot,
17077             smIORequest_t             *smIORequest,
17078             smDeviceHandle_t          *smDeviceHandle,
17079             smScsiInitiatorRequest_t  *smScsiRequest,
17080             smSatIOContext_t            *satIOContext
17081           )
17082 {
17083   /*
17084     Assumption: error check on lba and tl has been done in satRead*()
17085     lba = lba + tl;
17086   */
17087   bit32                     status;
17088   smSatIOContext_t            *satOrgIOContext = agNULL;
17089   smIniScsiCmnd_t           *scsiCmnd;
17090   agsaFisRegHostToDevice_t  *fis;
17091   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17092   bit32                     lba = 0;
17093   bit32                     DenomTL = 0xFF;
17094   bit32                     Remainder = 0;
17095   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
17096 
17097   SM_DBG2(("smsatRead_1: start\n"));
17098 
17099   fis             = satIOContext->pFis;
17100   satOrgIOContext = satIOContext->satOrgIOContext;
17101   scsiCmnd        = satOrgIOContext->pScsiCmnd;
17102 
17103   sm_memset(LBA,0, sizeof(LBA));
17104 
17105   switch (satOrgIOContext->ATACmd)
17106   {
17107   case SAT_READ_DMA:
17108     DenomTL = 0x100;
17109     break;
17110   case SAT_READ_SECTORS:
17111     DenomTL = 0x100;
17112     break;
17113   case SAT_READ_DMA_EXT:
17114     DenomTL = 0xFFFF;
17115     break;
17116   case SAT_READ_SECTORS_EXT:
17117     DenomTL = 0xFFFF;
17118     break;
17119   case SAT_READ_FPDMA_QUEUED:
17120     DenomTL = 0xFFFF;
17121     break;
17122   default:
17123     SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17124     return SM_RC_FAILURE;
17125     break;
17126   }
17127 
17128   Remainder = satOrgIOContext->OrgTL % DenomTL;
17129   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
17130   lba = satOrgIOContext->currentLBA;
17131 
17132   LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3));
17133   LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2));
17134   LBA[2] = (bit8)((lba & 0xFF00) >> 8);
17135   LBA[3] = (bit8)(lba & 0xFF);
17136 
17137   switch (satOrgIOContext->ATACmd)
17138   {
17139   case SAT_READ_DMA:
17140     fis->h.fisType        = 0x27;                   /* Reg host to device */
17141     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17142     fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
17143     fis->h.features       = 0;                      /* FIS reserve */
17144     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17145     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17146     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17147     fis->d.device         =
17148       (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
17149     fis->d.lbaLowExp      = 0;
17150     fis->d.lbaMidExp      = 0;
17151     fis->d.lbaHighExp     = 0;
17152     fis->d.featuresExp    = 0;
17153 
17154     if (satOrgIOContext->LoopNum == 1)
17155     {
17156       /* last loop */
17157       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
17158     }
17159     else
17160     {
17161       fis->d.sectorCount    = 0x0;                  /* FIS sector count (7:0) */
17162     }
17163 
17164     fis->d.sectorCountExp = 0;
17165     fis->d.reserved4      = 0;
17166     fis->d.control        = 0;                      /* FIS HOB bit clear */
17167     fis->d.reserved5      = 0;
17168 
17169     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17170 
17171     break;
17172   case SAT_READ_SECTORS:
17173     fis->h.fisType        = 0x27;                   /* Reg host to device */
17174     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17175     fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
17176     fis->h.features       = 0;                      /* FIS reserve */
17177     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17178     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17179     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17180     fis->d.device         =
17181       (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
17182     fis->d.lbaLowExp      = 0;
17183     fis->d.lbaMidExp      = 0;
17184     fis->d.lbaHighExp     = 0;
17185     fis->d.featuresExp    = 0;
17186     if (satOrgIOContext->LoopNum == 1)
17187     {
17188       /* last loop */
17189       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
17190     }
17191     else
17192     {
17193       fis->d.sectorCount    = 0x0;                   /* FIS sector count (7:0) */
17194     }
17195     fis->d.sectorCountExp = 0;
17196     fis->d.reserved4      = 0;
17197     fis->d.control        = 0;                      /* FIS HOB bit clear */
17198     fis->d.reserved5      = 0;
17199 
17200     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
17201 
17202     break;
17203   case SAT_READ_DMA_EXT:
17204     fis->h.fisType        = 0x27;                   /* Reg host to device */
17205     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17206     fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
17207     fis->h.features       = 0;                      /* FIS reserve */
17208     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17209     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17210     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17211     fis->d.device         = 0x40;                   /* FIS LBA mode set */
17212     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17213     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17214     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17215     fis->d.featuresExp    = 0;                      /* FIS reserve */
17216     if (satOrgIOContext->LoopNum == 1)
17217     {
17218       /* last loop */
17219       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17220       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17221 
17222     }
17223     else
17224     {
17225       fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
17226       fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
17227     }
17228     fis->d.reserved4      = 0;
17229     fis->d.control        = 0;                      /* FIS HOB bit clear */
17230     fis->d.reserved5      = 0;
17231 
17232     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17233 
17234     break;
17235   case SAT_READ_SECTORS_EXT:
17236     fis->h.fisType        = 0x27;                   /* Reg host to device */
17237     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17238     fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
17239     fis->h.features       = 0;                      /* FIS reserve */
17240     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17241     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17242     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17243     fis->d.device         = 0x40;                   /* FIS LBA mode set */
17244     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17245     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17246     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17247     fis->d.featuresExp    = 0;                      /* FIS reserve */
17248     if (satOrgIOContext->LoopNum == 1)
17249     {
17250       /* last loop */
17251       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17252       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);  /* FIS sector count (15:8) */
17253     }
17254     else
17255     {
17256       fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
17257       fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
17258     }
17259     fis->d.reserved4      = 0;
17260     fis->d.control        = 0;                      /* FIS HOB bit clear */
17261     fis->d.reserved5      = 0;
17262 
17263     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
17264     break;
17265   case SAT_READ_FPDMA_QUEUED:
17266     fis->h.fisType        = 0x27;                   /* Reg host to device */
17267     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17268     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
17269     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17270     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17271     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17272 
17273     /* Check FUA bit */
17274     if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
17275       fis->d.device       = 0xC0;                   /* FIS FUA set */
17276     else
17277       fis->d.device       = 0x40;                   /* FIS FUA clear */
17278 
17279     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17280     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17281     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17282     if (satOrgIOContext->LoopNum == 1)
17283     {
17284       /* last loop */
17285       fis->h.features       = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
17286       fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17287     }
17288     else
17289     {
17290       fis->h.features       = 0xFF;       /* FIS sector count (7:0) */
17291       fis->d.featuresExp    = 0xFF;       /* FIS sector count (15:8) */
17292     }
17293     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
17294     fis->d.sectorCountExp = 0;
17295     fis->d.reserved4      = 0;
17296     fis->d.control        = 0;                      /* FIS HOB bit clear */
17297     fis->d.reserved5      = 0;
17298 
17299     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
17300     break;
17301   default:
17302     SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17303     return SM_RC_FAILURE;
17304     break;
17305   }
17306 
17307   /* Initialize CB for SATA completion.
17308    */
17309   /* chained data */
17310   satIOContext->satCompleteCB = &smsatChainedDataIOCB;
17311 
17312   if (satOrgIOContext->ATACmd == SAT_READ_DMA || satOrgIOContext->ATACmd == SAT_READ_SECTORS)
17313   {
17314     smsatSplitSGL(smRoot,
17315                   smIORequest,
17316                   smDeviceHandle,
17317                   (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17318                   satOrgIOContext,
17319                   NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/
17320                   (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17321                   agFALSE);
17322   }
17323   else
17324   {
17325     smsatSplitSGL(smRoot,
17326                   smIORequest,
17327                   smDeviceHandle,
17328                   (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17329                   satOrgIOContext,
17330                   BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/
17331                   (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17332                   agFALSE);
17333   }
17334 
17335   /*
17336    * Prepare SGL and send FIS to LL layer.
17337    */
17338   satIOContext->reqType = agRequestType;       /* Save it */
17339 
17340   status = smsataLLIOStart( smRoot,
17341                             smIORequest,
17342                             smDeviceHandle,
17343                             (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest,
17344                             satIOContext);
17345 
17346   SM_DBG5(("smsatRead_1: return\n"));
17347   return (status);
17348 }
17349 
17350 osGLOBAL bit32
17351 smsatWrite_1(
17352              smRoot_t                  *smRoot,
17353              smIORequest_t             *smIORequest,
17354              smDeviceHandle_t          *smDeviceHandle,
17355              smScsiInitiatorRequest_t  *smScsiRequest,
17356              smSatIOContext_t            *satIOContext
17357            )
17358 {
17359   /*
17360     Assumption: error check on lba and tl has been done in satWrite*()
17361     lba = lba + tl;
17362   */
17363   bit32                     status;
17364   smSatIOContext_t            *satOrgIOContext = agNULL;
17365   smIniScsiCmnd_t           *scsiCmnd;
17366   agsaFisRegHostToDevice_t  *fis;
17367   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17368   bit32                     lba = 0;
17369   bit32                     DenomTL = 0xFF;
17370   bit32                     Remainder = 0;
17371   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
17372 
17373   SM_DBG2(("smsatWrite_1: start\n"));
17374 
17375   fis             = satIOContext->pFis;
17376   satOrgIOContext = satIOContext->satOrgIOContext;
17377   scsiCmnd        = satOrgIOContext->pScsiCmnd;
17378 
17379   sm_memset(LBA,0, sizeof(LBA));
17380 
17381   switch (satOrgIOContext->ATACmd)
17382   {
17383   case SAT_WRITE_DMA:
17384     DenomTL = 0x100;
17385     break;
17386   case SAT_WRITE_SECTORS:
17387     DenomTL = 0x100;
17388     break;
17389   case SAT_WRITE_DMA_EXT:
17390     DenomTL = 0xFFFF;
17391     break;
17392   case SAT_WRITE_DMA_FUA_EXT:
17393     DenomTL = 0xFFFF;
17394     break;
17395   case SAT_WRITE_SECTORS_EXT:
17396     DenomTL = 0xFFFF;
17397     break;
17398   case SAT_WRITE_FPDMA_QUEUED:
17399     DenomTL = 0xFFFF;
17400     break;
17401   default:
17402     SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17403     return SM_RC_FAILURE;
17404     break;
17405   }
17406 
17407   Remainder = satOrgIOContext->OrgTL % DenomTL;
17408   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
17409   lba = satOrgIOContext->currentLBA;
17410 
17411 
17412   LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3));
17413   LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2));
17414   LBA[2] = (bit8)((lba & 0xFF00) >> 8);
17415   LBA[3] = (bit8)(lba & 0xFF);
17416 
17417   switch (satOrgIOContext->ATACmd)
17418   {
17419   case SAT_WRITE_DMA:
17420     fis->h.fisType        = 0x27;                   /* Reg host to device */
17421     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
17422     fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
17423     fis->h.features       = 0;                      /* FIS reserve */
17424     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17425     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17426     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17427 
17428     /* FIS LBA mode set LBA (27:24) */
17429     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
17430 
17431     fis->d.lbaLowExp      = 0;
17432     fis->d.lbaMidExp      = 0;
17433     fis->d.lbaHighExp     = 0;
17434     fis->d.featuresExp    = 0;
17435     if (satOrgIOContext->LoopNum == 1)
17436     {
17437       /* last loop */
17438       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
17439     }
17440     else
17441     {
17442       fis->d.sectorCount    = 0x0;                   /* FIS sector count (7:0) */
17443     }
17444     fis->d.sectorCountExp = 0;
17445     fis->d.reserved4      = 0;
17446     fis->d.control        = 0;                      /* FIS HOB bit clear */
17447     fis->d.reserved5      = 0;
17448 
17449     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17450 
17451     break;
17452   case SAT_WRITE_SECTORS:
17453     fis->h.fisType        = 0x27;                   /* Reg host to device */
17454     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
17455     fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
17456     fis->h.features       = 0;                      /* FIS reserve */
17457     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17458     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17459     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17460 
17461     /* FIS LBA mode set LBA (27:24) */
17462     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
17463 
17464     fis->d.lbaLowExp      = 0;
17465     fis->d.lbaMidExp      = 0;
17466     fis->d.lbaHighExp     = 0;
17467     fis->d.featuresExp    = 0;
17468     if (satOrgIOContext->LoopNum == 1)
17469     {
17470       /* last loop */
17471       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
17472     }
17473     else
17474     {
17475       fis->d.sectorCount    = 0x0;                 /* FIS sector count (7:0) */
17476     }
17477     fis->d.sectorCountExp = 0;
17478     fis->d.reserved4      = 0;
17479     fis->d.control        = 0;                      /* FIS HOB bit clear */
17480     fis->d.reserved5      = 0;
17481 
17482     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
17483 
17484     break;
17485   case SAT_WRITE_DMA_EXT:
17486     fis->h.fisType        = 0x27;                   /* Reg host to device */
17487     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17488     fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
17489     fis->h.features       = 0;                      /* FIS reserve */
17490     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17491     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17492     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17493     fis->d.device         = 0x40;                   /* FIS LBA mode set */
17494     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17495     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17496     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17497     fis->d.featuresExp    = 0;                      /* FIS reserve */
17498     if (satOrgIOContext->LoopNum == 1)
17499     {
17500       /* last loop */
17501       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
17502       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17503     }
17504     else
17505     {
17506       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
17507       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
17508     }
17509     fis->d.reserved4      = 0;
17510     fis->d.control        = 0;                       /* FIS HOB bit clear */
17511     fis->d.reserved5      = 0;
17512 
17513     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17514 
17515     break;
17516   case SAT_WRITE_SECTORS_EXT:
17517     fis->h.fisType        = 0x27;                   /* Reg host to device */
17518     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17519     fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
17520 
17521     fis->h.features       = 0;                      /* FIS reserve */
17522     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17523     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17524     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17525     fis->d.device         = 0x40;                   /* FIS LBA mode set */
17526     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
17527     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17528     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17529     fis->d.featuresExp    = 0;                      /* FIS reserve */
17530     if (satOrgIOContext->LoopNum == 1)
17531     {
17532       /* last loop */
17533       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17534       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
17535     }
17536     else
17537     {
17538       fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
17539       fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
17540     }
17541     fis->d.reserved4      = 0;
17542     fis->d.control        = 0;                      /* FIS HOB bit clear */
17543     fis->d.reserved5      = 0;
17544 
17545     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
17546 
17547     break;
17548   case SAT_WRITE_FPDMA_QUEUED:
17549     fis->h.fisType        = 0x27;                   /* Reg host to device */
17550     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17551     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
17552     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
17553     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
17554     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
17555 
17556     /* Check FUA bit */
17557     if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
17558       fis->d.device       = 0xC0;                   /* FIS FUA set */
17559     else
17560       fis->d.device       = 0x40;                   /* FIS FUA clear */
17561 
17562     fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
17563     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17564     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17565     if (satOrgIOContext->LoopNum == 1)
17566     {
17567       /* last loop */
17568       fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
17569       fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
17570     }
17571     else
17572     {
17573       fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
17574       fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
17575     }
17576     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
17577     fis->d.sectorCountExp = 0;
17578     fis->d.reserved4      = 0;
17579     fis->d.control        = 0;                      /* FIS HOB bit clear */
17580     fis->d.reserved5      = 0;
17581 
17582     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
17583     break;
17584 
17585   default:
17586     SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17587     return SM_RC_FAILURE;
17588     break;
17589   }
17590 
17591   /* Initialize CB for SATA completion.
17592    */
17593   /* chained data */
17594   satIOContext->satCompleteCB = &smsatChainedDataIOCB;
17595 
17596   if (satOrgIOContext->ATACmd == SAT_WRITE_DMA || satOrgIOContext->ATACmd == SAT_WRITE_SECTORS)
17597   {
17598     smsatSplitSGL(smRoot,
17599                   smIORequest,
17600                   smDeviceHandle,
17601                   (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17602                   satOrgIOContext,
17603                   NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/
17604                   (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17605                   agFALSE);
17606   }
17607   else
17608   {
17609     smsatSplitSGL(smRoot,
17610                   smIORequest,
17611                   smDeviceHandle,
17612                   (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17613                   satOrgIOContext,
17614                   BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/
17615                   (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17616                   agFALSE);
17617   }
17618 
17619   /*
17620    * Prepare SGL and send FIS to LL layer.
17621    */
17622   satIOContext->reqType = agRequestType;       /* Save it */
17623 
17624   status = smsataLLIOStart( smRoot,
17625                             smIORequest,
17626                             smDeviceHandle,
17627                             (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest,
17628                             satIOContext);
17629 
17630   SM_DBG5(("smsatWrite_1: return\n"));
17631   return (status);
17632 }
17633 
17634 osGLOBAL bit32
17635 smsatPassthrough(
17636                     smRoot_t                  *smRoot,
17637                     smIORequest_t             *smIORequest,
17638                     smDeviceHandle_t          *smDeviceHandle,
17639                     smScsiInitiatorRequest_t  *smScsiRequest,
17640                     smSatIOContext_t            *satIOContext
17641                    )
17642 {
17643   smScsiRspSense_t          *pSense;
17644   smIniScsiCmnd_t           *scsiCmnd;
17645   smDeviceData_t            *pSatDevData;
17646   agsaFisRegHostToDevice_t	  *fis;
17647   bit32                      status;
17648   bit32 					agRequestType;
17649   smAtaPassThroughHdr_t       ataPassThroughHdr;
17650 
17651 
17652   pSense      = satIOContext->pSense;
17653   scsiCmnd    = &smScsiRequest->scsiCmnd;
17654   pSatDevData = satIOContext->pSatDevData;
17655   fis           = satIOContext->pFis;
17656 
17657   SM_DBG1(("smsatPassthrough: START!!!\n"));
17658 
17659   osti_memset(&ataPassThroughHdr, 0 , sizeof(smAtaPassThroughHdr_t));
17660 
17661   ataPassThroughHdr.opc = scsiCmnd->cdb[0];
17662   ataPassThroughHdr.mulCount = scsiCmnd->cdb[1] >> 5;
17663   ataPassThroughHdr.proto = (scsiCmnd->cdb[1] >> 1) & 0x0F;
17664   ataPassThroughHdr.extend = scsiCmnd->cdb[1] & 1;
17665   ataPassThroughHdr.offline = scsiCmnd->cdb[2] >> 6;
17666   ataPassThroughHdr.ckCond = (scsiCmnd->cdb[2] >> 5) & 1;
17667   ataPassThroughHdr.tType = (scsiCmnd->cdb[2] >> 4) & 1;
17668   ataPassThroughHdr.tDir = (scsiCmnd->cdb[2] >> 3) & 1;
17669   ataPassThroughHdr.byteBlock = (scsiCmnd->cdb[2] >> 2) & 1;
17670   ataPassThroughHdr.tlength = scsiCmnd->cdb[2] & 0x3;
17671 
17672   switch(ataPassThroughHdr.proto)
17673   {
17674     case 0:
17675     case 9:
17676     	    agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;	//Device Reset
17677 	    break;
17678     case 1:
17679        	    agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;		//Software reset
17680 	    break;
17681     case 3:
17682             agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;	//Non Data mode
17683 	    break;
17684     case 4:
17685        	    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;	//IO_Data_In mode
17686 	    break;
17687     case 5:
17688             agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;		//PIO_Data_out
17689             break;
17690     case 6:
17691             agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;	//DMA READ and WRITE
17692             break;
17693     case 8:
17694             agRequestType = AGSA_SATA_ATAP_EXECDEVDIAG; 	//device diagnostic
17695 	    break;
17696     case 12:
17697             agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;		//FPDMA Read and Write
17698             break;
17699     default:
17700             agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;	//Default Non Data Mode
17701             break;
17702   }
17703 
17704 
17705   if((ataPassThroughHdr.tlength == 0) && (agRequestType != AGSA_SATA_PROTOCOL_NON_DATA))
17706   {
17707     SM_DBG1(("smsatPassthrough SCSI_SNSCODE_INVALID_FIELD_IN_CDB\n"));
17708 
17709     smsatSetSensePayload( pSense,
17710                           SCSI_SNSKEY_ILLEGAL_REQUEST,
17711                           0,
17712 			  SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
17713                           satIOContext);
17714 
17715     tdsmIOCompletedCB( smRoot,
17716                        smIORequest,
17717                        smIOSuccess,
17718                        SCSI_STAT_CHECK_CONDITION,
17719                        satIOContext->pSmSenseData,
17720                        satIOContext->interruptContext );
17721 
17722     return SM_RC_SUCCESS;
17723   }
17724 
17725   if(scsiCmnd->cdb[0] == 0xA1)
17726   {
17727     SM_DBG1(("smsatPassthrough A1h: COMMAND: %x  FEATURE: %x \n",scsiCmnd->cdb[9],scsiCmnd->cdb[3]));
17728 
17729     fis->h.fisType        = 0x27;                   /* Reg host to device */
17730     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17731     fis->h.features       = scsiCmnd->cdb[3];
17732     fis->d.sectorCount	  = scsiCmnd->cdb[4];		  /* 0x01  FIS sector count (7:0) */
17733     fis->d.lbaLow 		  = scsiCmnd->cdb[5];		  /* Reading LBA  FIS LBA (7 :0 ) */
17734     fis->d.lbaMid         = scsiCmnd->cdb[6];
17735     fis->d.lbaHigh        = scsiCmnd->cdb[7];
17736     fis->d.device         = scsiCmnd->cdb[8];
17737     fis->h.command		  = scsiCmnd->cdb[9];
17738     fis->d.featuresExp	  = 0;
17739     fis->d.sectorCountExp = 0;
17740     fis->d.lbaLowExp	  = 0;
17741     fis->d.lbaMidExp	  = 0;
17742     fis->d.lbaHighExp 	  = 0;
17743     fis->d.reserved4	  = 0;
17744     fis->d.control		  = 0;					  /* FIS HOB bit clear */
17745     fis->d.reserved5	  = 0;
17746 
17747     /* Initialize CB for SATA completion*/
17748     satIOContext->satCompleteCB = &smsatPassthroughCB;
17749 
17750     /*
17751         * Prepare SGL and send FIS to LL layer.
17752     */
17753 
17754     satIOContext->reqType = agRequestType;
17755     status = smsataLLIOStart( smRoot,
17756                               smIORequest,
17757 	                      smDeviceHandle,
17758 			      smScsiRequest,
17759                               satIOContext);
17760     return status;
17761 
17762    }
17763    else if(scsiCmnd->cdb[0] == 0x85)
17764    {
17765      SM_DBG1(("smsatPassthrough 85h: COMMAND: %x  FEATURE: %x \n",scsiCmnd->cdb[14],scsiCmnd->cdb[4]));
17766 
17767      fis->h.fisType        = 0x27;                   /* Reg host to device */
17768      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17769 
17770      if(1 == ataPassThroughHdr.extend)
17771      {
17772        fis->d.featuresExp    = scsiCmnd->cdb[3];
17773        fis->d.sectorCountExp = scsiCmnd->cdb[5];
17774        fis->d.lbaMidExp      = scsiCmnd->cdb[9];
17775        fis->d.lbaHighExp     = scsiCmnd->cdb[11];
17776        fis->d.lbaLowExp      = scsiCmnd->cdb[7];
17777      }
17778      fis->h.features = scsiCmnd->cdb[4];
17779      fis->d.sectorCount = scsiCmnd->cdb[6];
17780      fis->d.lbaLow = scsiCmnd->cdb[8];
17781      fis->d.lbaMid = scsiCmnd->cdb[10];
17782      fis->d.lbaHigh = scsiCmnd->cdb[12];
17783      fis->d.device  = scsiCmnd->cdb[13];
17784      fis->h.command = scsiCmnd->cdb[14];
17785      fis->d.reserved4 = 0;
17786      fis->d.control = 0;
17787      fis->d.reserved5	  = 0;
17788 
17789 
17790      /* Initialize CB for SATA completion.
17791       */
17792 
17793      satIOContext->satCompleteCB = &smsatPassthroughCB;
17794 
17795      /*
17796        * Prepare SGL and send FIS to LL layer.
17797       */
17798      satIOContext->reqType = agRequestType;
17799      status = smsataLLIOStart( smRoot,
17800                                smIORequest,
17801                                smDeviceHandle,
17802                                smScsiRequest,
17803                                satIOContext);
17804      return status;
17805 
17806    }
17807    else
17808    {
17809      SM_DBG1(("smsatPassthrough : INVALD PASSTHROUGH!!!\n"));
17810      smsatSetSensePayload( pSense,
17811                           SCSI_SNSKEY_ILLEGAL_REQUEST,
17812                           0,
17813                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
17814                           satIOContext);
17815      tdsmIOCompletedCB( smRoot,
17816                        smIORequest,
17817                        smIOSuccess,
17818                        SCSI_STAT_CHECK_CONDITION,
17819                        satIOContext->pSmSenseData,
17820                        satIOContext->interruptContext );
17821 
17822      SM_DBG1(("smsatPassthrough : return control!!!\n"));
17823 
17824      return SM_RC_SUCCESS;
17825    }
17826 }
17827 
17828 osGLOBAL bit32
17829 smsatNonChainedWriteNVerify_Verify(
17830                                    smRoot_t                  *smRoot,
17831                                    smIORequest_t             *smIORequest,
17832                                    smDeviceHandle_t          *smDeviceHandle,
17833                                    smScsiInitiatorRequest_t  *smScsiRequest,
17834                                    smSatIOContext_t            *satIOContext
17835                                   )
17836 {
17837   bit32                     status;
17838   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17839   smDeviceData_t            *pSatDevData;
17840   smIniScsiCmnd_t           *scsiCmnd;
17841   agsaFisRegHostToDevice_t  *fis;
17842 
17843   pSatDevData   = satIOContext->pSatDevData;
17844   scsiCmnd      = &smScsiRequest->scsiCmnd;
17845   fis           = satIOContext->pFis;
17846   SM_DBG5(("smsatNonChainedWriteNVerify_Verify: start\n"));
17847   if (pSatDevData->sat48BitSupport == agTRUE)
17848   {
17849     fis->h.fisType        = 0x27;                   /* Reg host to device */
17850     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17851 
17852     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17853     fis->h.features       = 0;                      /* FIS reserve */
17854     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
17855     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
17856     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
17857     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
17858     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
17859     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17860     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17861     fis->d.featuresExp    = 0;                      /* FIS reserve */
17862     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
17863     fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
17864 
17865     fis->d.reserved4      = 0;
17866     fis->d.control        = 0;                      /* FIS HOB bit clear */
17867     fis->d.reserved5      = 0;
17868 
17869     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17870 
17871     /* Initialize CB for SATA completion.
17872      */
17873     satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
17874 
17875     /*
17876      * Prepare SGL and send FIS to LL layer.
17877      */
17878     satIOContext->reqType = agRequestType;       /* Save it */
17879 
17880     status = smsataLLIOStart( smRoot,
17881                               smIORequest,
17882                               smDeviceHandle,
17883                               smScsiRequest,
17884                               satIOContext);
17885 
17886 
17887     SM_DBG1(("smsatNonChainedWriteNVerify_Verify: return status %d!!!\n", status));
17888     return (status);
17889   }
17890   else
17891   {
17892     /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
17893     SM_DBG1(("smsatNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS!!!\n"));
17894     return SM_RC_FAILURE;
17895   }
17896 }
17897 
17898 osGLOBAL bit32
17899 smsatChainedWriteNVerify_Start_Verify(
17900                                       smRoot_t                  *smRoot,
17901                                       smIORequest_t             *smIORequest,
17902                                       smDeviceHandle_t          *smDeviceHandle,
17903                                       smScsiInitiatorRequest_t  *smScsiRequest,
17904                                       smSatIOContext_t            *satIOContext
17905                                      )
17906 {
17907   /*
17908     deal with transfer length; others have been handled previously at this point;
17909     no LBA check; no range check;
17910   */
17911   bit32                     status;
17912   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17913   smDeviceData_t            *pSatDevData;
17914   smIniScsiCmnd_t           *scsiCmnd;
17915   agsaFisRegHostToDevice_t  *fis;
17916   bit32                     lba = 0;
17917   bit32                     tl = 0;
17918   bit32                     LoopNum = 1;
17919   bit8                      LBA[4];
17920   bit8                      TL[4];
17921 
17922   pSatDevData   = satIOContext->pSatDevData;
17923   scsiCmnd      = &smScsiRequest->scsiCmnd;
17924   fis           = satIOContext->pFis;
17925 
17926   SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: start\n"));
17927   sm_memset(LBA, 0, sizeof(LBA));
17928   sm_memset(TL, 0, sizeof(TL));
17929   /* do not use memcpy due to indexing in LBA and TL */
17930   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
17931   LBA[1] = scsiCmnd->cdb[3];
17932   LBA[2] = scsiCmnd->cdb[4];
17933   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
17934   TL[0] = scsiCmnd->cdb[6];   /* MSB */
17935   TL[1] = scsiCmnd->cdb[7];
17936   TL[2] = scsiCmnd->cdb[7];
17937   TL[3] = scsiCmnd->cdb[8];   /* LSB */
17938   lba = smsatComputeCDB12LBA(satIOContext);
17939   tl = smsatComputeCDB12TL(satIOContext);
17940   if (pSatDevData->sat48BitSupport == agTRUE)
17941   {
17942     SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n"));
17943     fis->h.fisType        = 0x27;                   /* Reg host to device */
17944     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
17945 
17946     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17947     fis->h.features       = 0;                      /* FIS reserve */
17948     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
17949     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
17950     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
17951     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
17952     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
17953     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
17954     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
17955     fis->d.featuresExp    = 0;                      /* FIS reserve */
17956     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
17957     fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
17958 
17959     fis->d.reserved4      = 0;
17960     fis->d.control        = 0;                      /* FIS HOB bit clear */
17961     fis->d.reserved5      = 0;
17962 
17963     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17964     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
17965   }
17966   else
17967   {
17968     SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n"));
17969     fis->h.fisType        = 0x27;                   /* Reg host to device */
17970     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
17971     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
17972     fis->h.features       = 0;                      /* FIS reserve */
17973     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
17974     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
17975     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
17976       /* FIS LBA mode set LBA (27:24) */
17977     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
17978     fis->d.lbaLowExp      = 0;
17979     fis->d.lbaMidExp      = 0;
17980     fis->d.lbaHighExp     = 0;
17981     fis->d.featuresExp    = 0;
17982     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
17983     fis->d.sectorCountExp = 0;
17984     fis->d.reserved4      = 0;
17985     fis->d.control        = 0;                      /* FIS HOB bit clear */
17986     fis->d.reserved5      = 0;
17987 
17988     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17989     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
17990 
17991  }
17992 
17993   satIOContext->currentLBA = lba;
17994   satIOContext->OrgTL = tl;
17995 
17996   /*
17997     computing number of loop and remainder for tl
17998     0xFF in case not ext
17999     0xFFFF in case EXT
18000   */
18001   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
18002   {
18003     LoopNum = smsatComputeLoopNum(tl, 0xFF);
18004   }
18005   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
18006   {
18007     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
18008     LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
18009   }
18010   else
18011   {
18012     SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
18013     LoopNum = 1;
18014   }
18015 
18016   satIOContext->LoopNum = LoopNum;
18017 
18018   if (LoopNum == 1)
18019   {
18020     SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
18021     /* Initialize CB for SATA completion.
18022      */
18023     satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
18024   }
18025   else
18026   {
18027     SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: CHAINED data!!!\n"));
18028     /* re-setting tl */
18029     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
18030     {
18031        fis->d.sectorCount    = 0xFF;
18032     }
18033     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
18034     {
18035       fis->d.sectorCount    = 0xFF;
18036       fis->d.sectorCountExp = 0xFF;
18037     }
18038     else
18039     {
18040       SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
18041     }
18042 
18043     /* Initialize CB for SATA completion.
18044      */
18045     satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18046   }
18047 
18048 
18049   /*
18050    * Prepare SGL and send FIS to LL layer.
18051    */
18052   satIOContext->reqType = agRequestType;       /* Save it */
18053 
18054   status = smsataLLIOStart( smRoot,
18055                             smIORequest,
18056                             smDeviceHandle,
18057                             smScsiRequest,
18058                             satIOContext);
18059   return (status);
18060 
18061 
18062 }
18063 
18064 osGLOBAL bit32
18065 smsatChainedWriteNVerify_Write(
18066                                smRoot_t                  *smRoot,
18067                                smIORequest_t             *smIORequest,
18068                                smDeviceHandle_t          *smDeviceHandle,
18069                                smScsiInitiatorRequest_t  *smScsiRequest,
18070                                smSatIOContext_t            *satIOContext
18071                               )
18072 {
18073   /*
18074     Assumption: error check on lba and tl has been done in satWrite*()
18075     lba = lba + tl;
18076   */
18077   bit32                     status;
18078   smSatIOContext_t            *satOrgIOContext = agNULL;
18079   smIniScsiCmnd_t           *scsiCmnd;
18080   agsaFisRegHostToDevice_t  *fis;
18081   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18082   bit32                     lba = 0;
18083   bit32                     DenomTL = 0xFF;
18084   bit32                     Remainder = 0;
18085   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
18086 
18087   SM_DBG1(("smsatChainedWriteNVerify_Write: start\n"));
18088 
18089   fis             = satIOContext->pFis;
18090   satOrgIOContext = satIOContext->satOrgIOContext;
18091   scsiCmnd        = satOrgIOContext->pScsiCmnd;
18092 
18093 
18094   sm_memset(LBA,0, sizeof(LBA));
18095 
18096   switch (satOrgIOContext->ATACmd)
18097   {
18098   case SAT_WRITE_DMA:
18099     DenomTL = 0xFF;
18100     break;
18101   case SAT_WRITE_SECTORS:
18102     DenomTL = 0xFF;
18103     break;
18104   case SAT_WRITE_DMA_EXT:
18105     DenomTL = 0xFFFF;
18106     break;
18107   case SAT_WRITE_DMA_FUA_EXT:
18108     DenomTL = 0xFFFF;
18109     break;
18110   case SAT_WRITE_SECTORS_EXT:
18111     DenomTL = 0xFFFF;
18112     break;
18113   case SAT_WRITE_FPDMA_QUEUED:
18114     DenomTL = 0xFFFF;
18115     break;
18116   default:
18117     SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18118     return SM_RC_FAILURE;
18119     break;
18120   }
18121 
18122   Remainder = satOrgIOContext->OrgTL % DenomTL;
18123   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18124   lba = satOrgIOContext->currentLBA;
18125 
18126   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18127   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18128   LBA[2] = (bit8)((lba & 0xF0) >> 8);
18129   LBA[3] = (bit8)(lba & 0xF);               /* LSB */
18130 
18131   switch (satOrgIOContext->ATACmd)
18132   {
18133   case SAT_WRITE_DMA:
18134     fis->h.fisType        = 0x27;                   /* Reg host to device */
18135     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18136     fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
18137     fis->h.features       = 0;                      /* FIS reserve */
18138     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18139     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18140     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18141 
18142     /* FIS LBA mode set LBA (27:24) */
18143     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18144 
18145     fis->d.lbaLowExp      = 0;
18146     fis->d.lbaMidExp      = 0;
18147     fis->d.lbaHighExp     = 0;
18148     fis->d.featuresExp    = 0;
18149     if (satOrgIOContext->LoopNum == 1)
18150     {
18151       /* last loop */
18152       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
18153     }
18154     else
18155     {
18156       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
18157     }
18158     fis->d.sectorCountExp = 0;
18159     fis->d.reserved4      = 0;
18160     fis->d.control        = 0;                      /* FIS HOB bit clear */
18161     fis->d.reserved5      = 0;
18162 
18163     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18164 
18165     break;
18166   case SAT_WRITE_SECTORS:
18167     fis->h.fisType        = 0x27;                   /* Reg host to device */
18168     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18169     fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
18170     fis->h.features       = 0;                      /* FIS reserve */
18171     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18172     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18173     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18174 
18175     /* FIS LBA mode set LBA (27:24) */
18176     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18177 
18178     fis->d.lbaLowExp      = 0;
18179     fis->d.lbaMidExp      = 0;
18180     fis->d.lbaHighExp     = 0;
18181     fis->d.featuresExp    = 0;
18182     if (satOrgIOContext->LoopNum == 1)
18183     {
18184       /* last loop */
18185       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
18186     }
18187     else
18188     {
18189       fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
18190     }
18191     fis->d.sectorCountExp = 0;
18192     fis->d.reserved4      = 0;
18193     fis->d.control        = 0;                      /* FIS HOB bit clear */
18194     fis->d.reserved5      = 0;
18195 
18196     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18197 
18198     break;
18199   case SAT_WRITE_DMA_EXT:
18200     fis->h.fisType        = 0x27;                   /* Reg host to device */
18201     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18202     fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
18203     fis->h.features       = 0;                      /* FIS reserve */
18204     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18205     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18206     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18207     fis->d.device         = 0x40;                   /* FIS LBA mode set */
18208     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18209     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18210     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18211     fis->d.featuresExp    = 0;                      /* FIS reserve */
18212     if (satOrgIOContext->LoopNum == 1)
18213     {
18214       /* last loop */
18215       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
18216       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18217     }
18218     else
18219     {
18220       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
18221       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
18222     }
18223     fis->d.reserved4      = 0;
18224     fis->d.control        = 0;                       /* FIS HOB bit clear */
18225     fis->d.reserved5      = 0;
18226 
18227     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18228 
18229     break;
18230   case SAT_WRITE_SECTORS_EXT:
18231     fis->h.fisType        = 0x27;                   /* Reg host to device */
18232     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18233     fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
18234 
18235     fis->h.features       = 0;                      /* FIS reserve */
18236     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18237     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18238     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18239     fis->d.device         = 0x40;                   /* FIS LBA mode set */
18240     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18241     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18242     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18243     fis->d.featuresExp    = 0;                      /* FIS reserve */
18244     if (satOrgIOContext->LoopNum == 1)
18245     {
18246       /* last loop */
18247       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
18248       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
18249     }
18250     else
18251     {
18252       fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
18253       fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
18254     }
18255     fis->d.reserved4      = 0;
18256     fis->d.control        = 0;                      /* FIS HOB bit clear */
18257     fis->d.reserved5      = 0;
18258 
18259     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18260 
18261     break;
18262   case SAT_WRITE_FPDMA_QUEUED:
18263     fis->h.fisType        = 0x27;                   /* Reg host to device */
18264     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18265     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
18266     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18267     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18268     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18269 
18270     /* Check FUA bit */
18271     if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
18272       fis->d.device       = 0xC0;                   /* FIS FUA set */
18273     else
18274       fis->d.device       = 0x40;                   /* FIS FUA clear */
18275 
18276     fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
18277     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18278     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18279     if (satOrgIOContext->LoopNum == 1)
18280     {
18281       /* last loop */
18282       fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
18283       fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18284     }
18285     else
18286     {
18287       fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
18288       fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
18289     }
18290     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
18291     fis->d.sectorCountExp = 0;
18292     fis->d.reserved4      = 0;
18293     fis->d.control        = 0;                      /* FIS HOB bit clear */
18294     fis->d.reserved5      = 0;
18295 
18296     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
18297     break;
18298 
18299   default:
18300     SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18301     return SM_RC_FAILURE;
18302     break;
18303   }
18304 
18305   /* Initialize CB for SATA completion.
18306    */
18307   /* chained data */
18308   satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18309 
18310 
18311   /*
18312    * Prepare SGL and send FIS to LL layer.
18313    */
18314   satIOContext->reqType = agRequestType;       /* Save it */
18315 
18316   status = smsataLLIOStart( smRoot,
18317                             smIORequest,
18318                             smDeviceHandle,
18319                             smScsiRequest,
18320                             satIOContext);
18321 
18322   SM_DBG5(("satChainedWriteNVerify_Write: return\n"));
18323   return (status);
18324 }
18325 
18326 osGLOBAL bit32
18327 smsatChainedWriteNVerify_Verify(
18328                                 smRoot_t                  *smRoot,
18329                                 smIORequest_t             *smIORequest,
18330                                 smDeviceHandle_t          *smDeviceHandle,
18331                                 smScsiInitiatorRequest_t  *smScsiRequest,
18332                                 smSatIOContext_t            *satIOContext
18333                                )
18334 {
18335   bit32                     status;
18336   smSatIOContext_t         *satOrgIOContext = agNULL;
18337   agsaFisRegHostToDevice_t *fis;
18338   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18339   bit32                     lba = 0;
18340   bit32                     DenomTL = 0xFF;
18341   bit32                     Remainder = 0;
18342   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
18343 
18344   SM_DBG2(("smsatChainedWriteNVerify_Verify: start\n"));
18345   fis             = satIOContext->pFis;
18346   satOrgIOContext = satIOContext->satOrgIOContext;
18347   sm_memset(LBA,0, sizeof(LBA));
18348   switch (satOrgIOContext->ATACmd)
18349   {
18350   case SAT_READ_VERIFY_SECTORS:
18351     DenomTL = 0xFF;
18352     break;
18353   case SAT_READ_VERIFY_SECTORS_EXT:
18354     DenomTL = 0xFFFF;
18355     break;
18356   default:
18357     SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18358     return SM_RC_FAILURE;
18359     break;
18360   }
18361 
18362   Remainder = satOrgIOContext->OrgTL % DenomTL;
18363   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18364   lba = satOrgIOContext->currentLBA;
18365 
18366   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18367   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18368   LBA[2] = (bit8)((lba & 0xF0) >> 8);
18369   LBA[3] = (bit8)(lba & 0xF);               /* LSB */
18370 
18371   switch (satOrgIOContext->ATACmd)
18372   {
18373   case SAT_READ_VERIFY_SECTORS:
18374     fis->h.fisType        = 0x27;                   /* Reg host to device */
18375     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18376     fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
18377     fis->h.features       = 0;                      /* FIS reserve */
18378     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18379     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18380     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18381 
18382     /* FIS LBA mode set LBA (27:24) */
18383     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18384 
18385     fis->d.lbaLowExp      = 0;
18386     fis->d.lbaMidExp      = 0;
18387     fis->d.lbaHighExp     = 0;
18388     fis->d.featuresExp    = 0;
18389     if (satOrgIOContext->LoopNum == 1)
18390     {
18391       /* last loop */
18392       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
18393     }
18394     else
18395     {
18396       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
18397     }
18398     fis->d.sectorCountExp = 0;
18399     fis->d.reserved4      = 0;
18400     fis->d.control        = 0;                      /* FIS HOB bit clear */
18401     fis->d.reserved5      = 0;
18402 
18403     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18404 
18405     break;
18406   case SAT_READ_VERIFY_SECTORS_EXT:
18407     fis->h.fisType        = 0x27;                   /* Reg host to device */
18408     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18409     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
18410     fis->h.features       = 0;                      /* FIS reserve */
18411     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18412     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18413     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18414     fis->d.device         = 0x40;                   /* FIS LBA mode set */
18415     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18416     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18417     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18418     fis->d.featuresExp    = 0;                      /* FIS reserve */
18419     if (satOrgIOContext->LoopNum == 1)
18420     {
18421       /* last loop */
18422       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
18423       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18424     }
18425     else
18426     {
18427       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
18428       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
18429     }
18430     fis->d.reserved4      = 0;
18431     fis->d.control        = 0;                       /* FIS HOB bit clear */
18432     fis->d.reserved5      = 0;
18433 
18434     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18435 
18436     break;
18437 
18438   default:
18439     SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18440     return SM_RC_FAILURE;
18441     break;
18442   }
18443 
18444   /* Initialize CB for SATA completion.
18445    */
18446   /* chained data */
18447   satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18448 
18449 
18450   /*
18451    * Prepare SGL and send FIS to LL layer.
18452    */
18453   satIOContext->reqType = agRequestType;       /* Save it */
18454 
18455   status = smsataLLIOStart( smRoot,
18456                             smIORequest,
18457                             smDeviceHandle,
18458                             smScsiRequest,
18459                             satIOContext);
18460 
18461   SM_DBG5(("smsatChainedWriteNVerify_Verify: return\n"));
18462   return (status);
18463 }
18464 
18465 osGLOBAL bit32
18466 smsatChainedVerify(
18467                     smRoot_t                  *smRoot,
18468                     smIORequest_t             *smIORequest,
18469                     smDeviceHandle_t          *smDeviceHandle,
18470                     smScsiInitiatorRequest_t  *smScsiRequest,
18471                     smSatIOContext_t            *satIOContext
18472        )
18473 {
18474   bit32                     status;
18475   smSatIOContext_t         *satOrgIOContext = agNULL;
18476   agsaFisRegHostToDevice_t *fis;
18477   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18478   bit32                     lba = 0;
18479   bit32                     DenomTL = 0xFF;
18480   bit32                     Remainder = 0;
18481   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
18482 
18483   SM_DBG2(("smsatChainedVerify: start\n"));
18484   fis             = satIOContext->pFis;
18485   satOrgIOContext = satIOContext->satOrgIOContext;
18486   sm_memset(LBA,0, sizeof(LBA));
18487   switch (satOrgIOContext->ATACmd)
18488   {
18489   case SAT_READ_VERIFY_SECTORS:
18490     DenomTL = 0xFF;
18491     break;
18492   case SAT_READ_VERIFY_SECTORS_EXT:
18493     DenomTL = 0xFFFF;
18494     break;
18495   default:
18496     SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18497     return tiError;
18498     break;
18499   }
18500 
18501   Remainder = satOrgIOContext->OrgTL % DenomTL;
18502   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18503   lba = satOrgIOContext->currentLBA;
18504 
18505   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18506   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18507   LBA[2] = (bit8)((lba & 0xF0) >> 8);
18508   LBA[3] = (bit8)(lba & 0xF);               /* LSB */
18509 
18510   switch (satOrgIOContext->ATACmd)
18511   {
18512   case SAT_READ_VERIFY_SECTORS:
18513     fis->h.fisType        = 0x27;                   /* Reg host to device */
18514     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
18515     fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
18516     fis->h.features       = 0;                      /* FIS reserve */
18517     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18518     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18519     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18520 
18521     /* FIS LBA mode set LBA (27:24) */
18522     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18523 
18524     fis->d.lbaLowExp      = 0;
18525     fis->d.lbaMidExp      = 0;
18526     fis->d.lbaHighExp     = 0;
18527     fis->d.featuresExp    = 0;
18528     if (satOrgIOContext->LoopNum == 1)
18529     {
18530       /* last loop */
18531       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
18532     }
18533     else
18534     {
18535       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
18536     }
18537     fis->d.sectorCountExp = 0;
18538     fis->d.reserved4      = 0;
18539     fis->d.control        = 0;                      /* FIS HOB bit clear */
18540     fis->d.reserved5      = 0;
18541 
18542     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18543 
18544     break;
18545   case SAT_READ_VERIFY_SECTORS_EXT:
18546     fis->h.fisType        = 0x27;                   /* Reg host to device */
18547     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18548     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
18549     fis->h.features       = 0;                      /* FIS reserve */
18550     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
18551     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
18552     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
18553     fis->d.device         = 0x40;                   /* FIS LBA mode set */
18554     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
18555     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18556     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18557     fis->d.featuresExp    = 0;                      /* FIS reserve */
18558     if (satOrgIOContext->LoopNum == 1)
18559     {
18560       /* last loop */
18561       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
18562       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
18563     }
18564     else
18565     {
18566       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
18567       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
18568     }
18569     fis->d.reserved4      = 0;
18570     fis->d.control        = 0;                       /* FIS HOB bit clear */
18571     fis->d.reserved5      = 0;
18572 
18573     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18574 
18575     break;
18576 
18577   default:
18578     SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18579     return tiError;
18580     break;
18581   }
18582 
18583   /* Initialize CB for SATA completion.
18584    */
18585   /* chained data */
18586   satIOContext->satCompleteCB = &smsatChainedVerifyCB;
18587 
18588 
18589   /*
18590    * Prepare SGL and send FIS to LL layer.
18591    */
18592   satIOContext->reqType = agRequestType;       /* Save it */
18593 
18594   status = smsataLLIOStart( smRoot,
18595                             smIORequest,
18596                             smDeviceHandle,
18597                             smScsiRequest,
18598                             satIOContext);
18599 
18600   SM_DBG5(("satChainedVerify: return\n"));
18601   return (status);
18602 }
18603 
18604 osGLOBAL bit32
18605 smsatWriteSame10_1(
18606                     smRoot_t                  *smRoot,
18607                     smIORequest_t             *smIORequest,
18608                     smDeviceHandle_t          *smDeviceHandle,
18609                     smScsiInitiatorRequest_t  *smScsiRequest,
18610                     smSatIOContext_t            *satIOContext,
18611                     bit32                     lba
18612                   )
18613 {
18614   /*
18615     sends SAT_WRITE_DMA_EXT
18616   */
18617 
18618   bit32                     status;
18619   bit32                     agRequestType;
18620   agsaFisRegHostToDevice_t  *fis;
18621   bit8                      lba1, lba2 ,lba3, lba4;
18622 
18623   SM_DBG5(("smsatWriteSame10_1: start\n"));
18624   fis               = satIOContext->pFis;
18625   /* MSB */
18626   lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18627   lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18628   lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18629   /* LSB */
18630   lba4 = (bit8)(lba & 0x000000FF);
18631   /* SAT_WRITE_DMA_EXT */
18632   fis->h.fisType        = 0x27;                   /* Reg host to device */
18633   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18634   fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
18635   fis->h.features       = 0;                      /* FIS reserve */
18636   fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
18637   fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
18638   fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
18639   fis->d.device         = 0x40;                   /* FIS LBA mode set */
18640   fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
18641   fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18642   fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18643   fis->d.featuresExp    = 0;                      /* FIS reserve */
18644   /* one sector at a time */
18645   fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18646   fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18647   fis->d.reserved4      = 0;
18648   fis->d.control        = 0;                      /* FIS HOB bit clear */
18649   fis->d.reserved5      = 0;
18650   agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18651   /* Initialize CB for SATA completion.
18652    */
18653   satIOContext->satCompleteCB = &smsatWriteSame10CB;
18654   /*
18655    * Prepare SGL and send FIS to LL layer.
18656    */
18657   satIOContext->reqType = agRequestType;       /* Save it */
18658   status = smsataLLIOStart( smRoot,
18659                             smIORequest,
18660                             smDeviceHandle,
18661                             smScsiRequest,
18662                             satIOContext);
18663   SM_DBG5(("smsatWriteSame10_1 return status %d\n", status));
18664   return status;
18665 }
18666 
18667 
18668 osGLOBAL bit32
18669 smsatWriteSame10_2(
18670                     smRoot_t                  *smRoot,
18671                     smIORequest_t             *smIORequest,
18672                     smDeviceHandle_t          *smDeviceHandle,
18673                     smScsiInitiatorRequest_t  *smScsiRequest,
18674                     smSatIOContext_t            *satIOContext,
18675                     bit32                     lba
18676                   )
18677 {
18678   /*
18679     sends SAT_WRITE_SECTORS_EXT
18680   */
18681 
18682   bit32                     status;
18683   bit32                     agRequestType;
18684   agsaFisRegHostToDevice_t  *fis;
18685   bit8                      lba1, lba2 ,lba3, lba4;
18686 
18687   SM_DBG5(("smsatWriteSame10_2: start\n"));
18688   fis               = satIOContext->pFis;
18689   /* MSB */
18690   lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18691   lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18692   lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18693   /* LSB */
18694   lba4 = (bit8)(lba & 0x000000FF);
18695   /* SAT_WRITE_SECTORS_EXT */
18696   fis->h.fisType        = 0x27;                   /* Reg host to device */
18697   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18698   fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
18699   fis->h.features       = 0;                      /* FIS reserve */
18700   fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
18701   fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
18702   fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
18703   fis->d.device         = 0x40;                   /* FIS LBA mode set */
18704   fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
18705   fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18706   fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18707   fis->d.featuresExp    = 0;                      /* FIS reserve */
18708   /* one sector at a time */
18709   fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18710   fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18711   fis->d.reserved4      = 0;
18712   fis->d.control        = 0;                      /* FIS HOB bit clear */
18713   fis->d.reserved5      = 0;
18714   agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18715   /* Initialize CB for SATA completion.
18716    */
18717   satIOContext->satCompleteCB = &smsatWriteSame10CB;
18718   /*
18719    * Prepare SGL and send FIS to LL layer.
18720    */
18721   satIOContext->reqType = agRequestType;       /* Save it */
18722   status = smsataLLIOStart( smRoot,
18723                             smIORequest,
18724                             smDeviceHandle,
18725                             smScsiRequest,
18726                             satIOContext);
18727   SM_DBG5(("smsatWriteSame10_2 return status %d\n", status));
18728   return status;
18729 }
18730 
18731 
18732 osGLOBAL bit32
18733 smsatWriteSame10_3(
18734                     smRoot_t                  *smRoot,
18735                     smIORequest_t             *smIORequest,
18736                     smDeviceHandle_t          *smDeviceHandle,
18737                     smScsiInitiatorRequest_t  *smScsiRequest,
18738                     smSatIOContext_t            *satIOContext,
18739                     bit32                     lba
18740                   )
18741 {
18742   /*
18743     sends SAT_WRITE_FPDMA_QUEUED
18744   */
18745 
18746   bit32                     status;
18747   bit32                     agRequestType;
18748   agsaFisRegHostToDevice_t  *fis;
18749   bit8                      lba1, lba2 ,lba3, lba4;
18750 
18751   SM_DBG5(("smsatWriteSame10_3: start\n"));
18752   fis               = satIOContext->pFis;
18753   /* MSB */
18754   lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18755   lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18756   lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18757   /* LSB */
18758   lba4 = (bit8)(lba & 0x000000FF);
18759 
18760   /* SAT_WRITE_FPDMA_QUEUED */
18761   fis->h.fisType        = 0x27;                   /* Reg host to device */
18762   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18763   fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
18764 
18765 
18766   /* one sector at a time */
18767   fis->h.features       = 1;                      /* FIS sector count (7:0) */
18768   fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
18769 
18770   fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
18771   fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
18772   fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
18773   /* NO FUA bit in the WRITE SAME 10 */
18774   fis->d.device         = 0x40;                   /* FIS FUA clear */
18775   fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
18776   fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18777   fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18778   fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
18779   fis->d.sectorCountExp = 0;
18780   fis->d.reserved4      = 0;
18781   fis->d.control        = 0;                      /* FIS HOB bit clear */
18782   fis->d.reserved5      = 0;
18783   agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
18784 
18785   /* Initialize CB for SATA completion.
18786    */
18787   satIOContext->satCompleteCB = &smsatWriteSame10CB;
18788   /*
18789    * Prepare SGL and send FIS to LL layer.
18790    */
18791   satIOContext->reqType = agRequestType;       /* Save it */
18792   status = smsataLLIOStart( smRoot,
18793                             smIORequest,
18794                             smDeviceHandle,
18795                             smScsiRequest,
18796                             satIOContext);
18797 
18798   SM_DBG5(("smsatWriteSame10_3 return status %d\n", status));
18799   return status;
18800 }
18801 
18802 osGLOBAL bit32
18803 smsatStartStopUnit_1(
18804                      smRoot_t                  *smRoot,
18805                      smIORequest_t             *smIORequest,
18806                      smDeviceHandle_t          *smDeviceHandle,
18807                      smScsiInitiatorRequest_t  *smScsiRequest,
18808                      smSatIOContext_t            *satIOContext
18809         )
18810 {
18811   /*
18812     SAT Rev 8, Table 48, 9.11.3 p55
18813     sends STANDBY
18814   */
18815   bit32                     status;
18816   bit32                     agRequestType;
18817   agsaFisRegHostToDevice_t  *fis;
18818 
18819   SM_DBG5(("smsatStartStopUnit_1: start\n"));
18820   fis               = satIOContext->pFis;
18821   /* STANDBY */
18822   fis->h.fisType        = 0x27;                   /* Reg host to device */
18823   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18824   fis->h.command        = SAT_STANDBY;            /* 0xE2 */
18825   fis->h.features       = 0;                      /* FIS features NA       */
18826   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
18827   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
18828   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
18829   fis->d.lbaLowExp      = 0;
18830   fis->d.lbaMidExp      = 0;
18831   fis->d.lbaHighExp     = 0;
18832   fis->d.featuresExp    = 0;
18833   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
18834   fis->d.sectorCountExp = 0;
18835   fis->d.reserved4      = 0;
18836   fis->d.device         = 0;                      /* 0 */
18837   fis->d.control        = 0;                      /* FIS HOB bit clear */
18838   fis->d.reserved5      = 0;
18839 
18840   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18841 
18842   /* Initialize CB for SATA completion.
18843    */
18844   satIOContext->satCompleteCB = &smsatStartStopUnitCB;
18845 
18846   /*
18847    * Prepare SGL and send FIS to LL layer.
18848    */
18849   satIOContext->reqType = agRequestType;       /* Save it */
18850 
18851   status = smsataLLIOStart( smRoot,
18852                             smIORequest,
18853                             smDeviceHandle,
18854                             smScsiRequest,
18855                             satIOContext);
18856 
18857   SM_DBG5(("smsatStartStopUnit_1 return status %d\n", status));
18858   return status;
18859 }
18860 
18861 osGLOBAL bit32
18862 smsatSendDiagnostic_1(
18863                       smRoot_t                  *smRoot,
18864                       smIORequest_t             *smIORequest,
18865                       smDeviceHandle_t          *smDeviceHandle,
18866                       smScsiInitiatorRequest_t  *smScsiRequest,
18867                       smSatIOContext_t            *satIOContext
18868          )
18869 {
18870   /*
18871     SAT Rev9, Table29, p41
18872     send 2nd SAT_READ_VERIFY_SECTORS(_EXT)
18873   */
18874   bit32                     status;
18875   bit32                     agRequestType;
18876   smDeviceData_t            *pSatDevData;
18877   agsaFisRegHostToDevice_t  *fis;
18878 
18879   SM_DBG5(("smsatSendDiagnostic_1: start\n"));
18880   pSatDevData       = satIOContext->pSatDevData;
18881   fis               = satIOContext->pFis;
18882   /*
18883     sector count 1, LBA MAX
18884   */
18885   if (pSatDevData->sat48BitSupport == agTRUE)
18886   {
18887     /* sends READ VERIFY SECTOR(S) EXT*/
18888     fis->h.fisType        = 0x27;                   /* Reg host to device */
18889     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18890     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
18891     fis->h.features       = 0;                      /* FIS reserve */
18892     fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
18893     fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
18894     fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
18895     fis->d.lbaLowExp      = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */
18896     fis->d.lbaMidExp      = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */
18897     fis->d.lbaHighExp     = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */
18898     fis->d.featuresExp    = 0;                      /* FIS reserve */
18899     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18900     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18901     fis->d.reserved4      = 0;
18902     fis->d.device         = 0x40;                   /* 01000000 */
18903     fis->d.control        = 0;                      /* FIS HOB bit clear */
18904     fis->d.reserved5      = 0;
18905 
18906   }
18907   else
18908   {
18909     /* READ VERIFY SECTOR(S)*/
18910     fis->h.fisType        = 0x27;                   /* Reg host to device */
18911     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18912     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
18913     fis->h.features       = 0;                      /* FIS features NA       */
18914     fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
18915     fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
18916     fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
18917     fis->d.lbaLowExp      = 0;
18918     fis->d.lbaMidExp      = 0;
18919     fis->d.lbaHighExp     = 0;
18920     fis->d.featuresExp    = 0;
18921     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18922     fis->d.sectorCountExp = 0;
18923     fis->d.reserved4      = 0;
18924     fis->d.device         = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF));
18925                             /* DEV and LBA 27:24 */
18926     fis->d.control        = 0;                      /* FIS HOB bit clear */
18927     fis->d.reserved5      = 0;
18928 
18929   }
18930 
18931   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18932 
18933   /* Initialize CB for SATA completion.
18934    */
18935   satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
18936 
18937   /*
18938    * Prepare SGL and send FIS to LL layer.
18939    */
18940   satIOContext->reqType = agRequestType;       /* Save it */
18941 
18942   status = smsataLLIOStart( smRoot,
18943                             smIORequest,
18944                             smDeviceHandle,
18945                             smScsiRequest,
18946                             satIOContext);
18947 
18948 
18949   return status;
18950 }
18951 
18952 osGLOBAL bit32
18953 smsatSendDiagnostic_2(
18954                       smRoot_t                  *smRoot,
18955                       smIORequest_t             *smIORequest,
18956                       smDeviceHandle_t          *smDeviceHandle,
18957                       smScsiInitiatorRequest_t  *smScsiRequest,
18958                       smSatIOContext_t            *satIOContext
18959          )
18960 {
18961   /*
18962     SAT Rev9, Table29, p41
18963     send 3rd SAT_READ_VERIFY_SECTORS(_EXT)
18964   */
18965   bit32                     status;
18966   bit32                     agRequestType;
18967   smDeviceData_t            *pSatDevData;
18968   agsaFisRegHostToDevice_t  *fis;
18969 
18970   SM_DBG5(("smsatSendDiagnostic_2: start\n"));
18971 
18972   pSatDevData       = satIOContext->pSatDevData;
18973   fis               = satIOContext->pFis;
18974   /*
18975     sector count 1, LBA Random
18976   */
18977   if (pSatDevData->sat48BitSupport == agTRUE)
18978   {
18979     /* sends READ VERIFY SECTOR(S) EXT*/
18980     fis->h.fisType        = 0x27;                   /* Reg host to device */
18981     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18982     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
18983     fis->h.features       = 0;                      /* FIS reserve */
18984     fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
18985     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
18986     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
18987     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
18988     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
18989     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
18990     fis->d.featuresExp    = 0;                      /* FIS reserve */
18991     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
18992     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
18993     fis->d.reserved4      = 0;
18994     fis->d.device         = 0x40;                   /* 01000000 */
18995     fis->d.control        = 0;                      /* FIS HOB bit clear */
18996     fis->d.reserved5      = 0;
18997 
18998   }
18999   else
19000   {
19001     /* READ VERIFY SECTOR(S)*/
19002     fis->h.fisType        = 0x27;                   /* Reg host to device */
19003     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19004     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
19005     fis->h.features       = 0;                      /* FIS features NA       */
19006     fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
19007     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19008     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19009     fis->d.lbaLowExp      = 0;
19010     fis->d.lbaMidExp      = 0;
19011     fis->d.lbaHighExp     = 0;
19012     fis->d.featuresExp    = 0;
19013     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19014     fis->d.sectorCountExp = 0;
19015     fis->d.reserved4      = 0;
19016     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
19017     fis->d.control        = 0;                      /* FIS HOB bit clear */
19018     fis->d.reserved5      = 0;
19019 
19020   }
19021 
19022   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19023 
19024   /* Initialize CB for SATA completion.
19025    */
19026   satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
19027 
19028   /*
19029    * Prepare SGL and send FIS to LL layer.
19030    */
19031   satIOContext->reqType = agRequestType;       /* Save it */
19032 
19033   status = smsataLLIOStart( smRoot,
19034                             smIORequest,
19035                             smDeviceHandle,
19036                             smScsiRequest,
19037                             satIOContext);
19038 
19039 
19040   return status;
19041 }
19042 
19043 osGLOBAL bit32
19044 smsatModeSelect6n10_1(
19045                       smRoot_t                  *smRoot,
19046                       smIORequest_t             *smIORequest,
19047                       smDeviceHandle_t          *smDeviceHandle,
19048                       smScsiInitiatorRequest_t  *smScsiRequest,
19049                       smSatIOContext_t            *satIOContext
19050          )
19051 {
19052   /* sends either ATA SET FEATURES based on DRA bit */
19053   bit32                     status;
19054   bit32                     agRequestType;
19055   agsaFisRegHostToDevice_t  *fis;
19056   bit8                      *pLogPage;    /* Log Page data buffer */
19057   bit32                     StartingIndex = 0;
19058 
19059   fis           = satIOContext->pFis;
19060   pLogPage      = (bit8 *) smScsiRequest->sglVirtualAddr;
19061   SM_DBG5(("smsatModeSelect6n10_1: start\n"));
19062 
19063   if (pLogPage[3] == 8)
19064   {
19065     /* mode parameter block descriptor exists */
19066     StartingIndex = 12;
19067   }
19068   else
19069   {
19070     /* mode parameter block descriptor does not exist */
19071     StartingIndex = 4;
19072   }
19073 
19074   /* sends ATA SET FEATURES based on DRA bit */
19075   if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
19076   {
19077     SM_DBG5(("smsatModeSelect6n10_1: enable read look-ahead feature\n"));
19078     /* sends SET FEATURES */
19079     fis->h.fisType        = 0x27;                   /* Reg host to device */
19080     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19081 
19082     fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19083     fis->h.features       = 0xAA;                   /* enable read look-ahead */
19084     fis->d.lbaLow         = 0;                      /* */
19085     fis->d.lbaMid         = 0;                      /* */
19086     fis->d.lbaHigh        = 0;                      /* */
19087     fis->d.device         = 0;                      /* */
19088     fis->d.lbaLowExp      = 0;                      /* */
19089     fis->d.lbaMidExp      = 0;                      /* */
19090     fis->d.lbaHighExp     = 0;                      /* */
19091     fis->d.featuresExp    = 0;                      /* */
19092     fis->d.sectorCount    = 0;                      /* */
19093     fis->d.sectorCountExp = 0;                      /* */
19094     fis->d.reserved4      = 0;
19095     fis->d.control        = 0;                      /* FIS HOB bit clear */
19096     fis->d.reserved5      = 0;
19097 
19098     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19099 
19100     /* Initialize CB for SATA completion.
19101      */
19102     satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
19103 
19104     /*
19105      * Prepare SGL and send FIS to LL layer.
19106      */
19107     satIOContext->reqType = agRequestType;       /* Save it */
19108 
19109   status = smsataLLIOStart( smRoot,
19110                             smIORequest,
19111                             smDeviceHandle,
19112                             smScsiRequest,
19113                             satIOContext);
19114     return status;
19115   }
19116   else
19117   {
19118     SM_DBG5(("smsatModeSelect6n10_1: disable read look-ahead feature\n"));
19119         /* sends SET FEATURES */
19120     fis->h.fisType        = 0x27;                   /* Reg host to device */
19121     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19122 
19123     fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19124     fis->h.features       = 0x55;                   /* disable read look-ahead */
19125     fis->d.lbaLow         = 0;                      /* */
19126     fis->d.lbaMid         = 0;                      /* */
19127     fis->d.lbaHigh        = 0;                      /* */
19128     fis->d.device         = 0;                      /* */
19129     fis->d.lbaLowExp      = 0;                      /* */
19130     fis->d.lbaMidExp      = 0;                      /* */
19131     fis->d.lbaHighExp     = 0;                      /* */
19132     fis->d.featuresExp    = 0;                      /* */
19133     fis->d.sectorCount    = 0;                      /* */
19134     fis->d.sectorCountExp = 0;                      /* */
19135     fis->d.reserved4      = 0;
19136     fis->d.control        = 0;                      /* FIS HOB bit clear */
19137     fis->d.reserved5      = 0;
19138 
19139     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19140 
19141     /* Initialize CB for SATA completion.
19142      */
19143     satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
19144 
19145     /*
19146      * Prepare SGL and send FIS to LL layer.
19147      */
19148     satIOContext->reqType = agRequestType;       /* Save it */
19149 
19150   status = smsataLLIOStart( smRoot,
19151                             smIORequest,
19152                             smDeviceHandle,
19153                             smScsiRequest,
19154                             satIOContext);
19155     return status;
19156   }
19157 }
19158 
19159 
19160 osGLOBAL bit32
19161 smsatLogSense_1(
19162                 smRoot_t                  *smRoot,
19163                 smIORequest_t             *smIORequest,
19164                 smDeviceHandle_t          *smDeviceHandle,
19165                 smScsiInitiatorRequest_t  *smScsiRequest,
19166                 smSatIOContext_t            *satIOContext
19167                )
19168 {
19169   bit32                     status;
19170   bit32                     agRequestType;
19171   smDeviceData_t            *pSatDevData;
19172   agsaFisRegHostToDevice_t  *fis;
19173 
19174   pSatDevData   = satIOContext->pSatDevData;
19175   fis           = satIOContext->pFis;
19176 
19177   SM_DBG5(("smsatLogSense_1: start\n"));
19178 
19179   /* SAT Rev 8, 10.2.4 p74 */
19180   if ( pSatDevData->sat48BitSupport == agTRUE )
19181   {
19182     SM_DBG5(("smsatLogSense_1: case 2-1 sends READ LOG EXT\n"));
19183     /* sends READ LOG EXT */
19184     fis->h.fisType        = 0x27;                   /* Reg host to device */
19185     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19186 
19187     fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
19188     fis->h.features       = 0;                      /* FIS reserve */
19189     fis->d.lbaLow         = 0x07;                   /* 0x07 */
19190     fis->d.lbaMid         = 0;                      /*  */
19191     fis->d.lbaHigh        = 0;                      /*  */
19192     fis->d.device         = 0;                      /*  */
19193     fis->d.lbaLowExp      = 0;                      /*  */
19194     fis->d.lbaMidExp      = 0;                      /*  */
19195     fis->d.lbaHighExp     = 0;                      /*  */
19196     fis->d.featuresExp    = 0;                      /* FIS reserve */
19197     fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
19198     fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
19199     fis->d.reserved4      = 0;
19200     fis->d.control        = 0;                      /* FIS HOB bit clear */
19201     fis->d.reserved5      = 0;
19202 
19203     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19204 
19205     /* Initialize CB for SATA completion.
19206      */
19207     satIOContext->satCompleteCB = &smsatLogSenseCB;
19208 
19209     /*
19210      * Prepare SGL and send FIS to LL layer.
19211      */
19212     satIOContext->reqType = agRequestType;       /* Save it */
19213 
19214   status = smsataLLIOStart( smRoot,
19215                             smIORequest,
19216                             smDeviceHandle,
19217                             smScsiRequest,
19218                             satIOContext);
19219     return status;
19220 
19221   }
19222   else
19223   {
19224     SM_DBG5(("smsatLogSense_1: case 2-2 sends SMART READ LOG\n"));
19225     /* sends SMART READ LOG */
19226     fis->h.fisType        = 0x27;                   /* Reg host to device */
19227     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19228 
19229     fis->h.command        = SAT_SMART;              /* 0x2F */
19230     fis->h.features       = SAT_SMART_READ_LOG;     /* 0xd5 */
19231     fis->d.lbaLow         = 0x06;                   /* 0x06 */
19232     fis->d.lbaMid         = 0x00;                   /* 0x4f */
19233     fis->d.lbaHigh        = 0x00;                   /* 0xc2 */
19234     fis->d.device         = 0;                      /*  */
19235     fis->d.lbaLowExp      = 0;                      /*  */
19236     fis->d.lbaMidExp      = 0;                      /*  */
19237     fis->d.lbaHighExp     = 0;                      /*  */
19238     fis->d.featuresExp    = 0;                      /* FIS reserve */
19239     fis->d.sectorCount    = 0x01;                      /*  */
19240     fis->d.sectorCountExp = 0x00;                      /*  */
19241     fis->d.reserved4      = 0;
19242     fis->d.control        = 0;                      /* FIS HOB bit clear */
19243     fis->d.reserved5      = 0;
19244 
19245     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19246 
19247     /* Initialize CB for SATA completion.
19248      */
19249     satIOContext->satCompleteCB = &smsatLogSenseCB;
19250 
19251     /*
19252      * Prepare SGL and send FIS to LL layer.
19253      */
19254     satIOContext->reqType = agRequestType;       /* Save it */
19255 
19256   status = smsataLLIOStart( smRoot,
19257                             smIORequest,
19258                             smDeviceHandle,
19259                             smScsiRequest,
19260                             satIOContext);
19261     return status;
19262 
19263   }
19264 }
19265 
19266 osGLOBAL bit32
19267 smsatReassignBlocks_2(
19268                       smRoot_t                  *smRoot,
19269                       smIORequest_t             *smIORequest,
19270                       smDeviceHandle_t          *smDeviceHandle,
19271                       smScsiInitiatorRequest_t  *smScsiRequest,
19272                       smSatIOContext_t            *satIOContext,
19273                       bit8                      *LBA
19274                      )
19275 {
19276   /*
19277     assumes all LBA fits in ATA command; no boundary condition is checked here yet
19278     tiScsiRequest is TD generated for writing
19279   */
19280   bit32                     status;
19281   bit32                     agRequestType;
19282   smDeviceData_t            *pSatDevData;
19283   smScsiRspSense_t          *pSense;
19284   agsaFisRegHostToDevice_t  *fis;
19285 
19286   pSense        = satIOContext->pSense;
19287   pSatDevData   = satIOContext->pSatDevData;
19288   fis           = satIOContext->pFis;
19289   SM_DBG5(("smsatReassignBlocks_2: start\n"));
19290 
19291   if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
19292   {
19293     /* case 2 */
19294     /* WRITE DMA*/
19295     /* can't fit the transfer length */
19296     SM_DBG5(("smsatReassignBlocks_2: case 2\n"));
19297     fis->h.fisType        = 0x27;                   /* Reg host to device */
19298     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
19299     fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
19300     fis->h.features       = 0;                      /* FIS reserve */
19301     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19302     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19303     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19304 
19305     /* FIS LBA mode set LBA (27:24) */
19306     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19307 
19308     fis->d.lbaLowExp      = 0;
19309     fis->d.lbaMidExp      = 0;
19310     fis->d.lbaHighExp     = 0;
19311     fis->d.featuresExp    = 0;
19312     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19313     fis->d.sectorCountExp = 0;
19314     fis->d.reserved4      = 0;
19315     fis->d.control        = 0;                      /* FIS HOB bit clear */
19316     fis->d.reserved5      = 0;
19317 
19318     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
19319     satIOContext->ATACmd = SAT_WRITE_DMA;
19320   }
19321   else
19322   {
19323     /* case 1 */
19324     /* WRITE MULTIPLE or WRITE SECTOR(S) */
19325     /* WRITE SECTORS for easier implemetation */
19326     /* can't fit the transfer length */
19327     SM_DBG5(("smsatReassignBlocks_2: case 1\n"));
19328     fis->h.fisType        = 0x27;                   /* Reg host to device */
19329     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
19330     fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
19331     fis->h.features       = 0;                      /* FIS reserve */
19332     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19333     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19334     fis->d.lbaHigh        = LBA[7];                 /* FIS LBA (23:16) */
19335 
19336     /* FIS LBA mode set LBA (27:24) */
19337     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19338 
19339     fis->d.lbaLowExp      = 0;
19340     fis->d.lbaMidExp      = 0;
19341     fis->d.lbaHighExp     = 0;
19342     fis->d.featuresExp    = 0;
19343     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19344     fis->d.sectorCountExp = 0;
19345     fis->d.reserved4      = 0;
19346     fis->d.control        = 0;                      /* FIS HOB bit clear */
19347     fis->d.reserved5      = 0;
19348 
19349     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
19350     satIOContext->ATACmd = SAT_WRITE_SECTORS;
19351   }
19352 
19353   /* case 3 and 4 */
19354   if (pSatDevData->sat48BitSupport == agTRUE)
19355   {
19356     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
19357     {
19358       /* case 3 */
19359       /* WRITE DMA EXT or WRITE DMA FUA EXT */
19360       SM_DBG5(("smsatReassignBlocks_2: case 3\n"));
19361       fis->h.fisType        = 0x27;                   /* Reg host to device */
19362       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19363 
19364       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
19365       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
19366       satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
19367 
19368       fis->h.features       = 0;                      /* FIS reserve */
19369       fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19370       fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19371       fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19372       fis->d.device         = 0x40;                   /* FIS LBA mode set */
19373       fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19374       fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19375       fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19376       fis->d.featuresExp    = 0;                      /* FIS reserve */
19377       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19378       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
19379       fis->d.reserved4      = 0;
19380       fis->d.control        = 0;                      /* FIS HOB bit clear */
19381       fis->d.reserved5      = 0;
19382 
19383       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
19384     }
19385     else
19386     {
19387       /* case 4 */
19388       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
19389       /* WRITE SECTORS EXT for easier implemetation */
19390       SM_DBG5(("smsatReassignBlocks_2: case 4\n"));
19391       fis->h.fisType        = 0x27;                   /* Reg host to device */
19392       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19393       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
19394 
19395       fis->h.features       = 0;                      /* FIS reserve */
19396       fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19397       fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19398       fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19399       fis->d.device         = 0x40;                   /* FIS LBA mode set */
19400       fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19401       fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19402       fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19403       fis->d.featuresExp    = 0;                      /* FIS reserve */
19404       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19405       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
19406       fis->d.reserved4      = 0;
19407       fis->d.control        = 0;                      /* FIS HOB bit clear */
19408       fis->d.reserved5      = 0;
19409 
19410       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
19411       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
19412     }
19413   }
19414   /* case 5 */
19415   if (pSatDevData->satNCQ == agTRUE)
19416   {
19417     /* WRITE FPDMA QUEUED */
19418     if (pSatDevData->sat48BitSupport != agTRUE)
19419     {
19420       SM_DBG5(("smsatReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
19421       smsatSetSensePayload( pSense,
19422                             SCSI_SNSKEY_HARDWARE_ERROR,
19423                             0,
19424                             SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
19425                             satIOContext);
19426 
19427       /*smEnqueueIO(smRoot, satIOContext);*/
19428 
19429       tdsmIOCompletedCB( smRoot,
19430                          smIORequest,
19431                          smIOSuccess,
19432                          SCSI_STAT_CHECK_CONDITION,
19433                          satIOContext->pSmSenseData,
19434                          satIOContext->interruptContext );
19435       return SM_RC_SUCCESS;
19436     }
19437     SM_DBG6(("satWrite10: case 5\n"));
19438 
19439     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
19440 
19441     fis->h.fisType        = 0x27;                   /* Reg host to device */
19442     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19443     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
19444     fis->h.features       = 1;                      /* FIS sector count (7:0) */
19445     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19446     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19447     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19448 
19449     /* Check FUA bit */
19450     fis->d.device       = 0x40;                     /* FIS FUA clear */
19451 
19452     fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19453     fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19454     fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19455     fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
19456     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
19457     fis->d.sectorCountExp = 0;
19458     fis->d.reserved4      = 0;
19459     fis->d.control        = 0;                      /* FIS HOB bit clear */
19460     fis->d.reserved5      = 0;
19461 
19462     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
19463     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
19464   }
19465 
19466   satIOContext->satCompleteCB = &smsatReassignBlocksCB;
19467 
19468   /*
19469    * Prepare SGL and send FIS to LL layer.
19470    */
19471   satIOContext->reqType = agRequestType;       /* Save it */
19472 
19473   status = smsataLLIOStart( smRoot,
19474                             smIORequest,
19475                             smDeviceHandle,
19476                             /* not the original, should be the TD generated one */
19477                             smScsiRequest,
19478                             satIOContext);
19479   return (status);
19480 }
19481 
19482 osGLOBAL bit32
19483 smsatReassignBlocks_1(
19484                       smRoot_t                  *smRoot,
19485                       smIORequest_t             *smIORequest,
19486                       smDeviceHandle_t          *smDeviceHandle,
19487                       smScsiInitiatorRequest_t  *smScsiRequest,
19488                       smSatIOContext_t            *satIOContext,
19489                       smSatIOContext_t            *satOrgIOContext
19490                      )
19491 {
19492   /*
19493     assumes all LBA fits in ATA command; no boundary condition is checked here yet
19494     tiScsiRequest is OS generated; needs for accessing parameter list
19495   */
19496   bit32                     agRequestType;
19497   smDeviceData_t            *pSatDevData;
19498   smIniScsiCmnd_t           *scsiCmnd;
19499   agsaFisRegHostToDevice_t  *fis;
19500   bit8                      *pParmList;    /* Log Page data buffer */
19501   bit8                      LongLBA;
19502   bit8                      LBA[8];
19503   bit32                     startingIndex;
19504 
19505   pSatDevData   = satIOContext->pSatDevData;
19506   scsiCmnd      = &smScsiRequest->scsiCmnd;
19507   fis           = satIOContext->pFis;
19508   pParmList     = (bit8 *) smScsiRequest->sglVirtualAddr;
19509   SM_DBG5(("smsatReassignBlocks_1: start\n"));
19510   LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
19511   sm_memset(LBA, 0, sizeof(LBA));
19512   startingIndex = satOrgIOContext->ParmIndex;
19513   if (LongLBA == 0)
19514   {
19515     LBA[4] = pParmList[startingIndex];
19516     LBA[5] = pParmList[startingIndex+1];
19517     LBA[6] = pParmList[startingIndex+2];
19518     LBA[7] = pParmList[startingIndex+3];
19519     startingIndex = startingIndex + 4;
19520   }
19521   else
19522   {
19523     LBA[0] = pParmList[startingIndex];
19524     LBA[1] = pParmList[startingIndex+1];
19525     LBA[2] = pParmList[startingIndex+2];
19526     LBA[3] = pParmList[startingIndex+3];
19527     LBA[4] = pParmList[startingIndex+4];
19528     LBA[5] = pParmList[startingIndex+5];
19529     LBA[6] = pParmList[startingIndex+6];
19530     LBA[7] = pParmList[startingIndex+7];
19531     startingIndex = startingIndex + 8;
19532   }
19533 
19534   if (pSatDevData->sat48BitSupport == agTRUE)
19535   {
19536     /* sends READ VERIFY SECTOR(S) EXT*/
19537     fis->h.fisType        = 0x27;                   /* Reg host to device */
19538     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19539     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
19540     fis->h.features       = 0;                      /* FIS reserve */
19541     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19542     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19543     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19544     fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
19545     fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
19546     fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
19547     fis->d.featuresExp    = 0;                      /* FIS reserve */
19548     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19549     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
19550     fis->d.reserved4      = 0;
19551     fis->d.device         = 0x40;                   /* 01000000 */
19552     fis->d.control        = 0;                      /* FIS HOB bit clear */
19553     fis->d.reserved5      = 0;
19554   }
19555   else
19556   {
19557     /* READ VERIFY SECTOR(S)*/
19558     fis->h.fisType        = 0x27;                   /* Reg host to device */
19559     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19560     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
19561     fis->h.features       = 0;                      /* FIS features NA       */
19562     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
19563     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
19564     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
19565     fis->d.lbaLowExp      = 0;
19566     fis->d.lbaMidExp      = 0;
19567     fis->d.lbaHighExp     = 0;
19568     fis->d.featuresExp    = 0;
19569     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
19570     fis->d.sectorCountExp = 0;
19571     fis->d.reserved4      = 0;
19572     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19573                             /* DEV and LBA 27:24 */
19574     fis->d.control        = 0;                      /* FIS HOB bit clear */
19575     fis->d.reserved5      = 0;
19576   }
19577 
19578   sm_memcpy(satOrgIOContext->LBA, LBA, 8);
19579   satOrgIOContext->ParmIndex = startingIndex;
19580 
19581   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19582 
19583   /* Initialize CB for SATA completion.
19584    */
19585   satIOContext->satCompleteCB = &smsatReassignBlocksCB;
19586 
19587   /*
19588    * Prepare SGL and send FIS to LL layer.
19589    */
19590   satIOContext->reqType = agRequestType;       /* Save it */
19591 
19592   smsataLLIOStart( smRoot,
19593                             smIORequest,
19594                             smDeviceHandle,
19595                             smScsiRequest,
19596                             satIOContext);
19597 
19598   return SM_RC_SUCCESS;
19599 }
19600 
19601 osGLOBAL bit32
19602 smsatSendReadLogExt(
19603                      smRoot_t                  *smRoot,
19604                      smIORequest_t             *smIORequest,
19605                      smDeviceHandle_t          *smDeviceHandle,
19606                      smScsiInitiatorRequest_t  *smScsiRequest,
19607                      smSatIOContext_t            *satIOContext
19608        )
19609 {
19610   bit32                     status;
19611   bit32                     agRequestType;
19612   agsaFisRegHostToDevice_t  *fis;
19613 
19614   fis           = satIOContext->pFis;
19615   SM_DBG1(("smsatSendReadLogExt: start\n"));
19616   fis->h.fisType        = 0x27;                   /* Reg host to device */
19617   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19618   fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
19619   fis->h.features       = 0;                      /* FIS reserve */
19620   fis->d.lbaLow         = 0x10;                   /* Page number */
19621   fis->d.lbaMid         = 0;                      /*  */
19622   fis->d.lbaHigh        = 0;                      /*  */
19623   fis->d.device         = 0;                      /* DEV is ignored in SATA */
19624   fis->d.lbaLowExp      = 0;                      /*  */
19625   fis->d.lbaMidExp      = 0;                      /*  */
19626   fis->d.lbaHighExp     = 0;                      /*  */
19627   fis->d.featuresExp    = 0;                      /* FIS reserve */
19628   fis->d.sectorCount    = 0x01;                   /*  1 sector counts*/
19629   fis->d.sectorCountExp = 0x00;                   /*  1 sector counts */
19630   fis->d.reserved4      = 0;
19631   fis->d.control        = 0;                      /* FIS HOB bit clear */
19632   fis->d.reserved5      = 0;
19633 
19634   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19635 
19636   /* Initialize CB for SATA completion.
19637    */
19638   satIOContext->satCompleteCB = &smsatReadLogExtCB;
19639 
19640   /*
19641    * Prepare SGL and send FIS to LL layer.
19642    */
19643   satIOContext->reqType = agRequestType;       /* Save it */
19644 
19645   status = smsataLLIOStart( smRoot,
19646                             smIORequest,
19647                             smDeviceHandle,
19648                             smScsiRequest,
19649                             satIOContext);
19650 
19651   SM_DBG1(("smsatSendReadLogExt: end status %d!!!\n", status));
19652 
19653   return (status);
19654 }
19655 
19656 osGLOBAL bit32
19657 smsatCheckPowerMode(
19658                      smRoot_t                  *smRoot,
19659                      smIORequest_t             *smIORequest,
19660                      smDeviceHandle_t          *smDeviceHandle,
19661                      smScsiInitiatorRequest_t  *smScsiRequest,
19662                      smSatIOContext_t          *satIOContext
19663        )
19664 {
19665   /*
19666     sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands
19667     internally generated - no directly corresponding scsi
19668   */
19669   bit32                     status;
19670   bit32                     agRequestType;
19671   agsaFisRegHostToDevice_t  *fis;
19672 
19673   fis           = satIOContext->pFis;
19674   SM_DBG1(("smsatCheckPowerMode: start\n"));
19675   /*
19676    * Send the ATA CHECK POWER MODE command.
19677    */
19678   fis->h.fisType        = 0x27;                   /* Reg host to device */
19679   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19680   fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
19681   fis->h.features       = 0;
19682   fis->d.lbaLow         = 0;
19683   fis->d.lbaMid         = 0;
19684   fis->d.lbaHigh        = 0;
19685   fis->d.device         = 0;
19686   fis->d.lbaLowExp      = 0;
19687   fis->d.lbaMidExp      = 0;
19688   fis->d.lbaHighExp     = 0;
19689   fis->d.featuresExp    = 0;
19690   fis->d.sectorCount    = 0;
19691   fis->d.sectorCountExp = 0;
19692   fis->d.reserved4      = 0;
19693   fis->d.control        = 0;                      /* FIS HOB bit clear */
19694   fis->d.reserved5      = 0;
19695 
19696   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19697 
19698   /* Initialize CB for SATA completion.
19699    */
19700   satIOContext->satCompleteCB = &smsatCheckPowerModeCB;
19701 
19702   /*
19703    * Prepare SGL and send FIS to LL layer.
19704    */
19705   satIOContext->reqType = agRequestType;       /* Save it */
19706 
19707   status = smsataLLIOStart( smRoot,
19708                             smIORequest,
19709                             smDeviceHandle,
19710                             smScsiRequest,
19711                             satIOContext);
19712 
19713   SM_DBG5(("smsatCheckPowerMode: return\n"));
19714 
19715   return status;
19716 }
19717 
19718 osGLOBAL bit32
19719 smsatResetDevice(
19720                   smRoot_t                  *smRoot,
19721                   smIORequest_t             *smIORequest,
19722                   smDeviceHandle_t          *smDeviceHandle,
19723                   smScsiInitiatorRequest_t  *smScsiRequest, /* NULL */
19724                   smSatIOContext_t            *satIOContext
19725                 )
19726 {
19727   bit32                     status;
19728   bit32                     agRequestType;
19729   agsaFisRegHostToDevice_t  *fis;
19730 #ifdef  TD_DEBUG_ENABLE
19731   smIORequestBody_t         *smIORequestBody;
19732   smSatInternalIo_t           *satIntIoContext;
19733 #endif
19734 
19735   fis           = satIOContext->pFis;
19736   SM_DBG1(("smsatResetDevice: start\n"));
19737 #ifdef  TD_DEBUG_ENABLE
19738   satIntIoContext = satIOContext->satIntIoContext;
19739   smIORequestBody = satIntIoContext->satIntRequestBody;
19740 #endif
19741   SM_DBG5(("smsatResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody));
19742   /* any fis should work */
19743   fis->h.fisType        = 0x27;                   /* Reg host to device */
19744   fis->h.c_pmPort       = 0;                      /* C Bit is not set */
19745   fis->h.command        = 0;                      /* any command */
19746   fis->h.features       = 0;                      /* FIS reserve */
19747   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
19748   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19749   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19750   fis->d.device         = 0;                      /* FIS LBA mode  */
19751   fis->d.lbaLowExp      = 0;
19752   fis->d.lbaMidExp      = 0;
19753   fis->d.lbaHighExp     = 0;
19754   fis->d.featuresExp    = 0;
19755   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
19756   fis->d.sectorCountExp = 0;
19757   fis->d.reserved4      = 0;
19758   fis->d.control        = 0x4;                    /* SRST bit is set  */
19759   fis->d.reserved5      = 0;
19760 
19761   agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
19762 
19763   /* Initialize CB for SATA completion.
19764    */
19765   satIOContext->satCompleteCB = &smsatResetDeviceCB;
19766 
19767   /*
19768    * Prepare SGL and send FIS to LL layer.
19769    */
19770   satIOContext->reqType = agRequestType;       /* Save it */
19771 
19772 #ifdef SM_INTERNAL_DEBUG
19773   smhexdump("smsatResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19774 #ifdef  TD_DEBUG_ENABLE
19775   smhexdump("smsatResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19776 #endif
19777 #endif
19778 
19779   status = smsataLLIOStart( smRoot,
19780                             smIORequest,
19781                             smDeviceHandle,
19782                             smScsiRequest,
19783                             satIOContext);
19784 
19785   SM_DBG6(("smsatResetDevice: end status %d\n", status));
19786   return status;
19787 }
19788 
19789 osGLOBAL bit32
19790 smsatDeResetDevice(
19791                     smRoot_t                  *smRoot,
19792                     smIORequest_t             *smIORequest,
19793                     smDeviceHandle_t          *smDeviceHandle,
19794                     smScsiInitiatorRequest_t  *smScsiRequest,
19795                     smSatIOContext_t            *satIOContext
19796                    )
19797 {
19798   bit32                     status;
19799   bit32                     agRequestType;
19800   agsaFisRegHostToDevice_t  *fis;
19801 #ifdef  TD_DEBUG_ENABLE
19802   smIORequestBody_t         *smIORequestBody;
19803   smSatInternalIo_t           *satIntIoContext;
19804 #endif
19805 
19806   fis           = satIOContext->pFis;
19807   SM_DBG1(("smsatDeResetDevice: start\n"));
19808 #ifdef  TD_DEBUG_ENABLE
19809   satIntIoContext = satIOContext->satIntIoContext;
19810   smIORequestBody = satIntIoContext->satIntRequestBody;
19811 #endif
19812   SM_DBG5(("smsatDeResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody));
19813   /* any fis should work */
19814   fis->h.fisType        = 0x27;                   /* Reg host to device */
19815   fis->h.c_pmPort       = 0;                      /* C Bit is not set */
19816   fis->h.command        = 0;                      /* any command */
19817   fis->h.features       = 0;                      /* FIS reserve */
19818   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
19819   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19820   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19821   fis->d.device         = 0;                      /* FIS LBA mode  */
19822   fis->d.lbaLowExp      = 0;
19823   fis->d.lbaMidExp      = 0;
19824   fis->d.lbaHighExp     = 0;
19825   fis->d.featuresExp    = 0;
19826   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
19827   fis->d.sectorCountExp = 0;
19828   fis->d.reserved4      = 0;
19829   fis->d.control        = 0;                    /* SRST bit is not set  */
19830   fis->d.reserved5      = 0;
19831 
19832   agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT;
19833 
19834   /* Initialize CB for SATA completion.
19835    */
19836   satIOContext->satCompleteCB = &smsatDeResetDeviceCB;
19837 
19838   /*
19839    * Prepare SGL and send FIS to LL layer.
19840    */
19841   satIOContext->reqType = agRequestType;       /* Save it */
19842 
19843 #ifdef SM_INTERNAL_DEBUG
19844   smhexdump("smsatDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19845 #ifdef  TD_DEBUG_ENABLE
19846   smhexdump("smsatDeResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19847 #endif
19848 #endif
19849 
19850   status = smsataLLIOStart( smRoot,
19851                             smIORequest,
19852                             smDeviceHandle,
19853                             smScsiRequest,
19854                             satIOContext);
19855 
19856   SM_DBG6(("smsatDeResetDevice: end status %d\n", status));
19857   return status;
19858 }
19859 
19860 /* set feature for auto activate */
19861 osGLOBAL bit32
19862 smsatSetFeaturesAA(
19863            smRoot_t                  *smRoot,
19864            smIORequest_t             *smIORequest,
19865            smDeviceHandle_t          *smDeviceHandle,
19866            smScsiInitiatorRequest_t  *smScsiRequest,
19867            smSatIOContext_t          *satIOContext
19868            )
19869 {
19870   bit32                     status = SM_RC_FAILURE;
19871   bit32                     agRequestType;
19872   agsaFisRegHostToDevice_t  *fis;
19873 
19874   fis           = satIOContext->pFis;
19875   SM_DBG2(("smsatSetFeaturesAA: start\n"));
19876   /*
19877    * Send the Set Features command.
19878    * See SATA II 1.0a spec
19879    */
19880   fis->h.fisType        = 0x27;                   /* Reg host to device */
19881   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19882   fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19883   fis->h.features       = 0x10;                   /* enable SATA feature */
19884   fis->d.lbaLow         = 0;
19885   fis->d.lbaMid         = 0;
19886   fis->d.lbaHigh        = 0;
19887   fis->d.device         = 0;
19888   fis->d.lbaLowExp      = 0;
19889   fis->d.lbaMidExp      = 0;
19890   fis->d.lbaHighExp     = 0;
19891   fis->d.featuresExp    = 0;
19892   fis->d.sectorCount    = 0x02;                   /* DMA Setup FIS Auto-Activate */
19893   fis->d.sectorCountExp = 0;
19894   fis->d.reserved4      = 0;
19895   fis->d.control        = 0;                      /* FIS HOB bit clear */
19896   fis->d.reserved5      = 0;
19897 
19898   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19899 
19900   /* Initialize CB for SATA completion.
19901    */
19902   satIOContext->satCompleteCB = &smsatSetFeaturesAACB;
19903 
19904   /*
19905    * Prepare SGL and send FIS to LL layer.
19906    */
19907   satIOContext->reqType = agRequestType;       /* Save it */
19908 
19909   status = smsataLLIOStart( smRoot,
19910                           smIORequest,
19911                           smDeviceHandle,
19912                           smScsiRequest,
19913                           satIOContext);
19914 
19915   /* debugging code */
19916   if (smIORequest->tdData == smIORequest->smData)
19917   {
19918     SM_DBG1(("smsatSetFeaturesAA: incorrect smIORequest\n"));
19919   }
19920   SM_DBG2(("smsatSetFeatures: return\n"));
19921   return status;
19922 }
19923 
19924 
19925 /* set feature for DMA transfer mode*/
19926 osGLOBAL bit32
19927 smsatSetFeaturesDMA(
19928            smRoot_t                  *smRoot,
19929            smIORequest_t             *smIORequest,
19930            smDeviceHandle_t          *smDeviceHandle,
19931            smScsiInitiatorRequest_t  *smScsiRequest,
19932            smSatIOContext_t          *satIOContext
19933            )
19934 {
19935   bit32                     status = SM_RC_FAILURE;
19936   bit32                     agRequestType;
19937   smDeviceData_t            *pSatDevData;
19938   agsaFisRegHostToDevice_t  *fis;
19939 
19940   pSatDevData   = satIOContext->pSatDevData;
19941   fis           = satIOContext->pFis;
19942   SM_DBG2(("smsatSetFeaturesDMA: start\n"));
19943   /*
19944    * Send the Set Features command.
19945    * See SATA II 1.0a spec
19946    */
19947   fis->h.fisType        = 0x27;                   /* Reg host to device */
19948   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19949   fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
19950   fis->h.features       = 0x03;                   /* enable ATA transfer mode */
19951   fis->d.lbaLow         = 0;
19952   fis->d.lbaMid         = 0;
19953   fis->d.lbaHigh        = 0;
19954   fis->d.device         = 0;
19955   fis->d.lbaLowExp      = 0;
19956   fis->d.lbaMidExp      = 0;
19957   fis->d.lbaHighExp     = 0;
19958   fis->d.featuresExp    = 0;
19959   fis->d.sectorCount    = 0x40 |(bit8)pSatDevData->satUltraDMAMode;   /* enable Ultra DMA mode */
19960   fis->d.sectorCountExp = 0;
19961   fis->d.reserved4      = 0;
19962   fis->d.control        = 0;                      /* FIS HOB bit clear */
19963   fis->d.reserved5      = 0;
19964 
19965   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19966 
19967   /* Initialize CB for SATA completion.
19968    */
19969   satIOContext->satCompleteCB = &smsatSetFeaturesDMACB;
19970 
19971   /*
19972    * Prepare SGL and send FIS to LL layer.
19973    */
19974   satIOContext->reqType = agRequestType;       /* Save it */
19975 
19976   status = smsataLLIOStart( smRoot,
19977                           smIORequest,
19978                           smDeviceHandle,
19979                           smScsiRequest,
19980                           satIOContext);
19981 
19982   /* debugging code */
19983   if (smIORequest->tdData == smIORequest->smData)
19984   {
19985     SM_DBG1(("smsatSetFeaturesDMA: incorrect smIORequest\n"));
19986   }
19987 
19988   SM_DBG2(("smsatSetFeaturesDMA: return\n"));
19989 
19990   return status;
19991 }
19992 
19993 /* set feature for Read Look Ahead*/
19994 osGLOBAL bit32
19995 smsatSetFeaturesReadLookAhead(
19996            smRoot_t                  *smRoot,
19997            smIORequest_t             *smIORequest,
19998            smDeviceHandle_t          *smDeviceHandle,
19999            smScsiInitiatorRequest_t  *smScsiRequest,
20000            smSatIOContext_t          *satIOContext
20001            )
20002 {
20003   bit32                     status = SM_RC_FAILURE;
20004   bit32                     agRequestType;
20005   agsaFisRegHostToDevice_t  *fis;
20006 
20007   fis           = satIOContext->pFis;
20008   SM_DBG2(("smsatSetFeaturesReadLookAhead: start\n"));
20009   /*
20010    * Send the Set Features command.
20011    * See SATA II 1.0a spec
20012    */
20013   fis->h.fisType        = 0x27;                   /* Reg host to device */
20014   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
20015   fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
20016   fis->h.features       = 0xAA;                   /* Enable read look-ahead feature */
20017   fis->d.lbaLow         = 0;
20018   fis->d.lbaMid         = 0;
20019   fis->d.lbaHigh        = 0;
20020   fis->d.device         = 0;
20021   fis->d.lbaLowExp      = 0;
20022   fis->d.lbaMidExp      = 0;
20023   fis->d.lbaHighExp     = 0;
20024   fis->d.featuresExp    = 0;
20025   fis->d.sectorCount    = 0;
20026   fis->d.sectorCountExp = 0;
20027   fis->d.reserved4      = 0;
20028   fis->d.control        = 0;                      /* FIS HOB bit clear */
20029   fis->d.reserved5      = 0;
20030 
20031   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
20032 
20033   /* Initialize CB for SATA completion.
20034    */
20035   satIOContext->satCompleteCB = &smsatSetFeaturesReadLookAheadCB;
20036 
20037   /*
20038    * Prepare SGL and send FIS to LL layer.
20039    */
20040   satIOContext->reqType = agRequestType;       /* Save it */
20041 
20042   status = smsataLLIOStart( smRoot,
20043                           smIORequest,
20044                           smDeviceHandle,
20045                           smScsiRequest,
20046                           satIOContext);
20047 
20048   /* debugging code */
20049   if (smIORequest->tdData == smIORequest->smData)
20050   {
20051     SM_DBG1(("smsatSetFeaturesReadLookAhead: incorrect smIORequest\n"));
20052   }
20053 
20054   SM_DBG2(("smsatSetFeaturesReadLookAhead: return\n"));
20055 
20056   return status;
20057 }
20058 
20059 /* set feature for Volatile Write Cache*/
20060 osGLOBAL bit32
20061 smsatSetFeaturesVolatileWriteCache(
20062            smRoot_t                  *smRoot,
20063            smIORequest_t             *smIORequest,
20064            smDeviceHandle_t          *smDeviceHandle,
20065            smScsiInitiatorRequest_t  *smScsiRequest,
20066            smSatIOContext_t            *satIOContext
20067            )
20068 {
20069   bit32                     status = SM_RC_FAILURE;
20070   bit32                     agRequestType;
20071   agsaFisRegHostToDevice_t  *fis;
20072 
20073   fis           = satIOContext->pFis;
20074   SM_DBG2(("smsatSetFeaturesVolatileWriteCache: start\n"));
20075   /*
20076    * Send the Set Features command.
20077    * See SATA II 1.0a spec
20078    */
20079   fis->h.fisType        = 0x27;                   /* Reg host to device */
20080   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
20081   fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
20082   fis->h.features       = 0x02;                   /* Enable Volatile Write Cache feature */
20083   fis->d.lbaLow         = 0;
20084   fis->d.lbaMid         = 0;
20085   fis->d.lbaHigh        = 0;
20086   fis->d.device         = 0;
20087   fis->d.lbaLowExp      = 0;
20088   fis->d.lbaMidExp      = 0;
20089   fis->d.lbaHighExp     = 0;
20090   fis->d.featuresExp    = 0;
20091   fis->d.sectorCount    = 0;
20092   fis->d.sectorCountExp = 0;
20093   fis->d.reserved4      = 0;
20094   fis->d.control        = 0;                      /* FIS HOB bit clear */
20095   fis->d.reserved5      = 0;
20096 
20097   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
20098 
20099   /* Initialize CB for SATA completion.
20100    */
20101   satIOContext->satCompleteCB = &smsatSetFeaturesVolatileWriteCacheCB;
20102   /*
20103    * Prepare SGL and send FIS to LL layer.
20104    */
20105   satIOContext->reqType = agRequestType;       /* Save it */
20106 
20107   status = smsataLLIOStart( smRoot,
20108                           smIORequest,
20109                           smDeviceHandle,
20110                           smScsiRequest,
20111                           satIOContext);
20112   /* debugging code */
20113   if (smIORequest->tdData == smIORequest->smData)
20114   {
20115     SM_DBG1(("smsatSetFeaturesVolatileWriteCache: incorrect smIORequest\n"));
20116   }
20117   SM_DBG2(("smsatSetFeaturesVolatileWriteCache: return\n"));
20118 
20119   return status;
20120 }
20121 
20122 
20123 
20124 /******************************** start of utils    ***********************************************************/
20125 osGLOBAL FORCEINLINE void
20126 smsatBitSet(smRoot_t *smRoot, bit8 *data, bit32 index)
20127 {
20128   data[index>>3] |= (1 << (index&7));
20129 }
20130 
20131 osGLOBAL FORCEINLINE void
20132 smsatBitClear(smRoot_t *smRoot, bit8 *data, bit32 index)
20133 {
20134   data[index>>3] &= ~(1 << (index&7));
20135 }
20136 
20137 osGLOBAL FORCEINLINE BOOLEAN
20138 smsatBitTest(smRoot_t *smRoot, bit8 *data, bit32 index)
20139 {
20140    return ( (BOOLEAN)((data[index>>3] & (1 << (index&7)) ) ? 1: 0));
20141 }
20142 
20143 
20144 FORCEINLINE bit32
20145 smsatTagAlloc(
20146                smRoot_t         *smRoot,
20147                smDeviceData_t   *pSatDevData,
20148                bit8             *pTag
20149              )
20150 {
20151   bit32             retCode = agFALSE;
20152   bit32             i;
20153 
20154   tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK);
20155 
20156 #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
20157 
20158   if (tdsmBitScanForward(smRoot, &i, ~(pSatDevData->freeSATAFDMATagBitmap)))
20159   {
20160     smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20161     *pTag = (bit8)i;
20162     retCode = agTRUE;
20163   }
20164 
20165 #else
20166 
20167   for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
20168   {
20169     if ( 0 == smsatBitTest(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
20170     {
20171       smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20172       *pTag = (bit8) i;
20173       retCode = agTRUE;
20174       break;
20175     }
20176   }
20177 
20178 #endif
20179 
20180   tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK);
20181 
20182   return retCode;
20183 }
20184 
20185 FORCEINLINE bit32
20186 smsatTagRelease(
20187                 smRoot_t         *smRoot,
20188                 smDeviceData_t   *pSatDevData,
20189                 bit8              tag
20190                )
20191 {
20192   bit32             retCode = agFALSE;
20193 
20194   if ( tag < pSatDevData->satNCQMaxIO )
20195   {
20196     tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK);
20197     smsatBitClear(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
20198     tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK);
20199     /*tdsmInterlockedAnd(smRoot, (volatile LONG *)(&pSatDevData->freeSATAFDMATagBitmap), ~(1 << (tag&31)));*/
20200     retCode = agTRUE;
20201   }
20202   else
20203   {
20204     SM_DBG1(("smsatTagRelease: tag %d >= satNCQMaxIO %d!!!!\n", tag, pSatDevData->satNCQMaxIO));
20205   }
20206   return retCode;
20207 }
20208 
20209 
20210 
20211 osGLOBAL bit32
20212 smsatComputeCDB10LBA(smSatIOContext_t            *satIOContext)
20213 {
20214   smIniScsiCmnd_t           *scsiCmnd;
20215   smScsiInitiatorRequest_t  *smScsiRequest;
20216   bit32                     lba = 0;
20217 
20218   SM_DBG5(("smsatComputeCDB10LBA: start\n"));
20219   smScsiRequest = satIOContext->smScsiXchg;
20220   scsiCmnd      = &(smScsiRequest->scsiCmnd);
20221 
20222   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
20223     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
20224 
20225   return lba;
20226 }
20227 
20228 osGLOBAL bit32
20229 smsatComputeCDB10TL(smSatIOContext_t            *satIOContext)
20230 {
20231 
20232   smIniScsiCmnd_t           *scsiCmnd;
20233   smScsiInitiatorRequest_t  *smScsiRequest;
20234   bit32                     tl = 0;
20235 
20236   SM_DBG5(("smsatComputeCDB10TL: start\n"));
20237   smScsiRequest = satIOContext->smScsiXchg;
20238   scsiCmnd      = &(smScsiRequest->scsiCmnd);
20239 
20240   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
20241   return tl;
20242 }
20243 
20244 osGLOBAL bit32
20245 smsatComputeCDB12LBA(smSatIOContext_t            *satIOContext)
20246 {
20247   smIniScsiCmnd_t           *scsiCmnd;
20248   smScsiInitiatorRequest_t  *smScsiRequest;
20249   bit32                     lba = 0;
20250 
20251   SM_DBG5(("smsatComputeCDB12LBA: start\n"));
20252   smScsiRequest = satIOContext->smScsiXchg;
20253   scsiCmnd      = &(smScsiRequest->scsiCmnd);
20254 
20255   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
20256     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
20257 
20258   return lba;
20259 }
20260 
20261 osGLOBAL bit32
20262 smsatComputeCDB12TL(smSatIOContext_t            *satIOContext)
20263 {
20264 
20265   smIniScsiCmnd_t           *scsiCmnd;
20266   smScsiInitiatorRequest_t  *smScsiRequest;
20267   bit32                     tl = 0;
20268 
20269   SM_DBG5(("smsatComputeCDB12TL: start\n"));
20270   smScsiRequest = satIOContext->smScsiXchg;
20271   scsiCmnd      = &(smScsiRequest->scsiCmnd);
20272 
20273   tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
20274     + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
20275   return tl;
20276 }
20277 
20278 /*
20279   CBD16 has bit64 LBA
20280   But it has to be less than (2^28 - 1)
20281   Therefore, use last four bytes to compute LBA is OK
20282 */
20283 osGLOBAL bit32
20284 smsatComputeCDB16LBA(smSatIOContext_t            *satIOContext)
20285 {
20286   smIniScsiCmnd_t           *scsiCmnd;
20287   smScsiInitiatorRequest_t  *smScsiRequest;
20288   bit32                     lba = 0;
20289 
20290   SM_DBG5(("smsatComputeCDB16LBA: start\n"));
20291   smScsiRequest = satIOContext->smScsiXchg;
20292   scsiCmnd      = &(smScsiRequest->scsiCmnd);
20293 
20294   lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
20295     + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
20296 
20297   return lba;
20298 }
20299 
20300 osGLOBAL bit32
20301 smsatComputeCDB16TL(smSatIOContext_t            *satIOContext)
20302 {
20303 
20304   smIniScsiCmnd_t           *scsiCmnd;
20305   smScsiInitiatorRequest_t  *smScsiRequest;
20306   bit32                     tl = 0;
20307 
20308   SM_DBG5(("smsatComputeCDB16TL: start\n"));
20309   smScsiRequest = satIOContext->smScsiXchg;
20310   scsiCmnd      = &(smScsiRequest->scsiCmnd);
20311 
20312   tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
20313     + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
20314   return tl;
20315 }
20316 
20317 /*
20318   (tl, denom)
20319   tl can be upto bit32 because CDB16 has bit32 tl
20320   Therefore, fine
20321   either (tl, 0xFF) or (tl, 0xFFFF)
20322 */
20323 osGLOBAL FORCEINLINE bit32
20324 smsatComputeLoopNum(bit32 a, bit32 b)
20325 {
20326   bit32 LoopNum = 0;
20327 
20328   SM_DBG5(("smsatComputeLoopNum: start\n"));
20329 
20330   if (a < b || a == 0)
20331   {
20332     LoopNum = 1;
20333   }
20334   else
20335   {
20336     if (a == b || a == 0)
20337     {
20338       LoopNum = a/b;
20339     }
20340     else
20341     {
20342       LoopNum = a/b + 1;
20343     }
20344   }
20345 
20346   return LoopNum;
20347 }
20348 
20349 /*
20350   Generic new function for checking
20351   LBA itself, LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT
20352   and LBA+TL < Read Capacity Limit
20353   flag: false - not 48BitSupport; true - 48BitSupport
20354   returns TRUE when over the limit
20355 
20356 */
20357 osGLOBAL FORCEINLINE bit32
20358 smsatCheckLimit(bit8 *lba, bit8 *tl, int flag, smDeviceData_t *pSatDevData)
20359 {
20360   bit32 lbaCheck = agFALSE;
20361   int i;
20362   bit8 limit[8];
20363   bit32 rangeCheck = agFALSE;
20364   bit16 ans[8];       // 0 MSB, 8 LSB
20365   bit8  final_ans[9]; // 0 MSB, 9 LSB
20366   bit8  Bit28max[8];
20367   bit8  Bit48max[8];
20368   bit32 ReadCapCheck = agFALSE;
20369   bit32 ret;
20370 
20371   bit8  final_satMaxLBA[9];
20372   bit8  oneTL[8];
20373   bit8  temp_satMaxLBA[8];       // 0 MSB, 8 LSB
20374   /*
20375     check LBA
20376   */
20377   if (flag == agFALSE)
20378   {
20379     /* limit is 0xF FF FF = 2^28 - 1 */
20380     limit[0] = 0x0;   /* MSB */
20381     limit[1] = 0x0;
20382     limit[2] = 0x0;
20383     limit[3] = 0x0;
20384     limit[4] = 0xF;
20385     limit[5] = 0xFF;
20386     limit[6] = 0xFF;
20387     limit[7] = 0xFF;  /* LSB */
20388   }
20389   else
20390   {
20391     /* limit is 0xF FF FF = 2^48 - 1 */
20392     limit[0] = 0x0;   /* MSB */
20393     limit[1] = 0x0;
20394     limit[2] = 0xFF;
20395     limit[3] = 0xFF;
20396     limit[4] = 0xFF;
20397     limit[5] = 0xFF;
20398     limit[6] = 0xFF;
20399     limit[7] = 0xFF;  /* LSB */
20400   }
20401   //compare lba to limit
20402   for(i=0;i<8;i++)
20403   {
20404     if (lba[i] > limit[i])
20405     {
20406       SM_DBG1(("smsatCheckLimit: LBA check True at %d\n", i));
20407       lbaCheck = agTRUE;
20408       break;
20409     }
20410     else if (lba[i] < limit[i])
20411     {
20412       SM_DBG5(("smsatCheckLimit: LBA check False at %d\n", i));
20413       lbaCheck = agFALSE;
20414       break;
20415     }
20416     else
20417     {
20418       continue;
20419     }
20420   }
20421 
20422   if (lbaCheck == agTRUE)
20423   {
20424     SM_DBG1(("smsatCheckLimit: return LBA check True\n"));
20425     return agTRUE;
20426   }
20427 
20428   /*
20429     check LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT
20430   */
20431   sm_memset(ans, 0, sizeof(ans));
20432   sm_memset(final_ans, 0, sizeof(final_ans));
20433 
20434   // adding from LSB to MSB
20435   for(i=7;i>=0;i--)
20436   {
20437     ans[i] = (bit16)(lba[i] + tl[i]);
20438     if (i != 7)
20439     {
20440       ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
20441     }
20442   }
20443 
20444   /*
20445     filling in the final answer
20446    */
20447   final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
20448 
20449   for(i=1;i<=8;i++)
20450   {
20451     final_ans[i] = (bit8)(ans[i-1] & 0xFF);
20452   }
20453 
20454 
20455   if (flag == agFALSE)
20456   {
20457     sm_memset(Bit28max, 0, sizeof(Bit28max));
20458     Bit28max[4] = 0x10; // max =0x1000 0000
20459 
20460     //compare final_ans to max
20461     if (final_ans[0] != 0 || final_ans[1] != 0 || final_ans[2] != 0
20462         || final_ans[3] != 0 || final_ans[4] != 0)
20463     {
20464       SM_DBG1(("smsatCheckLimit: before 28Bit addressing TRUE\n"));
20465       rangeCheck = agTRUE;
20466     }
20467     else
20468     {
20469       for(i=5;i<=8;i++)
20470       {
20471         if (final_ans[i] > Bit28max[i-1])
20472         {
20473           SM_DBG1(("smsatCheckLimit: 28Bit addressing TRUE at %d\n", i));
20474           rangeCheck = agTRUE;
20475           break;
20476         }
20477         else if (final_ans[i] < Bit28max[i-1])
20478         {
20479           SM_DBG5(("smsatCheckLimit: 28Bit addressing FALSE at %d\n", i));
20480           rangeCheck = agFALSE;
20481           break;
20482         }
20483         else
20484         {
20485           continue;
20486         }
20487       }
20488     }
20489   }
20490   else
20491   {
20492     sm_memset(Bit48max, 0, sizeof(Bit48max));
20493     Bit48max[1] = 0x1; //max = 0x1 0000 0000 0000
20494 
20495     //compare final_ans to max
20496     if (final_ans[0] != 0 || final_ans[1] != 0)
20497     {
20498       SM_DBG1(("smsatCheckLimit: before 48Bit addressing TRUE\n"));
20499       rangeCheck = agTRUE;
20500     }
20501     else
20502     {
20503       for(i=2;i<=8;i++)
20504       {
20505         if (final_ans[i] > Bit48max[i-1])
20506         {
20507           SM_DBG1(("smsatCheckLimit: 48Bit addressing TRUE at %d\n", i));
20508           rangeCheck = agTRUE;
20509 	  break;
20510         }
20511         else if (final_ans[i] < Bit48max[i-1])
20512         {
20513           SM_DBG5(("smsatCheckLimit: 48Bit addressing FALSE at %d\n", i));
20514           rangeCheck = agFALSE;
20515 	  break;
20516         }
20517         else
20518         {
20519           continue;
20520         }
20521       }
20522     }
20523   }
20524   if (rangeCheck == agTRUE)
20525   {
20526     SM_DBG1(("smsatCheckLimit: return rangeCheck True\n"));
20527     return agTRUE;
20528   }
20529 
20530   /*
20531     LBA+TL < Read Capacity Limit
20532   */
20533   sm_memset(temp_satMaxLBA, 0, sizeof(temp_satMaxLBA));
20534   sm_memset(oneTL, 0, sizeof(oneTL));
20535   sm_memset(final_satMaxLBA, 0, sizeof(final_satMaxLBA));
20536   sm_memset(ans, 0, sizeof(ans));
20537 
20538   sm_memcpy(&temp_satMaxLBA, &pSatDevData->satMaxLBA, sizeof(temp_satMaxLBA));
20539   oneTL[7] = 1;
20540 
20541   // adding temp_satMaxLBA to oneTL
20542   for(i=7;i>=0;i--)
20543   {
20544     ans[i] = (bit16)(temp_satMaxLBA[i] + oneTL[i]);
20545     if (i != 7)
20546     {
20547       ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
20548     }
20549   }
20550 
20551   /*
20552     filling in the final answer
20553    */
20554   final_satMaxLBA[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
20555 
20556   for(i=1;i<=8;i++)
20557   {
20558     final_satMaxLBA[i] = (bit8)(ans[i-1] & 0xFF);
20559   }
20560   if ( pSatDevData->ReadCapacity == 10)
20561   {
20562     for (i=0;i<=8;i++)
20563     {
20564       if (final_ans[i] > final_satMaxLBA[i])
20565       {
20566         SM_DBG1(("smsatCheckLimit: Read Capacity 10 TRUE at %d\n", i));
20567         ReadCapCheck = agTRUE;
20568         break;
20569       }
20570       else if (final_ans[i] < final_satMaxLBA[i])
20571       {
20572         SM_DBG5(("smsatCheckLimit: Read Capacity 10 FALSE at %d\n", i));
20573         ReadCapCheck = agFALSE;
20574         break;
20575       }
20576       else
20577       {
20578         continue;
20579       }
20580     }
20581     if ( ReadCapCheck)
20582     {
20583       SM_DBG1(("smsatCheckLimit: after Read Capacity 10 TRUE\n"));
20584     }
20585     else
20586     {
20587       SM_DBG5(("smsatCheckLimit: after Read Capacity 10 FALSE\n"));
20588     }
20589   }
20590   else if ( pSatDevData->ReadCapacity == 16)
20591   {
20592     for (i=0;i<=8;i++)
20593     {
20594       if (final_ans[i] > final_satMaxLBA[i])
20595       {
20596         SM_DBG1(("smsatCheckLimit: Read Capacity 16 TRUE at %d\n", i));
20597         ReadCapCheck = agTRUE;
20598         break;
20599       }
20600       else if (final_ans[i] < final_satMaxLBA[i])
20601       {
20602         SM_DBG5(("smsatCheckLimit: Read Capacity 16 FALSE at %d\n", i));
20603         ReadCapCheck = agFALSE;
20604         break;
20605       }
20606       else
20607       {
20608         continue;
20609       }
20610     }
20611     if ( ReadCapCheck)
20612     {
20613       SM_DBG1(("smsatCheckLimit: after Read Capacity 16 TRUE\n"));
20614     }
20615     else
20616     {
20617       SM_DBG5(("smsatCheckLimit: after Read Capacity 16 FALSE\n"));
20618     }
20619   }
20620   else
20621   {
20622     SM_DBG5(("smsatCheckLimit: unknown pSatDevData->ReadCapacity %d\n", pSatDevData->ReadCapacity));
20623   }
20624 
20625   if (ReadCapCheck == agTRUE)
20626   {
20627     SM_DBG1(("smsatCheckLimit: return ReadCapCheck True\n"));
20628     return agTRUE;
20629   }
20630 
20631 
20632   ret = (lbaCheck | rangeCheck | ReadCapCheck);
20633   if (ret == agTRUE)
20634   {
20635     SM_DBG1(("smsatCheckLimit: final check TRUE\n"));
20636   }
20637   else
20638   {
20639     SM_DBG5(("smsatCheckLimit: final check FALSE\n"));
20640   }
20641   return   ret;
20642 }
20643 
20644 
20645 
20646 osGLOBAL void
20647 smsatPrintSgl(
20648             smRoot_t                  *smRoot,
20649             agsaEsgl_t                *agEsgl,
20650       bit32                     idx
20651       )
20652 {
20653   bit32                     i=0;
20654 #ifdef  TD_DEBUG_ENABLE
20655   agsaSgl_t                 *agSgl;
20656 #endif
20657 
20658   for (i=0;i<idx;i++)
20659   {
20660 #ifdef  TD_DEBUG_ENABLE
20661     agSgl = &(agEsgl->descriptor[i]);
20662 #endif
20663     SM_DBG3(("smsatPrintSgl: agSgl %d upperAddr 0x%08x lowerAddr 0x%08x len 0x%08x ext 0x%08x\n",
20664       i, agSgl->sgUpper, agSgl->sgLower, agSgl->len,  agSgl->extReserved));
20665   }
20666 
20667   return;
20668 }
20669 
20670 
20671 osGLOBAL void
20672 smsatSplitSGL(
20673      smRoot_t                  *smRoot,
20674      smIORequest_t             *smIORequest,
20675      smDeviceHandle_t          *smDeviceHandle,
20676      smScsiInitiatorRequest_t  *smScsiRequest,
20677      smSatIOContext_t          *satIOContext,
20678      bit32                     split, /*in sector number, depeding on IO value */
20679      bit32                     tl, /* in sector number */
20680      bit32                     flag
20681     )
20682 {
20683   agsaSgl_t                 *agSgl;
20684   agsaEsgl_t                *agEsgl;
20685   bit32                     i=0;
20686   smIniScsiCmnd_t           *scsiCmnd;
20687   bit32                     totalLen=0; /* in bytes */
20688   bit32                     splitLen=0; /* in bytes */
20689   bit32                     splitDiffByte = 0; /* in bytes */
20690   bit32                     splitDiffExtra = 0; /* in bytes */
20691   bit32                     splitIdx = 0;
20692   bit32                     UpperAddr, LowerAddr;
20693   bit32                     tmpLowerAddr;
20694   void                      *sglVirtualAddr;
20695   void                      *sglSplitVirtualAddr;
20696 
20697   scsiCmnd      = &smScsiRequest->scsiCmnd;
20698   SM_DBG3(("smsatSplitSGL: start\n"));
20699 
20700   if (smScsiRequest->smSgl1.type == 0x80000000) /* esgl */
20701   {
20702     if (flag == agFALSE)
20703     {
20704       SM_DBG3(("smsatSplitSGL: Not first time\n"));
20705       SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x LowerAddr 0x%08x\n", satIOContext->UpperAddr, satIOContext->LowerAddr));
20706       SM_DBG3(("smsatSplitSGL: SplitIdx %d AdjustBytes 0x%08x\n", satIOContext->SplitIdx, satIOContext->AdjustBytes));
20707 
20708       sglVirtualAddr = smScsiRequest->sglVirtualAddr;
20709 
20710       agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20711 
20712       sglSplitVirtualAddr = &(agEsgl->descriptor[satIOContext->SplitIdx]);
20713 
20714       agEsgl = (agsaEsgl_t *)sglSplitVirtualAddr;
20715 
20716       if (agEsgl == agNULL)
20717       {
20718         SM_DBG1(("smsatSplitSGL: error!\n"));
20719         return;
20720       }
20721       /* first sgl ajustment */
20722       agSgl = &(agEsgl->descriptor[0]);
20723       agSgl->sgUpper = satIOContext->UpperAddr;
20724       agSgl->sgLower = satIOContext->LowerAddr;
20725       agSgl->len = satIOContext->AdjustBytes;
20726       sm_memcpy(sglVirtualAddr, sglSplitVirtualAddr, (satIOContext->EsglLen) * sizeof(agsaSgl_t));
20727       agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20728       smsatPrintSgl(smRoot, (agsaEsgl_t *)sglVirtualAddr, satIOContext->EsglLen);
20729     }
20730     else
20731     {
20732       /* first time */
20733       SM_DBG3(("smsatSplitSGL: first time\n"));
20734       satIOContext->EsglLen = smScsiRequest->smSgl1.len;
20735       agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20736       if (agEsgl == agNULL)
20737       {
20738         return;
20739       }
20740       smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20741     }
20742 
20743     if (tl > split)
20744     {
20745       /* split */
20746       SM_DBG3(("smsatSplitSGL: split case\n"));
20747       i = 0;
20748       while (1)
20749       {
20750         agSgl = &(agEsgl->descriptor[i]);
20751         splitLen = splitLen + agSgl->len;
20752         if (splitLen >= split)
20753         {
20754           splitDiffExtra = splitLen - split;
20755           splitDiffByte = agSgl->len - splitDiffExtra;
20756           splitIdx = i;
20757           break;
20758         }
20759         i++;
20760       }
20761       SM_DBG3(("smsatSplitSGL: splitIdx %d\n", splitIdx));
20762       SM_DBG3(("smsatSplitSGL: splitDiffByte 0x%8x\n", splitDiffByte));
20763       SM_DBG3(("smsatSplitSGL: splitDiffExtra 0x%8x \n", splitDiffExtra));
20764 
20765 
20766       agSgl = &(agEsgl->descriptor[splitIdx]);
20767       UpperAddr = agSgl->sgUpper;
20768       LowerAddr = agSgl->sgLower;
20769       tmpLowerAddr = LowerAddr + splitDiffByte;
20770       if (tmpLowerAddr < LowerAddr)
20771       {
20772         UpperAddr = UpperAddr + 1;
20773       }
20774       SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x tmpLowerAddr 0x%08x\n", UpperAddr, tmpLowerAddr));
20775       agSgl->len = splitDiffByte;
20776       /* Esgl len adjustment */
20777       smScsiRequest->smSgl1.len =  splitIdx;
20778       /* expected data lent adjustment */
20779       scsiCmnd->expDataLength = 0x20000;
20780       /* remeber for the next round */
20781       satIOContext->UpperAddr = UpperAddr;
20782       satIOContext->LowerAddr = tmpLowerAddr;
20783       satIOContext->SplitIdx = splitIdx;
20784       satIOContext->AdjustBytes = splitDiffExtra;
20785       satIOContext->EsglLen =  satIOContext->EsglLen - smScsiRequest->smSgl1.len;
20786       satIOContext->OrgTL = satIOContext->OrgTL - 0x100;
20787 //    smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20788 
20789     }
20790     else
20791     {
20792       /* no split */
20793       SM_DBG3(("smsatSplitSGL: no split case\n"));
20794       /* Esgl len adjustment */
20795       smScsiRequest->smSgl1.len = satIOContext->EsglLen;
20796       for (i=0;i< smScsiRequest->smSgl1.len;i++)
20797       {
20798         agSgl = &(agEsgl->descriptor[i]);
20799         totalLen = totalLen + (agSgl->len);
20800       }
20801       /* expected data lent adjustment */
20802       scsiCmnd->expDataLength = totalLen;
20803 //    smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20804     }
20805   }
20806   else
20807   {
20808     SM_DBG1(("not exntened esgl\n"));
20809 
20810   }
20811 
20812   return;
20813 }
20814 
20815 
20816 /******************************** end   of utils    ***********************************************************/
20817 
20818 
20819 
20820