xref: /freebsd/sys/dev/pms/RefTisa/tisa/sassata/sata/host/sat.c (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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 /*****************************************************************************/
23 /** \file
24  *
25  * The file implementing SCSI/ATA Translation (SAT).
26  * The routines in this file are independent from HW LL API.
27  *
28  */
29 /*****************************************************************************/
30 #include <sys/cdefs.h>
31 #include <dev/pms/config.h>
32 
33 #include <dev/pms/freebsd/driver/common/osenv.h>
34 #include <dev/pms/freebsd/driver/common/ostypes.h>
35 #include <dev/pms/freebsd/driver/common/osdebug.h>
36 
37 #ifdef SATA_ENABLE
38 
39 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
40 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
41 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
42 
43 #include <dev/pms/RefTisa/tisa/api/titypes.h>
44 #include <dev/pms/RefTisa/tisa/api/ostiapi.h>
45 #include <dev/pms/RefTisa/tisa/api/tiapi.h>
46 #include <dev/pms/RefTisa/tisa/api/tiglobal.h>
47 
48 #ifdef FDS_SM
49 #include <dev/pms/RefTisa/sat/api/sm.h>
50 #include <dev/pms/RefTisa/sat/api/smapi.h>
51 #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
52 #endif
53 
54 #ifdef FDS_DM
55 #include <dev/pms/RefTisa/discovery/api/dm.h>
56 #include <dev/pms/RefTisa/discovery/api/dmapi.h>
57 #include <dev/pms/RefTisa/discovery/api/tddmapi.h>
58 #endif
59 
60 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
61 #include <dev/pms/freebsd/driver/common/osstring.h>
62 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
63 
64 #ifdef INITIATOR_DRIVER
65 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
66 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
67 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
68 #endif
69 
70 #ifdef TARGET_DRIVER
71 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
72 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
73 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
74 #endif
75 
76 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
77 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
78 
79 #include <dev/pms/RefTisa/tisa/sassata/sata/host/sat.h>
80 #include <dev/pms/RefTisa/tisa/sassata/sata/host/satproto.h>
81 
82 /*****************************************************************************
83  *! \brief  satIOStart
84  *
85  *   This routine is called to initiate a new SCSI request to SATL.
86  *
87  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
88  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
89  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
90  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
91  *  \param   satIOContext_t:   Pointer to the SAT IO Context
92  *
93  *  \return:
94  *
95  *  \e tiSuccess:     I/O request successfully initiated.
96  *  \e tiBusy:        No resources available, try again later.
97  *  \e tiIONoDevice:  Invalid device handle.
98  *  \e tiError:       Other errors that prevent the I/O request to be started.
99  *
100  *
101  *****************************************************************************/
102 GLOBAL bit32  satIOStart(
103                    tiRoot_t                  *tiRoot,
104                    tiIORequest_t             *tiIORequest,
105                    tiDeviceHandle_t          *tiDeviceHandle,
106                    tiScsiInitiatorRequest_t  *tiScsiRequest,
107                    satIOContext_t            *satIOContext
108                   )
109 {
110 
111   bit32             retVal = tiSuccess;
112   satDeviceData_t   *pSatDevData;
113   scsiRspSense_t    *pSense;
114   tiIniScsiCmnd_t   *scsiCmnd;
115   tiLUN_t           *pLun;
116   satInternalIo_t   *pSatIntIo;
117 #ifdef  TD_DEBUG_ENABLE
118   tdsaDeviceData_t  *oneDeviceData;
119 #endif
120 
121   pSense        = satIOContext->pSense;
122   pSatDevData   = satIOContext->pSatDevData;
123   scsiCmnd      = &tiScsiRequest->scsiCmnd;
124   pLun          = &scsiCmnd->lun;
125 
126   /*
127    * Reject all other LUN other than LUN 0.
128    */
129   if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
130          pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) &&
131         (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)
132      )
133   {
134     TI_DBG1(("satIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
135                  scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
136     satSetSensePayload( pSense,
137                         SCSI_SNSKEY_ILLEGAL_REQUEST,
138                         0,
139                         SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
140                         satIOContext);
141 
142     ostiInitiatorIOCompleted( tiRoot,
143                               tiIORequest,
144                               tiIOSuccess,
145                               SCSI_STAT_CHECK_CONDITION,
146                               satIOContext->pTiSenseData,
147                               satIOContext->interruptContext );
148     retVal = tiSuccess;
149     goto ext;
150   }
151 
152   TI_DBG6(("satIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
153 
154   /* this may happen after tiCOMReset until OS sends inquiry */
155   if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
156   {
157 #ifdef  TD_DEBUG_ENABLE
158     oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
159 #endif
160     TI_DBG1(("satIOStart: invalid identify device data did %d\n", oneDeviceData->id));
161     retVal = tiIONoDevice;
162     goto ext;
163   }
164   /*
165    * Check if we need to return BUSY, i.e. recovery in progress
166    */
167   if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
168   {
169 #ifdef  TD_DEBUG_ENABLE
170     oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
171 #endif
172     TI_DBG1(("satIOStart: IN RECOVERY STATE cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
173                  scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
174     TI_DBG1(("satIOStart: IN RECOVERY STATE did %d\n", oneDeviceData->id));
175 
176     TI_DBG1(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
177     TI_DBG1(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
178     retVal = tiError;
179     goto ext;
180 //    return tiBusy;
181   }
182 
183   if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
184   {
185      if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
186      {
187         return satReportLun(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
188      }
189      else
190      {
191         return satPacket(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
192      }
193   }
194   else /* pSatDevData->satDeviceType != SATA_ATAPI_DEVICE */
195   {
196      /* Parse CDB */
197      switch(scsiCmnd->cdb[0])
198      {
199        case SCSIOPC_READ_6:
200          retVal = satRead6( tiRoot,
201                             tiIORequest,
202                             tiDeviceHandle,
203                             tiScsiRequest,
204                             satIOContext);
205          break;
206 
207        case SCSIOPC_READ_10:
208          retVal = satRead10( tiRoot,
209                              tiIORequest,
210                              tiDeviceHandle,
211                              tiScsiRequest,
212                              satIOContext);
213          break;
214 
215        case SCSIOPC_READ_12:
216          TI_DBG5(("satIOStart: SCSIOPC_READ_12\n"));
217          retVal = satRead12( tiRoot,
218                              tiIORequest,
219                              tiDeviceHandle,
220                              tiScsiRequest,
221                              satIOContext);
222          break;
223 
224        case SCSIOPC_READ_16:
225          retVal = satRead16( tiRoot,
226                              tiIORequest,
227                              tiDeviceHandle,
228                              tiScsiRequest,
229                              satIOContext);
230          break;
231 
232        case SCSIOPC_WRITE_6:
233          retVal = satWrite6( tiRoot,
234                              tiIORequest,
235                              tiDeviceHandle,
236                              tiScsiRequest,
237                              satIOContext);
238          break;
239 
240        case SCSIOPC_WRITE_10:
241          retVal = satWrite10( tiRoot,
242                               tiIORequest,
243                               tiDeviceHandle,
244                               tiScsiRequest,
245                               satIOContext);
246          break;
247 
248        case SCSIOPC_WRITE_12:
249          TI_DBG5(("satIOStart: SCSIOPC_WRITE_12 \n"));
250          retVal = satWrite12( tiRoot,
251                               tiIORequest,
252                               tiDeviceHandle,
253                               tiScsiRequest,
254                               satIOContext);
255 
256          break;
257 
258        case SCSIOPC_WRITE_16:
259          TI_DBG5(("satIOStart: SCSIOPC_WRITE_16\n"));
260          retVal = satWrite16( tiRoot,
261                               tiIORequest,
262                               tiDeviceHandle,
263                               tiScsiRequest,
264                               satIOContext);
265 
266          break;
267 
268        case SCSIOPC_VERIFY_10:
269          retVal = satVerify10( tiRoot,
270                                tiIORequest,
271                                tiDeviceHandle,
272                                tiScsiRequest,
273                                satIOContext);
274          break;
275 
276        case SCSIOPC_VERIFY_12:
277          TI_DBG5(("satIOStart: SCSIOPC_VERIFY_12\n"));
278          retVal = satVerify12( tiRoot,
279                                tiIORequest,
280                                tiDeviceHandle,
281                                tiScsiRequest,
282                                satIOContext);
283          break;
284 
285        case SCSIOPC_VERIFY_16:
286          TI_DBG5(("satIOStart: SCSIOPC_VERIFY_16\n"));
287          retVal = satVerify16( tiRoot,
288                                tiIORequest,
289                                tiDeviceHandle,
290                                tiScsiRequest,
291                                satIOContext);
292          break;
293 
294        case SCSIOPC_TEST_UNIT_READY:
295          retVal = satTestUnitReady( tiRoot,
296                                     tiIORequest,
297                                     tiDeviceHandle,
298                                     tiScsiRequest,
299                                     satIOContext);
300          break;
301 
302        case SCSIOPC_INQUIRY:
303          retVal = satInquiry( tiRoot,
304                               tiIORequest,
305                               tiDeviceHandle,
306                               tiScsiRequest,
307                               satIOContext);
308          break;
309 
310        case SCSIOPC_REQUEST_SENSE:
311          retVal = satRequestSense( tiRoot,
312                                    tiIORequest,
313                                    tiDeviceHandle,
314                                    tiScsiRequest,
315                                    satIOContext);
316          break;
317 
318        case SCSIOPC_MODE_SENSE_6:
319          retVal = satModeSense6( tiRoot,
320                                  tiIORequest,
321                                  tiDeviceHandle,
322                                  tiScsiRequest,
323                                  satIOContext);
324          break;
325 
326        case SCSIOPC_MODE_SENSE_10:
327          retVal = satModeSense10( tiRoot,
328                                  tiIORequest,
329                                  tiDeviceHandle,
330                                  tiScsiRequest,
331                                  satIOContext);
332          break;
333 
334 
335        case SCSIOPC_READ_CAPACITY_10:
336          retVal = satReadCapacity10( tiRoot,
337                                      tiIORequest,
338                                      tiDeviceHandle,
339                                      tiScsiRequest,
340                                      satIOContext);
341          break;
342 
343        case SCSIOPC_READ_CAPACITY_16:
344          retVal = satReadCapacity16( tiRoot,
345                                      tiIORequest,
346                                      tiDeviceHandle,
347                                      tiScsiRequest,
348                                      satIOContext);
349          break;
350 
351        case SCSIOPC_REPORT_LUN:
352          retVal = satReportLun( tiRoot,
353                                 tiIORequest,
354                                 tiDeviceHandle,
355                                 tiScsiRequest,
356                                 satIOContext);
357          break;
358 
359        case SCSIOPC_FORMAT_UNIT:
360          TI_DBG5(("satIOStart: SCSIOPC_FORMAT_UNIT\n"));
361          retVal = satFormatUnit( tiRoot,
362                                  tiIORequest,
363                                  tiDeviceHandle,
364                                  tiScsiRequest,
365                                  satIOContext);
366          break;
367        case SCSIOPC_SEND_DIAGNOSTIC: /* Table 28, p40 */
368          TI_DBG5(("satIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
369          retVal = satSendDiagnostic( tiRoot,
370                                      tiIORequest,
371                                      tiDeviceHandle,
372                                      tiScsiRequest,
373                                      satIOContext);
374          break;
375 
376        case SCSIOPC_START_STOP_UNIT:
377          TI_DBG5(("satIOStart: SCSIOPC_START_STOP_UNIT\n"));
378          retVal = satStartStopUnit( tiRoot,
379                                     tiIORequest,
380                                     tiDeviceHandle,
381                                     tiScsiRequest,
382                                     satIOContext);
383          break;
384 
385        case SCSIOPC_WRITE_SAME_10: /*  sector and LBA; SAT p64 case 3 accessing payload and very
386                                       inefficient now */
387          TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_10\n"));
388          retVal = satWriteSame10( tiRoot,
389                                   tiIORequest,
390                                   tiDeviceHandle,
391                                   tiScsiRequest,
392                                   satIOContext);
393          break;
394 
395        case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */
396          TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_16\n"));
397          retVal = satWriteSame16( tiRoot,
398                                   tiIORequest,
399                                   tiDeviceHandle,
400                                   tiScsiRequest,
401                                   satIOContext);
402          break;
403 
404        case SCSIOPC_LOG_SENSE: /* SCT and log parameter(informational exceptions) */
405          TI_DBG5(("satIOStart: SCSIOPC_LOG_SENSE\n"));
406          retVal = satLogSense( tiRoot,
407                                tiIORequest,
408                                tiDeviceHandle,
409                                tiScsiRequest,
410                                satIOContext);
411          break;
412 
413        case SCSIOPC_MODE_SELECT_6: /*mode layout and AlloLen check */
414          TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_6\n"));
415          retVal = satModeSelect6( tiRoot,
416                                   tiIORequest,
417                                   tiDeviceHandle,
418                                   tiScsiRequest,
419                                   satIOContext);
420          break;
421 
422        case SCSIOPC_MODE_SELECT_10: /* mode layout and AlloLen check and sharing CB with  satModeSelect6*/
423          TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_10\n"));
424          retVal = satModeSelect10( tiRoot,
425                                    tiIORequest,
426                                    tiDeviceHandle,
427                                    tiScsiRequest,
428                                    satIOContext);
429          break;
430 
431        case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with
432                                            satSynchronizeCache16 */
433          TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
434          retVal = satSynchronizeCache10( tiRoot,
435                                          tiIORequest,
436                                          tiDeviceHandle,
437                                          tiScsiRequest,
438                                          satIOContext);
439          break;
440 
441        case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with
442                                             satSynchronizeCache16 */
443 
444          TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
445          retVal = satSynchronizeCache16( tiRoot,
446                                          tiIORequest,
447                                          tiDeviceHandle,
448                                          tiScsiRequest,
449                                          satIOContext);
450          break;
451 
452        case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */
453          TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
454          retVal = satWriteAndVerify10( tiRoot,
455                                        tiIORequest,
456                                        tiDeviceHandle,
457                                        tiScsiRequest,
458                                        satIOContext);
459          break;
460 
461        case SCSIOPC_WRITE_AND_VERIFY_12:
462          TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
463          retVal = satWriteAndVerify12( tiRoot,
464                                        tiIORequest,
465                                        tiDeviceHandle,
466                                        tiScsiRequest,
467                                        satIOContext);
468          break;
469 
470        case SCSIOPC_WRITE_AND_VERIFY_16:
471          TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
472          retVal = satWriteAndVerify16( tiRoot,
473                                        tiIORequest,
474                                        tiDeviceHandle,
475                                        tiScsiRequest,
476                                        satIOContext);
477 
478          break;
479 
480        case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
481          TI_DBG5(("satIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
482          retVal = satReadMediaSerialNumber( tiRoot,
483                                             tiIORequest,
484                                             tiDeviceHandle,
485                                             tiScsiRequest,
486                                             satIOContext);
487 
488          break;
489 
490        case SCSIOPC_READ_BUFFER:
491          TI_DBG5(("satIOStart: SCSIOPC_READ_BUFFER\n"));
492          retVal = satReadBuffer( tiRoot,
493                                  tiIORequest,
494                                  tiDeviceHandle,
495                                  tiScsiRequest,
496                                  satIOContext);
497 
498          break;
499 
500        case SCSIOPC_WRITE_BUFFER:
501          TI_DBG5(("satIOStart: SCSIOPC_WRITE_BUFFER\n"));
502          retVal = satWriteBuffer( tiRoot,
503                                  tiIORequest,
504                                  tiDeviceHandle,
505                                  tiScsiRequest,
506                                  satIOContext);
507 
508          break;
509 
510        case SCSIOPC_REASSIGN_BLOCKS:
511          TI_DBG5(("satIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
512          retVal = satReassignBlocks( tiRoot,
513                                  tiIORequest,
514                                  tiDeviceHandle,
515                                  tiScsiRequest,
516                                  satIOContext);
517 
518          break;
519 
520        default:
521          /* Not implemented SCSI cmd, set up error response */
522          TI_DBG1(("satIOStart: unsupported SCSI cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
523                     scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
524 
525          satSetSensePayload( pSense,
526                              SCSI_SNSKEY_ILLEGAL_REQUEST,
527                              0,
528                              SCSI_SNSCODE_INVALID_COMMAND,
529                              satIOContext);
530 
531          ostiInitiatorIOCompleted( tiRoot,
532                                    tiIORequest,
533                                    tiIOSuccess,
534                                    SCSI_STAT_CHECK_CONDITION,
535                                    satIOContext->pTiSenseData,
536                                    satIOContext->interruptContext );
537          retVal = tiSuccess;
538 
539          break;
540 
541      }  /* end switch  */
542   }
543   if (retVal == tiBusy)
544   {
545 #ifdef  TD_DEBUG_ENABLE
546     oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
547 #endif
548     TI_DBG1(("satIOStart: BUSY did %d\n", oneDeviceData->id));
549     TI_DBG3(("satIOStart: LL is busy or target queue is full\n"));
550     TI_DBG3(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
551     TI_DBG3(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
552     pSatIntIo               = satIOContext->satIntIoContext;
553 
554     /* interal structure free */
555     satFreeIntIoResource( tiRoot,
556                           pSatDevData,
557                           pSatIntIo);
558   }
559 
560 ext:
561   return retVal;
562 }
563 
564 
565 /*****************************************************************************/
566 /*! \brief Setup up the SCSI Sense response.
567  *
568  *  This function is used to setup up the Sense Data payload for
569  *     CHECK CONDITION status.
570  *
571  *  \param pSense:      Pointer to the scsiRspSense_t sense data structure.
572  *  \param SnsKey:      SCSI Sense Key.
573  *  \param SnsInfo:     SCSI Sense Info.
574  *  \param SnsCode:     SCSI Sense Code.
575  *
576  *  \return: None
577  */
578 /*****************************************************************************/
579 void satSetSensePayload( scsiRspSense_t   *pSense,
580                          bit8             SnsKey,
581                          bit32            SnsInfo,
582                          bit16            SnsCode,
583                          satIOContext_t   *satIOContext
584                          )
585 {
586   /* for fixed format sense data, SPC-4, p37 */
587   bit32      i;
588   bit32      senseLength;
589 
590   TI_DBG5(("satSetSensePayload: start\n"));
591 
592   senseLength  = sizeof(scsiRspSense_t);
593 
594   /* zero out the data area */
595   for (i=0;i< senseLength;i++)
596   {
597     ((bit8*)pSense)[i] = 0;
598   }
599 
600   /*
601    * SCSI Sense Data part of response data
602    */
603   pSense->snsRespCode  = 0x70;    /*  0xC0 == vendor specific */
604                                       /*  0x70 == standard current error */
605   pSense->senseKey     = SnsKey;
606   /*
607    * Put sense info in scsi order format
608    */
609   pSense->info[0]      = (bit8)((SnsInfo >> 24) & 0xff);
610   pSense->info[1]      = (bit8)((SnsInfo >> 16) & 0xff);
611   pSense->info[2]      = (bit8)((SnsInfo >> 8) & 0xff);
612   pSense->info[3]      = (bit8)((SnsInfo) & 0xff);
613   pSense->addSenseLen  = 11;          /* fixed size of sense data = 18 */
614   pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
615   pSense->senseQual    = (bit8)(SnsCode & 0xFF);
616   /*
617    * Set pointer in scsi status
618    */
619   switch(SnsKey)
620   {
621     /*
622      * set illegal request sense key specific error in cdb, no bit pointer
623      */
624     case SCSI_SNSKEY_ILLEGAL_REQUEST:
625       pSense->skeySpecific[0] = 0xC8;
626       break;
627 
628     default:
629       break;
630   }
631   /* setting sense data length */
632   if (satIOContext != agNULL)
633   {
634     satIOContext->pTiSenseData->senseLen = 18;
635   }
636   else
637   {
638     TI_DBG1(("satSetSensePayload: satIOContext is NULL\n"));
639   }
640 }
641 
642 /*****************************************************************************/
643 /*! \brief Setup up the SCSI Sense response.
644  *
645  *  This function is used to setup up the Sense Data payload for
646  *     CHECK CONDITION status.
647  *
648  *  \param pSense:      Pointer to the scsiRspSense_t sense data structure.
649  *  \param SnsKey:      SCSI Sense Key.
650  *  \param SnsInfo:     SCSI Sense Info.
651  *  \param SnsCode:     SCSI Sense Code.
652  *
653  *  \return: None
654  */
655 /*****************************************************************************/
656 
657 void satSetDeferredSensePayload( scsiRspSense_t  *pSense,
658                                  bit8             SnsKey,
659                                  bit32            SnsInfo,
660                                  bit16            SnsCode,
661                                  satIOContext_t   *satIOContext
662                                  )
663 {
664   /* for fixed format sense data, SPC-4, p37 */
665   bit32      i;
666   bit32      senseLength;
667 
668   senseLength  = sizeof(scsiRspSense_t);
669 
670   /* zero out the data area */
671   for (i=0;i< senseLength;i++)
672   {
673     ((bit8*)pSense)[i] = 0;
674   }
675 
676   /*
677    * SCSI Sense Data part of response data
678    */
679   pSense->snsRespCode  = 0x71;        /*  0xC0 == vendor specific */
680                                       /*  0x70 == standard current error */
681   pSense->senseKey     = SnsKey;
682   /*
683    * Put sense info in scsi order format
684    */
685   pSense->info[0]      = (bit8)((SnsInfo >> 24) & 0xff);
686   pSense->info[1]      = (bit8)((SnsInfo >> 16) & 0xff);
687   pSense->info[2]      = (bit8)((SnsInfo >> 8) & 0xff);
688   pSense->info[3]      = (bit8)((SnsInfo) & 0xff);
689   pSense->addSenseLen  = 11;          /* fixed size of sense data = 18 */
690   pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
691   pSense->senseQual    = (bit8)(SnsCode & 0xFF);
692   /*
693    * Set pointer in scsi status
694    */
695   switch(SnsKey)
696   {
697     /*
698      * set illegal request sense key specific error in cdb, no bit pointer
699      */
700     case SCSI_SNSKEY_ILLEGAL_REQUEST:
701       pSense->skeySpecific[0] = 0xC8;
702       break;
703 
704     default:
705       break;
706   }
707 
708   /* setting sense data length */
709   if (satIOContext != agNULL)
710   {
711     satIOContext->pTiSenseData->senseLen = 18;
712   }
713   else
714   {
715     TI_DBG1(("satSetDeferredSensePayload: satIOContext is NULL\n"));
716   }
717 
718 }
719 /*****************************************************************************/
720 /*! \brief SAT implementation for ATAPI Packet Command.
721  *
722  *  SAT implementation for ATAPI Packet and send FIS request to LL layer.
723  *
724  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
725  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
726  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
727  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
728  *  \param   satIOContext_t:   Pointer to the SAT IO Context
729  *
730  *  \return If command is started successfully
731  *    - \e tiSuccess:     I/O request successfully initiated.
732  *    - \e tiBusy:        No resources available, try again later.
733  *    - \e tiIONoDevice:  Invalid device handle.
734  *    - \e tiError:       Other errors.
735  */
736 /*****************************************************************************/
737 GLOBAL bit32  satPacket(
738                    tiRoot_t                  *tiRoot,
739                    tiIORequest_t             *tiIORequest,
740                    tiDeviceHandle_t          *tiDeviceHandle,
741                    tiScsiInitiatorRequest_t  *tiScsiRequest,
742                    satIOContext_t            *satIOContext)
743 {
744   bit32                     status;
745   bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
746   satDeviceData_t           *pSatDevData;
747   tiIniScsiCmnd_t           *scsiCmnd;
748   agsaFisRegHostToDevice_t  *fis;
749 
750   pSatDevData   = satIOContext->pSatDevData;
751   scsiCmnd      = &tiScsiRequest->scsiCmnd;
752   fis           = satIOContext->pFis;
753 
754   TI_DBG3(("satPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
755            scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
756            scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
757            scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
758 
759   fis->h.fisType        = 0x27;                   /* Reg host to device */
760   fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
761   fis->h.command        = SAT_PACKET;             /* 0xA0 */
762   if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
763   {
764      fis->h.features    = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
765   }
766   else
767   {
768      fis->h.features    = 0;                      /* FIS reserve */
769   }
770   /* Byte count low and byte count high */
771   if ( scsiCmnd->expDataLength > 0xFFFF )
772   {
773      fis->d.lbaMid = 0xFF;                               /* FIS LBA (7 :0 ) */
774      fis->d.lbaHigh = 0xFF;                              /* FIS LBA (15:8 ) */
775   }
776   else
777   {
778      fis->d.lbaMid = (bit8)scsiCmnd->expDataLength;       /* FIS LBA (7 :0 ) */
779      fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (15:8 ) */
780   }
781 
782   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
783   fis->d.device         = 0;                      /* FIS LBA (27:24) and FIS LBA mode  */
784   fis->d.lbaLowExp      = 0;
785   fis->d.lbaMidExp      = 0;
786   fis->d.lbaHighExp     = 0;
787   fis->d.featuresExp    = 0;
788   fis->d.sectorCount    = 0;                       /* FIS sector count (7:0) */
789   fis->d.sectorCountExp = 0;
790   fis->d.reserved4      = 0;
791   fis->d.control        = 0;                      /* FIS HOB bit clear */
792   fis->d.reserved5      = 0;
793 
794   satIOContext->ATACmd = SAT_PACKET;
795 
796   if (tiScsiRequest->dataDirection == tiDirectionIn)
797   {
798       agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
799   }
800   else
801   {
802       agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
803   }
804 
805   if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
806   {
807      /*DMA transfer mode*/
808      fis->h.features |= 0x01;
809   }
810   else
811   {
812      /*PIO transfer mode*/
813      fis->h.features |= 0x0;
814   }
815 
816   satIOContext->satCompleteCB = &satPacketCB;
817 
818   /*
819    * Prepare SGL and send FIS to LL layer.
820    */
821   satIOContext->reqType = agRequestType;       /* Save it */
822 
823   status = sataLLIOStart( tiRoot,
824                           tiIORequest,
825                           tiDeviceHandle,
826                           tiScsiRequest,
827                           satIOContext);
828 
829   TI_DBG5(("satPacket: return\n"));
830   return (status);
831 }
832 
833 /*****************************************************************************/
834 /*! \brief SAT implementation for satSetFeatures.
835  *
836  *  This function creates SetFeatures fis and sends the request to LL layer
837  *
838  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
839  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
840  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
841  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
842  *  \param   satIOContext_t:   Pointer to the SAT IO Context
843  *
844  *  \return If command is started successfully
845  *    - \e tiSuccess:     I/O request successfully initiated.
846  *    - \e tiBusy:        No resources available, try again later.
847  *    - \e tiIONoDevice:  Invalid device handle.
848  *    - \e tiError:       Other errors.
849  */
850 /*****************************************************************************/
851 GLOBAL bit32  satSetFeatures(
852                             tiRoot_t                  *tiRoot,
853                             tiIORequest_t             *tiIORequest,
854                             tiDeviceHandle_t          *tiDeviceHandle,
855                             tiScsiInitiatorRequest_t  *tiScsiRequest,
856                             satIOContext_t            *satIOContext,
857                             bit8                      bIsDMAMode
858                             )
859 {
860   bit32                     status;
861   bit32                     agRequestType;
862   agsaFisRegHostToDevice_t  *fis;
863 
864   fis           = satIOContext->pFis;
865   TI_DBG3(("satSetFeatures: start\n"));
866 
867   /*
868    * Send the Set Features command.
869    */
870   fis->h.fisType        = 0x27;                   /* Reg host to device */
871   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
872   fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
873   fis->h.features       = 0x03;                   /* set transfer mode */
874   fis->d.lbaLow         = 0;
875   fis->d.lbaMid         = 0;
876   fis->d.lbaHigh        = 0;
877   fis->d.device         = 0;
878   fis->d.lbaLowExp      = 0;
879   fis->d.lbaMidExp      = 0;
880   fis->d.lbaHighExp     = 0;
881   fis->d.featuresExp    = 0;
882   fis->d.sectorCountExp = 0;
883   fis->d.reserved4      = 0;
884   fis->d.control        = 0;                      /* FIS HOB bit clear */
885   fis->d.reserved5      = 0;
886 
887   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
888 
889   /* Initialize CB for SATA completion.
890    */
891   if (bIsDMAMode)
892   {
893       fis->d.sectorCount = 0x45;
894       /*satIOContext->satCompleteCB = &satSetFeaturesDMACB;*/
895   }
896   else
897   {
898       fis->d.sectorCount = 0x0C;
899       /*satIOContext->satCompleteCB = &satSetFeaturesPIOCB;*/
900   }
901   satIOContext->satCompleteCB = &satSetFeaturesCB;
902 
903   /*
904    * Prepare SGL and send FIS to LL layer.
905    */
906   satIOContext->reqType = agRequestType;       /* Save it */
907 
908   status = sataLLIOStart( tiRoot,
909                           tiIORequest,
910                           tiDeviceHandle,
911                           tiScsiRequest,
912                           satIOContext);
913 
914   TI_DBG5(("satSetFeatures: return\n"));
915 
916   return status;
917 }
918 /*****************************************************************************/
919 /*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device.
920  *
921  *  SAT implementation for SCSI REQUEST SENSE.
922  *
923  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
924  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
925  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
926  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
927  *  \param   satIOContext_t:   Pointer to the SAT IO Context
928  *
929  *  \return If command is started successfully
930  *    - \e tiSuccess:     I/O request successfully initiated.
931  *    - \e tiBusy:        No resources available, try again later.
932  *    - \e tiIONoDevice:  Invalid device handle.
933  *    - \e tiError:       Other errors.
934  */
935 /*****************************************************************************/
936 GLOBAL bit32  satRequestSenseForATAPI(
937                    tiRoot_t                  *tiRoot,
938                    tiIORequest_t             *tiIORequest,
939                    tiDeviceHandle_t          *tiDeviceHandle,
940                    tiScsiInitiatorRequest_t  *tiScsiRequest,
941                    satIOContext_t            *satIOContext)
942 {
943   bit32                     status;
944   bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
945   satDeviceData_t           *pSatDevData;
946   tiIniScsiCmnd_t           *scsiCmnd;
947   agsaFisRegHostToDevice_t  *fis;
948 
949   pSatDevData   = satIOContext->pSatDevData;
950   scsiCmnd      = &tiScsiRequest->scsiCmnd;
951   fis           = satIOContext->pFis;
952 
953   scsiCmnd->cdb[0]   = SCSIOPC_REQUEST_SENSE;
954   scsiCmnd->cdb[1]   = 0;
955   scsiCmnd->cdb[2]   = 0;
956   scsiCmnd->cdb[3]   = 0;
957   scsiCmnd->cdb[4]   = SENSE_DATA_LENGTH;
958   scsiCmnd->cdb[5]   = 0;
959   TI_DBG3(("satRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
960            scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
961            scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
962            scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
963 
964   fis->h.fisType        = 0x27;                   /* Reg host to device */
965   fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
966   fis->h.command        = SAT_PACKET;             /* 0xA0 */
967   if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
968   {
969      fis->h.features    = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
970   }
971   else
972   {
973      fis->h.features    = 0;                         /* FIS reserve */
974   }
975 
976   fis->d.lbaLow         = 0;                         /* FIS LBA (7 :0 ) */
977   fis->d.lbaMid         = 0;                         /* FIS LBA (15:8 ) */
978   fis->d.lbaHigh        = 0x20;                      /* FIS LBA (23:16) */
979   fis->d.device         = 0;                         /* FIS LBA (27:24) and FIS LBA mode  */
980   fis->d.lbaLowExp      = 0;
981   fis->d.lbaMidExp      = 0;
982   fis->d.lbaHighExp     = 0;
983   fis->d.featuresExp    = 0;
984   fis->d.sectorCount    = 0;                          /* FIS sector count (7:0) */
985   fis->d.sectorCountExp = 0;
986   fis->d.reserved4      = 0;
987   fis->d.control        = 0;                         /* FIS HOB bit clear */
988   fis->d.reserved5      = (bit32)(scsiCmnd->cdb[0]|(scsiCmnd->cdb[1]<<8)|(scsiCmnd->cdb[2]<<16)|(scsiCmnd->cdb[3]<<24));
989 
990   satIOContext->ATACmd = SAT_PACKET;
991 
992   agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
993 
994   //if (pSatDevData->sat48BitSupport == agTRUE)
995   {
996     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
997     {
998        fis->h.features |= 0x01;
999     }
1000     else
1001     {
1002        fis->h.features |= 0x0;
1003     }
1004   }
1005 
1006   satIOContext->satCompleteCB = &satRequestSenseForATAPICB;
1007 
1008   /*
1009    * Prepare SGL and send FIS to LL layer.
1010    */
1011   satIOContext->reqType = agRequestType;       /* Save it */
1012 
1013   status = sataLLIOStart( tiRoot,
1014                           tiIORequest,
1015                           tiDeviceHandle,
1016                           tiScsiRequest,
1017                           satIOContext);
1018 
1019   TI_DBG5(("satRequestSenseForATAPI: return\n"));
1020   return (status);
1021 }
1022 /*****************************************************************************/
1023 /*! \brief SAT implementation for satDeviceReset.
1024  *
1025  *  This function creates DEVICE RESET fis and sends the request to LL layer
1026  *
1027  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1028  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1029  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1030  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1031  *  \param   satIOContext_t:   Pointer to the SAT IO Context
1032  *
1033  *  \return If command is started successfully
1034  *    - \e tiSuccess:     I/O request successfully initiated.
1035  *    - \e tiBusy:        No resources available, try again later.
1036  *    - \e tiIONoDevice:  Invalid device handle.
1037  *    - \e tiError:       Other errors.
1038  */
1039 /*****************************************************************************/
1040 GLOBAL bit32 satDeviceReset(
1041                             tiRoot_t                  *tiRoot,
1042                             tiIORequest_t             *tiIORequest,
1043                             tiDeviceHandle_t          *tiDeviceHandle,
1044                             tiScsiInitiatorRequest_t  *tiScsiRequest,
1045                             satIOContext_t            *satIOContext
1046                             )
1047 {
1048   bit32                     status;
1049   bit32                     agRequestType;
1050   agsaFisRegHostToDevice_t  *fis;
1051 
1052   fis           = satIOContext->pFis;
1053 
1054   TI_DBG3(("satDeviceReset: start\n"));
1055 
1056   /*
1057    * Send the  Execute Device Diagnostic command.
1058    */
1059   fis->h.fisType        = 0x27;                   /* Reg host to device */
1060   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1061   fis->h.command        = SAT_DEVICE_RESET;   /* 0x90 */
1062   fis->h.features       = 0;
1063   fis->d.lbaLow         = 0;
1064   fis->d.lbaMid         = 0;
1065   fis->d.lbaHigh        = 0;
1066   fis->d.device         = 0;
1067   fis->d.lbaLowExp      = 0;
1068   fis->d.lbaMidExp      = 0;
1069   fis->d.lbaHighExp     = 0;
1070   fis->d.featuresExp    = 0;
1071   fis->d.sectorCount    = 0;
1072   fis->d.sectorCountExp = 0;
1073   fis->d.reserved4      = 0;
1074   fis->d.control        = 0;                      /* FIS HOB bit clear */
1075   fis->d.reserved5      = 0;
1076 
1077   agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
1078 
1079   /* Initialize CB for SATA completion.
1080    */
1081   satIOContext->satCompleteCB = &satDeviceResetCB;
1082 
1083   /*
1084    * Prepare SGL and send FIS to LL layer.
1085    */
1086   satIOContext->reqType = agRequestType;       /* Save it */
1087 
1088   status = sataLLIOStart( tiRoot,
1089                           tiIORequest,
1090                           tiDeviceHandle,
1091                           tiScsiRequest,
1092                           satIOContext);
1093 
1094   TI_DBG3(("satDeviceReset: return\n"));
1095 
1096   return status;
1097 }
1098 
1099 /*****************************************************************************/
1100 /*! \brief SAT implementation for saExecuteDeviceDiagnostic.
1101  *
1102  *  This function creates Execute Device Diagnostic fis and sends the request to LL layer
1103  *
1104  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1105  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1106  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1107  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1108  *  \param   satIOContext_t:   Pointer to the SAT IO Context
1109  *
1110  *  \return If command is started successfully
1111  *    - \e tiSuccess:     I/O request successfully initiated.
1112  *    - \e tiBusy:        No resources available, try again later.
1113  *    - \e tiIONoDevice:  Invalid device handle.
1114  *    - \e tiError:       Other errors.
1115  */
1116 /*****************************************************************************/
1117 GLOBAL bit32  satExecuteDeviceDiagnostic(
1118                             tiRoot_t                  *tiRoot,
1119                             tiIORequest_t             *tiIORequest,
1120                             tiDeviceHandle_t          *tiDeviceHandle,
1121                             tiScsiInitiatorRequest_t  *tiScsiRequest,
1122                             satIOContext_t            *satIOContext
1123                             )
1124 {
1125   bit32                     status;
1126   bit32                     agRequestType;
1127   agsaFisRegHostToDevice_t  *fis;
1128 
1129   fis           = satIOContext->pFis;
1130 
1131   TI_DBG3(("satExecuteDeviceDiagnostic: start\n"));
1132 
1133   /*
1134    * Send the  Execute Device Diagnostic command.
1135    */
1136   fis->h.fisType        = 0x27;                   /* Reg host to device */
1137   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1138   fis->h.command        = SAT_EXECUTE_DEVICE_DIAGNOSTIC;   /* 0x90 */
1139   fis->h.features       = 0;
1140   fis->d.lbaLow         = 0;
1141   fis->d.lbaMid         = 0;
1142   fis->d.lbaHigh        = 0;
1143   fis->d.device         = 0;
1144   fis->d.lbaLowExp      = 0;
1145   fis->d.lbaMidExp      = 0;
1146   fis->d.lbaHighExp     = 0;
1147   fis->d.featuresExp    = 0;
1148   fis->d.sectorCount    = 0;
1149   fis->d.sectorCountExp = 0;
1150   fis->d.reserved4      = 0;
1151   fis->d.control        = 0;                      /* FIS HOB bit clear */
1152   fis->d.reserved5      = 0;
1153 
1154   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
1155 
1156   /* Initialize CB for SATA completion.
1157    */
1158   satIOContext->satCompleteCB = &satExecuteDeviceDiagnosticCB;
1159 
1160   /*
1161    * Prepare SGL and send FIS to LL layer.
1162    */
1163   satIOContext->reqType = agRequestType;       /* Save it */
1164 
1165   status = sataLLIOStart( tiRoot,
1166                           tiIORequest,
1167                           tiDeviceHandle,
1168                           tiScsiRequest,
1169                           satIOContext);
1170 
1171   TI_DBG5(("satExecuteDeviceDiagnostic: return\n"));
1172 
1173   return status;
1174 }
1175 
1176 
1177 /*****************************************************************************/
1178 /*! \brief SAT implementation for SCSI READ10.
1179  *
1180  *  SAT implementation for SCSI READ10 and send FIS request to LL layer.
1181  *
1182  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1183  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1184  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1185  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1186  *  \param   satIOContext_t:   Pointer to the SAT IO Context
1187  *
1188  *  \return If command is started successfully
1189  *    - \e tiSuccess:     I/O request successfully initiated.
1190  *    - \e tiBusy:        No resources available, try again later.
1191  *    - \e tiIONoDevice:  Invalid device handle.
1192  *    - \e tiError:       Other errors.
1193  */
1194 /*****************************************************************************/
1195 GLOBAL bit32  satRead10(
1196                    tiRoot_t                  *tiRoot,
1197                    tiIORequest_t             *tiIORequest,
1198                    tiDeviceHandle_t          *tiDeviceHandle,
1199                    tiScsiInitiatorRequest_t *tiScsiRequest,
1200                    satIOContext_t            *satIOContext)
1201 {
1202 
1203   bit32                     status;
1204   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1205   satDeviceData_t           *pSatDevData;
1206   scsiRspSense_t            *pSense;
1207   tiIniScsiCmnd_t           *scsiCmnd;
1208   agsaFisRegHostToDevice_t  *fis;
1209   bit32                     lba = 0;
1210   bit32                     tl = 0;
1211   bit32                     LoopNum = 1;
1212   bit8                      LBA[4];
1213   bit8                      TL[4];
1214   bit32                     rangeChk = agFALSE; /* lba and tl range check */
1215 
1216   pSense        = satIOContext->pSense;
1217   pSatDevData   = satIOContext->pSatDevData;
1218   scsiCmnd      = &tiScsiRequest->scsiCmnd;
1219   fis           = satIOContext->pFis;
1220 
1221   TI_DBG5(("satRead10: start\n"));
1222   TI_DBG5(("satRead10: pSatDevData=%p\n", pSatDevData));
1223   //  tdhexdump("satRead10", (bit8 *)scsiCmnd->cdb, 10);
1224 
1225   /* checking FUA_NV */
1226   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1227   {
1228     satSetSensePayload( pSense,
1229                         SCSI_SNSKEY_ILLEGAL_REQUEST,
1230                         0,
1231                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1232                         satIOContext);
1233 
1234     ostiInitiatorIOCompleted( tiRoot,
1235                               tiIORequest,
1236                               tiIOSuccess,
1237                               SCSI_STAT_CHECK_CONDITION,
1238                               satIOContext->pTiSenseData,
1239                               satIOContext->interruptContext );
1240 
1241     TI_DBG1(("satRead10: return FUA_NV\n"));
1242     return tiSuccess;
1243 
1244   }
1245 
1246   /* checking CONTROL */
1247   /* NACA == 1 or LINK == 1*/
1248   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
1249   {
1250     satSetSensePayload( pSense,
1251                         SCSI_SNSKEY_ILLEGAL_REQUEST,
1252                         0,
1253                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1254                         satIOContext);
1255 
1256     ostiInitiatorIOCompleted( tiRoot,
1257                               tiIORequest,
1258                               tiIOSuccess,
1259                               SCSI_STAT_CHECK_CONDITION,
1260                               satIOContext->pTiSenseData,
1261                               satIOContext->interruptContext );
1262 
1263     TI_DBG1(("satRead10: return control\n"));
1264     return tiSuccess;
1265   }
1266 
1267   osti_memset(LBA, 0, sizeof(LBA));
1268   osti_memset(TL, 0, sizeof(TL));
1269 
1270   /* do not use memcpy due to indexing in LBA and TL */
1271   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
1272   LBA[1] = scsiCmnd->cdb[3];
1273   LBA[2] = scsiCmnd->cdb[4];
1274   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
1275 
1276   TL[0] = 0;
1277   TL[1] = 0;
1278   TL[2] = scsiCmnd->cdb[7];   /* MSB */
1279   TL[3] = scsiCmnd->cdb[8];   /* LSB */
1280 
1281   rangeChk = satAddNComparebit32(LBA, TL);
1282 
1283   /* cbd10; computing LBA and transfer length */
1284   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
1285     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
1286   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
1287 
1288 
1289   TI_DBG5(("satRead10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
1290   TI_DBG5(("satRead10: lba 0x%x functioned lba 0x%x\n", lba, satComputeCDB10LBA(satIOContext)));
1291   TI_DBG5(("satRead10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
1292 
1293   /* Table 34, 9.1, p 46 */
1294   /*
1295     note: As of 2/10/2006, no support for DMA QUEUED
1296    */
1297 
1298   /*
1299     Table 34, 9.1, p 46, b
1300     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
1301     return check condition
1302   */
1303 
1304   if (pSatDevData->satNCQ != agTRUE &&
1305       pSatDevData->sat48BitSupport != agTRUE
1306       )
1307   {
1308     if (lba > SAT_TR_LBA_LIMIT - 1)
1309     {
1310       TI_DBG1(("satRead10: return LBA out of range, not EXT\n"));
1311       satSetSensePayload( pSense,
1312                           SCSI_SNSKEY_ILLEGAL_REQUEST,
1313                           0,
1314                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1315                           satIOContext);
1316 
1317       ostiInitiatorIOCompleted( tiRoot,
1318                                 tiIORequest,
1319                                 tiIOSuccess,
1320                                 SCSI_STAT_CHECK_CONDITION,
1321                                 satIOContext->pTiSenseData,
1322                                 satIOContext->interruptContext );
1323 
1324     return tiSuccess;
1325     }
1326 
1327 
1328     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
1329     {
1330       TI_DBG1(("satRead10: return LBA+TL out of range, not EXT\n"));
1331       satSetSensePayload( pSense,
1332                           SCSI_SNSKEY_ILLEGAL_REQUEST,
1333                           0,
1334                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1335                           satIOContext);
1336 
1337       ostiInitiatorIOCompleted( tiRoot,
1338                                 tiIORequest,
1339                                 tiIOSuccess,
1340                                 SCSI_STAT_CHECK_CONDITION,
1341                                 satIOContext->pTiSenseData,
1342                                 satIOContext->interruptContext );
1343 
1344     return tiSuccess;
1345     }
1346   }
1347 
1348   /* case 1 and 2 */
1349   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
1350   {
1351     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1352     {
1353       /* case 2 */
1354       /* READ DMA*/
1355       /* in case that we can't fit the transfer length,
1356          we need to make it fit by sending multiple ATA cmnds */
1357       TI_DBG5(("satRead10: case 2\n"));
1358 
1359 
1360       fis->h.fisType        = 0x27;                   /* Reg host to device */
1361       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1362       fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
1363       fis->h.features       = 0;                      /* FIS reserve */
1364       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1365       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1366       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1367       fis->d.device         =
1368         (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
1369       fis->d.lbaLowExp      = 0;
1370       fis->d.lbaMidExp      = 0;
1371       fis->d.lbaHighExp     = 0;
1372       fis->d.featuresExp    = 0;
1373       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1374       fis->d.sectorCountExp = 0;
1375       fis->d.reserved4      = 0;
1376       fis->d.control        = 0;                      /* FIS HOB bit clear */
1377       fis->d.reserved5      = 0;
1378 
1379 
1380       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1381       satIOContext->ATACmd = SAT_READ_DMA;
1382     }
1383     else
1384     {
1385       /* case 1 */
1386       /* READ MULTIPLE or READ SECTOR(S) */
1387       /* READ SECTORS for easier implemetation */
1388       /* in case that we can't fit the transfer length,
1389          we need to make it fit by sending multiple ATA cmnds */
1390       TI_DBG5(("satRead10: case 1\n"));
1391 
1392       fis->h.fisType        = 0x27;                   /* Reg host to device */
1393       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1394       fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
1395       fis->h.features       = 0;                      /* FIS reserve */
1396       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1397       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1398       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1399       fis->d.device         =
1400         (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
1401       fis->d.lbaLowExp      = 0;
1402       fis->d.lbaMidExp      = 0;
1403       fis->d.lbaHighExp     = 0;
1404       fis->d.featuresExp    = 0;
1405       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1406       fis->d.sectorCountExp = 0;
1407       fis->d.reserved4      = 0;
1408       fis->d.control        = 0;                      /* FIS HOB bit clear */
1409       fis->d.reserved5      = 0;
1410 
1411 
1412       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1413       satIOContext->ATACmd = SAT_READ_SECTORS;
1414     }
1415   }
1416 
1417    /* case 3 and 4 */
1418   if (pSatDevData->sat48BitSupport == agTRUE)
1419   {
1420     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1421     {
1422       /* case 3 */
1423       /* READ DMA EXT */
1424       TI_DBG5(("satRead10: case 3\n"));
1425       fis->h.fisType        = 0x27;                   /* Reg host to device */
1426 
1427       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1428       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
1429       fis->h.features       = 0;                      /* FIS reserve */
1430       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1431       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1432       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1433       fis->d.device         = 0x40;                   /* FIS LBA mode set */
1434       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
1435       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1436       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1437       fis->d.featuresExp    = 0;                      /* FIS reserve */
1438       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1439       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
1440       fis->d.reserved4      = 0;
1441       fis->d.control        = 0;                      /* FIS HOB bit clear */
1442       fis->d.reserved5      = 0;
1443 
1444       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1445       satIOContext->ATACmd = SAT_READ_DMA_EXT;
1446 
1447     }
1448     else
1449     {
1450       /* case 4 */
1451       /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
1452       /* READ SECTORS EXT for easier implemetation */
1453       TI_DBG5(("satRead10: case 4\n"));
1454       fis->h.fisType        = 0x27;                   /* Reg host to device */
1455       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1456 
1457       /* Check FUA bit */
1458       if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1459       {
1460 
1461         /* for now, no support for FUA */
1462         satSetSensePayload( pSense,
1463                             SCSI_SNSKEY_ILLEGAL_REQUEST,
1464                             0,
1465                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1466                             satIOContext);
1467 
1468         ostiInitiatorIOCompleted( tiRoot,
1469                                   tiIORequest,
1470                                   tiIOSuccess,
1471                                   SCSI_STAT_CHECK_CONDITION,
1472                                   satIOContext->pTiSenseData,
1473                                   satIOContext->interruptContext );
1474         return tiSuccess;
1475       }
1476 
1477       fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
1478 
1479       fis->h.features       = 0;                      /* FIS reserve */
1480       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1481       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1482       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1483       fis->d.device         = 0x40;                   /* FIS LBA mode set */
1484       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
1485       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1486       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1487       fis->d.featuresExp    = 0;                      /* FIS reserve */
1488       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1489       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
1490       fis->d.reserved4      = 0;
1491       fis->d.control        = 0;                      /* FIS HOB bit clear */
1492       fis->d.reserved5      = 0;
1493 
1494       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1495       satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
1496     }
1497   }
1498 
1499   /* case 5 */
1500   if (pSatDevData->satNCQ == agTRUE)
1501   {
1502     /* READ FPDMA QUEUED */
1503     if (pSatDevData->sat48BitSupport != agTRUE)
1504     {
1505       TI_DBG5(("satRead10: case 5 !!! error NCQ but 28 bit address support \n"));
1506       satSetSensePayload( pSense,
1507                           SCSI_SNSKEY_ILLEGAL_REQUEST,
1508                           0,
1509                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1510                           satIOContext);
1511 
1512       ostiInitiatorIOCompleted( tiRoot,
1513                                 tiIORequest,
1514                                 tiIOSuccess,
1515                                 SCSI_STAT_CHECK_CONDITION,
1516                                 satIOContext->pTiSenseData,
1517                                 satIOContext->interruptContext );
1518       return tiSuccess;
1519     }
1520 
1521     TI_DBG6(("satRead10: case 5\n"));
1522 
1523     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
1524 
1525     fis->h.fisType        = 0x27;                   /* Reg host to device */
1526     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1527     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
1528     fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1529     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1530     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1531     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1532 
1533     /* Check FUA bit */
1534     if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1535       fis->d.device       = 0xC0;                   /* FIS FUA set */
1536     else
1537       fis->d.device       = 0x40;                   /* FIS FUA clear */
1538 
1539     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
1540     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1541     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1542     fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
1543     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
1544     fis->d.sectorCountExp = 0;
1545     fis->d.reserved4      = 0;
1546     fis->d.control        = 0;                      /* FIS HOB bit clear */
1547     fis->d.reserved5      = 0;
1548 
1549     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1550     satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
1551   }
1552 
1553 
1554   //  tdhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
1555 
1556   /* saves the current LBA and orginal TL */
1557   satIOContext->currentLBA = lba;
1558   satIOContext->OrgTL = tl;
1559 
1560  /*
1561     computing number of loop and remainder for tl
1562     0xFF in case not ext
1563     0xFFFF in case EXT
1564   */
1565   if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1566   {
1567     LoopNum = satComputeLoopNum(tl, 0xFF);
1568   }
1569   else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1570   {
1571     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1572     LoopNum = satComputeLoopNum(tl, 0xFFFF);
1573   }
1574   else
1575   {
1576     /* SAT_READ_FPDMA_QUEUED */
1577     LoopNum = satComputeLoopNum(tl, 0xFFFF);
1578   }
1579 
1580   satIOContext->LoopNum = LoopNum;
1581 
1582   /* Initialize CB for SATA completion.
1583    */
1584   if (LoopNum == 1)
1585   {
1586     TI_DBG5(("satRead10: NON CHAINED data\n"));
1587     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
1588   }
1589   else
1590   {
1591     TI_DBG1(("satRead10: CHAINED data\n"));
1592     /* re-setting tl */
1593     if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1594     {
1595        fis->d.sectorCount    = 0xFF;
1596     }
1597     else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1598     {
1599       /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1600       fis->d.sectorCount    = 0xFF;
1601       fis->d.sectorCountExp = 0xFF;
1602     }
1603     else
1604     {
1605       /* SAT_READ_FPDMA_QUEUED */
1606       fis->h.features       = 0xFF;
1607       fis->d.featuresExp    = 0xFF;
1608     }
1609 
1610     /* chained data */
1611     satIOContext->satCompleteCB = &satChainedDataIOCB;
1612 
1613   }
1614 
1615   /*
1616    * Prepare SGL and send FIS to LL layer.
1617    */
1618   satIOContext->reqType = agRequestType;       /* Save it */
1619 
1620   status = sataLLIOStart( tiRoot,
1621                           tiIORequest,
1622                           tiDeviceHandle,
1623                           tiScsiRequest,
1624                           satIOContext);
1625 
1626   TI_DBG5(("satRead10: return\n"));
1627   return (status);
1628 
1629 }
1630 
1631 
1632 /*****************************************************************************/
1633 /*! \brief SAT implementation for SCSI satRead_1.
1634  *
1635  *  SAT implementation for SCSI satRead_1
1636  *  Sub function of satRead10
1637  *
1638  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1639  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1640  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1641  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1642  *  \param   satIOContext_t:   Pointer to the SAT IO Context
1643  *
1644  *  \return If command is started successfully
1645  *    - \e tiSuccess:     I/O request successfully initiated.
1646  *    - \e tiBusy:        No resources available, try again later.
1647  *    - \e tiIONoDevice:  Invalid device handle.
1648  *    - \e tiError:       Other errors.
1649  */
1650 /*****************************************************************************/
1651 /*
1652  * as a part of loop for read10
1653  */
1654 GLOBAL bit32  satRead_1(
1655                           tiRoot_t                  *tiRoot,
1656                           tiIORequest_t             *tiIORequest,
1657                           tiDeviceHandle_t          *tiDeviceHandle,
1658                           tiScsiInitiatorRequest_t *tiScsiRequest,
1659                           satIOContext_t            *satIOContext)
1660 {
1661   /*
1662     Assumption: error check on lba and tl has been done in satRead*()
1663     lba = lba + tl;
1664   */
1665   bit32                     status;
1666   satIOContext_t            *satOrgIOContext = agNULL;
1667   tiIniScsiCmnd_t           *scsiCmnd;
1668   agsaFisRegHostToDevice_t  *fis;
1669   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1670   bit32                     lba = 0;
1671   bit32                     DenomTL = 0xFF;
1672   bit32                     Remainder = 0;
1673   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
1674 
1675   TI_DBG2(("satRead_1: start\n"));
1676 
1677   fis             = satIOContext->pFis;
1678   satOrgIOContext = satIOContext->satOrgIOContext;
1679   scsiCmnd        = satOrgIOContext->pScsiCmnd;
1680 
1681   osti_memset(LBA,0, sizeof(LBA));
1682 
1683   switch (satOrgIOContext->ATACmd)
1684   {
1685   case SAT_READ_DMA:
1686     DenomTL = 0xFF;
1687     break;
1688   case SAT_READ_SECTORS:
1689     DenomTL = 0xFF;
1690     break;
1691   case SAT_READ_DMA_EXT:
1692     DenomTL = 0xFFFF;
1693     break;
1694   case SAT_READ_SECTORS_EXT:
1695     DenomTL = 0xFFFF;
1696     break;
1697   case SAT_READ_FPDMA_QUEUED:
1698     DenomTL = 0xFFFF;
1699     break;
1700   default:
1701     TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1702     return tiError;
1703     break;
1704   }
1705 
1706   Remainder = satOrgIOContext->OrgTL % DenomTL;
1707   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
1708   lba = satOrgIOContext->currentLBA;
1709 
1710   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3));
1711   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
1712   LBA[2] = (bit8)((lba & 0xF0) >> 8);
1713   LBA[3] = (bit8)(lba & 0xF);
1714 
1715 
1716   switch (satOrgIOContext->ATACmd)
1717   {
1718   case SAT_READ_DMA:
1719     fis->h.fisType        = 0x27;                   /* Reg host to device */
1720     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1721     fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
1722     fis->h.features       = 0;                      /* FIS reserve */
1723     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1724     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1725     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1726     fis->d.device         =
1727       (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
1728     fis->d.lbaLowExp      = 0;
1729     fis->d.lbaMidExp      = 0;
1730     fis->d.lbaHighExp     = 0;
1731     fis->d.featuresExp    = 0;
1732 
1733     if (satOrgIOContext->LoopNum == 1)
1734     {
1735       /* last loop */
1736       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
1737     }
1738     else
1739     {
1740       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
1741     }
1742 
1743     fis->d.sectorCountExp = 0;
1744     fis->d.reserved4      = 0;
1745     fis->d.control        = 0;                      /* FIS HOB bit clear */
1746     fis->d.reserved5      = 0;
1747 
1748     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1749 
1750     break;
1751   case SAT_READ_SECTORS:
1752     fis->h.fisType        = 0x27;                   /* Reg host to device */
1753     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1754     fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
1755     fis->h.features       = 0;                      /* FIS reserve */
1756     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1757     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1758     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1759     fis->d.device         =
1760       (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
1761     fis->d.lbaLowExp      = 0;
1762     fis->d.lbaMidExp      = 0;
1763     fis->d.lbaHighExp     = 0;
1764     fis->d.featuresExp    = 0;
1765     if (satOrgIOContext->LoopNum == 1)
1766     {
1767       /* last loop */
1768       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
1769     }
1770     else
1771     {
1772       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
1773     }
1774     fis->d.sectorCountExp = 0;
1775     fis->d.reserved4      = 0;
1776     fis->d.control        = 0;                      /* FIS HOB bit clear */
1777     fis->d.reserved5      = 0;
1778 
1779     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1780 
1781     break;
1782   case SAT_READ_DMA_EXT:
1783     fis->h.fisType        = 0x27;                   /* Reg host to device */
1784     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1785     fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
1786     fis->h.features       = 0;                      /* FIS reserve */
1787     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1788     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1789     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1790     fis->d.device         = 0x40;                   /* FIS LBA mode set */
1791     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
1792     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1793     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1794     fis->d.featuresExp    = 0;                      /* FIS reserve */
1795     if (satOrgIOContext->LoopNum == 1)
1796     {
1797       /* last loop */
1798       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
1799       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
1800 
1801     }
1802     else
1803     {
1804       fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
1805       fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
1806     }
1807     fis->d.reserved4      = 0;
1808     fis->d.control        = 0;                      /* FIS HOB bit clear */
1809     fis->d.reserved5      = 0;
1810 
1811     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1812 
1813     break;
1814   case SAT_READ_SECTORS_EXT:
1815     fis->h.fisType        = 0x27;                   /* Reg host to device */
1816     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1817     fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
1818     fis->h.features       = 0;                      /* FIS reserve */
1819     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1820     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1821     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1822     fis->d.device         = 0x40;                   /* FIS LBA mode set */
1823     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
1824     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1825     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1826     fis->d.featuresExp    = 0;                      /* FIS reserve */
1827     if (satOrgIOContext->LoopNum == 1)
1828     {
1829       /* last loop */
1830       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
1831       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);  /* FIS sector count (15:8) */
1832     }
1833     else
1834     {
1835       fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
1836       fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
1837     }
1838     fis->d.reserved4      = 0;
1839     fis->d.control        = 0;                      /* FIS HOB bit clear */
1840     fis->d.reserved5      = 0;
1841 
1842     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1843     break;
1844   case SAT_READ_FPDMA_QUEUED:
1845     fis->h.fisType        = 0x27;                   /* Reg host to device */
1846     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1847     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
1848     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1849     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1850     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1851 
1852     /* Check FUA bit */
1853     if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1854       fis->d.device       = 0xC0;                   /* FIS FUA set */
1855     else
1856       fis->d.device       = 0x40;                   /* FIS FUA clear */
1857 
1858     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
1859     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1860     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1861     if (satOrgIOContext->LoopNum == 1)
1862     {
1863       /* last loop */
1864       fis->h.features       = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
1865       fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
1866     }
1867     else
1868     {
1869       fis->h.features       = 0xFF;       /* FIS sector count (7:0) */
1870       fis->d.featuresExp    = 0xFF;       /* FIS sector count (15:8) */
1871     }
1872     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
1873     fis->d.sectorCountExp = 0;
1874     fis->d.reserved4      = 0;
1875     fis->d.control        = 0;                      /* FIS HOB bit clear */
1876     fis->d.reserved5      = 0;
1877 
1878     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1879     break;
1880   default:
1881     TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1882     return tiError;
1883     break;
1884   }
1885 
1886   /* Initialize CB for SATA completion.
1887    */
1888   /* chained data */
1889   satIOContext->satCompleteCB = &satChainedDataIOCB;
1890 
1891 
1892   /*
1893    * Prepare SGL and send FIS to LL layer.
1894    */
1895   satIOContext->reqType = agRequestType;       /* Save it */
1896 
1897   status = sataLLIOStart( tiRoot,
1898                           tiIORequest,
1899                           tiDeviceHandle,
1900                           tiScsiRequest,
1901                           satIOContext);
1902 
1903   TI_DBG5(("satRead_1: return\n"));
1904   return (status);
1905 }
1906 /*****************************************************************************/
1907 /*! \brief SAT implementation for SCSI READ12.
1908  *
1909  *  SAT implementation for SCSI READ12 and send FIS request to LL layer.
1910  *
1911  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1912  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1913  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1914  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1915  *  \param   satIOContext_t:   Pointer to the SAT IO Context
1916  *
1917  *  \return If command is started successfully
1918  *    - \e tiSuccess:     I/O request successfully initiated.
1919  *    - \e tiBusy:        No resources available, try again later.
1920  *    - \e tiIONoDevice:  Invalid device handle.
1921  *    - \e tiError:       Other errors.
1922  */
1923 /*****************************************************************************/
1924 GLOBAL bit32  satRead12(
1925                    tiRoot_t                  *tiRoot,
1926                    tiIORequest_t             *tiIORequest,
1927                    tiDeviceHandle_t          *tiDeviceHandle,
1928                    tiScsiInitiatorRequest_t *tiScsiRequest,
1929                    satIOContext_t            *satIOContext)
1930 {
1931   bit32                     status;
1932   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1933   satDeviceData_t           *pSatDevData;
1934   scsiRspSense_t            *pSense;
1935   tiIniScsiCmnd_t           *scsiCmnd;
1936   agsaFisRegHostToDevice_t  *fis;
1937   bit32                     lba = 0;
1938   bit32                     tl = 0;
1939   bit32                     LoopNum = 1;
1940   bit8                      LBA[4];
1941   bit8                      TL[4];
1942   bit32                     rangeChk = agFALSE; /* lba and tl range check */
1943 
1944   pSense        = satIOContext->pSense;
1945   pSatDevData   = satIOContext->pSatDevData;
1946   scsiCmnd      = &tiScsiRequest->scsiCmnd;
1947   fis           = satIOContext->pFis;
1948 
1949   TI_DBG5(("satRead12: start\n"));
1950 
1951   /* checking FUA_NV */
1952   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1953   {
1954     satSetSensePayload( pSense,
1955                         SCSI_SNSKEY_ILLEGAL_REQUEST,
1956                         0,
1957                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1958                         satIOContext);
1959 
1960     ostiInitiatorIOCompleted( tiRoot,
1961                               tiIORequest,
1962                               tiIOSuccess,
1963                               SCSI_STAT_CHECK_CONDITION,
1964                               satIOContext->pTiSenseData,
1965                               satIOContext->interruptContext );
1966 
1967     TI_DBG1(("satRead12: return FUA_NV\n"));
1968     return tiSuccess;
1969 
1970   }
1971 
1972   /* checking CONTROL */
1973   /* NACA == 1 or LINK == 1*/
1974   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
1975   {
1976     satSetSensePayload( pSense,
1977                         SCSI_SNSKEY_ILLEGAL_REQUEST,
1978                         0,
1979                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1980                         satIOContext);
1981 
1982     ostiInitiatorIOCompleted( tiRoot,
1983                               tiIORequest,
1984                               tiIOSuccess,
1985                               SCSI_STAT_CHECK_CONDITION,
1986                               satIOContext->pTiSenseData,
1987                               satIOContext->interruptContext );
1988 
1989     TI_DBG2(("satRead12: return control\n"));
1990     return tiSuccess;
1991   }
1992 
1993   osti_memset(LBA, 0, sizeof(LBA));
1994   osti_memset(TL, 0, sizeof(TL));
1995 
1996   /* do not use memcpy due to indexing in LBA and TL */
1997   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
1998   LBA[1] = scsiCmnd->cdb[3];
1999   LBA[2] = scsiCmnd->cdb[4];
2000   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
2001 
2002   TL[0] = scsiCmnd->cdb[6];   /* MSB */
2003   TL[1] = scsiCmnd->cdb[7];
2004   TL[2] = scsiCmnd->cdb[8];
2005   TL[3] = scsiCmnd->cdb[9];   /* LSB */
2006 
2007   rangeChk = satAddNComparebit32(LBA, TL);
2008 
2009   lba = satComputeCDB12LBA(satIOContext);
2010   tl = satComputeCDB12TL(satIOContext);
2011 
2012   /* Table 34, 9.1, p 46 */
2013   /*
2014     note: As of 2/10/2006, no support for DMA QUEUED
2015    */
2016 
2017   /*
2018     Table 34, 9.1, p 46, b
2019     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2020     return check condition
2021   */
2022   if (pSatDevData->satNCQ != agTRUE &&
2023       pSatDevData->sat48BitSupport != agTRUE
2024       )
2025   {
2026     if (lba > SAT_TR_LBA_LIMIT - 1)
2027     {
2028       TI_DBG1(("satRead12: return LBA out of range, not EXT\n"));
2029       satSetSensePayload( pSense,
2030                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2031                           0,
2032                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2033                           satIOContext);
2034 
2035       ostiInitiatorIOCompleted( tiRoot,
2036                                 tiIORequest,
2037                                 tiIOSuccess,
2038                                 SCSI_STAT_CHECK_CONDITION,
2039                                 satIOContext->pTiSenseData,
2040                                 satIOContext->interruptContext );
2041 
2042     return tiSuccess;
2043     }
2044     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
2045     {
2046       TI_DBG1(("satRead12: return LBA+TL out of range, not EXT\n"));
2047       satSetSensePayload( pSense,
2048                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2049                           0,
2050                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2051                           satIOContext);
2052 
2053       ostiInitiatorIOCompleted( tiRoot,
2054                                 tiIORequest,
2055                                 tiIOSuccess,
2056                                 SCSI_STAT_CHECK_CONDITION,
2057                                 satIOContext->pTiSenseData,
2058                                 satIOContext->interruptContext );
2059 
2060     return tiSuccess;
2061     }
2062   }
2063 
2064   /* case 1 and 2 */
2065   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
2066   {
2067     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2068     {
2069       /* case 2 */
2070       /* READ DMA*/
2071       /* in case that we can't fit the transfer length,
2072          we need to make it fit by sending multiple ATA cmnds */
2073       TI_DBG5(("satRead12: case 2\n"));
2074 
2075 
2076       fis->h.fisType        = 0x27;                   /* Reg host to device */
2077       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2078       fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
2079       fis->h.features       = 0;                      /* FIS reserve */
2080       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2081       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2082       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2083       fis->d.device         =
2084         (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2085       fis->d.lbaLowExp      = 0;
2086       fis->d.lbaMidExp      = 0;
2087       fis->d.lbaHighExp     = 0;
2088       fis->d.featuresExp    = 0;
2089       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2090       fis->d.sectorCountExp = 0;
2091       fis->d.reserved4      = 0;
2092       fis->d.control        = 0;                      /* FIS HOB bit clear */
2093       fis->d.reserved5      = 0;
2094 
2095 
2096       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2097       satIOContext->ATACmd = SAT_READ_DMA;
2098     }
2099     else
2100     {
2101       /* case 1 */
2102       /* READ MULTIPLE or READ SECTOR(S) */
2103       /* READ SECTORS for easier implemetation */
2104       /* can't fit the transfer length but need to make it fit by sending multiple*/
2105       TI_DBG5(("satRead12: case 1\n"));
2106 
2107       fis->h.fisType        = 0x27;                   /* Reg host to device */
2108       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2109       fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
2110       fis->h.features       = 0;                      /* FIS reserve */
2111       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2112       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2113       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2114       fis->d.device         =
2115         (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2116       fis->d.lbaLowExp      = 0;
2117       fis->d.lbaMidExp      = 0;
2118       fis->d.lbaHighExp     = 0;
2119       fis->d.featuresExp    = 0;
2120       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2121       fis->d.sectorCountExp = 0;
2122       fis->d.reserved4      = 0;
2123       fis->d.control        = 0;                      /* FIS HOB bit clear */
2124       fis->d.reserved5      = 0;
2125 
2126 
2127       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2128       satIOContext->ATACmd = SAT_READ_SECTORS;
2129     }
2130   }
2131 
2132   /* case 3 and 4 */
2133   if (pSatDevData->sat48BitSupport == agTRUE)
2134   {
2135     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2136     {
2137       /* case 3 */
2138       /* READ DMA EXT */
2139       TI_DBG5(("satRead12: case 3\n"));
2140       fis->h.fisType        = 0x27;                   /* Reg host to device */
2141 
2142       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2143       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
2144       fis->h.features       = 0;                      /* FIS reserve */
2145       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2146       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2147       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2148       fis->d.device         = 0x40;                   /* FIS LBA mode set */
2149       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
2150       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2151       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2152       fis->d.featuresExp    = 0;                      /* FIS reserve */
2153       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2154       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
2155       fis->d.reserved4      = 0;
2156       fis->d.control        = 0;                      /* FIS HOB bit clear */
2157       fis->d.reserved5      = 0;
2158 
2159       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2160       satIOContext->ATACmd = SAT_READ_DMA_EXT;
2161 
2162     }
2163     else
2164     {
2165       /* case 4 */
2166       /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2167       /* READ SECTORS EXT for easier implemetation */
2168       TI_DBG5(("satRead12: case 4\n"));
2169       fis->h.fisType        = 0x27;                   /* Reg host to device */
2170       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2171 
2172       /* Check FUA bit */
2173       if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2174       {
2175         /* for now, no support for FUA */
2176         satSetSensePayload( pSense,
2177                             SCSI_SNSKEY_ILLEGAL_REQUEST,
2178                             0,
2179                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2180                             satIOContext);
2181 
2182         ostiInitiatorIOCompleted( tiRoot,
2183                                   tiIORequest,
2184                                   tiIOSuccess,
2185                                   SCSI_STAT_CHECK_CONDITION,
2186                                   satIOContext->pTiSenseData,
2187                                   satIOContext->interruptContext );
2188         return tiSuccess;
2189       }
2190 
2191       fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
2192 
2193       fis->h.features       = 0;                      /* FIS reserve */
2194       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2195       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2196       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2197       fis->d.device         = 0x40;                   /* FIS LBA mode set */
2198       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
2199       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2200       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2201       fis->d.featuresExp    = 0;                      /* FIS reserve */
2202       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2203       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
2204       fis->d.reserved4      = 0;
2205       fis->d.control        = 0;                      /* FIS HOB bit clear */
2206       fis->d.reserved5      = 0;
2207 
2208       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2209       satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2210     }
2211   }
2212 
2213   /* case 5 */
2214   if (pSatDevData->satNCQ == agTRUE)
2215   {
2216     /* READ FPDMA QUEUED */
2217     if (pSatDevData->sat48BitSupport != agTRUE)
2218     {
2219       TI_DBG5(("satRead12: case 5 !!! error NCQ but 28 bit address support \n"));
2220       satSetSensePayload( pSense,
2221                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2222                           0,
2223                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2224                           satIOContext);
2225 
2226       ostiInitiatorIOCompleted( tiRoot,
2227                                 tiIORequest,
2228                                 tiIOSuccess,
2229                                 SCSI_STAT_CHECK_CONDITION,
2230                                 satIOContext->pTiSenseData,
2231                                 satIOContext->interruptContext );
2232       return tiSuccess;
2233     }
2234 
2235     TI_DBG6(("satRead12: case 5\n"));
2236 
2237     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2238 
2239     fis->h.fisType        = 0x27;                   /* Reg host to device */
2240     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2241     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
2242     fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2243     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2244     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2245     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2246 
2247     /* Check FUA bit */
2248     if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2249       fis->d.device       = 0xC0;                   /* FIS FUA set */
2250     else
2251       fis->d.device       = 0x40;                   /* FIS FUA clear */
2252 
2253     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
2254     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2255     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2256     fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
2257     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
2258     fis->d.sectorCountExp = 0;
2259     fis->d.reserved4      = 0;
2260     fis->d.control        = 0;                      /* FIS HOB bit clear */
2261     fis->d.reserved5      = 0;
2262 
2263     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2264     satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2265   }
2266 
2267   /* saves the current LBA and orginal TL */
2268   satIOContext->currentLBA = lba;
2269   satIOContext->OrgTL = tl;
2270 
2271   /*
2272     computing number of loop and remainder for tl
2273     0xFF in case not ext
2274     0xFFFF in case EXT
2275   */
2276   if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2277   {
2278     LoopNum = satComputeLoopNum(tl, 0xFF);
2279   }
2280   else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2281   {
2282     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2283     LoopNum = satComputeLoopNum(tl, 0xFFFF);
2284   }
2285   else
2286   {
2287     /* SAT_READ_FPDMA_QUEUEDK */
2288     LoopNum = satComputeLoopNum(tl, 0xFFFF);
2289   }
2290 
2291   satIOContext->LoopNum = LoopNum;
2292 
2293   if (LoopNum == 1)
2294   {
2295     TI_DBG5(("satRead12: NON CHAINED data\n"));
2296     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2297   }
2298   else
2299   {
2300     TI_DBG1(("satRead12: CHAINED data\n"));
2301     /* re-setting tl */
2302     if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2303     {
2304        fis->d.sectorCount    = 0xFF;
2305     }
2306     else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2307     {
2308       /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2309       fis->d.sectorCount    = 0xFF;
2310       fis->d.sectorCountExp = 0xFF;
2311     }
2312     else
2313     {
2314       /* SAT_READ_FPDMA_QUEUED */
2315       fis->h.features       = 0xFF;
2316       fis->d.featuresExp    = 0xFF;
2317     }
2318 
2319     /* chained data */
2320     satIOContext->satCompleteCB = &satChainedDataIOCB;
2321   }
2322 
2323   /*
2324    * Prepare SGL and send FIS to LL layer.
2325    */
2326   satIOContext->reqType = agRequestType;       /* Save it */
2327 
2328   status = sataLLIOStart( tiRoot,
2329                           tiIORequest,
2330                           tiDeviceHandle,
2331                           tiScsiRequest,
2332                           satIOContext);
2333 
2334   TI_DBG5(("satRead12: return\n"));
2335   return (status);
2336 }
2337 /*****************************************************************************/
2338 /*! \brief SAT implementation for SCSI READ16.
2339  *
2340  *  SAT implementation for SCSI READ16 and send FIS request to LL layer.
2341  *
2342  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
2343  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
2344  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
2345  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
2346  *  \param   satIOContext_t:   Pointer to the SAT IO Context
2347  *
2348  *  \return If command is started successfully
2349  *    - \e tiSuccess:     I/O request successfully initiated.
2350  *    - \e tiBusy:        No resources available, try again later.
2351  *    - \e tiIONoDevice:  Invalid device handle.
2352  *    - \e tiError:       Other errors.
2353  */
2354 /*****************************************************************************/
2355 GLOBAL bit32  satRead16(
2356                    tiRoot_t                  *tiRoot,
2357                    tiIORequest_t             *tiIORequest,
2358                    tiDeviceHandle_t          *tiDeviceHandle,
2359                    tiScsiInitiatorRequest_t *tiScsiRequest,
2360                    satIOContext_t            *satIOContext)
2361 {
2362   bit32                     status;
2363   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2364   satDeviceData_t           *pSatDevData;
2365   scsiRspSense_t            *pSense;
2366   tiIniScsiCmnd_t           *scsiCmnd;
2367   agsaFisRegHostToDevice_t  *fis;
2368   bit32                     lba = 0;
2369   bit32                     tl = 0;
2370   bit32                     LoopNum = 1;
2371   bit8                      LBA[8];
2372   bit8                      TL[8];
2373   bit32                     rangeChk = agFALSE; /* lba and tl range check */
2374   bit32                     limitChk = agFALSE; /* lba and tl range check */
2375 
2376   pSense        = satIOContext->pSense;
2377   pSatDevData   = satIOContext->pSatDevData;
2378   scsiCmnd      = &tiScsiRequest->scsiCmnd;
2379   fis           = satIOContext->pFis;
2380 
2381   TI_DBG5(("satRead16: start\n"));
2382 
2383   /* checking FUA_NV */
2384   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
2385   {
2386     satSetSensePayload( pSense,
2387                         SCSI_SNSKEY_ILLEGAL_REQUEST,
2388                         0,
2389                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2390                         satIOContext);
2391 
2392     ostiInitiatorIOCompleted( tiRoot,
2393                               tiIORequest,
2394                               tiIOSuccess,
2395                               SCSI_STAT_CHECK_CONDITION,
2396                               satIOContext->pTiSenseData,
2397                               satIOContext->interruptContext );
2398 
2399     TI_DBG1(("satRead16: return FUA_NV\n"));
2400     return tiSuccess;
2401 
2402   }
2403 
2404   /* checking CONTROL */
2405   /* NACA == 1 or LINK == 1*/
2406   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
2407   {
2408     satSetSensePayload( pSense,
2409                         SCSI_SNSKEY_ILLEGAL_REQUEST,
2410                         0,
2411                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2412                         satIOContext);
2413 
2414     ostiInitiatorIOCompleted( tiRoot,
2415                               tiIORequest,
2416                               tiIOSuccess,
2417                               SCSI_STAT_CHECK_CONDITION,
2418                               satIOContext->pTiSenseData,
2419                               satIOContext->interruptContext );
2420 
2421     TI_DBG1(("satRead16: return control\n"));
2422     return tiSuccess;
2423   }
2424 
2425 
2426   osti_memset(LBA, 0, sizeof(LBA));
2427   osti_memset(TL, 0, sizeof(TL));
2428 
2429 
2430   /* do not use memcpy due to indexing in LBA and TL */
2431   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
2432   LBA[1] = scsiCmnd->cdb[3];
2433   LBA[2] = scsiCmnd->cdb[4];
2434   LBA[3] = scsiCmnd->cdb[5];
2435   LBA[4] = scsiCmnd->cdb[6];
2436   LBA[5] = scsiCmnd->cdb[7];
2437   LBA[6] = scsiCmnd->cdb[8];
2438   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
2439 
2440   TL[0] = 0;
2441   TL[1] = 0;
2442   TL[2] = 0;
2443   TL[3] = 0;
2444   TL[4] = scsiCmnd->cdb[10];   /* MSB */
2445   TL[5] = scsiCmnd->cdb[11];
2446   TL[6] = scsiCmnd->cdb[12];
2447   TL[7] = scsiCmnd->cdb[13];   /* LSB */
2448 
2449  rangeChk = satAddNComparebit64(LBA, TL);
2450 
2451  limitChk = satCompareLBALimitbit(LBA);
2452 
2453  lba = satComputeCDB16LBA(satIOContext);
2454  tl = satComputeCDB16TL(satIOContext);
2455 
2456 
2457   /* Table 34, 9.1, p 46 */
2458   /*
2459     note: As of 2/10/2006, no support for DMA QUEUED
2460    */
2461 
2462   /*
2463     Table 34, 9.1, p 46, b
2464     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2465     return check condition
2466   */
2467   if (pSatDevData->satNCQ != agTRUE &&
2468       pSatDevData->sat48BitSupport != agTRUE
2469       )
2470   {
2471     if (limitChk)
2472     {
2473       TI_DBG1(("satRead16: return LBA out of range, not EXT\n"));
2474       satSetSensePayload( pSense,
2475                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2476                           0,
2477                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2478                           satIOContext);
2479 
2480       ostiInitiatorIOCompleted( tiRoot,
2481                                 tiIORequest,
2482                                 tiIOSuccess,
2483                                 SCSI_STAT_CHECK_CONDITION,
2484                                 satIOContext->pTiSenseData,
2485                                 satIOContext->interruptContext );
2486 
2487     return tiSuccess;
2488     }
2489     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
2490     {
2491       TI_DBG1(("satRead16: return LBA+TL out of range, not EXT\n"));
2492       satSetSensePayload( pSense,
2493                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2494                           0,
2495                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2496                           satIOContext);
2497 
2498       ostiInitiatorIOCompleted( tiRoot,
2499                                 tiIORequest,
2500                                 tiIOSuccess,
2501                                 SCSI_STAT_CHECK_CONDITION,
2502                                 satIOContext->pTiSenseData,
2503                                 satIOContext->interruptContext );
2504 
2505     return tiSuccess;
2506     }
2507   }
2508 
2509   /* case 1 and 2 */
2510   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
2511   {
2512     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2513     {
2514       /* case 2 */
2515       /* READ DMA*/
2516       /* in case that we can't fit the transfer length,
2517          we need to make it fit by sending multiple ATA cmnds */
2518       TI_DBG5(("satRead16: case 2\n"));
2519 
2520 
2521       fis->h.fisType        = 0x27;                   /* Reg host to device */
2522       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2523       fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
2524       fis->h.features       = 0;                      /* FIS reserve */
2525       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2526       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2527       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2528       fis->d.device         =
2529         (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2530       fis->d.lbaLowExp      = 0;
2531       fis->d.lbaMidExp      = 0;
2532       fis->d.lbaHighExp     = 0;
2533       fis->d.featuresExp    = 0;
2534       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2535       fis->d.sectorCountExp = 0;
2536       fis->d.reserved4      = 0;
2537       fis->d.control        = 0;                      /* FIS HOB bit clear */
2538       fis->d.reserved5      = 0;
2539 
2540 
2541       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2542       satIOContext->ATACmd = SAT_READ_DMA;
2543     }
2544     else
2545     {
2546       /* case 1 */
2547       /* READ MULTIPLE or READ SECTOR(S) */
2548       /* READ SECTORS for easier implemetation */
2549       /* can't fit the transfer length but need to make it fit by sending multiple*/
2550       TI_DBG5(("satRead16: case 1\n"));
2551 
2552       fis->h.fisType        = 0x27;                   /* Reg host to device */
2553       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2554       fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
2555       fis->h.features       = 0;                      /* FIS reserve */
2556       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2557       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2558       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2559       fis->d.device         =
2560         (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2561       fis->d.lbaLowExp      = 0;
2562       fis->d.lbaMidExp      = 0;
2563       fis->d.lbaHighExp     = 0;
2564       fis->d.featuresExp    = 0;
2565       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2566       fis->d.sectorCountExp = 0;
2567       fis->d.reserved4      = 0;
2568       fis->d.control        = 0;                      /* FIS HOB bit clear */
2569       fis->d.reserved5      = 0;
2570 
2571 
2572       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2573       satIOContext->ATACmd = SAT_READ_SECTORS;
2574     }
2575   }
2576 
2577   /* case 3 and 4 */
2578   if (pSatDevData->sat48BitSupport == agTRUE)
2579   {
2580     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2581     {
2582       /* case 3 */
2583       /* READ DMA EXT */
2584       TI_DBG5(("satRead16: case 3\n"));
2585       fis->h.fisType        = 0x27;                   /* Reg host to device */
2586 
2587       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2588       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
2589       fis->h.features       = 0;                      /* FIS reserve */
2590       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2591       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2592       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2593       fis->d.device         = 0x40;                   /* FIS LBA mode set */
2594       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
2595       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
2596       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
2597       fis->d.featuresExp    = 0;                      /* FIS reserve */
2598       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2599       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
2600       fis->d.reserved4      = 0;
2601       fis->d.control        = 0;                      /* FIS HOB bit clear */
2602       fis->d.reserved5      = 0;
2603 
2604       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2605       satIOContext->ATACmd = SAT_READ_DMA_EXT;
2606 
2607     }
2608     else
2609     {
2610       /* case 4 */
2611       /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2612       /* READ SECTORS EXT for easier implemetation */
2613       TI_DBG5(("satRead16: case 4\n"));
2614       fis->h.fisType        = 0x27;                   /* Reg host to device */
2615       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2616 
2617       /* Check FUA bit */
2618       if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2619       {
2620 
2621         /* for now, no support for FUA */
2622         satSetSensePayload( pSense,
2623                             SCSI_SNSKEY_ILLEGAL_REQUEST,
2624                             0,
2625                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2626                             satIOContext);
2627 
2628         ostiInitiatorIOCompleted( tiRoot,
2629                                   tiIORequest,
2630                                   tiIOSuccess,
2631                                   SCSI_STAT_CHECK_CONDITION,
2632                                   satIOContext->pTiSenseData,
2633                                   satIOContext->interruptContext );
2634         return tiSuccess;
2635       }
2636 
2637       fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
2638 
2639       fis->h.features       = 0;                      /* FIS reserve */
2640       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2641       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2642       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2643       fis->d.device         = 0x40;                   /* FIS LBA mode set */
2644       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
2645       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
2646       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
2647       fis->d.featuresExp    = 0;                      /* FIS reserve */
2648       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2649       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
2650       fis->d.reserved4      = 0;
2651       fis->d.control        = 0;                      /* FIS HOB bit clear */
2652       fis->d.reserved5      = 0;
2653 
2654       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2655       satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2656     }
2657   }
2658 
2659 
2660   /* case 5 */
2661   if (pSatDevData->satNCQ == agTRUE)
2662   {
2663     /* READ FPDMA QUEUED */
2664     if (pSatDevData->sat48BitSupport != agTRUE)
2665     {
2666       TI_DBG5(("satRead16: case 5 !!! error NCQ but 28 bit address support \n"));
2667       satSetSensePayload( pSense,
2668                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2669                           0,
2670                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2671                           satIOContext);
2672 
2673       ostiInitiatorIOCompleted( tiRoot,
2674                                 tiIORequest,
2675                                 tiIOSuccess,
2676                                 SCSI_STAT_CHECK_CONDITION,
2677                                 satIOContext->pTiSenseData,
2678                                 satIOContext->interruptContext );
2679       return tiSuccess;
2680     }
2681 
2682     TI_DBG6(("satRead16: case 5\n"));
2683 
2684     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2685 
2686     fis->h.fisType        = 0x27;                   /* Reg host to device */
2687     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2688     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
2689     fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2690     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2691     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2692     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2693 
2694     /* Check FUA bit */
2695     if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2696       fis->d.device       = 0xC0;                   /* FIS FUA set */
2697     else
2698       fis->d.device       = 0x40;                   /* FIS FUA clear */
2699 
2700     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
2701     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
2702     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
2703     fis->d.featuresExp    = scsiCmnd->cdb[12];      /* FIS sector count (15:8) */
2704     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
2705     fis->d.sectorCountExp = 0;
2706     fis->d.reserved4      = 0;
2707     fis->d.control        = 0;                      /* FIS HOB bit clear */
2708     fis->d.reserved5      = 0;
2709 
2710     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2711     satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2712   }
2713 
2714   /* saves the current LBA and orginal TL */
2715   satIOContext->currentLBA = lba;
2716   satIOContext->OrgTL = tl;
2717 
2718   /*
2719     computing number of loop and remainder for tl
2720     0xFF in case not ext
2721     0xFFFF in case EXT
2722   */
2723   if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2724   {
2725     LoopNum = satComputeLoopNum(tl, 0xFF);
2726   }
2727   else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2728   {
2729     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2730     LoopNum = satComputeLoopNum(tl, 0xFFFF);
2731   }
2732   else
2733   {
2734     /* SAT_READ_FPDMA_QUEUEDK */
2735     LoopNum = satComputeLoopNum(tl, 0xFFFF);
2736   }
2737   satIOContext->LoopNum = LoopNum;
2738 
2739   if (LoopNum == 1)
2740   {
2741     TI_DBG5(("satRead16: NON CHAINED data\n"));
2742     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2743   }
2744   else
2745   {
2746     TI_DBG1(("satRead16: CHAINED data\n"));
2747     /* re-setting tl */
2748     if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2749     {
2750        fis->d.sectorCount    = 0xFF;
2751     }
2752     else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2753     {
2754       /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2755       fis->d.sectorCount    = 0xFF;
2756       fis->d.sectorCountExp = 0xFF;
2757     }
2758     else
2759     {
2760       /* SAT_READ_FPDMA_QUEUED */
2761       fis->h.features       = 0xFF;
2762       fis->d.featuresExp    = 0xFF;
2763     }
2764 
2765     /* chained data */
2766     satIOContext->satCompleteCB = &satChainedDataIOCB;
2767   }
2768 
2769   /*
2770    * Prepare SGL and send FIS to LL layer.
2771    */
2772   satIOContext->reqType = agRequestType;       /* Save it */
2773 
2774   status = sataLLIOStart( tiRoot,
2775                           tiIORequest,
2776                           tiDeviceHandle,
2777                           tiScsiRequest,
2778                           satIOContext);
2779 
2780   TI_DBG5(("satRead16: return\n"));
2781   return (status);
2782 
2783 }
2784 
2785 /*****************************************************************************/
2786 /*! \brief SAT implementation for SCSI READ6.
2787  *
2788  *  SAT implementation for SCSI READ6 and send FIS request to LL layer.
2789  *
2790  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
2791  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
2792  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
2793  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
2794  *  \param   satIOContext_t:   Pointer to the SAT IO Context
2795  *
2796  *  \return If command is started successfully
2797  *    - \e tiSuccess:     I/O request successfully initiated.
2798  *    - \e tiBusy:        No resources available, try again later.
2799  *    - \e tiIONoDevice:  Invalid device handle.
2800  *    - \e tiError:       Other errors.
2801  */
2802 /*****************************************************************************/
2803 GLOBAL bit32  satRead6(
2804                    tiRoot_t                  *tiRoot,
2805                    tiIORequest_t             *tiIORequest,
2806                    tiDeviceHandle_t          *tiDeviceHandle,
2807                    tiScsiInitiatorRequest_t *tiScsiRequest,
2808                    satIOContext_t            *satIOContext)
2809 {
2810 
2811   bit32                     status;
2812   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2813   satDeviceData_t           *pSatDevData;
2814   scsiRspSense_t            *pSense;
2815   tiIniScsiCmnd_t           *scsiCmnd;
2816   agsaFisRegHostToDevice_t  *fis;
2817   bit32                     lba = 0;
2818   bit16                     tl = 0;
2819 
2820   pSense        = satIOContext->pSense;
2821   pSatDevData   = satIOContext->pSatDevData;
2822   scsiCmnd      = &tiScsiRequest->scsiCmnd;
2823   fis           = satIOContext->pFis;
2824 
2825 
2826    TI_DBG5(("satRead6: start\n"));
2827 
2828   /* no FUA checking since read6 */
2829 
2830 
2831   /* checking CONTROL */
2832   /* NACA == 1 or LINK == 1*/
2833   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
2834   {
2835     satSetSensePayload( pSense,
2836                         SCSI_SNSKEY_ILLEGAL_REQUEST,
2837                         0,
2838                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2839                         satIOContext);
2840 
2841     ostiInitiatorIOCompleted( tiRoot,
2842                               tiIORequest,
2843                               tiIOSuccess,
2844                               SCSI_STAT_CHECK_CONDITION,
2845                               satIOContext->pTiSenseData,
2846                               satIOContext->interruptContext );
2847 
2848     TI_DBG2(("satRead6: return control\n"));
2849     return tiSuccess;
2850   }
2851 
2852   /* cbd6; computing LBA and transfer length */
2853   lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
2854     + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
2855   tl = scsiCmnd->cdb[4];
2856 
2857 
2858   /* Table 34, 9.1, p 46 */
2859   /*
2860     note: As of 2/10/2006, no support for DMA QUEUED
2861    */
2862 
2863   /*
2864     Table 34, 9.1, p 46, b
2865     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2866     return check condition
2867   */
2868   if (pSatDevData->satNCQ != agTRUE &&
2869       pSatDevData->sat48BitSupport != agTRUE
2870       )
2871   {
2872     if (lba > SAT_TR_LBA_LIMIT - 1)
2873     {
2874       satSetSensePayload( pSense,
2875                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2876                           0,
2877                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2878                           satIOContext);
2879 
2880       ostiInitiatorIOCompleted( tiRoot,
2881                                 tiIORequest,
2882                                 tiIOSuccess,
2883                                 SCSI_STAT_CHECK_CONDITION,
2884                                 satIOContext->pTiSenseData,
2885                                 satIOContext->interruptContext );
2886 
2887     TI_DBG1(("satRead6: return LBA out of range\n"));
2888     return tiSuccess;
2889     }
2890   }
2891 
2892   /* case 1 and 2 */
2893   if (lba + tl <= SAT_TR_LBA_LIMIT)
2894   {
2895     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2896     {
2897       /* case 2 */
2898       /* READ DMA*/
2899       TI_DBG5(("satRead6: case 2\n"));
2900 
2901 
2902       fis->h.fisType        = 0x27;                   /* Reg host to device */
2903       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2904       fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
2905       fis->h.features       = 0;                      /* FIS reserve */
2906       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
2907       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
2908       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
2909       fis->d.device         = 0x40;                   /* FIS LBA mode  */
2910       fis->d.lbaLowExp      = 0;
2911       fis->d.lbaMidExp      = 0;
2912       fis->d.lbaHighExp     = 0;
2913       fis->d.featuresExp    = 0;
2914       if (tl == 0)
2915       {
2916         /* temporary fix */
2917         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
2918       }
2919       else
2920       {
2921         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
2922       }
2923       fis->d.sectorCountExp = 0;
2924       fis->d.reserved4      = 0;
2925       fis->d.control        = 0;                      /* FIS HOB bit clear */
2926       fis->d.reserved5      = 0;
2927 
2928       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2929     }
2930     else
2931     {
2932       /* case 1 */
2933       /* READ SECTORS for easier implemetation */
2934       TI_DBG5(("satRead6: case 1\n"));
2935 
2936       fis->h.fisType        = 0x27;                   /* Reg host to device */
2937       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2938       fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
2939       fis->h.features       = 0;                      /* FIS reserve */
2940       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
2941       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
2942       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
2943       fis->d.device         = 0x40;                   /* FIS LBA mode  */
2944       fis->d.lbaLowExp      = 0;
2945       fis->d.lbaMidExp      = 0;
2946       fis->d.lbaHighExp     = 0;
2947       fis->d.featuresExp    = 0;
2948       if (tl == 0)
2949       {
2950         /* temporary fix */
2951         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
2952       }
2953       else
2954       {
2955         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
2956       }
2957       fis->d.sectorCountExp = 0;
2958       fis->d.reserved4      = 0;
2959       fis->d.control        = 0;                      /* FIS HOB bit clear */
2960       fis->d.reserved5      = 0;
2961 
2962       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2963 
2964     }
2965   }
2966 
2967   /* case 3 and 4 */
2968   if (pSatDevData->sat48BitSupport == agTRUE)
2969   {
2970     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2971     {
2972       /* case 3 */
2973       /* READ DMA EXT only */
2974       TI_DBG5(("satRead6: case 3\n"));
2975       fis->h.fisType        = 0x27;                   /* Reg host to device */
2976       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2977       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
2978       fis->h.features       = 0;                      /* FIS reserve */
2979       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
2980       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
2981       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
2982       fis->d.device         = 0x40;                   /* FIS LBA mode set */
2983       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
2984       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2985       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2986       fis->d.featuresExp    = 0;                      /* FIS reserve */
2987       if (tl == 0)
2988       {
2989         /* sector count is 256, 0x100*/
2990         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
2991         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
2992       }
2993       else
2994       {
2995         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
2996         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
2997       }
2998       fis->d.reserved4      = 0;
2999       fis->d.control        = 0;                      /* FIS HOB bit clear */
3000       fis->d.reserved5      = 0;
3001 
3002       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
3003     }
3004     else
3005     {
3006       /* case 4 */
3007       /* READ SECTORS EXT for easier implemetation */
3008       TI_DBG5(("satRead6: case 4\n"));
3009 
3010       fis->h.fisType        = 0x27;                   /* Reg host to device */
3011       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3012       fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
3013       fis->h.features       = 0;                      /* FIS reserve */
3014       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
3015       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
3016       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
3017       fis->d.device         = 0x40;                   /* FIS LBA mode set */
3018       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
3019       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3020       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3021       fis->d.featuresExp    = 0;                      /* FIS reserve */
3022       if (tl == 0)
3023       {
3024         /* sector count is 256, 0x100*/
3025         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
3026         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
3027       }
3028       else
3029       {
3030         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
3031         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
3032       }
3033       fis->d.reserved4      = 0;
3034       fis->d.control        = 0;                      /* FIS HOB bit clear */
3035       fis->d.reserved5      = 0;
3036 
3037       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
3038     }
3039   }
3040 
3041   /* case 5 */
3042   if (pSatDevData->satNCQ == agTRUE)
3043   {
3044     /* READ FPDMA QUEUED */
3045     if (pSatDevData->sat48BitSupport != agTRUE)
3046     {
3047       /* sanity check */
3048       TI_DBG5(("satRead6: case 5 !!! error NCQ but 28 bit address support \n"));
3049       satSetSensePayload( pSense,
3050                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3051                           0,
3052                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3053                           satIOContext);
3054 
3055       ostiInitiatorIOCompleted( tiRoot,
3056                                 tiIORequest,
3057                                 tiIOSuccess,
3058                                 SCSI_STAT_CHECK_CONDITION,
3059                                 satIOContext->pTiSenseData,
3060                                 satIOContext->interruptContext );
3061       return tiSuccess;
3062     }
3063     TI_DBG5(("satRead6: case 5\n"));
3064 
3065     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
3066 
3067     fis->h.fisType        = 0x27;                   /* Reg host to device */
3068     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3069     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
3070     fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
3071     fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
3072     fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
3073     fis->d.device         = 0x40;                   /* FIS FUA clear */
3074     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
3075     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3076     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3077     if (tl == 0)
3078     {
3079       /* sector count is 256, 0x100*/
3080       fis->h.features       = 0;                         /* FIS sector count (7:0) */
3081       fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
3082     }
3083     else
3084     {
3085       fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
3086       fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
3087     }
3088     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
3089     fis->d.sectorCountExp = 0;
3090     fis->d.reserved4      = 0;
3091     fis->d.control        = 0;                      /* FIS HOB bit clear */
3092     fis->d.reserved5      = 0;
3093 
3094     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
3095   }
3096 
3097    /* Initialize CB for SATA completion.
3098    */
3099   satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3100 
3101   /*
3102    * Prepare SGL and send FIS to LL layer.
3103    */
3104   satIOContext->reqType = agRequestType;       /* Save it */
3105 
3106   status = sataLLIOStart( tiRoot,
3107                           tiIORequest,
3108                           tiDeviceHandle,
3109                           tiScsiRequest,
3110                           satIOContext);
3111   return (status);
3112 
3113 }
3114 
3115 /*****************************************************************************/
3116 /*! \brief SAT implementation for SCSI WRITE16.
3117  *
3118  *  SAT implementation for SCSI WRITE16 and send FIS request to LL layer.
3119  *
3120  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
3121  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
3122  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
3123  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
3124  *  \param   satIOContext_t:   Pointer to the SAT IO Context
3125  *
3126  *  \return If command is started successfully
3127  *    - \e tiSuccess:     I/O request successfully initiated.
3128  *    - \e tiBusy:        No resources available, try again later.
3129  *    - \e tiIONoDevice:  Invalid device handle.
3130  *    - \e tiError:       Other errors.
3131  */
3132 /*****************************************************************************/
3133 GLOBAL bit32  satWrite16(
3134                    tiRoot_t                  *tiRoot,
3135                    tiIORequest_t             *tiIORequest,
3136                    tiDeviceHandle_t          *tiDeviceHandle,
3137                    tiScsiInitiatorRequest_t *tiScsiRequest,
3138                    satIOContext_t            *satIOContext)
3139 {
3140   bit32                     status;
3141   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3142   satDeviceData_t           *pSatDevData;
3143   scsiRspSense_t            *pSense;
3144   tiIniScsiCmnd_t           *scsiCmnd;
3145   agsaFisRegHostToDevice_t  *fis;
3146   bit32                     lba = 0;
3147   bit32                     tl = 0;
3148   bit32                     LoopNum = 1;
3149   bit8                      LBA[8];
3150   bit8                      TL[8];
3151   bit32                     rangeChk = agFALSE; /* lba and tl range check */
3152   bit32                     limitChk = agFALSE; /* lba and tl range check */
3153 
3154   pSense        = satIOContext->pSense;
3155   pSatDevData   = satIOContext->pSatDevData;
3156   scsiCmnd      = &tiScsiRequest->scsiCmnd;
3157   fis           = satIOContext->pFis;
3158 
3159   TI_DBG5(("satWrite16: start\n"));
3160 
3161   /* checking FUA_NV */
3162   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3163   {
3164     satSetSensePayload( pSense,
3165                         SCSI_SNSKEY_ILLEGAL_REQUEST,
3166                         0,
3167                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3168                         satIOContext);
3169 
3170     ostiInitiatorIOCompleted( tiRoot,
3171                               tiIORequest,
3172                               tiIOSuccess,
3173                               SCSI_STAT_CHECK_CONDITION,
3174                               satIOContext->pTiSenseData,
3175                               satIOContext->interruptContext );
3176 
3177     TI_DBG1(("satWrite16: return FUA_NV\n"));
3178     return tiSuccess;
3179 
3180   }
3181 
3182   /* checking CONTROL */
3183   /* NACA == 1 or LINK == 1*/
3184   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
3185   {
3186     satSetSensePayload( pSense,
3187                         SCSI_SNSKEY_ILLEGAL_REQUEST,
3188                         0,
3189                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3190                         satIOContext);
3191 
3192     ostiInitiatorIOCompleted( tiRoot,
3193                               tiIORequest,
3194                               tiIOSuccess,
3195                               SCSI_STAT_CHECK_CONDITION,
3196                               satIOContext->pTiSenseData,
3197                               satIOContext->interruptContext );
3198 
3199     TI_DBG1(("satWrite16: return control\n"));
3200     return tiSuccess;
3201   }
3202 
3203 
3204   osti_memset(LBA, 0, sizeof(LBA));
3205   osti_memset(TL, 0, sizeof(TL));
3206 
3207 
3208   /* do not use memcpy due to indexing in LBA and TL */
3209   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
3210   LBA[1] = scsiCmnd->cdb[3];
3211   LBA[2] = scsiCmnd->cdb[4];
3212   LBA[3] = scsiCmnd->cdb[5];
3213   LBA[4] = scsiCmnd->cdb[6];
3214   LBA[5] = scsiCmnd->cdb[7];
3215   LBA[6] = scsiCmnd->cdb[8];
3216   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
3217 
3218   TL[0] = 0;
3219   TL[1] = 0;
3220   TL[2] = 0;
3221   TL[3] = 0;
3222   TL[4] = scsiCmnd->cdb[10];   /* MSB */
3223   TL[5] = scsiCmnd->cdb[11];
3224   TL[6] = scsiCmnd->cdb[12];
3225   TL[7] = scsiCmnd->cdb[13];   /* LSB */
3226 
3227   rangeChk = satAddNComparebit64(LBA, TL);
3228 
3229   limitChk = satCompareLBALimitbit(LBA);
3230 
3231   lba = satComputeCDB16LBA(satIOContext);
3232   tl = satComputeCDB16TL(satIOContext);
3233 
3234 
3235 
3236   /* Table 34, 9.1, p 46 */
3237   /*
3238     note: As of 2/10/2006, no support for DMA QUEUED
3239   */
3240 
3241   /*
3242     Table 34, 9.1, p 46, b
3243     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3244     return check condition
3245   */
3246   if (pSatDevData->satNCQ != agTRUE &&
3247      pSatDevData->sat48BitSupport != agTRUE
3248      )
3249   {
3250     if (limitChk)
3251     {
3252       TI_DBG1(("satWrite16: return LBA out of range, not EXT\n"));
3253       satSetSensePayload( pSense,
3254                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3255                           0,
3256                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3257                           satIOContext);
3258 
3259       ostiInitiatorIOCompleted( tiRoot,
3260                                 tiIORequest,
3261                                 tiIOSuccess,
3262                                 SCSI_STAT_CHECK_CONDITION,
3263                                 satIOContext->pTiSenseData,
3264                                 satIOContext->interruptContext );
3265 
3266     return tiSuccess;
3267     }
3268     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
3269     {
3270       TI_DBG1(("satWrite16: return LBA+TL out of range, not EXT\n"));
3271       satSetSensePayload( pSense,
3272                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3273                           0,
3274                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3275                           satIOContext);
3276 
3277       ostiInitiatorIOCompleted( tiRoot,
3278                                 tiIORequest,
3279                                 tiIOSuccess,
3280                                 SCSI_STAT_CHECK_CONDITION,
3281                                 satIOContext->pTiSenseData,
3282                                 satIOContext->interruptContext );
3283 
3284     return tiSuccess;
3285     }
3286   }
3287 
3288   /* case 1 and 2 */
3289   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
3290   {
3291     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3292     {
3293       /* case 2 */
3294       /* WRITE DMA*/
3295       /* In case that we can't fit the transfer length, we loop */
3296       TI_DBG5(("satWrite16: case 2\n"));
3297       fis->h.fisType        = 0x27;                   /* Reg host to device */
3298       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3299       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
3300       fis->h.features       = 0;                      /* FIS reserve */
3301       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3302       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3303       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3304 
3305       /* FIS LBA mode set LBA (27:24) */
3306       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3307 
3308       fis->d.lbaLowExp      = 0;
3309       fis->d.lbaMidExp      = 0;
3310       fis->d.lbaHighExp     = 0;
3311       fis->d.featuresExp    = 0;
3312       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3313       fis->d.sectorCountExp = 0;
3314       fis->d.reserved4      = 0;
3315       fis->d.control        = 0;                      /* FIS HOB bit clear */
3316       fis->d.reserved5      = 0;
3317 
3318       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3319       satIOContext->ATACmd = SAT_WRITE_DMA;
3320     }
3321     else
3322     {
3323       /* case 1 */
3324       /* WRITE MULTIPLE or WRITE SECTOR(S) */
3325       /* WRITE SECTORS for easier implemetation */
3326       /* In case that we can't fit the transfer length, we loop */
3327       TI_DBG5(("satWrite16: case 1\n"));
3328       fis->h.fisType        = 0x27;                   /* Reg host to device */
3329       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3330       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
3331       fis->h.features       = 0;                      /* FIS reserve */
3332       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3333       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3334       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3335 
3336       /* FIS LBA mode set LBA (27:24) */
3337       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3338 
3339       fis->d.lbaLowExp      = 0;
3340       fis->d.lbaMidExp      = 0;
3341       fis->d.lbaHighExp     = 0;
3342       fis->d.featuresExp    = 0;
3343       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3344       fis->d.sectorCountExp = 0;
3345       fis->d.reserved4      = 0;
3346       fis->d.control        = 0;                      /* FIS HOB bit clear */
3347       fis->d.reserved5      = 0;
3348 
3349       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3350       satIOContext->ATACmd = SAT_WRITE_SECTORS;
3351     }
3352   }
3353 
3354   /* case 3 and 4 */
3355   if (pSatDevData->sat48BitSupport == agTRUE)
3356   {
3357     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3358     {
3359       /* case 3 */
3360       /* WRITE DMA EXT or WRITE DMA FUA EXT */
3361       TI_DBG5(("satWrite16: case 3\n"));
3362       fis->h.fisType        = 0x27;                   /* Reg host to device */
3363       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3364 
3365       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3366       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
3367 
3368       fis->h.features       = 0;                      /* FIS reserve */
3369       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3370       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3371       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3372       fis->d.device         = 0x40;                   /* FIS LBA mode set */
3373       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
3374       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
3375       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
3376       fis->d.featuresExp    = 0;                      /* FIS reserve */
3377       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3378       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
3379       fis->d.reserved4      = 0;
3380       fis->d.control        = 0;                      /* FIS HOB bit clear */
3381       fis->d.reserved5      = 0;
3382 
3383       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3384       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3385     }
3386     else
3387     {
3388       /* case 4 */
3389       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3390       /* WRITE SECTORS EXT for easier implemetation */
3391       TI_DBG5(("satWrite16: case 4\n"));
3392       fis->h.fisType        = 0x27;                   /* Reg host to device */
3393       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3394       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
3395 
3396       fis->h.features       = 0;                      /* FIS reserve */
3397       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3398       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3399       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3400       fis->d.device         = 0x40;                   /* FIS LBA mode set */
3401       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
3402       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
3403       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
3404       fis->d.featuresExp    = 0;                      /* FIS reserve */
3405       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3406       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
3407       fis->d.reserved4      = 0;
3408       fis->d.control        = 0;                      /* FIS HOB bit clear */
3409       fis->d.reserved5      = 0;
3410 
3411       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3412       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3413     }
3414   }
3415 
3416   /* case 5 */
3417   if (pSatDevData->satNCQ == agTRUE)
3418   {
3419     /* WRITE FPDMA QUEUED */
3420     if (pSatDevData->sat48BitSupport != agTRUE)
3421     {
3422       TI_DBG5(("satWrite16: case 5 !!! error NCQ but 28 bit address support \n"));
3423       satSetSensePayload( pSense,
3424                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3425                           0,
3426                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3427                           satIOContext);
3428 
3429       ostiInitiatorIOCompleted( tiRoot,
3430                                 tiIORequest,
3431                                 tiIOSuccess,
3432                                 SCSI_STAT_CHECK_CONDITION,
3433                                 satIOContext->pTiSenseData,
3434                                 satIOContext->interruptContext );
3435       return tiSuccess;
3436     }
3437     TI_DBG6(("satWrite16: case 5\n"));
3438 
3439     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3440 
3441     fis->h.fisType        = 0x27;                   /* Reg host to device */
3442     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3443     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3444     fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3445     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3446     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3447     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3448 
3449     /* Check FUA bit */
3450     if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
3451       fis->d.device       = 0xC0;                   /* FIS FUA set */
3452     else
3453       fis->d.device       = 0x40;                   /* FIS FUA clear */
3454 
3455     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
3456     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
3457     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
3458     fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
3459     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
3460     fis->d.sectorCountExp = 0;
3461     fis->d.reserved4      = 0;
3462     fis->d.control        = 0;                      /* FIS HOB bit clear */
3463     fis->d.reserved5      = 0;
3464 
3465     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3466     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3467   }
3468 
3469   satIOContext->currentLBA = lba;
3470   satIOContext->OrgTL = tl;
3471 
3472   /*
3473     computing number of loop and remainder for tl
3474     0xFF in case not ext
3475     0xFFFF in case EXT
3476   */
3477   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3478   {
3479     LoopNum = satComputeLoopNum(tl, 0xFF);
3480   }
3481   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3482            fis->h.command == SAT_WRITE_DMA_EXT     ||
3483            fis->h.command == SAT_WRITE_DMA_FUA_EXT
3484            )
3485   {
3486     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3487     LoopNum = satComputeLoopNum(tl, 0xFFFF);
3488   }
3489   else
3490   {
3491     /* SAT_WRITE_FPDMA_QUEUEDK */
3492     LoopNum = satComputeLoopNum(tl, 0xFFFF);
3493   }
3494 
3495   satIOContext->LoopNum = LoopNum;
3496 
3497 
3498   if (LoopNum == 1)
3499   {
3500     TI_DBG5(("satWrite16: NON CHAINED data\n"));
3501     /* Initialize CB for SATA completion.
3502      */
3503     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3504   }
3505   else
3506   {
3507     TI_DBG1(("satWrite16: CHAINED data\n"));
3508     /* re-setting tl */
3509     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3510     {
3511        fis->d.sectorCount    = 0xFF;
3512     }
3513     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3514              fis->h.command == SAT_WRITE_DMA_EXT ||
3515              fis->h.command == SAT_WRITE_DMA_FUA_EXT
3516              )
3517     {
3518       fis->d.sectorCount    = 0xFF;
3519       fis->d.sectorCountExp = 0xFF;
3520     }
3521     else
3522     {
3523       /* SAT_WRITE_FPDMA_QUEUED */
3524       fis->h.features       = 0xFF;
3525       fis->d.featuresExp    = 0xFF;
3526     }
3527 
3528     /* Initialize CB for SATA completion.
3529      */
3530     satIOContext->satCompleteCB = &satChainedDataIOCB;
3531   }
3532 
3533 
3534   /*
3535    * Prepare SGL and send FIS to LL layer.
3536    */
3537   satIOContext->reqType = agRequestType;       /* Save it */
3538 
3539   status = sataLLIOStart( tiRoot,
3540                           tiIORequest,
3541                           tiDeviceHandle,
3542                           tiScsiRequest,
3543                           satIOContext);
3544   return (status);
3545 }
3546 
3547 /*****************************************************************************/
3548 /*! \brief SAT implementation for SCSI WRITE12.
3549  *
3550  *  SAT implementation for SCSI WRITE12 and send FIS request to LL layer.
3551  *
3552  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
3553  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
3554  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
3555  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
3556  *  \param   satIOContext_t:   Pointer to the SAT IO Context
3557  *
3558  *  \return If command is started successfully
3559  *    - \e tiSuccess:     I/O request successfully initiated.
3560  *    - \e tiBusy:        No resources available, try again later.
3561  *    - \e tiIONoDevice:  Invalid device handle.
3562  *    - \e tiError:       Other errors.
3563  */
3564 /*****************************************************************************/
3565 GLOBAL bit32  satWrite12(
3566                    tiRoot_t                  *tiRoot,
3567                    tiIORequest_t             *tiIORequest,
3568                    tiDeviceHandle_t          *tiDeviceHandle,
3569                    tiScsiInitiatorRequest_t *tiScsiRequest,
3570                    satIOContext_t            *satIOContext)
3571 {
3572   bit32                     status;
3573   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3574   satDeviceData_t           *pSatDevData;
3575   scsiRspSense_t            *pSense;
3576   tiIniScsiCmnd_t           *scsiCmnd;
3577   agsaFisRegHostToDevice_t  *fis;
3578   bit32                     lba = 0;
3579   bit32                     tl = 0;
3580   bit32                     LoopNum = 1;
3581   bit8                      LBA[4];
3582   bit8                      TL[4];
3583   bit32                     rangeChk = agFALSE; /* lba and tl range check */
3584 
3585   pSense        = satIOContext->pSense;
3586   pSatDevData   = satIOContext->pSatDevData;
3587   scsiCmnd      = &tiScsiRequest->scsiCmnd;
3588   fis           = satIOContext->pFis;
3589 
3590   TI_DBG5(("satWrite12: start\n"));
3591 
3592   /* checking FUA_NV */
3593   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3594   {
3595     satSetSensePayload( pSense,
3596                         SCSI_SNSKEY_ILLEGAL_REQUEST,
3597                         0,
3598                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3599                         satIOContext);
3600 
3601     ostiInitiatorIOCompleted( tiRoot,
3602                               tiIORequest,
3603                               tiIOSuccess,
3604                               SCSI_STAT_CHECK_CONDITION,
3605                               satIOContext->pTiSenseData,
3606                               satIOContext->interruptContext );
3607 
3608     TI_DBG1(("satWrite12: return FUA_NV\n"));
3609     return tiSuccess;
3610 
3611   }
3612 
3613 
3614   /* checking CONTROL */
3615   /* NACA == 1 or LINK == 1*/
3616   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
3617   {
3618     satSetSensePayload( pSense,
3619                         SCSI_SNSKEY_ILLEGAL_REQUEST,
3620                         0,
3621                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3622                         satIOContext);
3623 
3624     ostiInitiatorIOCompleted( tiRoot,
3625                               tiIORequest,
3626                               tiIOSuccess,
3627                               SCSI_STAT_CHECK_CONDITION,
3628                               satIOContext->pTiSenseData,
3629                               satIOContext->interruptContext );
3630 
3631     TI_DBG1(("satWrite12: return control\n"));
3632     return tiSuccess;
3633   }
3634 
3635 
3636   osti_memset(LBA, 0, sizeof(LBA));
3637   osti_memset(TL, 0, sizeof(TL));
3638 
3639   /* do not use memcpy due to indexing in LBA and TL */
3640   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
3641   LBA[1] = scsiCmnd->cdb[3];
3642   LBA[2] = scsiCmnd->cdb[4];
3643   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
3644 
3645   TL[0] = scsiCmnd->cdb[6];   /* MSB */
3646   TL[1] = scsiCmnd->cdb[7];
3647   TL[2] = scsiCmnd->cdb[8];
3648   TL[3] = scsiCmnd->cdb[9];   /* LSB */
3649 
3650   rangeChk = satAddNComparebit32(LBA, TL);
3651 
3652   lba = satComputeCDB12LBA(satIOContext);
3653   tl = satComputeCDB12TL(satIOContext);
3654 
3655 
3656   /* Table 34, 9.1, p 46 */
3657   /*
3658     note: As of 2/10/2006, no support for DMA QUEUED
3659    */
3660 
3661   /*
3662     Table 34, 9.1, p 46, b
3663     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3664     return check condition
3665   */
3666   if (pSatDevData->satNCQ != agTRUE &&
3667       pSatDevData->sat48BitSupport != agTRUE
3668       )
3669   {
3670     if (lba > SAT_TR_LBA_LIMIT - 1)
3671     {
3672       satSetSensePayload( pSense,
3673                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3674                           0,
3675                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3676                           satIOContext);
3677 
3678       ostiInitiatorIOCompleted( tiRoot,
3679                                 tiIORequest,
3680                                 tiIOSuccess,
3681                                 SCSI_STAT_CHECK_CONDITION,
3682                                 satIOContext->pTiSenseData,
3683                                 satIOContext->interruptContext );
3684 
3685     TI_DBG1(("satWrite12: return LBA out of range, not EXT\n"));
3686     return tiSuccess;
3687     }
3688 
3689     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
3690     {
3691       TI_DBG1(("satWrite12: return LBA+TL out of range, not EXT\n"));
3692       satSetSensePayload( pSense,
3693                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3694                           0,
3695                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3696                           satIOContext);
3697 
3698       ostiInitiatorIOCompleted( tiRoot,
3699                                 tiIORequest,
3700                                 tiIOSuccess,
3701                                 SCSI_STAT_CHECK_CONDITION,
3702                                 satIOContext->pTiSenseData,
3703                                 satIOContext->interruptContext );
3704 
3705     return tiSuccess;
3706     }
3707   }
3708 
3709 
3710   /* case 1 and 2 */
3711   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
3712   {
3713     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3714     {
3715       /* case 2 */
3716       /* WRITE DMA*/
3717       /* In case that we can't fit the transfer length, we loop */
3718       TI_DBG5(("satWrite12: case 2\n"));
3719       fis->h.fisType        = 0x27;                   /* Reg host to device */
3720       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3721       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
3722       fis->h.features       = 0;                      /* FIS reserve */
3723       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3724       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3725       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3726 
3727       /* FIS LBA mode set LBA (27:24) */
3728       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3729 
3730       fis->d.lbaLowExp      = 0;
3731       fis->d.lbaMidExp      = 0;
3732       fis->d.lbaHighExp     = 0;
3733       fis->d.featuresExp    = 0;
3734       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3735       fis->d.sectorCountExp = 0;
3736       fis->d.reserved4      = 0;
3737       fis->d.control        = 0;                      /* FIS HOB bit clear */
3738       fis->d.reserved5      = 0;
3739 
3740       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3741       satIOContext->ATACmd = SAT_WRITE_DMA;
3742     }
3743     else
3744     {
3745       /* case 1 */
3746       /* WRITE MULTIPLE or WRITE SECTOR(S) */
3747       /* WRITE SECTORS for easier implemetation */
3748       /* In case that we can't fit the transfer length, we loop */
3749       TI_DBG5(("satWrite12: case 1\n"));
3750       fis->h.fisType        = 0x27;                   /* Reg host to device */
3751       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3752       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
3753       fis->h.features       = 0;                      /* FIS reserve */
3754       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3755       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3756       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3757 
3758       /* FIS LBA mode set LBA (27:24) */
3759       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3760 
3761       fis->d.lbaLowExp      = 0;
3762       fis->d.lbaMidExp      = 0;
3763       fis->d.lbaHighExp     = 0;
3764       fis->d.featuresExp    = 0;
3765       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3766       fis->d.sectorCountExp = 0;
3767       fis->d.reserved4      = 0;
3768       fis->d.control        = 0;                      /* FIS HOB bit clear */
3769       fis->d.reserved5      = 0;
3770 
3771       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3772       satIOContext->ATACmd = SAT_WRITE_SECTORS;
3773     }
3774   }
3775 
3776   /* case 3 and 4 */
3777   if (pSatDevData->sat48BitSupport == agTRUE)
3778   {
3779     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3780     {
3781       /* case 3 */
3782       /* WRITE DMA EXT or WRITE DMA FUA EXT */
3783       TI_DBG5(("satWrite12: case 3\n"));
3784       fis->h.fisType        = 0x27;                   /* Reg host to device */
3785       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3786 
3787       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3788       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
3789 
3790       fis->h.features       = 0;                      /* FIS reserve */
3791       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3792       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3793       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3794       fis->d.device         = 0x40;                   /* FIS LBA mode set */
3795       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
3796       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3797       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3798       fis->d.featuresExp    = 0;                      /* FIS reserve */
3799       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3800       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
3801       fis->d.reserved4      = 0;
3802       fis->d.control        = 0;                      /* FIS HOB bit clear */
3803       fis->d.reserved5      = 0;
3804 
3805       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3806       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3807     }
3808     else
3809     {
3810       /* case 4 */
3811       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3812       /* WRITE SECTORS EXT for easier implemetation */
3813       TI_DBG5(("satWrite12: case 4\n"));
3814       fis->h.fisType        = 0x27;                   /* Reg host to device */
3815       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3816       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
3817 
3818       fis->h.features       = 0;                      /* FIS reserve */
3819       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3820       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3821       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3822       fis->d.device         = 0x40;                   /* FIS LBA mode set */
3823       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
3824       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3825       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3826       fis->d.featuresExp    = 0;                      /* FIS reserve */
3827       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3828       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
3829       fis->d.reserved4      = 0;
3830       fis->d.control        = 0;                      /* FIS HOB bit clear */
3831       fis->d.reserved5      = 0;
3832 
3833       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3834       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3835     }
3836   }
3837 
3838   /* case 5 */
3839   if (pSatDevData->satNCQ == agTRUE)
3840   {
3841     /* WRITE FPDMA QUEUED */
3842     if (pSatDevData->sat48BitSupport != agTRUE)
3843     {
3844       TI_DBG5(("satWrite12: case 5 !!! error NCQ but 28 bit address support \n"));
3845        satSetSensePayload( pSense,
3846                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3847                           0,
3848                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3849                           satIOContext);
3850 
3851       ostiInitiatorIOCompleted( tiRoot,
3852                                 tiIORequest,
3853                                 tiIOSuccess,
3854                                 SCSI_STAT_CHECK_CONDITION,
3855                                 satIOContext->pTiSenseData,
3856                                 satIOContext->interruptContext );
3857       return tiSuccess;
3858     }
3859     TI_DBG6(("satWrite12: case 5\n"));
3860 
3861     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3862 
3863     fis->h.fisType        = 0x27;                   /* Reg host to device */
3864     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3865     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3866     fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3867     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3868     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3869     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3870 
3871     /* Check FUA bit */
3872     if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
3873       fis->d.device       = 0xC0;                   /* FIS FUA set */
3874     else
3875       fis->d.device       = 0x40;                   /* FIS FUA clear */
3876 
3877     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
3878     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3879     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3880     fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
3881     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
3882     fis->d.sectorCountExp = 0;
3883     fis->d.reserved4      = 0;
3884     fis->d.control        = 0;                      /* FIS HOB bit clear */
3885     fis->d.reserved5      = 0;
3886 
3887     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3888     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3889   }
3890 
3891   satIOContext->currentLBA = lba;
3892   satIOContext->OrgTL = tl;
3893 
3894   /*
3895     computing number of loop and remainder for tl
3896     0xFF in case not ext
3897     0xFFFF in case EXT
3898   */
3899   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3900   {
3901     LoopNum = satComputeLoopNum(tl, 0xFF);
3902   }
3903   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3904            fis->h.command == SAT_WRITE_DMA_EXT     ||
3905            fis->h.command == SAT_WRITE_DMA_FUA_EXT
3906            )
3907   {
3908     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3909     LoopNum = satComputeLoopNum(tl, 0xFFFF);
3910   }
3911   else
3912   {
3913     /* SAT_WRITE_FPDMA_QUEUEDK */
3914     LoopNum = satComputeLoopNum(tl, 0xFFFF);
3915   }
3916 
3917   satIOContext->LoopNum = LoopNum;
3918 
3919 
3920   if (LoopNum == 1)
3921   {
3922     TI_DBG5(("satWrite12: NON CHAINED data\n"));
3923     /* Initialize CB for SATA completion.
3924      */
3925     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3926   }
3927   else
3928   {
3929     TI_DBG1(("satWrite12: CHAINED data\n"));
3930     /* re-setting tl */
3931     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3932     {
3933        fis->d.sectorCount    = 0xFF;
3934     }
3935     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3936              fis->h.command == SAT_WRITE_DMA_EXT ||
3937              fis->h.command == SAT_WRITE_DMA_FUA_EXT
3938              )
3939     {
3940       fis->d.sectorCount    = 0xFF;
3941       fis->d.sectorCountExp = 0xFF;
3942     }
3943     else
3944     {
3945       /* SAT_WRITE_FPDMA_QUEUED */
3946       fis->h.features       = 0xFF;
3947       fis->d.featuresExp    = 0xFF;
3948     }
3949 
3950     /* Initialize CB for SATA completion.
3951      */
3952     satIOContext->satCompleteCB = &satChainedDataIOCB;
3953   }
3954 
3955 
3956   /*
3957    * Prepare SGL and send FIS to LL layer.
3958    */
3959   satIOContext->reqType = agRequestType;       /* Save it */
3960 
3961   status = sataLLIOStart( tiRoot,
3962                           tiIORequest,
3963                           tiDeviceHandle,
3964                           tiScsiRequest,
3965                           satIOContext);
3966   return (status);
3967 }
3968 
3969 /*****************************************************************************/
3970 /*! \brief SAT implementation for SCSI WRITE10.
3971  *
3972  *  SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
3973  *
3974  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
3975  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
3976  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
3977  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
3978  *  \param   satIOContext_t:   Pointer to the SAT IO Context
3979  *
3980  *  \return If command is started successfully
3981  *    - \e tiSuccess:     I/O request successfully initiated.
3982  *    - \e tiBusy:        No resources available, try again later.
3983  *    - \e tiIONoDevice:  Invalid device handle.
3984  *    - \e tiError:       Other errors.
3985  */
3986 /*****************************************************************************/
3987 GLOBAL bit32  satWrite10(
3988                    tiRoot_t                  *tiRoot,
3989                    tiIORequest_t             *tiIORequest,
3990                    tiDeviceHandle_t          *tiDeviceHandle,
3991                    tiScsiInitiatorRequest_t *tiScsiRequest,
3992                    satIOContext_t            *satIOContext)
3993 {
3994 
3995   bit32                     status;
3996   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3997   satDeviceData_t           *pSatDevData;
3998   scsiRspSense_t            *pSense;
3999   tiIniScsiCmnd_t           *scsiCmnd;
4000   agsaFisRegHostToDevice_t  *fis;
4001   bit32                     lba = 0;
4002   bit32                     tl = 0;
4003   bit32                     LoopNum = 1;
4004   bit8                      LBA[4];
4005   bit8                      TL[4];
4006   bit32                     rangeChk = agFALSE; /* lba and tl range check */
4007 
4008   pSense        = satIOContext->pSense;
4009   pSatDevData   = satIOContext->pSatDevData;
4010   scsiCmnd      = &tiScsiRequest->scsiCmnd;
4011   fis           = satIOContext->pFis;
4012 
4013   TI_DBG5(("satWrite10: start\n"));
4014 
4015   /* checking FUA_NV */
4016   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
4017   {
4018     satSetSensePayload( pSense,
4019                         SCSI_SNSKEY_ILLEGAL_REQUEST,
4020                         0,
4021                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4022                         satIOContext);
4023 
4024     ostiInitiatorIOCompleted( tiRoot,
4025                               tiIORequest,
4026                               tiIOSuccess,
4027                               SCSI_STAT_CHECK_CONDITION,
4028                               satIOContext->pTiSenseData,
4029                               satIOContext->interruptContext );
4030 
4031     TI_DBG1(("satWrite10: return FUA_NV\n"));
4032     return tiSuccess;
4033 
4034   }
4035 
4036   /* checking CONTROL */
4037   /* NACA == 1 or LINK == 1*/
4038   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
4039   {
4040     satSetSensePayload( pSense,
4041                         SCSI_SNSKEY_ILLEGAL_REQUEST,
4042                         0,
4043                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4044                         satIOContext);
4045 
4046     ostiInitiatorIOCompleted( tiRoot,
4047                               tiIORequest,
4048                               tiIOSuccess,
4049                               SCSI_STAT_CHECK_CONDITION,
4050                               satIOContext->pTiSenseData,
4051                               satIOContext->interruptContext );
4052 
4053     TI_DBG1(("satWrite10: return control\n"));
4054     return tiSuccess;
4055   }
4056 
4057   osti_memset(LBA, 0, sizeof(LBA));
4058   osti_memset(TL, 0, sizeof(TL));
4059 
4060   /* do not use memcpy due to indexing in LBA and TL */
4061   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
4062   LBA[1] = scsiCmnd->cdb[3];
4063   LBA[2] = scsiCmnd->cdb[4];
4064   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
4065 
4066   TL[0] = 0;
4067   TL[1] = 0;
4068   TL[2] = scsiCmnd->cdb[7];  /* MSB */
4069   TL[3] = scsiCmnd->cdb[8];  /* LSB */
4070 
4071   rangeChk = satAddNComparebit32(LBA, TL);
4072 
4073 
4074   /* cbd10; computing LBA and transfer length */
4075   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
4076     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
4077   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
4078 
4079   TI_DBG5(("satWrite10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
4080   TI_DBG5(("satWrite10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
4081 
4082   /* Table 34, 9.1, p 46 */
4083   /*
4084     note: As of 2/10/2006, no support for DMA QUEUED
4085    */
4086 
4087   /*
4088     Table 34, 9.1, p 46, b
4089     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4090     return check condition
4091   */
4092   if (pSatDevData->satNCQ != agTRUE &&
4093       pSatDevData->sat48BitSupport != agTRUE
4094       )
4095   {
4096     if (lba > SAT_TR_LBA_LIMIT - 1)
4097     {
4098       satSetSensePayload( pSense,
4099                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4100                           0,
4101                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4102                           satIOContext);
4103 
4104       ostiInitiatorIOCompleted( tiRoot,
4105                                 tiIORequest,
4106                                 tiIOSuccess,
4107                                 SCSI_STAT_CHECK_CONDITION,
4108                                 satIOContext->pTiSenseData,
4109                                 satIOContext->interruptContext );
4110 
4111       TI_DBG1(("satWrite10: return LBA out of range, not EXT\n"));
4112       TI_DBG1(("satWrite10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
4113              scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
4114       TI_DBG1(("satWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
4115       return tiSuccess;
4116     }
4117 
4118     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
4119     {
4120       TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
4121       satSetSensePayload( pSense,
4122                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4123                           0,
4124                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4125                           satIOContext);
4126 
4127       ostiInitiatorIOCompleted( tiRoot,
4128                                 tiIORequest,
4129                                 tiIOSuccess,
4130                                 SCSI_STAT_CHECK_CONDITION,
4131                                 satIOContext->pTiSenseData,
4132                                 satIOContext->interruptContext );
4133 
4134       return tiSuccess;
4135     }
4136 
4137   }
4138 
4139 
4140   /* case 1 and 2 */
4141   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
4142   {
4143     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4144     {
4145       /* case 2 */
4146       /* WRITE DMA*/
4147       /* can't fit the transfer length */
4148       TI_DBG5(("satWrite10: case 2\n"));
4149       fis->h.fisType        = 0x27;                   /* Reg host to device */
4150       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4151       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
4152       fis->h.features       = 0;                      /* FIS reserve */
4153       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4154       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4155       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4156 
4157       /* FIS LBA mode set LBA (27:24) */
4158       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4159 
4160       fis->d.lbaLowExp      = 0;
4161       fis->d.lbaMidExp      = 0;
4162       fis->d.lbaHighExp     = 0;
4163       fis->d.featuresExp    = 0;
4164       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4165       fis->d.sectorCountExp = 0;
4166       fis->d.reserved4      = 0;
4167       fis->d.control        = 0;                      /* FIS HOB bit clear */
4168       fis->d.reserved5      = 0;
4169 
4170       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4171       satIOContext->ATACmd = SAT_WRITE_DMA;
4172     }
4173     else
4174     {
4175       /* case 1 */
4176       /* WRITE MULTIPLE or WRITE SECTOR(S) */
4177       /* WRITE SECTORS for easier implemetation */
4178       /* can't fit the transfer length */
4179       TI_DBG5(("satWrite10: case 1\n"));
4180       fis->h.fisType        = 0x27;                   /* Reg host to device */
4181       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4182       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
4183       fis->h.features       = 0;                      /* FIS reserve */
4184       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4185       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4186       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4187 
4188       /* FIS LBA mode set LBA (27:24) */
4189       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4190 
4191       fis->d.lbaLowExp      = 0;
4192       fis->d.lbaMidExp      = 0;
4193       fis->d.lbaHighExp     = 0;
4194       fis->d.featuresExp    = 0;
4195       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4196       fis->d.sectorCountExp = 0;
4197       fis->d.reserved4      = 0;
4198       fis->d.control        = 0;                      /* FIS HOB bit clear */
4199       fis->d.reserved5      = 0;
4200 
4201       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4202       satIOContext->ATACmd = SAT_WRITE_SECTORS;
4203     }
4204   }
4205   /* case 3 and 4 */
4206   if (pSatDevData->sat48BitSupport == agTRUE)
4207   {
4208     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4209     {
4210       /* case 3 */
4211       /* WRITE DMA EXT or WRITE DMA FUA EXT */
4212       TI_DBG5(("satWrite10: case 3\n"));
4213       fis->h.fisType        = 0x27;                   /* Reg host to device */
4214       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4215 
4216       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
4217       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
4218       satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
4219 
4220       fis->h.features       = 0;                      /* FIS reserve */
4221       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4222       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4223       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4224       fis->d.device         = 0x40;                   /* FIS LBA mode set */
4225       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4226       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4227       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4228       fis->d.featuresExp    = 0;                      /* FIS reserve */
4229       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4230       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4231       fis->d.reserved4      = 0;
4232       fis->d.control        = 0;                      /* FIS HOB bit clear */
4233       fis->d.reserved5      = 0;
4234 
4235       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4236     }
4237     else
4238     {
4239       /* case 4 */
4240       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
4241       /* WRITE SECTORS EXT for easier implemetation */
4242       TI_DBG5(("satWrite10: case 4\n"));
4243       fis->h.fisType        = 0x27;                   /* Reg host to device */
4244       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4245       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
4246 
4247       fis->h.features       = 0;                      /* FIS reserve */
4248       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4249       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4250       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4251       fis->d.device         = 0x40;                   /* FIS LBA mode set */
4252       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4253       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4254       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4255       fis->d.featuresExp    = 0;                      /* FIS reserve */
4256       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4257       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4258       fis->d.reserved4      = 0;
4259       fis->d.control        = 0;                      /* FIS HOB bit clear */
4260       fis->d.reserved5      = 0;
4261 
4262       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4263       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
4264     }
4265   }
4266   /* case 5 */
4267   if (pSatDevData->satNCQ == agTRUE)
4268   {
4269     /* WRITE FPDMA QUEUED */
4270     if (pSatDevData->sat48BitSupport != agTRUE)
4271     {
4272       TI_DBG5(("satWrite10: case 5 !!! error NCQ but 28 bit address support \n"));
4273       satSetSensePayload( pSense,
4274                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4275                           0,
4276                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4277                           satIOContext);
4278 
4279       ostiInitiatorIOCompleted( tiRoot,
4280                                 tiIORequest,
4281                                 tiIOSuccess,
4282                                 SCSI_STAT_CHECK_CONDITION,
4283                                 satIOContext->pTiSenseData,
4284                                 satIOContext->interruptContext );
4285       return tiSuccess;
4286     }
4287     TI_DBG6(("satWrite10: case 5\n"));
4288 
4289     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4290 
4291     fis->h.fisType        = 0x27;                   /* Reg host to device */
4292     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4293     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4294     fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4295     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4296     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4297     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4298 
4299     /* Check FUA bit */
4300     if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4301       fis->d.device       = 0xC0;                   /* FIS FUA set */
4302     else
4303       fis->d.device       = 0x40;                   /* FIS FUA clear */
4304 
4305     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4306     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4307     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4308     fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4309     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4310     fis->d.sectorCountExp = 0;
4311     fis->d.reserved4      = 0;
4312     fis->d.control        = 0;                      /* FIS HOB bit clear */
4313     fis->d.reserved5      = 0;
4314 
4315     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4316     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
4317   }
4318 
4319   //  tdhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
4320 
4321   satIOContext->currentLBA = lba;
4322   satIOContext->OrgTL = tl;
4323 
4324   /*
4325     computing number of loop and remainder for tl
4326     0xFF in case not ext
4327     0xFFFF in case EXT
4328   */
4329   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4330   {
4331     LoopNum = satComputeLoopNum(tl, 0xFF);
4332   }
4333   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4334            fis->h.command == SAT_WRITE_DMA_EXT     ||
4335            fis->h.command == SAT_WRITE_DMA_FUA_EXT
4336            )
4337   {
4338     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
4339     LoopNum = satComputeLoopNum(tl, 0xFFFF);
4340   }
4341   else
4342   {
4343     /* SAT_WRITE_FPDMA_QUEUEDK */
4344     LoopNum = satComputeLoopNum(tl, 0xFFFF);
4345   }
4346 
4347   satIOContext->LoopNum = LoopNum;
4348 
4349 
4350   if (LoopNum == 1)
4351   {
4352     TI_DBG5(("satWrite10: NON CHAINED data\n"));
4353     /* Initialize CB for SATA completion.
4354      */
4355     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4356   }
4357   else
4358   {
4359     TI_DBG1(("satWrite10: CHAINED data\n"));
4360     /* re-setting tl */
4361     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4362     {
4363        fis->d.sectorCount    = 0xFF;
4364     }
4365     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4366              fis->h.command == SAT_WRITE_DMA_EXT ||
4367              fis->h.command == SAT_WRITE_DMA_FUA_EXT
4368              )
4369     {
4370       fis->d.sectorCount    = 0xFF;
4371       fis->d.sectorCountExp = 0xFF;
4372     }
4373     else
4374     {
4375       /* SAT_WRITE_FPDMA_QUEUED */
4376       fis->h.features       = 0xFF;
4377       fis->d.featuresExp    = 0xFF;
4378     }
4379 
4380     /* Initialize CB for SATA completion.
4381      */
4382     satIOContext->satCompleteCB = &satChainedDataIOCB;
4383   }
4384 
4385 
4386   /*
4387    * Prepare SGL and send FIS to LL layer.
4388    */
4389   satIOContext->reqType = agRequestType;       /* Save it */
4390 
4391   status = sataLLIOStart( tiRoot,
4392                           tiIORequest,
4393                           tiDeviceHandle,
4394                           tiScsiRequest,
4395                           satIOContext);
4396   return (status);
4397 }
4398 
4399 /*****************************************************************************/
4400 /*! \brief SAT implementation for SCSI satWrite_1.
4401  *
4402  *  SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
4403  *  This is used when WRITE10 is divided into multiple ATA commands
4404  *
4405  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4406  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4407  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4408  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4409  *  \param   satIOContext_t:   Pointer to the SAT IO Context
4410  *
4411  *  \return If command is started successfully
4412  *    - \e tiSuccess:     I/O request successfully initiated.
4413  *    - \e tiBusy:        No resources available, try again later.
4414  *    - \e tiIONoDevice:  Invalid device handle.
4415  *    - \e tiError:       Other errors.
4416  */
4417 /*****************************************************************************/
4418 GLOBAL bit32  satWrite_1(
4419                    tiRoot_t                  *tiRoot,
4420                    tiIORequest_t             *tiIORequest,
4421                    tiDeviceHandle_t          *tiDeviceHandle,
4422                    tiScsiInitiatorRequest_t *tiScsiRequest,
4423                    satIOContext_t            *satIOContext)
4424 {
4425   /*
4426     Assumption: error check on lba and tl has been done in satWrite*()
4427     lba = lba + tl;
4428   */
4429   bit32                     status;
4430   satIOContext_t            *satOrgIOContext = agNULL;
4431   tiIniScsiCmnd_t           *scsiCmnd;
4432   agsaFisRegHostToDevice_t  *fis;
4433   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4434   bit32                     lba = 0;
4435   bit32                     DenomTL = 0xFF;
4436   bit32                     Remainder = 0;
4437   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
4438 
4439   TI_DBG2(("satWrite_1: start\n"));
4440 
4441   fis             = satIOContext->pFis;
4442   satOrgIOContext = satIOContext->satOrgIOContext;
4443   scsiCmnd        = satOrgIOContext->pScsiCmnd;
4444 
4445   osti_memset(LBA,0, sizeof(LBA));
4446 
4447   switch (satOrgIOContext->ATACmd)
4448   {
4449   case SAT_WRITE_DMA:
4450     DenomTL = 0xFF;
4451     break;
4452   case SAT_WRITE_SECTORS:
4453     DenomTL = 0xFF;
4454     break;
4455   case SAT_WRITE_DMA_EXT:
4456     DenomTL = 0xFFFF;
4457     break;
4458   case SAT_WRITE_DMA_FUA_EXT:
4459     DenomTL = 0xFFFF;
4460     break;
4461   case SAT_WRITE_SECTORS_EXT:
4462     DenomTL = 0xFFFF;
4463     break;
4464   case SAT_WRITE_FPDMA_QUEUED:
4465     DenomTL = 0xFFFF;
4466     break;
4467   default:
4468     TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4469     return tiError;
4470     break;
4471   }
4472 
4473   Remainder = satOrgIOContext->OrgTL % DenomTL;
4474   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
4475   lba = satOrgIOContext->currentLBA;
4476 
4477   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
4478   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
4479   LBA[2] = (bit8)((lba & 0xF0) >> 8);
4480   LBA[3] = (bit8)(lba & 0xF);               /* LSB */
4481 
4482   switch (satOrgIOContext->ATACmd)
4483   {
4484   case SAT_WRITE_DMA:
4485     fis->h.fisType        = 0x27;                   /* Reg host to device */
4486     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4487     fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
4488     fis->h.features       = 0;                      /* FIS reserve */
4489     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4490     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4491     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4492 
4493     /* FIS LBA mode set LBA (27:24) */
4494     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4495 
4496     fis->d.lbaLowExp      = 0;
4497     fis->d.lbaMidExp      = 0;
4498     fis->d.lbaHighExp     = 0;
4499     fis->d.featuresExp    = 0;
4500     if (satOrgIOContext->LoopNum == 1)
4501     {
4502       /* last loop */
4503       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
4504     }
4505     else
4506     {
4507       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
4508     }
4509     fis->d.sectorCountExp = 0;
4510     fis->d.reserved4      = 0;
4511     fis->d.control        = 0;                      /* FIS HOB bit clear */
4512     fis->d.reserved5      = 0;
4513 
4514     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4515 
4516     break;
4517   case SAT_WRITE_SECTORS:
4518     fis->h.fisType        = 0x27;                   /* Reg host to device */
4519     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4520     fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
4521     fis->h.features       = 0;                      /* FIS reserve */
4522     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4523     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4524     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4525 
4526     /* FIS LBA mode set LBA (27:24) */
4527     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4528 
4529     fis->d.lbaLowExp      = 0;
4530     fis->d.lbaMidExp      = 0;
4531     fis->d.lbaHighExp     = 0;
4532     fis->d.featuresExp    = 0;
4533     if (satOrgIOContext->LoopNum == 1)
4534     {
4535       /* last loop */
4536       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
4537     }
4538     else
4539     {
4540       fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
4541     }
4542     fis->d.sectorCountExp = 0;
4543     fis->d.reserved4      = 0;
4544     fis->d.control        = 0;                      /* FIS HOB bit clear */
4545     fis->d.reserved5      = 0;
4546 
4547     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4548 
4549     break;
4550   case SAT_WRITE_DMA_EXT:
4551     fis->h.fisType        = 0x27;                   /* Reg host to device */
4552     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4553     fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
4554     fis->h.features       = 0;                      /* FIS reserve */
4555     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4556     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4557     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4558     fis->d.device         = 0x40;                   /* FIS LBA mode set */
4559     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
4560     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4561     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4562     fis->d.featuresExp    = 0;                      /* FIS reserve */
4563     if (satOrgIOContext->LoopNum == 1)
4564     {
4565       /* last loop */
4566       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
4567       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
4568     }
4569     else
4570     {
4571       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
4572       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
4573     }
4574     fis->d.reserved4      = 0;
4575     fis->d.control        = 0;                       /* FIS HOB bit clear */
4576     fis->d.reserved5      = 0;
4577 
4578     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4579 
4580     break;
4581   case SAT_WRITE_SECTORS_EXT:
4582     fis->h.fisType        = 0x27;                   /* Reg host to device */
4583     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4584     fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
4585 
4586     fis->h.features       = 0;                      /* FIS reserve */
4587     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4588     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4589     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4590     fis->d.device         = 0x40;                   /* FIS LBA mode set */
4591     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
4592     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4593     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4594     fis->d.featuresExp    = 0;                      /* FIS reserve */
4595     if (satOrgIOContext->LoopNum == 1)
4596     {
4597       /* last loop */
4598       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
4599       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
4600     }
4601     else
4602     {
4603       fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
4604       fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
4605     }
4606     fis->d.reserved4      = 0;
4607     fis->d.control        = 0;                      /* FIS HOB bit clear */
4608     fis->d.reserved5      = 0;
4609 
4610     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4611 
4612     break;
4613   case SAT_WRITE_FPDMA_QUEUED:
4614     fis->h.fisType        = 0x27;                   /* Reg host to device */
4615     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4616     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4617     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4618     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4619     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4620 
4621     /* Check FUA bit */
4622     if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4623       fis->d.device       = 0xC0;                   /* FIS FUA set */
4624     else
4625       fis->d.device       = 0x40;                   /* FIS FUA clear */
4626 
4627     fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
4628     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4629     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4630     if (satOrgIOContext->LoopNum == 1)
4631     {
4632       /* last loop */
4633       fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
4634       fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
4635     }
4636     else
4637     {
4638       fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
4639       fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
4640     }
4641     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4642     fis->d.sectorCountExp = 0;
4643     fis->d.reserved4      = 0;
4644     fis->d.control        = 0;                      /* FIS HOB bit clear */
4645     fis->d.reserved5      = 0;
4646 
4647     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4648     break;
4649 
4650   default:
4651     TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4652     return tiError;
4653     break;
4654   }
4655 
4656   /* Initialize CB for SATA completion.
4657    */
4658   /* chained data */
4659   satIOContext->satCompleteCB = &satChainedDataIOCB;
4660 
4661 
4662   /*
4663    * Prepare SGL and send FIS to LL layer.
4664    */
4665   satIOContext->reqType = agRequestType;       /* Save it */
4666 
4667   status = sataLLIOStart( tiRoot,
4668                           tiIORequest,
4669                           tiDeviceHandle,
4670                           tiScsiRequest,
4671                           satIOContext);
4672 
4673   TI_DBG5(("satWrite_1: return\n"));
4674   return (status);
4675 }
4676 
4677 /*****************************************************************************/
4678 /*! \brief SAT implementation for SCSI WRITE6.
4679  *
4680  *  SAT implementation for SCSI WRITE6 and send FIS request to LL layer.
4681  *
4682  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4683  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4684  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4685  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4686  *  \param   satIOContext_t:   Pointer to the SAT IO Context
4687  *
4688  *  \return If command is started successfully
4689  *    - \e tiSuccess:     I/O request successfully initiated.
4690  *    - \e tiBusy:        No resources available, try again later.
4691  *    - \e tiIONoDevice:  Invalid device handle.
4692  *    - \e tiError:       Other errors.
4693  */
4694 /*****************************************************************************/
4695 GLOBAL bit32  satWrite6(
4696                    tiRoot_t                  *tiRoot,
4697                    tiIORequest_t             *tiIORequest,
4698                    tiDeviceHandle_t          *tiDeviceHandle,
4699                    tiScsiInitiatorRequest_t *tiScsiRequest,
4700                    satIOContext_t            *satIOContext)
4701 {
4702 
4703   bit32                     status;
4704   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4705   satDeviceData_t           *pSatDevData;
4706   scsiRspSense_t            *pSense;
4707   tiIniScsiCmnd_t           *scsiCmnd;
4708   agsaFisRegHostToDevice_t  *fis;
4709   bit32                     lba = 0;
4710   bit16                     tl = 0;
4711 
4712   pSense        = satIOContext->pSense;
4713   pSatDevData   = satIOContext->pSatDevData;
4714   scsiCmnd      = &tiScsiRequest->scsiCmnd;
4715   fis           = satIOContext->pFis;
4716 
4717   TI_DBG5(("satWrite6: start\n"));
4718 
4719   /* checking CONTROL */
4720   /* NACA == 1 or LINK == 1*/
4721   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
4722   {
4723     satSetSensePayload( pSense,
4724                         SCSI_SNSKEY_ILLEGAL_REQUEST,
4725                         0,
4726                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4727                         satIOContext);
4728 
4729     ostiInitiatorIOCompleted( tiRoot,
4730                               tiIORequest,
4731                               tiIOSuccess,
4732                               SCSI_STAT_CHECK_CONDITION,
4733                               satIOContext->pTiSenseData,
4734                               satIOContext->interruptContext );
4735 
4736     TI_DBG1(("satWrite6: return control\n"));
4737     return tiSuccess;
4738   }
4739 
4740 
4741   /* cbd6; computing LBA and transfer length */
4742   lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
4743     + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
4744   tl = scsiCmnd->cdb[4];
4745 
4746 
4747   /* Table 34, 9.1, p 46 */
4748   /*
4749     note: As of 2/10/2006, no support for DMA QUEUED
4750    */
4751 
4752   /*
4753     Table 34, 9.1, p 46, b
4754     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4755     return check condition
4756   */
4757   if (pSatDevData->satNCQ != agTRUE &&
4758       pSatDevData->sat48BitSupport != agTRUE
4759       )
4760   {
4761     if (lba > SAT_TR_LBA_LIMIT - 1)
4762     {
4763       satSetSensePayload( pSense,
4764                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4765                           0,
4766                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4767                           satIOContext);
4768 
4769       ostiInitiatorIOCompleted( tiRoot,
4770                                 tiIORequest,
4771                                 tiIOSuccess,
4772                                 SCSI_STAT_CHECK_CONDITION,
4773                                 satIOContext->pTiSenseData,
4774                                 satIOContext->interruptContext );
4775 
4776     TI_DBG1(("satWrite6: return LBA out of range\n"));
4777     return tiSuccess;
4778     }
4779   }
4780 
4781   /* case 1 and 2 */
4782   if (lba + tl <= SAT_TR_LBA_LIMIT)
4783   {
4784     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4785     {
4786       /* case 2 */
4787       /* WRITE DMA*/
4788       TI_DBG5(("satWrite6: case 2\n"));
4789 
4790 
4791       fis->h.fisType        = 0x27;                   /* Reg host to device */
4792       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4793       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
4794       fis->h.features       = 0;                      /* FIS reserve */
4795       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4796       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4797       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4798       fis->d.device         = 0x40;                   /* FIS LBA mode  */
4799       fis->d.lbaLowExp      = 0;
4800       fis->d.lbaMidExp      = 0;
4801       fis->d.lbaHighExp     = 0;
4802       fis->d.featuresExp    = 0;
4803       if (tl == 0)
4804       {
4805         /* temporary fix */
4806         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4807       }
4808       else
4809       {
4810         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4811       }
4812       fis->d.sectorCountExp = 0;
4813       fis->d.reserved4      = 0;
4814       fis->d.control        = 0;                      /* FIS HOB bit clear */
4815       fis->d.reserved5      = 0;
4816 
4817       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4818     }
4819     else
4820     {
4821       /* case 1 */
4822       /* WRITE SECTORS for easier implemetation */
4823       TI_DBG5(("satWrite6: case 1\n"));
4824 
4825       fis->h.fisType        = 0x27;                   /* Reg host to device */
4826       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4827       fis->h.command        = SAT_WRITE_SECTORS;          /* 0xCA */
4828       fis->h.features       = 0;                      /* FIS reserve */
4829       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4830       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4831       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4832       fis->d.device         = 0x40;                   /* FIS LBA mode  */
4833       fis->d.lbaLowExp      = 0;
4834       fis->d.lbaMidExp      = 0;
4835       fis->d.lbaHighExp     = 0;
4836       fis->d.featuresExp    = 0;
4837       if (tl == 0)
4838       {
4839         /* temporary fix */
4840         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4841       }
4842       else
4843       {
4844         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4845       }
4846       fis->d.sectorCountExp = 0;
4847       fis->d.reserved4      = 0;
4848       fis->d.control        = 0;                      /* FIS HOB bit clear */
4849       fis->d.reserved5      = 0;
4850 
4851       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4852 
4853     }
4854   }
4855 
4856   /* case 3 and 4 */
4857   if (pSatDevData->sat48BitSupport == agTRUE)
4858   {
4859     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4860     {
4861       /* case 3 */
4862       /* WRITE DMA EXT only */
4863       TI_DBG5(("satWrite6: case 3\n"));
4864       fis->h.fisType        = 0x27;                   /* Reg host to device */
4865       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4866       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
4867       fis->h.features       = 0;                      /* FIS reserve */
4868       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4869       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4870       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4871       fis->d.device         = 0x40;                   /* FIS LBA mode set */
4872       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4873       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4874       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4875       fis->d.featuresExp    = 0;                      /* FIS reserve */
4876       if (tl == 0)
4877       {
4878         /* sector count is 256, 0x100*/
4879         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4880         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4881       }
4882       else
4883       {
4884         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4885         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4886       }
4887       fis->d.reserved4      = 0;
4888       fis->d.control        = 0;                      /* FIS HOB bit clear */
4889       fis->d.reserved5      = 0;
4890 
4891       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4892     }
4893     else
4894     {
4895       /* case 4 */
4896       /* WRITE SECTORS EXT for easier implemetation */
4897       TI_DBG5(("satWrite6: case 4\n"));
4898 
4899       fis->h.fisType        = 0x27;                   /* Reg host to device */
4900       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4901       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
4902       fis->h.features       = 0;                      /* FIS reserve */
4903       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4904       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4905       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4906       fis->d.device         = 0x40;                   /* FIS LBA mode set */
4907       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4908       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4909       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4910       fis->d.featuresExp    = 0;                      /* FIS reserve */
4911       if (tl == 0)
4912       {
4913         /* sector count is 256, 0x100*/
4914         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4915         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4916       }
4917       else
4918       {
4919         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4920         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4921       }
4922       fis->d.reserved4      = 0;
4923       fis->d.control        = 0;                      /* FIS HOB bit clear */
4924       fis->d.reserved5      = 0;
4925 
4926       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4927     }
4928   }
4929 
4930    /* case 5 */
4931   if (pSatDevData->satNCQ == agTRUE)
4932   {
4933     /* WRITE FPDMA QUEUED */
4934     if (pSatDevData->sat48BitSupport != agTRUE)
4935     {
4936       /* sanity check */
4937       TI_DBG5(("satWrite6: case 5 !!! error NCQ but 28 bit address support \n"));
4938        satSetSensePayload( pSense,
4939                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4940                           0,
4941                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4942                           satIOContext);
4943 
4944       ostiInitiatorIOCompleted( tiRoot,
4945                                 tiIORequest,
4946                                 tiIOSuccess,
4947                                 SCSI_STAT_CHECK_CONDITION,
4948                                 satIOContext->pTiSenseData,
4949                                 satIOContext->interruptContext );
4950       return tiSuccess;
4951     }
4952     TI_DBG5(("satWrite6: case 5\n"));
4953 
4954     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4955 
4956     fis->h.fisType        = 0x27;                   /* Reg host to device */
4957     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4958     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4959     fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4960     fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4961     fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4962     fis->d.device         = 0x40;                   /* FIS FUA clear */
4963     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4964     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4965     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4966     if (tl == 0)
4967     {
4968       /* sector count is 256, 0x100*/
4969       fis->h.features       = 0;                         /* FIS sector count (7:0) */
4970       fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
4971     }
4972     else
4973     {
4974       fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4975       fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
4976     }
4977     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4978     fis->d.sectorCountExp = 0;
4979     fis->d.reserved4      = 0;
4980     fis->d.control        = 0;                      /* FIS HOB bit clear */
4981     fis->d.reserved5      = 0;
4982 
4983     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4984   }
4985 
4986   /* Initialize CB for SATA completion.
4987    */
4988   satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4989 
4990   /*
4991    * Prepare SGL and send FIS to LL layer.
4992    */
4993   satIOContext->reqType = agRequestType;       /* Save it */
4994 
4995   status = sataLLIOStart( tiRoot,
4996                           tiIORequest,
4997                           tiDeviceHandle,
4998                           tiScsiRequest,
4999                           satIOContext);
5000   return (status);
5001 }
5002 
5003 
5004 /*****************************************************************************/
5005 /*! \brief SAT implementation for SCSI TEST UNIT READY.
5006  *
5007  *  SAT implementation for SCSI TUR and send FIS request to LL layer.
5008  *
5009  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5010  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5011  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5012  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5013  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5014  *
5015  *  \return If command is started successfully
5016  *    - \e tiSuccess:     I/O request successfully initiated.
5017  *    - \e tiBusy:        No resources available, try again later.
5018  *    - \e tiIONoDevice:  Invalid device handle.
5019  *    - \e tiError:       Other errors.
5020  */
5021 /*****************************************************************************/
5022 GLOBAL bit32  satTestUnitReady(
5023                    tiRoot_t                  *tiRoot,
5024                    tiIORequest_t             *tiIORequest,
5025                    tiDeviceHandle_t          *tiDeviceHandle,
5026                    tiScsiInitiatorRequest_t *tiScsiRequest,
5027                    satIOContext_t            *satIOContext)
5028 {
5029 
5030   bit32                     status;
5031   bit32                     agRequestType;
5032   satDeviceData_t           *pSatDevData;
5033   scsiRspSense_t            *pSense;
5034   tiIniScsiCmnd_t           *scsiCmnd;
5035   agsaFisRegHostToDevice_t  *fis;
5036 
5037   pSense        = satIOContext->pSense;
5038   pSatDevData   = satIOContext->pSatDevData;
5039   scsiCmnd      = &tiScsiRequest->scsiCmnd;
5040   fis           = satIOContext->pFis;
5041 
5042   TI_DBG6(("satTestUnitReady: entry tiDeviceHandle=%p tiIORequest=%p\n",
5043       tiDeviceHandle, tiIORequest));
5044 
5045   /* checking CONTROL */
5046   /* NACA == 1 or LINK == 1*/
5047   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5048   {
5049     satSetSensePayload( pSense,
5050                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5051                         0,
5052                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5053                         satIOContext);
5054 
5055     ostiInitiatorIOCompleted( tiRoot,
5056                               tiIORequest,
5057                               tiIOSuccess,
5058                               SCSI_STAT_CHECK_CONDITION,
5059                               satIOContext->pTiSenseData,
5060                               satIOContext->interruptContext );
5061 
5062     TI_DBG1(("satTestUnitReady: return control\n"));
5063     return tiSuccess;
5064   }
5065 
5066   /* SAT revision 8, 8.11.2, p42*/
5067   if (pSatDevData->satStopState == agTRUE)
5068   {
5069     satSetSensePayload( pSense,
5070                         SCSI_SNSKEY_NOT_READY,
5071                         0,
5072                         SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
5073                         satIOContext);
5074 
5075     ostiInitiatorIOCompleted( tiRoot,
5076                               tiIORequest,
5077                               tiIOSuccess,
5078                               SCSI_STAT_CHECK_CONDITION,
5079                               satIOContext->pTiSenseData,
5080                               satIOContext->interruptContext );
5081     TI_DBG1(("satTestUnitReady: stop state\n"));
5082     return tiSuccess;
5083   }
5084 
5085   /*
5086    * Check if format is in progress
5087    */
5088 
5089   if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
5090   {
5091     TI_DBG1(("satTestUnitReady() FORMAT_IN_PROGRESS  tiDeviceHandle=%p tiIORequest=%p\n",
5092          tiDeviceHandle, tiIORequest));
5093 
5094     satSetSensePayload( pSense,
5095                         SCSI_SNSKEY_NOT_READY,
5096                         0,
5097                         SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
5098                         satIOContext);
5099 
5100     ostiInitiatorIOCompleted( tiRoot,
5101                               tiIORequest,
5102                               tiIOSuccess,
5103                               SCSI_STAT_CHECK_CONDITION,
5104                               satIOContext->pTiSenseData,
5105                               satIOContext->interruptContext );
5106     TI_DBG1(("satTestUnitReady: format in progress\n"));
5107     return tiSuccess;
5108   }
5109 
5110   /*
5111     check previously issued ATA command
5112   */
5113   if (pSatDevData->satPendingIO != 0)
5114   {
5115     if (pSatDevData->satDeviceFaultState == agTRUE)
5116     {
5117       satSetSensePayload( pSense,
5118                           SCSI_SNSKEY_HARDWARE_ERROR,
5119                           0,
5120                           SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
5121                           satIOContext);
5122 
5123       ostiInitiatorIOCompleted( tiRoot,
5124                                 tiIORequest,
5125                                 tiIOSuccess,
5126                                 SCSI_STAT_CHECK_CONDITION,
5127                                 satIOContext->pTiSenseData,
5128                                 satIOContext->interruptContext );
5129       TI_DBG1(("satTestUnitReady: previous command ended in error\n"));
5130       return tiSuccess;
5131     }
5132   }
5133   /*
5134     check removalbe media feature set
5135    */
5136   if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
5137   {
5138     TI_DBG5(("satTestUnitReady: sending get media status cmnd\n"));
5139     /* send GET MEDIA STATUS command */
5140     fis->h.fisType        = 0x27;                   /* Reg host to device */
5141     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5142     fis->h.command        = SAT_GET_MEDIA_STATUS;   /* 0xDA */
5143     fis->h.features       = 0;                      /* FIS features NA       */
5144     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
5145     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
5146     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
5147     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
5148     fis->d.lbaLowExp      = 0;
5149     fis->d.lbaMidExp      = 0;
5150     fis->d.lbaHighExp     = 0;
5151     fis->d.featuresExp    = 0;
5152     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
5153     fis->d.sectorCountExp = 0;
5154     fis->d.reserved4      = 0;
5155     fis->d.control        = 0;                      /* FIS HOB bit clear */
5156     fis->d.reserved5      = 0;
5157     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5158 
5159     /* Initialize CB for SATA completion.
5160      */
5161     satIOContext->satCompleteCB = &satTestUnitReadyCB;
5162 
5163     /*
5164      * Prepare SGL and send FIS to LL layer.
5165      */
5166     satIOContext->reqType = agRequestType;       /* Save it */
5167 
5168     status = sataLLIOStart( tiRoot,
5169                             tiIORequest,
5170                             tiDeviceHandle,
5171                             tiScsiRequest,
5172                             satIOContext);
5173 
5174     return (status);
5175   }
5176   /*
5177     number 6) in SAT p42
5178     send ATA CHECK POWER MODE
5179   */
5180    TI_DBG5(("satTestUnitReady: sending check power mode cmnd\n"));
5181    status = satTestUnitReady_1( tiRoot,
5182                                tiIORequest,
5183                                tiDeviceHandle,
5184                                tiScsiRequest,
5185                                satIOContext);
5186    return (status);
5187 }
5188 
5189 
5190 /*****************************************************************************/
5191 /*! \brief SAT implementation for SCSI satTestUnitReady_1.
5192  *
5193  *  SAT implementation for SCSI satTestUnitReady_1.
5194  *
5195  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5196  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5197  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5198  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5199  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5200  *
5201  *  \return If command is started successfully
5202  *    - \e tiSuccess:     I/O request successfully initiated.
5203  *    - \e tiBusy:        No resources available, try again later.
5204  *    - \e tiIONoDevice:  Invalid device handle.
5205  *    - \e tiError:       Other errors.
5206  */
5207 /*****************************************************************************/
5208 GLOBAL bit32  satTestUnitReady_1(
5209                          tiRoot_t                  *tiRoot,
5210                          tiIORequest_t             *tiIORequest,
5211                          tiDeviceHandle_t          *tiDeviceHandle,
5212                          tiScsiInitiatorRequest_t *tiScsiRequest,
5213                          satIOContext_t            *satIOContext)
5214 {
5215   /*
5216     sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY
5217     internally generated - no directly corresponding scsi
5218     called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42
5219   */
5220   bit32                     status;
5221   bit32                     agRequestType;
5222   agsaFisRegHostToDevice_t  *fis;
5223 
5224   fis           = satIOContext->pFis;
5225 
5226   TI_DBG5(("satTestUnitReady_1: start\n"));
5227 
5228   /*
5229    * Send the ATA CHECK POWER MODE command.
5230    */
5231   fis->h.fisType        = 0x27;                   /* Reg host to device */
5232   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5233   fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
5234   fis->h.features       = 0;
5235   fis->d.lbaLow         = 0;
5236   fis->d.lbaMid         = 0;
5237   fis->d.lbaHigh        = 0;
5238   fis->d.device         = 0;
5239   fis->d.lbaLowExp      = 0;
5240   fis->d.lbaMidExp      = 0;
5241   fis->d.lbaHighExp     = 0;
5242   fis->d.featuresExp    = 0;
5243   fis->d.sectorCount    = 0;
5244   fis->d.sectorCountExp = 0;
5245   fis->d.reserved4      = 0;
5246   fis->d.control        = 0;                      /* FIS HOB bit clear */
5247   fis->d.reserved5      = 0;
5248 
5249   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5250 
5251   /* Initialize CB for SATA completion.
5252    */
5253   satIOContext->satCompleteCB = &satTestUnitReadyCB;
5254 
5255   /*
5256    * Prepare SGL and send FIS to LL layer.
5257    */
5258   satIOContext->reqType = agRequestType;       /* Save it */
5259 
5260   status = sataLLIOStart( tiRoot,
5261                           tiIORequest,
5262                           tiDeviceHandle,
5263                           tiScsiRequest,
5264                           satIOContext);
5265 
5266   TI_DBG5(("satTestUnitReady_1: return\n"));
5267 
5268   return status;
5269 }
5270 
5271 
5272 /*****************************************************************************/
5273 /*! \brief SAT implementation for SCSI satReportLun.
5274  *
5275  *  SAT implementation for SCSI satReportLun. Only LUN0 is reported.
5276  *
5277  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5278  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5279  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5280  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5281  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5282  *
5283  *  \return If command is started successfully
5284  *    - \e tiSuccess:     I/O request successfully initiated.
5285  *    - \e tiBusy:        No resources available, try again later.
5286  *    - \e tiIONoDevice:  Invalid device handle.
5287  *    - \e tiError:       Other errors.
5288  */
5289 /*****************************************************************************/
5290 GLOBAL bit32  satReportLun(
5291                    tiRoot_t                  *tiRoot,
5292                    tiIORequest_t             *tiIORequest,
5293                    tiDeviceHandle_t          *tiDeviceHandle,
5294                    tiScsiInitiatorRequest_t *tiScsiRequest,
5295                    satIOContext_t            *satIOContext)
5296 {
5297   scsiRspSense_t        *pSense;
5298   bit32                 allocationLen;
5299   bit32                 reportLunLen;
5300   scsiReportLun_t       *pReportLun;
5301   tiIniScsiCmnd_t       *scsiCmnd;
5302 
5303   TI_DBG5(("satReportLun entry: tiDeviceHandle=%p tiIORequest=%p\n",
5304       tiDeviceHandle, tiIORequest));
5305 
5306   pSense     = satIOContext->pSense;
5307   pReportLun = (scsiReportLun_t *) tiScsiRequest->sglVirtualAddr;
5308   scsiCmnd   = &tiScsiRequest->scsiCmnd;
5309 
5310 //  tdhexdump("satReportLun cdb", (bit8 *)scsiCmnd, 16);
5311 
5312   /* Find the buffer size allocated by Initiator */
5313   allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
5314                   (((bit32)scsiCmnd->cdb[7]) << 16) |
5315                   (((bit32)scsiCmnd->cdb[8]) << 8 ) |
5316                   (((bit32)scsiCmnd->cdb[9])      );
5317 
5318   reportLunLen  = 16;     /* 8 byte header and 8 bytes of LUN0 */
5319 
5320   if (allocationLen < reportLunLen)
5321   {
5322     TI_DBG1(("satReportLun *** ERROR *** insufficient len=0x%x tiDeviceHandle=%p tiIORequest=%p\n",
5323         reportLunLen, tiDeviceHandle, tiIORequest));
5324 
5325     satSetSensePayload( pSense,
5326                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5327                         0,
5328                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5329                         satIOContext);
5330 
5331     ostiInitiatorIOCompleted( tiRoot,
5332                               tiIORequest,
5333                               tiIOSuccess,
5334                               SCSI_STAT_CHECK_CONDITION,
5335                               satIOContext->pTiSenseData,
5336                               satIOContext->interruptContext );
5337     return tiSuccess;
5338 
5339   }
5340 
5341   /* Set length to one entry */
5342   pReportLun->len[0] = 0;
5343   pReportLun->len[1] = 0;
5344   pReportLun->len[2] = 0;
5345   pReportLun->len[3] = sizeof (tiLUN_t);
5346 
5347   pReportLun->reserved = 0;
5348 
5349   /* Set to LUN 0:
5350    * - address method to 0x00: Peripheral device addressing method,
5351    * - bus identifier to 0
5352    */
5353   pReportLun->lunList[0].lun[0] = 0;
5354   pReportLun->lunList[0].lun[1] = 0;
5355   pReportLun->lunList[0].lun[2] = 0;
5356   pReportLun->lunList[0].lun[3] = 0;
5357   pReportLun->lunList[0].lun[4] = 0;
5358   pReportLun->lunList[0].lun[5] = 0;
5359   pReportLun->lunList[0].lun[6] = 0;
5360   pReportLun->lunList[0].lun[7] = 0;
5361 
5362   if (allocationLen > reportLunLen)
5363   {
5364     /* underrun */
5365     TI_DBG1(("satReportLun reporting underrun reportLunLen=0x%x allocationLen=0x%x \n", reportLunLen, allocationLen));
5366 
5367     ostiInitiatorIOCompleted( tiRoot,
5368                               tiIORequest,
5369                               tiIOUnderRun,
5370                               allocationLen - reportLunLen,
5371                               agNULL,
5372                               satIOContext->interruptContext );
5373 
5374 
5375   }
5376   else
5377   {
5378     ostiInitiatorIOCompleted( tiRoot,
5379                               tiIORequest,
5380                               tiIOSuccess,
5381                               SCSI_STAT_GOOD,
5382                               agNULL,
5383                               satIOContext->interruptContext);
5384   }
5385   return tiSuccess;
5386 }
5387 
5388 
5389 /*****************************************************************************/
5390 /*! \brief SAT implementation for SCSI REQUEST SENSE.
5391  *
5392  *  SAT implementation for SCSI REQUEST SENSE.
5393  *
5394  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5395  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5396  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5397  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5398  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5399  *
5400  *  \return If command is started successfully
5401  *    - \e tiSuccess:     I/O request successfully initiated.
5402  *    - \e tiBusy:        No resources available, try again later.
5403  *    - \e tiIONoDevice:  Invalid device handle.
5404  *    - \e tiError:       Other errors.
5405  */
5406 /*****************************************************************************/
5407 GLOBAL bit32  satRequestSense(
5408                    tiRoot_t                  *tiRoot,
5409                    tiIORequest_t             *tiIORequest,
5410                    tiDeviceHandle_t          *tiDeviceHandle,
5411                    tiScsiInitiatorRequest_t *tiScsiRequest,
5412                    satIOContext_t            *satIOContext)
5413 {
5414   /*
5415     SAT Rev 8 p38, Table25
5416     sending SMART RETURN STATUS
5417     Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB()
5418     Only fixed format sense data is support. In other words, we don't support DESC bit is set
5419     in Request Sense
5420    */
5421   bit32                     status;
5422   bit32                     agRequestType;
5423   scsiRspSense_t            *pSense;
5424   satDeviceData_t           *pSatDevData;
5425   tiIniScsiCmnd_t           *scsiCmnd;
5426   agsaFisRegHostToDevice_t  *fis;
5427   tdIORequestBody_t         *tdIORequestBody;
5428   satInternalIo_t           *satIntIo = agNULL;
5429   satIOContext_t            *satIOContext2;
5430 
5431   TI_DBG4(("satRequestSense entry: tiDeviceHandle=%p tiIORequest=%p\n",
5432       tiDeviceHandle, tiIORequest));
5433 
5434   pSense            = (scsiRspSense_t *) tiScsiRequest->sglVirtualAddr;
5435   pSatDevData       = satIOContext->pSatDevData;
5436   scsiCmnd          = &tiScsiRequest->scsiCmnd;
5437   fis               = satIOContext->pFis;
5438 
5439   TI_DBG4(("satRequestSense: pSatDevData=%p\n", pSatDevData));
5440 
5441   /* checking CONTROL */
5442   /* NACA == 1 or LINK == 1*/
5443   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5444   {
5445     satSetSensePayload( pSense,
5446                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5447                         0,
5448                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5449                         satIOContext);
5450 
5451     ostiInitiatorIOCompleted( tiRoot,
5452                               tiIORequest,
5453                               tiIOSuccess,
5454                               SCSI_STAT_CHECK_CONDITION,
5455                               satIOContext->pTiSenseData,
5456                               satIOContext->interruptContext );
5457 
5458     TI_DBG1(("satRequestSense: return control\n"));
5459     return tiSuccess;
5460   }
5461 
5462   /*
5463     Only fixed format sense data is support. In other words, we don't support DESC bit is set
5464     in Request Sense
5465    */
5466   if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
5467   {
5468     satSetSensePayload( pSense,
5469                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5470                         0,
5471                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5472                         satIOContext);
5473 
5474     ostiInitiatorIOCompleted( tiRoot,
5475                               tiIORequest,
5476                               tiIOSuccess,
5477                               SCSI_STAT_CHECK_CONDITION,
5478                               satIOContext->pTiSenseData,
5479                               satIOContext->interruptContext );
5480 
5481     TI_DBG1(("satRequestSense: DESC bit is set, which we don't support\n"));
5482     return tiSuccess;
5483   }
5484 
5485 
5486   if (pSatDevData->satSMARTEnabled == agTRUE)
5487   {
5488     /* sends SMART RETURN STATUS */
5489     fis->h.fisType        = 0x27;                   /* Reg host to device */
5490     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5491 
5492     fis->h.command        = SAT_SMART_RETURN_STATUS;    /* 0xB0 */
5493     fis->h.features       = 0xDA;                   /* FIS features */
5494     fis->d.featuresExp    = 0;                      /* FIS reserve */
5495     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
5496     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
5497     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
5498     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
5499     fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
5500     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5501     fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
5502     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5503     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
5504     fis->d.control        = 0;                      /* FIS HOB bit clear */
5505     fis->d.reserved4      = 0;
5506     fis->d.reserved5      = 0;
5507 
5508     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5509     /* Initialize CB for SATA completion.
5510      */
5511     satIOContext->satCompleteCB = &satRequestSenseCB;
5512 
5513     /*
5514      * Prepare SGL and send FIS to LL layer.
5515      */
5516     satIOContext->reqType = agRequestType;       /* Save it */
5517 
5518     status = sataLLIOStart( tiRoot,
5519                             tiIORequest,
5520                             tiDeviceHandle,
5521                             tiScsiRequest,
5522                             satIOContext);
5523 
5524     TI_DBG4(("satRequestSense: if return, status %d\n", status));
5525     return (status);
5526   }
5527   else
5528   {
5529     /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE
5530       then call satRequestSense2 */
5531 
5532     TI_DBG4(("satRequestSense: before satIntIo %p\n", satIntIo));
5533     /* allocate iocontext */
5534     satIntIo = satAllocIntIoResource( tiRoot,
5535                                       tiIORequest, /* original request */
5536                                       pSatDevData,
5537                                       tiScsiRequest->scsiCmnd.expDataLength,
5538                                       satIntIo);
5539 
5540     TI_DBG4(("satRequestSense: after satIntIo %p\n", satIntIo));
5541 
5542     if (satIntIo == agNULL)
5543     {
5544       /* memory allocation failure */
5545       satFreeIntIoResource( tiRoot,
5546                             pSatDevData,
5547                             satIntIo);
5548 
5549       /* failed during sending SMART RETURN STATUS */
5550       satSetSensePayload( pSense,
5551                           SCSI_SNSKEY_NO_SENSE,
5552                           0,
5553                           SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5554                           satIOContext);
5555 
5556       ostiInitiatorIOCompleted( tiRoot,
5557                                 tiIORequest,
5558                                 tiIOSuccess,
5559                                 SCSI_STAT_GOOD,
5560                                 agNULL,
5561                                 satIOContext->interruptContext );
5562 
5563       TI_DBG4(("satRequestSense: else fail 1\n"));
5564       return tiSuccess;
5565     } /* end of memory allocation failure */
5566 
5567 
5568     /*
5569      * Need to initialize all the fields within satIOContext except
5570      * reqType and satCompleteCB which will be set depending on cmd.
5571      */
5572 
5573     if (satIntIo == agNULL)
5574     {
5575       TI_DBG4(("satRequestSense: satIntIo is NULL\n"));
5576     }
5577     else
5578     {
5579       TI_DBG4(("satRequestSense: satIntIo is NOT NULL\n"));
5580     }
5581     /* use this --- tttttthe one the same */
5582 
5583 
5584     satIntIo->satOrgTiIORequest = tiIORequest;
5585     tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
5586     satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
5587 
5588     satIOContext2->pSatDevData   = pSatDevData;
5589     satIOContext2->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
5590     satIOContext2->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
5591     satIOContext2->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
5592     satIOContext2->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
5593     satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
5594     satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
5595     satIOContext2->interruptContext = satIOContext->interruptContext;
5596     satIOContext2->satIntIoContext  = satIntIo;
5597     satIOContext2->ptiDeviceHandle = tiDeviceHandle;
5598     satIOContext2->satOrgIOContext = satIOContext;
5599 
5600     TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
5601 
5602     TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
5603 
5604     TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
5605 
5606     TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
5607 
5608     status = satRequestSense_1( tiRoot,
5609                                &(satIntIo->satIntTiIORequest),
5610                                tiDeviceHandle,
5611                                &(satIntIo->satIntTiScsiXchg),
5612                                satIOContext2);
5613 
5614     if (status != tiSuccess)
5615     {
5616       satFreeIntIoResource( tiRoot,
5617                             pSatDevData,
5618                             satIntIo);
5619 
5620       /* failed during sending SMART RETURN STATUS */
5621       satSetSensePayload( pSense,
5622                           SCSI_SNSKEY_NO_SENSE,
5623                           0,
5624                           SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5625                           satIOContext);
5626 
5627       ostiInitiatorIOCompleted( tiRoot,
5628                                 tiIORequest,
5629                                 tiIOSuccess,
5630                                 SCSI_STAT_CHECK_CONDITION,
5631                                 agNULL,
5632                                 satIOContext->interruptContext );
5633 
5634       TI_DBG1(("satRequestSense: else fail 2\n"));
5635       return tiSuccess;
5636     }
5637     TI_DBG4(("satRequestSense: else return success\n"));
5638     return tiSuccess;
5639   }
5640 }
5641 
5642 
5643 /*****************************************************************************/
5644 /*! \brief SAT implementation for SCSI REQUEST SENSE.
5645  *
5646  *  SAT implementation for SCSI REQUEST SENSE.
5647  *  Sub function of satRequestSense
5648  *
5649  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5650  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5651  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5652  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5653  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5654  *
5655  *  \return If command is started successfully
5656  *    - \e tiSuccess:     I/O request successfully initiated.
5657  *    - \e tiBusy:        No resources available, try again later.
5658  *    - \e tiIONoDevice:  Invalid device handle.
5659  *    - \e tiError:       Other errors.
5660  */
5661 /*****************************************************************************/
5662 GLOBAL bit32  satRequestSense_1(
5663                    tiRoot_t                  *tiRoot,
5664                    tiIORequest_t             *tiIORequest,
5665                    tiDeviceHandle_t          *tiDeviceHandle,
5666                    tiScsiInitiatorRequest_t *tiScsiRequest,
5667                    satIOContext_t            *satIOContext)
5668 {
5669   /*
5670     sends SAT_CHECK_POWER_MODE
5671   */
5672   bit32                     status;
5673   bit32                     agRequestType;
5674   agsaFisRegHostToDevice_t  *fis;
5675 
5676   TI_DBG4(("satRequestSense_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
5677       tiDeviceHandle, tiIORequest));
5678 
5679   fis               = satIOContext->pFis;
5680   /*
5681    * Send the ATA CHECK POWER MODE command.
5682    */
5683   fis->h.fisType        = 0x27;                   /* Reg host to device */
5684   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5685 
5686   fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
5687   fis->h.features       = 0;
5688   fis->d.lbaLow         = 0;
5689   fis->d.lbaMid         = 0;
5690   fis->d.lbaHigh        = 0;
5691   fis->d.device         = 0;
5692   fis->d.lbaLowExp      = 0;
5693   fis->d.lbaMidExp      = 0;
5694   fis->d.lbaHighExp     = 0;
5695   fis->d.featuresExp    = 0;
5696   fis->d.sectorCount    = 0;
5697   fis->d.sectorCountExp = 0;
5698   fis->d.reserved4      = 0;
5699   fis->d.control        = 0;                      /* FIS HOB bit clear */
5700   fis->d.reserved5      = 0;
5701 
5702   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5703 
5704   /* Initialize CB for SATA completion.
5705    */
5706   satIOContext->satCompleteCB = &satRequestSenseCB;
5707 
5708   /*
5709    * Prepare SGL and send FIS to LL layer.
5710    */
5711   satIOContext->reqType = agRequestType;       /* Save it */
5712 
5713 
5714   TI_DBG4(("satRequestSense_1: agSgl1.len %d\n", tiScsiRequest->agSgl1.len));
5715 
5716   TI_DBG4(("satRequestSense_1: agSgl1.upper %d\n", tiScsiRequest->agSgl1.upper));
5717 
5718   TI_DBG4(("satRequestSense_1: agSgl1.lower %d\n", tiScsiRequest->agSgl1.lower));
5719 
5720   TI_DBG4(("satRequestSense_1: agSgl1.type %d\n", tiScsiRequest->agSgl1.type));
5721 
5722   //  tdhexdump("satRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
5723 
5724   status = sataLLIOStart( tiRoot,
5725                           tiIORequest,
5726                           tiDeviceHandle,
5727                           tiScsiRequest,
5728                           satIOContext);
5729 
5730 
5731 
5732   return status;
5733 }
5734 
5735 
5736 /*****************************************************************************/
5737 /*! \brief SAT implementation for SCSI INQUIRY.
5738  *
5739  *  SAT implementation for SCSI INQUIRY.
5740  *
5741  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5742  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5743  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5744  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5745  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5746  *
5747  *  \return If command is started successfully
5748  *    - \e tiSuccess:     I/O request successfully initiated.
5749  *    - \e tiBusy:        No resources available, try again later.
5750  *    - \e tiIONoDevice:  Invalid device handle.
5751  *    - \e tiError:       Other errors.
5752  */
5753 /*****************************************************************************/
5754 GLOBAL bit32  satInquiry(
5755                    tiRoot_t                  *tiRoot,
5756                    tiIORequest_t             *tiIORequest,
5757                    tiDeviceHandle_t          *tiDeviceHandle,
5758                    tiScsiInitiatorRequest_t *tiScsiRequest,
5759                    satIOContext_t            *satIOContext)
5760 {
5761   /*
5762     CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8
5763   */
5764   scsiRspSense_t            *pSense;
5765   tiIniScsiCmnd_t           *scsiCmnd;
5766   satDeviceData_t           *pSatDevData;
5767   bit32                     status;
5768 
5769   TI_DBG5(("satInquiry: start\n"));
5770   TI_DBG5(("satInquiry entry: tiDeviceHandle=%p tiIORequest=%p\n",
5771       tiDeviceHandle, tiIORequest));
5772   pSense      = satIOContext->pSense;
5773   scsiCmnd    = &tiScsiRequest->scsiCmnd;
5774   pSatDevData = satIOContext->pSatDevData;
5775   TI_DBG5(("satInquiry: pSatDevData=%p\n", pSatDevData));
5776   //tdhexdump("satInquiry", (bit8 *)scsiCmnd->cdb, 6);
5777   /* checking CONTROL */
5778   /* NACA == 1 or LINK == 1*/
5779   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5780   {
5781     satSetSensePayload( pSense,
5782                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5783                         0,
5784                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5785                         satIOContext);
5786     ostiInitiatorIOCompleted( tiRoot,
5787                               tiIORequest,
5788                               tiIOSuccess,
5789                               SCSI_STAT_CHECK_CONDITION,
5790                               satIOContext->pTiSenseData,
5791                               satIOContext->interruptContext );
5792     TI_DBG2(("satInquiry: return control\n"));
5793     return tiSuccess;
5794   }
5795 
5796   /* checking EVPD and Allocation Length */
5797   /* SPC-4 spec 6.4 p141 */
5798   /* EVPD bit == 0 && PAGE CODE != 0 */
5799   if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
5800        (scsiCmnd->cdb[2] != 0)
5801        )
5802   {
5803     satSetSensePayload( pSense,
5804                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5805                         0,
5806                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5807                         satIOContext);
5808     ostiInitiatorIOCompleted( tiRoot,
5809                               tiIORequest,
5810                               tiIOSuccess,
5811                               SCSI_STAT_CHECK_CONDITION,
5812                               satIOContext->pTiSenseData,
5813                               satIOContext->interruptContext );
5814     TI_DBG1(("satInquiry: return EVPD and PAGE CODE\n"));
5815     return tiSuccess;
5816   }
5817   TI_DBG6(("satInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4]));
5818 
5819   /* convert OS IO to TD internal IO */
5820   if ( pSatDevData->IDDeviceValid == agFALSE)
5821   {
5822     status = satStartIDDev(
5823                          tiRoot,
5824                          tiIORequest,
5825                          tiDeviceHandle,
5826                          tiScsiRequest,
5827                          satIOContext
5828                          );
5829     TI_DBG6(("satInquiry: end status %d\n", status));
5830     return status;
5831   }
5832   else
5833   {
5834     TI_DBG6(("satInquiry: calling satInquiryIntCB\n"));
5835     satInquiryIntCB(
5836                     tiRoot,
5837                     tiIORequest,
5838                     tiDeviceHandle,
5839                     tiScsiRequest,
5840                     satIOContext
5841                     );
5842 
5843     return tiSuccess;
5844   }
5845 
5846 }
5847 
5848 
5849 /*****************************************************************************/
5850 /*! \brief SAT implementation for SCSI satReadCapacity10.
5851  *
5852  *  SAT implementation for SCSI satReadCapacity10.
5853  *
5854  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5855  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5856  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5857  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5858  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5859  *
5860  *  \return If command is started successfully
5861  *    - \e tiSuccess:     I/O request successfully initiated.
5862  *    - \e tiBusy:        No resources available, try again later.
5863  *    - \e tiIONoDevice:  Invalid device handle.
5864  *    - \e tiError:       Other errors.
5865  */
5866 /*****************************************************************************/
5867 GLOBAL bit32  satReadCapacity10(
5868                    tiRoot_t                  *tiRoot,
5869                    tiIORequest_t             *tiIORequest,
5870                    tiDeviceHandle_t          *tiDeviceHandle,
5871                    tiScsiInitiatorRequest_t *tiScsiRequest,
5872                    satIOContext_t            *satIOContext)
5873 {
5874   scsiRspSense_t          *pSense;
5875   tiIniScsiCmnd_t         *scsiCmnd;
5876   bit8              *pVirtAddr;
5877   satDeviceData_t         *pSatDevData;
5878   agsaSATAIdentifyData_t  *pSATAIdData;
5879   bit32                   lastLba;
5880   bit32                   word117_118;
5881   bit32                   word117;
5882   bit32                   word118;
5883   TI_DBG5(("satReadCapacity10: start: tiDeviceHandle=%p tiIORequest=%p\n",
5884       tiDeviceHandle, tiIORequest));
5885 
5886   pSense      = satIOContext->pSense;
5887   pVirtAddr   = (bit8 *) tiScsiRequest->sglVirtualAddr;
5888   scsiCmnd    = &tiScsiRequest->scsiCmnd;
5889   pSatDevData = satIOContext->pSatDevData;
5890   pSATAIdData = &pSatDevData->satIdentifyData;
5891 
5892 
5893   /* checking CONTROL */
5894   /* NACA == 1 or LINK == 1*/
5895   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
5896   {
5897     satSetSensePayload( pSense,
5898                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5899                         0,
5900                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5901                         satIOContext);
5902 
5903     ostiInitiatorIOCompleted( tiRoot,
5904                               tiIORequest,
5905                               tiIOSuccess,
5906                               SCSI_STAT_CHECK_CONDITION,
5907                               satIOContext->pTiSenseData,
5908                               satIOContext->interruptContext );
5909 
5910     TI_DBG1(("satReadCapacity10: return control\n"));
5911     return tiSuccess;
5912   }
5913 
5914 
5915   /*
5916    * If Logical block address is not set to zero, return error
5917    */
5918   if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
5919   {
5920     TI_DBG1(("satReadCapacity10 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
5921         tiDeviceHandle, tiIORequest));
5922 
5923     satSetSensePayload( pSense,
5924                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5925                         0,
5926                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5927                         satIOContext);
5928 
5929     ostiInitiatorIOCompleted( tiRoot,
5930                               tiIORequest,
5931                               tiIOSuccess,
5932                               SCSI_STAT_CHECK_CONDITION,
5933                               satIOContext->pTiSenseData,
5934                               satIOContext->interruptContext );
5935     return tiSuccess;
5936 
5937   }
5938 
5939   /*
5940    * If PMI bit is not zero, return error
5941    */
5942   if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
5943   {
5944     TI_DBG1(("satReadCapacity10 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
5945         tiDeviceHandle, tiIORequest));
5946 
5947     satSetSensePayload( pSense,
5948                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5949                         0,
5950                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5951                         satIOContext);
5952 
5953     ostiInitiatorIOCompleted( tiRoot,
5954                               tiIORequest,
5955                               tiIOSuccess,
5956                               SCSI_STAT_CHECK_CONDITION,
5957                               satIOContext->pTiSenseData,
5958                               satIOContext->interruptContext );
5959     return tiSuccess;
5960 
5961   }
5962 
5963   /*
5964     filling in Read Capacity parameter data
5965     saved identify device has been already flipped
5966     See ATA spec p125 and p136 and SBC spec p54
5967   */
5968   /*
5969    * If 48-bit addressing is supported, set capacity information from Identify
5970    * Device Word 100-103.
5971    */
5972   if (pSatDevData->sat48BitSupport == agTRUE)
5973   {
5974     /*
5975      * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data:
5976      * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL
5977      * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL
5978      * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would
5979      * then issue a READ CAPACITY(16) command.
5980      */
5981     /* ATA Identify Device information word 100 - 103 */
5982     if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
5983     {
5984       pVirtAddr[0] = 0xFF;        /* MSB number of block */
5985       pVirtAddr[1] = 0xFF;
5986       pVirtAddr[2] = 0xFF;
5987       pVirtAddr[3] = 0xFF;        /* LSB number of block */
5988       TI_DBG1(("satReadCapacity10: returns 0xFFFFFFFF\n"));
5989     }
5990     else  /* Fit the Readcapacity10 4-bytes response length */
5991     {
5992       lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
5993                   (pSATAIdData->maxLBA0_15);
5994       lastLba = lastLba - 1;      /* LBA starts from zero */
5995 
5996       /*
5997         for testing
5998       lastLba = lastLba - (512*10) - 1;
5999       */
6000 
6001 
6002       pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
6003       pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6004       pVirtAddr[2] = (bit8)((lastLba >> 8)  & 0xFF);
6005       pVirtAddr[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
6006 
6007       TI_DBG3(("satReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
6008       TI_DBG3(("satReadCapacity10: LBA 0 is 0x%x %d\n", pVirtAddr[0], pVirtAddr[0]));
6009       TI_DBG3(("satReadCapacity10: LBA 1 is 0x%x %d\n", pVirtAddr[1], pVirtAddr[1]));
6010       TI_DBG3(("satReadCapacity10: LBA 2 is 0x%x %d\n", pVirtAddr[2], pVirtAddr[2]));
6011       TI_DBG3(("satReadCapacity10: LBA 3 is 0x%x %d\n", pVirtAddr[3], pVirtAddr[3]));
6012 
6013     }
6014   }
6015 
6016   /*
6017    * For 28-bit addressing, set capacity information from Identify
6018    * Device Word 60-61.
6019    */
6020   else
6021   {
6022     /* ATA Identify Device information word 60 - 61 */
6023     lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6024                 (pSATAIdData->numOfUserAddressableSectorsLo);
6025     lastLba = lastLba - 1;      /* LBA starts from zero */
6026 
6027     pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
6028     pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6029     pVirtAddr[2] = (bit8)((lastLba >> 8)  & 0xFF);
6030     pVirtAddr[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
6031   }
6032   /* SAT Rev 8d */
6033   if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
6034   {
6035     TI_DBG5(("satReadCapacity10: Default Block Length is 512\n"));
6036     /*
6037      * Set the block size, fixed at 512 bytes.
6038      */
6039     pVirtAddr[4] = 0x00;        /* MSB block size in bytes */
6040     pVirtAddr[5] = 0x00;
6041     pVirtAddr[6] = 0x02;
6042     pVirtAddr[7] = 0x00;        /* LSB block size in bytes */
6043   }
6044   else
6045   {
6046     word118 = pSATAIdData->word112_126[6];
6047     word117 = pSATAIdData->word112_126[5];
6048 
6049     word117_118 = (word118 << 16) + word117;
6050     word117_118 = word117_118 * 2;
6051     pVirtAddr[4] = (bit8)((word117_118 >> 24) & 0xFF);        /* MSB block size in bytes */
6052     pVirtAddr[5] = (bit8)((word117_118 >> 16) & 0xFF);
6053     pVirtAddr[6] = (bit8)((word117_118 >> 8) & 0xFF);
6054     pVirtAddr[7] = (bit8)(word117_118 & 0xFF);                /* LSB block size in bytes */
6055 
6056     TI_DBG1(("satReadCapacity10: Nondefault word118 %d 0x%x \n", word118, word118));
6057     TI_DBG1(("satReadCapacity10: Nondefault word117 %d 0x%x \n", word117, word117));
6058     TI_DBG1(("satReadCapacity10: Nondefault Block Length is %d 0x%x \n",word117_118, word117_118));
6059 
6060   }
6061 
6062   /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6063   pSatDevData->satMaxLBA[0] = 0;            /* MSB */
6064   pSatDevData->satMaxLBA[1] = 0;
6065   pSatDevData->satMaxLBA[2] = 0;
6066   pSatDevData->satMaxLBA[3] = 0;
6067   pSatDevData->satMaxLBA[4] = pVirtAddr[0];
6068   pSatDevData->satMaxLBA[5] = pVirtAddr[1];
6069   pSatDevData->satMaxLBA[6] = pVirtAddr[2];
6070   pSatDevData->satMaxLBA[7] = pVirtAddr[3]; /* LSB */
6071 
6072 
6073   TI_DBG4(("satReadCapacity10 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
6074         pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6075         pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6076         tiDeviceHandle, tiIORequest));
6077 
6078 
6079   /*
6080    * Send the completion response now.
6081    */
6082   ostiInitiatorIOCompleted( tiRoot,
6083                             tiIORequest,
6084                             tiIOSuccess,
6085                             SCSI_STAT_GOOD,
6086                             agNULL,
6087                             satIOContext->interruptContext);
6088   return tiSuccess;
6089 }
6090 
6091 
6092 /*****************************************************************************/
6093 /*! \brief SAT implementation for SCSI satReadCapacity16.
6094  *
6095  *  SAT implementation for SCSI satReadCapacity16.
6096  *
6097  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
6098  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
6099  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
6100  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
6101  *  \param   satIOContext_t:   Pointer to the SAT IO Context
6102  *
6103  *  \return If command is started successfully
6104  *    - \e tiSuccess:     I/O request successfully initiated.
6105  *    - \e tiBusy:        No resources available, try again later.
6106  *    - \e tiIONoDevice:  Invalid device handle.
6107  *    - \e tiError:       Other errors.
6108  */
6109 /*****************************************************************************/
6110 GLOBAL bit32  satReadCapacity16(
6111                    tiRoot_t                  *tiRoot,
6112                    tiIORequest_t             *tiIORequest,
6113                    tiDeviceHandle_t          *tiDeviceHandle,
6114                    tiScsiInitiatorRequest_t *tiScsiRequest,
6115                    satIOContext_t            *satIOContext)
6116 {
6117 
6118   scsiRspSense_t          *pSense;
6119   tiIniScsiCmnd_t         *scsiCmnd;
6120   bit8                    *pVirtAddr;
6121   satDeviceData_t         *pSatDevData;
6122   agsaSATAIdentifyData_t  *pSATAIdData;
6123   bit32                   lastLbaLo;
6124   bit32                   allocationLen;
6125   bit32                   readCapacityLen  = 32;
6126   bit32                   i = 0;
6127   TI_DBG5(("satReadCapacity16 start: tiDeviceHandle=%p tiIORequest=%p\n",
6128       tiDeviceHandle, tiIORequest));
6129 
6130   pSense      = satIOContext->pSense;
6131   pVirtAddr   = (bit8 *) tiScsiRequest->sglVirtualAddr;
6132   scsiCmnd    = &tiScsiRequest->scsiCmnd;
6133   pSatDevData = satIOContext->pSatDevData;
6134   pSATAIdData = &pSatDevData->satIdentifyData;
6135 
6136   /* Find the buffer size allocated by Initiator */
6137   allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
6138                   (((bit32)scsiCmnd->cdb[11]) << 16) |
6139                   (((bit32)scsiCmnd->cdb[12]) << 8 ) |
6140                   (((bit32)scsiCmnd->cdb[13])      );
6141 
6142 
6143   if (allocationLen < readCapacityLen)
6144   {
6145     TI_DBG1(("satReadCapacity16 *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x\n", allocationLen, readCapacityLen));
6146 
6147     satSetSensePayload( pSense,
6148                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6149                         0,
6150                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6151                         satIOContext);
6152 
6153     ostiInitiatorIOCompleted( tiRoot,
6154                               tiIORequest,
6155                               tiIOSuccess,
6156                               SCSI_STAT_CHECK_CONDITION,
6157                               satIOContext->pTiSenseData,
6158                               satIOContext->interruptContext );
6159     return tiSuccess;
6160 
6161   }
6162 
6163   /* checking CONTROL */
6164   /* NACA == 1 or LINK == 1*/
6165   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
6166   {
6167     satSetSensePayload( pSense,
6168                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6169                         0,
6170                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6171                         satIOContext);
6172 
6173     ostiInitiatorIOCompleted( tiRoot,
6174                               tiIORequest,
6175                               tiIOSuccess,
6176                               SCSI_STAT_CHECK_CONDITION,
6177                               satIOContext->pTiSenseData,
6178                               satIOContext->interruptContext );
6179 
6180     TI_DBG1(("satReadCapacity16: return control\n"));
6181     return tiSuccess;
6182   }
6183 
6184   /*
6185    * If Logical blcok address is not set to zero, return error
6186    */
6187   if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) ||
6188       (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9])  )
6189   {
6190     TI_DBG1(("satReadCapacity16 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
6191         tiDeviceHandle, tiIORequest));
6192 
6193     satSetSensePayload( pSense,
6194                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6195                         0,
6196                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6197                         satIOContext);
6198 
6199     ostiInitiatorIOCompleted( tiRoot,
6200                               tiIORequest,
6201                               tiIOSuccess,
6202                               SCSI_STAT_CHECK_CONDITION,
6203                               satIOContext->pTiSenseData,
6204                               satIOContext->interruptContext );
6205     return tiSuccess;
6206 
6207   }
6208 
6209   /*
6210    * If PMI bit is not zero, return error
6211    */
6212   if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
6213   {
6214     TI_DBG1(("satReadCapacity16 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
6215         tiDeviceHandle, tiIORequest));
6216 
6217     satSetSensePayload( pSense,
6218                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6219                         0,
6220                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6221                         satIOContext);
6222 
6223     ostiInitiatorIOCompleted( tiRoot,
6224                               tiIORequest,
6225                               tiIOSuccess,
6226                               SCSI_STAT_CHECK_CONDITION,
6227                               satIOContext->pTiSenseData,
6228                               satIOContext->interruptContext );
6229     return tiSuccess;
6230 
6231   }
6232 
6233   /*
6234     filling in Read Capacity parameter data
6235   */
6236 
6237   /*
6238    * If 48-bit addressing is supported, set capacity information from Identify
6239    * Device Word 100-103.
6240    */
6241   if (pSatDevData->sat48BitSupport == agTRUE)
6242   {
6243     pVirtAddr[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff);  /* MSB */
6244     pVirtAddr[1] = (bit8)((pSATAIdData->maxLBA48_63)        & 0xff);
6245     pVirtAddr[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
6246     pVirtAddr[3] = (bit8)((pSATAIdData->maxLBA32_47)        & 0xff);
6247 
6248     lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
6249     lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
6250 
6251     pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6252     pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6253     pVirtAddr[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
6254     pVirtAddr[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
6255 
6256   }
6257 
6258   /*
6259    * For 28-bit addressing, set capacity information from Identify
6260    * Device Word 60-61.
6261    */
6262   else
6263   {
6264     pVirtAddr[0] = 0;       /* MSB */
6265     pVirtAddr[1] = 0;
6266     pVirtAddr[2] = 0;
6267     pVirtAddr[3] = 0;
6268 
6269     lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6270                   (pSATAIdData->numOfUserAddressableSectorsLo);
6271     lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
6272 
6273     pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6274     pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6275     pVirtAddr[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
6276     pVirtAddr[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
6277 
6278   }
6279 
6280   /*
6281    * Set the block size, fixed at 512 bytes.
6282    */
6283   pVirtAddr[8]  = 0x00;        /* MSB block size in bytes */
6284   pVirtAddr[9]  = 0x00;
6285   pVirtAddr[10] = 0x02;
6286   pVirtAddr[11] = 0x00;        /* LSB block size in bytes */
6287 
6288 
6289   /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6290   pSatDevData->satMaxLBA[0] = pVirtAddr[0];            /* MSB */
6291   pSatDevData->satMaxLBA[1] = pVirtAddr[1];
6292   pSatDevData->satMaxLBA[2] = pVirtAddr[2];
6293   pSatDevData->satMaxLBA[3] = pVirtAddr[3];
6294   pSatDevData->satMaxLBA[4] = pVirtAddr[4];
6295   pSatDevData->satMaxLBA[5] = pVirtAddr[5];
6296   pSatDevData->satMaxLBA[6] = pVirtAddr[6];
6297   pSatDevData->satMaxLBA[7] = pVirtAddr[7];             /* LSB */
6298 
6299   TI_DBG5(("satReadCapacity16 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
6300         pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6301         pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6302         pVirtAddr[8], pVirtAddr[9], pVirtAddr[10], pVirtAddr[11],
6303         tiDeviceHandle, tiIORequest));
6304 
6305   for(i=12;i<=31;i++)
6306   {
6307     pVirtAddr[i] = 0x00;
6308   }
6309 
6310   /*
6311    * Send the completion response now.
6312    */
6313   if (allocationLen > readCapacityLen)
6314   {
6315     /* underrun */
6316     TI_DBG1(("satReadCapacity16 reporting underrun readCapacityLen=0x%x allocationLen=0x%x \n", readCapacityLen, allocationLen));
6317 
6318     ostiInitiatorIOCompleted( tiRoot,
6319                               tiIORequest,
6320                               tiIOUnderRun,
6321                               allocationLen - readCapacityLen,
6322                               agNULL,
6323                               satIOContext->interruptContext );
6324 
6325 
6326   }
6327   else
6328   {
6329     ostiInitiatorIOCompleted( tiRoot,
6330                               tiIORequest,
6331                               tiIOSuccess,
6332                               SCSI_STAT_GOOD,
6333                               agNULL,
6334                               satIOContext->interruptContext);
6335   }
6336   return tiSuccess;
6337 
6338 }
6339 
6340 
6341 /*****************************************************************************/
6342 /*! \brief SAT implementation for SCSI MODE SENSE (6).
6343  *
6344  *  SAT implementation for SCSI MODE SENSE (6).
6345  *
6346  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
6347  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
6348  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
6349  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
6350  *  \param   satIOContext_t:   Pointer to the SAT IO Context
6351  *
6352  *  \return If command is started successfully
6353  *    - \e tiSuccess:     I/O request successfully initiated.
6354  *    - \e tiBusy:        No resources available, try again later.
6355  *    - \e tiIONoDevice:  Invalid device handle.
6356  *    - \e tiError:       Other errors.
6357  */
6358 /*****************************************************************************/
6359 GLOBAL bit32  satModeSense6(
6360                    tiRoot_t                  *tiRoot,
6361                    tiIORequest_t             *tiIORequest,
6362                    tiDeviceHandle_t          *tiDeviceHandle,
6363                    tiScsiInitiatorRequest_t *tiScsiRequest,
6364                    satIOContext_t            *satIOContext)
6365 {
6366 
6367   scsiRspSense_t          *pSense;
6368   bit32                   requestLen;
6369   tiIniScsiCmnd_t         *scsiCmnd;
6370   bit32                   pageSupported;
6371   bit8                    page;
6372   bit8                    *pModeSense;    /* Mode Sense data buffer */
6373   satDeviceData_t         *pSatDevData;
6374   bit8                    PC;
6375   bit8                    AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN];
6376   bit8                    Control[MODE_SENSE6_CONTROL_PAGE_LEN];
6377   bit8                    RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN];
6378   bit8                    Caching[MODE_SENSE6_CACHING_LEN];
6379   bit8                    InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN];
6380   bit8                    lenRead = 0;
6381 
6382 
6383   TI_DBG5(("satModeSense6 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6384       tiDeviceHandle, tiIORequest));
6385 
6386   pSense      = satIOContext->pSense;
6387   scsiCmnd    = &tiScsiRequest->scsiCmnd;
6388   pModeSense  = (bit8 *) tiScsiRequest->sglVirtualAddr;
6389   pSatDevData = satIOContext->pSatDevData;
6390 
6391   //tdhexdump("satModeSense6", (bit8 *)scsiCmnd->cdb, 6);
6392   /* checking CONTROL */
6393   /* NACA == 1 or LINK == 1*/
6394   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
6395   {
6396     satSetSensePayload( pSense,
6397                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6398                         0,
6399                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6400                         satIOContext);
6401 
6402     ostiInitiatorIOCompleted( tiRoot,
6403                               tiIORequest,
6404                               tiIOSuccess,
6405                               SCSI_STAT_CHECK_CONDITION,
6406                               satIOContext->pTiSenseData,
6407                               satIOContext->interruptContext );
6408 
6409     TI_DBG2(("satModeSense6: return control\n"));
6410     return tiSuccess;
6411   }
6412 
6413   /* checking PC(Page Control)
6414      SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6415   */
6416   PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
6417   if (PC != 0)
6418   {
6419     satSetSensePayload( pSense,
6420                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6421                         0,
6422                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6423                         satIOContext);
6424 
6425     ostiInitiatorIOCompleted( tiRoot,
6426                               tiIORequest,
6427                               tiIOSuccess,
6428                               SCSI_STAT_CHECK_CONDITION,
6429                               satIOContext->pTiSenseData,
6430                               satIOContext->interruptContext );
6431 
6432     TI_DBG1(("satModeSense6: return due to PC value pc 0x%x\n", PC >> 6));
6433     return tiSuccess;
6434   }
6435 
6436   /* reading PAGE CODE */
6437   page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
6438 
6439 
6440   TI_DBG5(("satModeSense6: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
6441              page, tiDeviceHandle, tiIORequest));
6442 
6443   requestLen = scsiCmnd->cdb[4];
6444 
6445     /*
6446     Based on page code value, returns a corresponding mode page
6447     note: no support for subpage
6448   */
6449 
6450   switch(page)
6451   {
6452     case MODESENSE_RETURN_ALL_PAGES:
6453     case MODESENSE_CONTROL_PAGE: /* control */
6454     case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6455     case MODESENSE_CACHING: /* caching */
6456     case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6457       pageSupported = agTRUE;
6458       break;
6459     case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
6460     default:
6461       pageSupported = agFALSE;
6462       break;
6463   }
6464 
6465   if (pageSupported == agFALSE)
6466   {
6467 
6468     TI_DBG1(("satModeSense6 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
6469         page, tiDeviceHandle, tiIORequest));
6470 
6471     satSetSensePayload( pSense,
6472                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6473                         0,
6474                         SCSI_SNSCODE_INVALID_COMMAND,
6475                         satIOContext);
6476 
6477     ostiInitiatorIOCompleted( tiRoot,
6478                               tiIORequest,
6479                               tiIOSuccess,
6480                               SCSI_STAT_CHECK_CONDITION,
6481                               satIOContext->pTiSenseData,
6482                               satIOContext->interruptContext );
6483     return tiSuccess;
6484   }
6485 
6486   switch(page)
6487   {
6488   case MODESENSE_RETURN_ALL_PAGES:
6489     lenRead = (bit8)MIN(requestLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
6490     break;
6491   case MODESENSE_CONTROL_PAGE: /* control */
6492     lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CONTROL_PAGE_LEN);
6493     break;
6494   case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6495     lenRead = (bit8)MIN(requestLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
6496     break;
6497   case MODESENSE_CACHING: /* caching */
6498     lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CACHING_LEN);
6499     break;
6500   case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6501     lenRead = (bit8)MIN(requestLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
6502     break;
6503   default:
6504     TI_DBG1(("satModeSense6: default error page %d\n", page));
6505     break;
6506   }
6507 
6508   if (page == MODESENSE_RETURN_ALL_PAGES)
6509   {
6510     TI_DBG5(("satModeSense6: MODESENSE_RETURN_ALL_PAGES\n"));
6511     AllPages[0] = (bit8)(lenRead - 1);
6512     AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */
6513     AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6514     AllPages[3] = 0x08; /* block descriptor length */
6515 
6516     /*
6517      * Fill-up direct-access device block-descriptor, SAT, Table 19
6518      */
6519 
6520     /* density code */
6521     AllPages[4]  = 0x04; /* density-code : reserved for direct-access */
6522     /* number of blocks */
6523     AllPages[5]  = 0x00; /* unspecified */
6524     AllPages[6]  = 0x00; /* unspecified */
6525     AllPages[7]  = 0x00; /* unspecified */
6526     /* reserved */
6527     AllPages[8]  = 0x00; /* reserved */
6528     /* Block size */
6529     AllPages[9]  = 0x00;
6530     AllPages[10] = 0x02;   /* Block size is always 512 bytes */
6531     AllPages[11] = 0x00;
6532 
6533     /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
6534     AllPages[12] = 0x01; /* page code */
6535     AllPages[13] = 0x0A; /* page length */
6536     AllPages[14] = 0x40; /* ARRE is set */
6537     AllPages[15] = 0x00;
6538     AllPages[16] = 0x00;
6539     AllPages[17] = 0x00;
6540     AllPages[18] = 0x00;
6541     AllPages[19] = 0x00;
6542     AllPages[20] = 0x00;
6543     AllPages[21] = 0x00;
6544     AllPages[22] = 0x00;
6545     AllPages[23] = 0x00;
6546     /* MODESENSE_CACHING */
6547     AllPages[24] = 0x08; /* page code */
6548     AllPages[25] = 0x12; /* page length */
6549 #ifdef NOT_YET
6550     if (pSatDevData->satWriteCacheEnabled == agTRUE)
6551     {
6552       AllPages[26] = 0x04;/* WCE bit is set */
6553     }
6554     else
6555     {
6556       AllPages[26] = 0x00;/* WCE bit is NOT set */
6557     }
6558 #endif
6559     AllPages[26] = 0x00;/* WCE bit is NOT set */
6560 
6561     AllPages[27] = 0x00;
6562     AllPages[28] = 0x00;
6563     AllPages[29] = 0x00;
6564     AllPages[30] = 0x00;
6565     AllPages[31] = 0x00;
6566     AllPages[32] = 0x00;
6567     AllPages[33] = 0x00;
6568     AllPages[34] = 0x00;
6569     AllPages[35] = 0x00;
6570     if (pSatDevData->satLookAheadEnabled == agTRUE)
6571     {
6572       AllPages[36] = 0x00;/* DRA bit is NOT set */
6573     }
6574     else
6575     {
6576       AllPages[36] = 0x20;/* DRA bit is set */
6577     }
6578     AllPages[37] = 0x00;
6579     AllPages[38] = 0x00;
6580     AllPages[39] = 0x00;
6581     AllPages[40] = 0x00;
6582     AllPages[41] = 0x00;
6583     AllPages[42] = 0x00;
6584     AllPages[43] = 0x00;
6585     /* MODESENSE_CONTROL_PAGE */
6586     AllPages[44] = 0x0A; /* page code */
6587     AllPages[45] = 0x0A; /* page length */
6588     AllPages[46] = 0x02; /* only GLTSD bit is set */
6589     if (pSatDevData->satNCQ == agTRUE)
6590     {
6591       AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6592     }
6593     else
6594     {
6595       AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6596     }
6597     AllPages[48] = 0x00;
6598     AllPages[49] = 0x00;
6599     AllPages[50] = 0x00; /* obsolete */
6600     AllPages[51] = 0x00; /* obsolete */
6601     AllPages[52] = 0xFF; /* Busy Timeout Period */
6602     AllPages[53] = 0xFF; /* Busy Timeout Period */
6603     AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */
6604     AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */
6605     /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
6606     AllPages[56] = 0x1C; /* page code */
6607     AllPages[57] = 0x0A; /* page length */
6608     if (pSatDevData->satSMARTEnabled == agTRUE)
6609     {
6610       AllPages[58] = 0x00;/* DEXCPT bit is NOT set */
6611     }
6612     else
6613     {
6614       AllPages[58] = 0x08;/* DEXCPT bit is set */
6615     }
6616     AllPages[59] = 0x00; /* We don't support MRIE */
6617     AllPages[60] = 0x00; /* Interval timer vendor-specific */
6618     AllPages[61] = 0x00;
6619     AllPages[62] = 0x00;
6620     AllPages[63] = 0x00;
6621     AllPages[64] = 0x00; /* REPORT-COUNT */
6622     AllPages[65] = 0x00;
6623     AllPages[66] = 0x00;
6624     AllPages[67] = 0x00;
6625 
6626     osti_memcpy(pModeSense, &AllPages, lenRead);
6627   }
6628   else if (page == MODESENSE_CONTROL_PAGE)
6629   {
6630     TI_DBG5(("satModeSense6: MODESENSE_CONTROL_PAGE\n"));
6631     Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1;
6632     Control[1] = 0x00; /* default medium type (currently mounted medium type) */
6633     Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6634     Control[3] = 0x08; /* block descriptor length */
6635     /*
6636      * Fill-up direct-access device block-descriptor, SAT, Table 19
6637      */
6638 
6639     /* density code */
6640     Control[4]  = 0x04; /* density-code : reserved for direct-access */
6641     /* number of blocks */
6642     Control[5]  = 0x00; /* unspecified */
6643     Control[6]  = 0x00; /* unspecified */
6644     Control[7]  = 0x00; /* unspecified */
6645     /* reserved */
6646     Control[8]  = 0x00; /* reserved */
6647     /* Block size */
6648     Control[9]  = 0x00;
6649     Control[10] = 0x02;   /* Block size is always 512 bytes */
6650     Control[11] = 0x00;
6651     /*
6652      * Fill-up control mode page, SAT, Table 65
6653      */
6654     Control[12] = 0x0A; /* page code */
6655     Control[13] = 0x0A; /* page length */
6656     Control[14] = 0x02; /* only GLTSD bit is set */
6657     if (pSatDevData->satNCQ == agTRUE)
6658     {
6659       Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6660     }
6661     else
6662     {
6663       Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6664     }
6665     Control[16] = 0x00;
6666     Control[17] = 0x00;
6667     Control[18] = 0x00; /* obsolete */
6668     Control[19] = 0x00; /* obsolete */
6669     Control[20] = 0xFF; /* Busy Timeout Period */
6670     Control[21] = 0xFF; /* Busy Timeout Period */
6671     Control[22] = 0x00; /* we don't support non-000b value for the self-test code */
6672     Control[23] = 0x00; /* we don't support non-000b value for the self-test code */
6673 
6674     osti_memcpy(pModeSense, &Control, lenRead);
6675 
6676   }
6677   else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
6678   {
6679     TI_DBG5(("satModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
6680     RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1;
6681     RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */
6682     RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6683     RWErrorRecovery[3] = 0x08; /* block descriptor length */
6684     /*
6685      * Fill-up direct-access device block-descriptor, SAT, Table 19
6686      */
6687 
6688     /* density code */
6689     RWErrorRecovery[4]  = 0x04; /* density-code : reserved for direct-access */
6690     /* number of blocks */
6691     RWErrorRecovery[5]  = 0x00; /* unspecified */
6692     RWErrorRecovery[6]  = 0x00; /* unspecified */
6693     RWErrorRecovery[7]  = 0x00; /* unspecified */
6694     /* reserved */
6695     RWErrorRecovery[8]  = 0x00; /* reserved */
6696     /* Block size */
6697     RWErrorRecovery[9]  = 0x00;
6698     RWErrorRecovery[10] = 0x02;   /* Block size is always 512 bytes */
6699     RWErrorRecovery[11] = 0x00;
6700     /*
6701      * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
6702      */
6703     RWErrorRecovery[12] = 0x01; /* page code */
6704     RWErrorRecovery[13] = 0x0A; /* page length */
6705     RWErrorRecovery[14] = 0x40; /* ARRE is set */
6706     RWErrorRecovery[15] = 0x00;
6707     RWErrorRecovery[16] = 0x00;
6708     RWErrorRecovery[17] = 0x00;
6709     RWErrorRecovery[18] = 0x00;
6710     RWErrorRecovery[19] = 0x00;
6711     RWErrorRecovery[20] = 0x00;
6712     RWErrorRecovery[21] = 0x00;
6713     RWErrorRecovery[22] = 0x00;
6714     RWErrorRecovery[23] = 0x00;
6715 
6716     osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
6717 
6718   }
6719   else if (page == MODESENSE_CACHING)
6720   {
6721     TI_DBG5(("satModeSense6: MODESENSE_CACHING\n"));
6722     /* special case */
6723     if (requestLen == 4 && page == MODESENSE_CACHING)
6724     {
6725       TI_DBG5(("satModeSense6: linux 2.6.8.24 support\n"));
6726 
6727       pModeSense[0] = 0x20 - 1; /* 32 - 1 */
6728       pModeSense[1] = 0x00; /* default medium type (currently mounted medium type) */
6729       pModeSense[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6730       pModeSense[3] = 0x08; /* block descriptor length */
6731       ostiInitiatorIOCompleted( tiRoot,
6732                                 tiIORequest,
6733                                 tiIOSuccess,
6734                                 SCSI_STAT_GOOD,
6735                                 agNULL,
6736                                 satIOContext->interruptContext);
6737       return tiSuccess;
6738     }
6739     Caching[0] = MODE_SENSE6_CACHING_LEN - 1;
6740     Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
6741     Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6742     Caching[3] = 0x08; /* block descriptor length */
6743     /*
6744      * Fill-up direct-access device block-descriptor, SAT, Table 19
6745      */
6746 
6747     /* density code */
6748     Caching[4]  = 0x04; /* density-code : reserved for direct-access */
6749     /* number of blocks */
6750     Caching[5]  = 0x00; /* unspecified */
6751     Caching[6]  = 0x00; /* unspecified */
6752     Caching[7]  = 0x00; /* unspecified */
6753     /* reserved */
6754     Caching[8]  = 0x00; /* reserved */
6755     /* Block size */
6756     Caching[9]  = 0x00;
6757     Caching[10] = 0x02;   /* Block size is always 512 bytes */
6758     Caching[11] = 0x00;
6759     /*
6760      * Fill-up Caching mode page, SAT, Table 67
6761      */
6762     /* length 20 */
6763     Caching[12] = 0x08; /* page code */
6764     Caching[13] = 0x12; /* page length */
6765 #ifdef NOT_YET
6766     if (pSatDevData->satWriteCacheEnabled == agTRUE)
6767     {
6768       Caching[14] = 0x04;/* WCE bit is set */
6769     }
6770     else
6771     {
6772       Caching[14] = 0x00;/* WCE bit is NOT set */
6773     }
6774 #endif
6775     Caching[14] = 0x00;/* WCE bit is NOT set */
6776 
6777     Caching[15] = 0x00;
6778     Caching[16] = 0x00;
6779     Caching[17] = 0x00;
6780     Caching[18] = 0x00;
6781     Caching[19] = 0x00;
6782     Caching[20] = 0x00;
6783     Caching[21] = 0x00;
6784     Caching[22] = 0x00;
6785     Caching[23] = 0x00;
6786     if (pSatDevData->satLookAheadEnabled == agTRUE)
6787     {
6788       Caching[24] = 0x00;/* DRA bit is NOT set */
6789     }
6790     else
6791     {
6792       Caching[24] = 0x20;/* DRA bit is set */
6793     }
6794     Caching[25] = 0x00;
6795     Caching[26] = 0x00;
6796     Caching[27] = 0x00;
6797     Caching[28] = 0x00;
6798     Caching[29] = 0x00;
6799     Caching[30] = 0x00;
6800     Caching[31] = 0x00;
6801 
6802     osti_memcpy(pModeSense, &Caching, lenRead);
6803 
6804   }
6805   else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
6806   {
6807     TI_DBG5(("satModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
6808     InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1;
6809     InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */
6810     InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6811     InfoExceptionCtrl[3] = 0x08; /* block descriptor length */
6812     /*
6813      * Fill-up direct-access device block-descriptor, SAT, Table 19
6814      */
6815 
6816     /* density code */
6817     InfoExceptionCtrl[4]  = 0x04; /* density-code : reserved for direct-access */
6818     /* number of blocks */
6819     InfoExceptionCtrl[5]  = 0x00; /* unspecified */
6820     InfoExceptionCtrl[6]  = 0x00; /* unspecified */
6821     InfoExceptionCtrl[7]  = 0x00; /* unspecified */
6822     /* reserved */
6823     InfoExceptionCtrl[8]  = 0x00; /* reserved */
6824     /* Block size */
6825     InfoExceptionCtrl[9]  = 0x00;
6826     InfoExceptionCtrl[10] = 0x02;   /* Block size is always 512 bytes */
6827     InfoExceptionCtrl[11] = 0x00;
6828     /*
6829      * Fill-up informational-exceptions control mode page, SAT, Table 68
6830      */
6831     InfoExceptionCtrl[12] = 0x1C; /* page code */
6832     InfoExceptionCtrl[13] = 0x0A; /* page length */
6833      if (pSatDevData->satSMARTEnabled == agTRUE)
6834     {
6835       InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */
6836     }
6837     else
6838     {
6839       InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */
6840     }
6841     InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */
6842     InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */
6843     InfoExceptionCtrl[17] = 0x00;
6844     InfoExceptionCtrl[18] = 0x00;
6845     InfoExceptionCtrl[19] = 0x00;
6846     InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */
6847     InfoExceptionCtrl[21] = 0x00;
6848     InfoExceptionCtrl[22] = 0x00;
6849     InfoExceptionCtrl[23] = 0x00;
6850     osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
6851 
6852   }
6853   else
6854   {
6855     /* Error */
6856     TI_DBG1(("satModeSense6: Error page %d\n", page));
6857     satSetSensePayload( pSense,
6858                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6859                         0,
6860                         SCSI_SNSCODE_INVALID_COMMAND,
6861                         satIOContext);
6862 
6863     ostiInitiatorIOCompleted( tiRoot,
6864                               tiIORequest,
6865                               tiIOSuccess,
6866                               SCSI_STAT_CHECK_CONDITION,
6867                               satIOContext->pTiSenseData,
6868                               satIOContext->interruptContext );
6869     return tiSuccess;
6870   }
6871 
6872   /* there can be only underrun not overrun in error case */
6873   if (requestLen > lenRead)
6874   {
6875     TI_DBG6(("satModeSense6 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
6876 
6877     ostiInitiatorIOCompleted( tiRoot,
6878                               tiIORequest,
6879                               tiIOUnderRun,
6880                               requestLen - lenRead,
6881                               agNULL,
6882                               satIOContext->interruptContext );
6883 
6884 
6885   }
6886   else
6887   {
6888     ostiInitiatorIOCompleted( tiRoot,
6889                               tiIORequest,
6890                               tiIOSuccess,
6891                               SCSI_STAT_GOOD,
6892                               agNULL,
6893                               satIOContext->interruptContext);
6894   }
6895 
6896   return tiSuccess;
6897 
6898 }
6899 
6900 /*****************************************************************************/
6901 /*! \brief SAT implementation for SCSI MODE SENSE (10).
6902  *
6903  *  SAT implementation for SCSI MODE SENSE (10).
6904  *
6905  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
6906  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
6907  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
6908  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
6909  *  \param   satIOContext_t:   Pointer to the SAT IO Context
6910  *
6911  *  \return If command is started successfully
6912  *    - \e tiSuccess:     I/O request successfully initiated.
6913  *    - \e tiBusy:        No resources available, try again later.
6914  *    - \e tiIONoDevice:  Invalid device handle.
6915  *    - \e tiError:       Other errors.
6916  */
6917 /*****************************************************************************/
6918 GLOBAL bit32  satModeSense10(
6919                    tiRoot_t                  *tiRoot,
6920                    tiIORequest_t             *tiIORequest,
6921                    tiDeviceHandle_t          *tiDeviceHandle,
6922                    tiScsiInitiatorRequest_t *tiScsiRequest,
6923                    satIOContext_t            *satIOContext)
6924 {
6925 
6926   scsiRspSense_t          *pSense;
6927   bit32                   requestLen;
6928   tiIniScsiCmnd_t         *scsiCmnd;
6929   bit32                   pageSupported;
6930   bit8                    page;
6931   bit8                    *pModeSense;    /* Mode Sense data buffer */
6932   satDeviceData_t         *pSatDevData;
6933   bit8                    PC; /* page control */
6934   bit8                    LLBAA; /* Long LBA Accepted */
6935   bit32                   index;
6936   bit8                    AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN];
6937   bit8                    Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN];
6938   bit8                    RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN];
6939   bit8                    Caching[MODE_SENSE10_CACHING_LLBAA_LEN];
6940   bit8                    InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN];
6941   bit8                    lenRead = 0;
6942 
6943   TI_DBG5(("satModeSense10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6944       tiDeviceHandle, tiIORequest));
6945 
6946   pSense      = satIOContext->pSense;
6947   scsiCmnd    = &tiScsiRequest->scsiCmnd;
6948   pModeSense  = (bit8 *) tiScsiRequest->sglVirtualAddr;
6949   pSatDevData = satIOContext->pSatDevData;
6950 
6951   /* checking CONTROL */
6952   /* NACA == 1 or LINK == 1*/
6953   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
6954   {
6955     satSetSensePayload( pSense,
6956                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6957                         0,
6958                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6959                         satIOContext);
6960 
6961     ostiInitiatorIOCompleted( tiRoot,
6962                               tiIORequest,
6963                               tiIOSuccess,
6964                               SCSI_STAT_CHECK_CONDITION,
6965                               satIOContext->pTiSenseData,
6966                               satIOContext->interruptContext );
6967 
6968     TI_DBG2(("satModeSense10: return control\n"));
6969     return tiSuccess;
6970   }
6971 
6972   /* checking PC(Page Control)
6973      SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6974   */
6975   PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
6976   if (PC != 0)
6977   {
6978     satSetSensePayload( pSense,
6979                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6980                         0,
6981                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6982                         satIOContext);
6983 
6984     ostiInitiatorIOCompleted( tiRoot,
6985                               tiIORequest,
6986                               tiIOSuccess,
6987                               SCSI_STAT_CHECK_CONDITION,
6988                               satIOContext->pTiSenseData,
6989                               satIOContext->interruptContext );
6990 
6991     TI_DBG1(("satModeSense10: return due to PC value pc 0x%x\n", PC));
6992     return tiSuccess;
6993   }
6994   /* finding LLBAA bit */
6995   LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
6996   /* reading PAGE CODE */
6997   page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
6998 
6999   TI_DBG5(("satModeSense10: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
7000              page, tiDeviceHandle, tiIORequest));
7001   requestLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7002 
7003   /*
7004     Based on page code value, returns a corresponding mode page
7005     note: no support for subpage
7006   */
7007   switch(page)
7008   {
7009     case MODESENSE_RETURN_ALL_PAGES: /* return all pages */
7010     case MODESENSE_CONTROL_PAGE: /* control */
7011     case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7012     case MODESENSE_CACHING: /* caching */
7013     case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7014       pageSupported = agTRUE;
7015       break;
7016     case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
7017     default:
7018       pageSupported = agFALSE;
7019       break;
7020   }
7021 
7022   if (pageSupported == agFALSE)
7023   {
7024 
7025     TI_DBG1(("satModeSense10 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
7026         page, tiDeviceHandle, tiIORequest));
7027 
7028     satSetSensePayload( pSense,
7029                         SCSI_SNSKEY_ILLEGAL_REQUEST,
7030                         0,
7031                         SCSI_SNSCODE_INVALID_COMMAND,
7032                         satIOContext);
7033 
7034     ostiInitiatorIOCompleted( tiRoot,
7035                               tiIORequest,
7036                               tiIOSuccess,
7037                               SCSI_STAT_CHECK_CONDITION,
7038                               satIOContext->pTiSenseData,
7039                               satIOContext->interruptContext );
7040     return tiSuccess;
7041   }
7042 
7043   switch(page)
7044   {
7045   case MODESENSE_RETURN_ALL_PAGES:
7046     if (LLBAA)
7047     {
7048       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
7049     }
7050     else
7051     {
7052       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
7053     }
7054     break;
7055   case MODESENSE_CONTROL_PAGE: /* control */
7056     if (LLBAA)
7057     {
7058       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
7059     }
7060     else
7061     {
7062       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LEN);
7063     }
7064     break;
7065   case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7066     if (LLBAA)
7067     {
7068       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
7069     }
7070     else
7071     {
7072       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
7073     }
7074     break;
7075   case MODESENSE_CACHING: /* caching */
7076     if (LLBAA)
7077     {
7078       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LLBAA_LEN);
7079     }
7080     else
7081     {
7082       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LEN);
7083     }
7084     break;
7085   case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7086     if (LLBAA)
7087     {
7088       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
7089     }
7090     else
7091     {
7092       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
7093     }
7094     break;
7095   default:
7096     TI_DBG1(("satModeSense10: default error page %d\n", page));
7097     break;
7098   }
7099 
7100   if (page == MODESENSE_RETURN_ALL_PAGES)
7101   {
7102     TI_DBG5(("satModeSense10: MODESENSE_RETURN_ALL_PAGES\n"));
7103     AllPages[0] = 0;
7104     AllPages[1] = (bit8)(lenRead - 2);
7105     AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7106     AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7107     if (LLBAA)
7108     {
7109       AllPages[4] = 0x00; /* reserved and LONGLBA */
7110       AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */
7111     }
7112     else
7113     {
7114       AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7115     }
7116     AllPages[5] = 0x00; /* reserved */
7117     AllPages[6] = 0x00; /* block descriptot length */
7118     if (LLBAA)
7119     {
7120       AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7121     }
7122     else
7123     {
7124       AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7125     }
7126 
7127     /*
7128      * Fill-up direct-access device block-descriptor, SAT, Table 19
7129      */
7130 
7131     if (LLBAA)
7132     {
7133       /* density code */
7134       AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
7135       /* number of blocks */
7136       AllPages[9]   = 0x00; /* unspecified */
7137       AllPages[10]  = 0x00; /* unspecified */
7138       AllPages[11]  = 0x00; /* unspecified */
7139       AllPages[12]  = 0x00; /* unspecified */
7140       AllPages[13]  = 0x00; /* unspecified */
7141       AllPages[14]  = 0x00; /* unspecified */
7142       AllPages[15]  = 0x00; /* unspecified */
7143       /* reserved */
7144       AllPages[16]  = 0x00; /* reserved */
7145       AllPages[17]  = 0x00; /* reserved */
7146       AllPages[18]  = 0x00; /* reserved */
7147       AllPages[19]  = 0x00; /* reserved */
7148       /* Block size */
7149       AllPages[20]  = 0x00;
7150       AllPages[21]  = 0x00;
7151       AllPages[22]  = 0x02;   /* Block size is always 512 bytes */
7152       AllPages[23]  = 0x00;
7153     }
7154     else
7155     {
7156       /* density code */
7157       AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
7158       /* number of blocks */
7159       AllPages[9]   = 0x00; /* unspecified */
7160       AllPages[10]  = 0x00; /* unspecified */
7161       AllPages[11]  = 0x00; /* unspecified */
7162       /* reserved */
7163       AllPages[12]  = 0x00; /* reserved */
7164       /* Block size */
7165       AllPages[13]  = 0x00;
7166       AllPages[14]  = 0x02;   /* Block size is always 512 bytes */
7167       AllPages[15]  = 0x00;
7168     }
7169 
7170     if (LLBAA)
7171     {
7172       index = 24;
7173     }
7174     else
7175     {
7176       index = 16;
7177     }
7178     /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
7179     AllPages[index+0] = 0x01; /* page code */
7180     AllPages[index+1] = 0x0A; /* page length */
7181     AllPages[index+2] = 0x40; /* ARRE is set */
7182     AllPages[index+3] = 0x00;
7183     AllPages[index+4] = 0x00;
7184     AllPages[index+5] = 0x00;
7185     AllPages[index+6] = 0x00;
7186     AllPages[index+7] = 0x00;
7187     AllPages[index+8] = 0x00;
7188     AllPages[index+9] = 0x00;
7189     AllPages[index+10] = 0x00;
7190     AllPages[index+11] = 0x00;
7191 
7192     /* MODESENSE_CACHING */
7193     /*
7194      * Fill-up Caching mode page, SAT, Table 67
7195      */
7196     /* length 20 */
7197     AllPages[index+12] = 0x08; /* page code */
7198     AllPages[index+13] = 0x12; /* page length */
7199 #ifdef NOT_YET
7200     if (pSatDevData->satWriteCacheEnabled == agTRUE)
7201     {
7202       AllPages[index+14] = 0x04;/* WCE bit is set */
7203     }
7204     else
7205     {
7206       AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7207     }
7208 #endif
7209     AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7210     AllPages[index+15] = 0x00;
7211     AllPages[index+16] = 0x00;
7212     AllPages[index+17] = 0x00;
7213     AllPages[index+18] = 0x00;
7214     AllPages[index+19] = 0x00;
7215     AllPages[index+20] = 0x00;
7216     AllPages[index+21] = 0x00;
7217     AllPages[index+22] = 0x00;
7218     AllPages[index+23] = 0x00;
7219     if (pSatDevData->satLookAheadEnabled == agTRUE)
7220     {
7221       AllPages[index+24] = 0x00;/* DRA bit is NOT set */
7222     }
7223     else
7224     {
7225       AllPages[index+24] = 0x20;/* DRA bit is set */
7226     }
7227     AllPages[index+25] = 0x00;
7228     AllPages[index+26] = 0x00;
7229     AllPages[index+27] = 0x00;
7230     AllPages[index+28] = 0x00;
7231     AllPages[index+29] = 0x00;
7232     AllPages[index+30] = 0x00;
7233     AllPages[index+31] = 0x00;
7234 
7235     /* MODESENSE_CONTROL_PAGE */
7236     /*
7237      * Fill-up control mode page, SAT, Table 65
7238      */
7239     AllPages[index+32] = 0x0A; /* page code */
7240     AllPages[index+33] = 0x0A; /* page length */
7241     AllPages[index+34] = 0x02; /* only GLTSD bit is set */
7242     if (pSatDevData->satNCQ == agTRUE)
7243     {
7244       AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7245     }
7246     else
7247     {
7248       AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7249     }
7250     AllPages[index+36] = 0x00;
7251     AllPages[index+37] = 0x00;
7252     AllPages[index+38] = 0x00; /* obsolete */
7253     AllPages[index+39] = 0x00; /* obsolete */
7254     AllPages[index+40] = 0xFF; /* Busy Timeout Period */
7255     AllPages[index+41] = 0xFF; /* Busy Timeout Period */
7256     AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */
7257     AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */
7258 
7259     /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
7260     /*
7261      * Fill-up informational-exceptions control mode page, SAT, Table 68
7262      */
7263     AllPages[index+44] = 0x1C; /* page code */
7264     AllPages[index+45] = 0x0A; /* page length */
7265      if (pSatDevData->satSMARTEnabled == agTRUE)
7266     {
7267       AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */
7268     }
7269     else
7270     {
7271       AllPages[index+46] = 0x08;/* DEXCPT bit is set */
7272     }
7273     AllPages[index+47] = 0x00; /* We don't support MRIE */
7274     AllPages[index+48] = 0x00; /* Interval timer vendor-specific */
7275     AllPages[index+49] = 0x00;
7276     AllPages[index+50] = 0x00;
7277     AllPages[index+51] = 0x00;
7278     AllPages[index+52] = 0x00; /* REPORT-COUNT */
7279     AllPages[index+53] = 0x00;
7280     AllPages[index+54] = 0x00;
7281     AllPages[index+55] = 0x00;
7282 
7283     osti_memcpy(pModeSense, &AllPages, lenRead);
7284   }
7285   else if (page == MODESENSE_CONTROL_PAGE)
7286   {
7287     TI_DBG5(("satModeSense10: MODESENSE_CONTROL_PAGE\n"));
7288     Control[0] = 0;
7289     Control[1] = (bit8)(lenRead - 2);
7290     Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7291     Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7292     if (LLBAA)
7293     {
7294       Control[4] = 0x00; /* reserved and LONGLBA */
7295       Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */
7296     }
7297     else
7298     {
7299       Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7300     }
7301     Control[5] = 0x00; /* reserved */
7302     Control[6] = 0x00; /* block descriptot length */
7303     if (LLBAA)
7304     {
7305       Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7306     }
7307     else
7308     {
7309       Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7310     }
7311 
7312     /*
7313      * Fill-up direct-access device block-descriptor, SAT, Table 19
7314      */
7315 
7316     if (LLBAA)
7317     {
7318       /* density code */
7319       Control[8]   = 0x04; /* density-code : reserved for direct-access */
7320       /* number of blocks */
7321       Control[9]   = 0x00; /* unspecified */
7322       Control[10]  = 0x00; /* unspecified */
7323       Control[11]  = 0x00; /* unspecified */
7324       Control[12]  = 0x00; /* unspecified */
7325       Control[13]  = 0x00; /* unspecified */
7326       Control[14]  = 0x00; /* unspecified */
7327       Control[15]  = 0x00; /* unspecified */
7328       /* reserved */
7329       Control[16]  = 0x00; /* reserved */
7330       Control[17]  = 0x00; /* reserved */
7331       Control[18]  = 0x00; /* reserved */
7332       Control[19]  = 0x00; /* reserved */
7333       /* Block size */
7334       Control[20]  = 0x00;
7335       Control[21]  = 0x00;
7336       Control[22]  = 0x02;   /* Block size is always 512 bytes */
7337       Control[23]  = 0x00;
7338     }
7339     else
7340     {
7341       /* density code */
7342       Control[8]   = 0x04; /* density-code : reserved for direct-access */
7343       /* number of blocks */
7344       Control[9]   = 0x00; /* unspecified */
7345       Control[10]  = 0x00; /* unspecified */
7346       Control[11]  = 0x00; /* unspecified */
7347       /* reserved */
7348       Control[12]  = 0x00; /* reserved */
7349       /* Block size */
7350       Control[13]  = 0x00;
7351       Control[14]  = 0x02;   /* Block size is always 512 bytes */
7352       Control[15]  = 0x00;
7353     }
7354 
7355     if (LLBAA)
7356     {
7357       index = 24;
7358     }
7359     else
7360     {
7361       index = 16;
7362     }
7363     /*
7364      * Fill-up control mode page, SAT, Table 65
7365      */
7366     Control[index+0] = 0x0A; /* page code */
7367     Control[index+1] = 0x0A; /* page length */
7368     Control[index+2] = 0x02; /* only GLTSD bit is set */
7369     if (pSatDevData->satNCQ == agTRUE)
7370     {
7371       Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7372     }
7373     else
7374     {
7375       Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7376     }
7377     Control[index+4] = 0x00;
7378     Control[index+5] = 0x00;
7379     Control[index+6] = 0x00; /* obsolete */
7380     Control[index+7] = 0x00; /* obsolete */
7381     Control[index+8] = 0xFF; /* Busy Timeout Period */
7382     Control[index+9] = 0xFF; /* Busy Timeout Period */
7383     Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */
7384     Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */
7385 
7386     osti_memcpy(pModeSense, &Control, lenRead);
7387   }
7388   else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
7389   {
7390     TI_DBG5(("satModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
7391     RWErrorRecovery[0] = 0;
7392     RWErrorRecovery[1] = (bit8)(lenRead - 2);
7393     RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7394     RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7395     if (LLBAA)
7396     {
7397       RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */
7398       RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */
7399     }
7400     else
7401     {
7402       RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7403     }
7404     RWErrorRecovery[5] = 0x00; /* reserved */
7405     RWErrorRecovery[6] = 0x00; /* block descriptot length */
7406     if (LLBAA)
7407     {
7408       RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7409     }
7410     else
7411     {
7412       RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7413     }
7414 
7415     /*
7416      * Fill-up direct-access device block-descriptor, SAT, Table 19
7417      */
7418 
7419     if (LLBAA)
7420     {
7421       /* density code */
7422       RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
7423       /* number of blocks */
7424       RWErrorRecovery[9]   = 0x00; /* unspecified */
7425       RWErrorRecovery[10]  = 0x00; /* unspecified */
7426       RWErrorRecovery[11]  = 0x00; /* unspecified */
7427       RWErrorRecovery[12]  = 0x00; /* unspecified */
7428       RWErrorRecovery[13]  = 0x00; /* unspecified */
7429       RWErrorRecovery[14]  = 0x00; /* unspecified */
7430       RWErrorRecovery[15]  = 0x00; /* unspecified */
7431       /* reserved */
7432       RWErrorRecovery[16]  = 0x00; /* reserved */
7433       RWErrorRecovery[17]  = 0x00; /* reserved */
7434       RWErrorRecovery[18]  = 0x00; /* reserved */
7435       RWErrorRecovery[19]  = 0x00; /* reserved */
7436       /* Block size */
7437       RWErrorRecovery[20]  = 0x00;
7438       RWErrorRecovery[21]  = 0x00;
7439       RWErrorRecovery[22]  = 0x02;   /* Block size is always 512 bytes */
7440       RWErrorRecovery[23]  = 0x00;
7441     }
7442     else
7443     {
7444       /* density code */
7445       RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
7446       /* number of blocks */
7447       RWErrorRecovery[9]   = 0x00; /* unspecified */
7448       RWErrorRecovery[10]  = 0x00; /* unspecified */
7449       RWErrorRecovery[11]  = 0x00; /* unspecified */
7450       /* reserved */
7451       RWErrorRecovery[12]  = 0x00; /* reserved */
7452       /* Block size */
7453       RWErrorRecovery[13]  = 0x00;
7454       RWErrorRecovery[14]  = 0x02;   /* Block size is always 512 bytes */
7455       RWErrorRecovery[15]  = 0x00;
7456     }
7457 
7458     if (LLBAA)
7459     {
7460       index = 24;
7461     }
7462     else
7463     {
7464       index = 16;
7465     }
7466     /*
7467      * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
7468      */
7469     RWErrorRecovery[index+0] = 0x01; /* page code */
7470     RWErrorRecovery[index+1] = 0x0A; /* page length */
7471     RWErrorRecovery[index+2] = 0x40; /* ARRE is set */
7472     RWErrorRecovery[index+3] = 0x00;
7473     RWErrorRecovery[index+4] = 0x00;
7474     RWErrorRecovery[index+5] = 0x00;
7475     RWErrorRecovery[index+6] = 0x00;
7476     RWErrorRecovery[index+7] = 0x00;
7477     RWErrorRecovery[index+8] = 0x00;
7478     RWErrorRecovery[index+9] = 0x00;
7479     RWErrorRecovery[index+10] = 0x00;
7480     RWErrorRecovery[index+11] = 0x00;
7481 
7482     osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
7483   }
7484   else if (page == MODESENSE_CACHING)
7485   {
7486     TI_DBG5(("satModeSense10: MODESENSE_CACHING\n"));
7487     Caching[0] = 0;
7488     Caching[1] = (bit8)(lenRead - 2);
7489     Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7490     Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7491     if (LLBAA)
7492     {
7493       Caching[4] = 0x00; /* reserved and LONGLBA */
7494       Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */
7495     }
7496     else
7497     {
7498       Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7499     }
7500     Caching[5] = 0x00; /* reserved */
7501     Caching[6] = 0x00; /* block descriptot length */
7502     if (LLBAA)
7503     {
7504       Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7505     }
7506     else
7507     {
7508       Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7509     }
7510 
7511     /*
7512      * Fill-up direct-access device block-descriptor, SAT, Table 19
7513      */
7514 
7515     if (LLBAA)
7516     {
7517       /* density code */
7518       Caching[8]   = 0x04; /* density-code : reserved for direct-access */
7519       /* number of blocks */
7520       Caching[9]   = 0x00; /* unspecified */
7521       Caching[10]  = 0x00; /* unspecified */
7522       Caching[11]  = 0x00; /* unspecified */
7523       Caching[12]  = 0x00; /* unspecified */
7524       Caching[13]  = 0x00; /* unspecified */
7525       Caching[14]  = 0x00; /* unspecified */
7526       Caching[15]  = 0x00; /* unspecified */
7527       /* reserved */
7528       Caching[16]  = 0x00; /* reserved */
7529       Caching[17]  = 0x00; /* reserved */
7530       Caching[18]  = 0x00; /* reserved */
7531       Caching[19]  = 0x00; /* reserved */
7532       /* Block size */
7533       Caching[20]  = 0x00;
7534       Caching[21]  = 0x00;
7535       Caching[22]  = 0x02;   /* Block size is always 512 bytes */
7536       Caching[23]  = 0x00;
7537     }
7538     else
7539     {
7540       /* density code */
7541       Caching[8]   = 0x04; /* density-code : reserved for direct-access */
7542       /* number of blocks */
7543       Caching[9]   = 0x00; /* unspecified */
7544       Caching[10]  = 0x00; /* unspecified */
7545       Caching[11]  = 0x00; /* unspecified */
7546       /* reserved */
7547       Caching[12]  = 0x00; /* reserved */
7548       /* Block size */
7549       Caching[13]  = 0x00;
7550       Caching[14]  = 0x02;   /* Block size is always 512 bytes */
7551       Caching[15]  = 0x00;
7552     }
7553 
7554     if (LLBAA)
7555     {
7556       index = 24;
7557     }
7558     else
7559     {
7560       index = 16;
7561     }
7562     /*
7563      * Fill-up Caching mode page, SAT, Table 67
7564      */
7565     /* length 20 */
7566     Caching[index+0] = 0x08; /* page code */
7567     Caching[index+1] = 0x12; /* page length */
7568 #ifdef NOT_YET
7569     if (pSatDevData->satWriteCacheEnabled == agTRUE)
7570     {
7571       Caching[index+2] = 0x04;/* WCE bit is set */
7572     }
7573     else
7574     {
7575       Caching[index+2] = 0x00;/* WCE bit is NOT set */
7576     }
7577 #endif
7578     Caching[index+2] = 0x00;/* WCE bit is NOT set */
7579     Caching[index+3] = 0x00;
7580     Caching[index+4] = 0x00;
7581     Caching[index+5] = 0x00;
7582     Caching[index+6] = 0x00;
7583     Caching[index+7] = 0x00;
7584     Caching[index+8] = 0x00;
7585     Caching[index+9] = 0x00;
7586     Caching[index+10] = 0x00;
7587     Caching[index+11] = 0x00;
7588     if (pSatDevData->satLookAheadEnabled == agTRUE)
7589     {
7590       Caching[index+12] = 0x00;/* DRA bit is NOT set */
7591     }
7592     else
7593     {
7594       Caching[index+12] = 0x20;/* DRA bit is set */
7595     }
7596     Caching[index+13] = 0x00;
7597     Caching[index+14] = 0x00;
7598     Caching[index+15] = 0x00;
7599     Caching[index+16] = 0x00;
7600     Caching[index+17] = 0x00;
7601     Caching[index+18] = 0x00;
7602     Caching[index+19] = 0x00;
7603     osti_memcpy(pModeSense, &Caching, lenRead);
7604 
7605   }
7606   else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
7607   {
7608     TI_DBG5(("satModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
7609     InfoExceptionCtrl[0] = 0;
7610     InfoExceptionCtrl[1] = (bit8)(lenRead - 2);
7611     InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7612     InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7613     if (LLBAA)
7614     {
7615       InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */
7616       InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */
7617     }
7618     else
7619     {
7620       InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7621     }
7622     InfoExceptionCtrl[5] = 0x00; /* reserved */
7623     InfoExceptionCtrl[6] = 0x00; /* block descriptot length */
7624     if (LLBAA)
7625     {
7626       InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7627     }
7628     else
7629     {
7630       InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7631     }
7632 
7633     /*
7634      * Fill-up direct-access device block-descriptor, SAT, Table 19
7635      */
7636 
7637     if (LLBAA)
7638     {
7639       /* density code */
7640       InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
7641       /* number of blocks */
7642       InfoExceptionCtrl[9]   = 0x00; /* unspecified */
7643       InfoExceptionCtrl[10]  = 0x00; /* unspecified */
7644       InfoExceptionCtrl[11]  = 0x00; /* unspecified */
7645       InfoExceptionCtrl[12]  = 0x00; /* unspecified */
7646       InfoExceptionCtrl[13]  = 0x00; /* unspecified */
7647       InfoExceptionCtrl[14]  = 0x00; /* unspecified */
7648       InfoExceptionCtrl[15]  = 0x00; /* unspecified */
7649       /* reserved */
7650       InfoExceptionCtrl[16]  = 0x00; /* reserved */
7651       InfoExceptionCtrl[17]  = 0x00; /* reserved */
7652       InfoExceptionCtrl[18]  = 0x00; /* reserved */
7653       InfoExceptionCtrl[19]  = 0x00; /* reserved */
7654       /* Block size */
7655       InfoExceptionCtrl[20]  = 0x00;
7656       InfoExceptionCtrl[21]  = 0x00;
7657       InfoExceptionCtrl[22]  = 0x02;   /* Block size is always 512 bytes */
7658       InfoExceptionCtrl[23]  = 0x00;
7659     }
7660     else
7661     {
7662       /* density code */
7663       InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
7664       /* number of blocks */
7665       InfoExceptionCtrl[9]   = 0x00; /* unspecified */
7666       InfoExceptionCtrl[10]  = 0x00; /* unspecified */
7667       InfoExceptionCtrl[11]  = 0x00; /* unspecified */
7668       /* reserved */
7669       InfoExceptionCtrl[12]  = 0x00; /* reserved */
7670       /* Block size */
7671       InfoExceptionCtrl[13]  = 0x00;
7672       InfoExceptionCtrl[14]  = 0x02;   /* Block size is always 512 bytes */
7673       InfoExceptionCtrl[15]  = 0x00;
7674     }
7675 
7676     if (LLBAA)
7677     {
7678       index = 24;
7679     }
7680     else
7681     {
7682       index = 16;
7683     }
7684     /*
7685      * Fill-up informational-exceptions control mode page, SAT, Table 68
7686      */
7687     InfoExceptionCtrl[index+0] = 0x1C; /* page code */
7688     InfoExceptionCtrl[index+1] = 0x0A; /* page length */
7689      if (pSatDevData->satSMARTEnabled == agTRUE)
7690     {
7691       InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */
7692     }
7693     else
7694     {
7695       InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */
7696     }
7697     InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */
7698     InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */
7699     InfoExceptionCtrl[index+5] = 0x00;
7700     InfoExceptionCtrl[index+6] = 0x00;
7701     InfoExceptionCtrl[index+7] = 0x00;
7702     InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */
7703     InfoExceptionCtrl[index+9] = 0x00;
7704     InfoExceptionCtrl[index+10] = 0x00;
7705     InfoExceptionCtrl[index+11] = 0x00;
7706     osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
7707 
7708   }
7709   else
7710   {
7711     /* Error */
7712     TI_DBG1(("satModeSense10: Error page %d\n", page));
7713     satSetSensePayload( pSense,
7714                         SCSI_SNSKEY_ILLEGAL_REQUEST,
7715                         0,
7716                         SCSI_SNSCODE_INVALID_COMMAND,
7717                         satIOContext);
7718 
7719     ostiInitiatorIOCompleted( tiRoot,
7720                               tiIORequest,
7721                               tiIOSuccess,
7722                               SCSI_STAT_CHECK_CONDITION,
7723                               satIOContext->pTiSenseData,
7724                               satIOContext->interruptContext );
7725     return tiSuccess;
7726   }
7727 
7728   if (requestLen > lenRead)
7729   {
7730     TI_DBG1(("satModeSense10 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
7731 
7732     ostiInitiatorIOCompleted( tiRoot,
7733                               tiIORequest,
7734                               tiIOUnderRun,
7735                               requestLen - lenRead,
7736                               agNULL,
7737                               satIOContext->interruptContext );
7738 
7739 
7740   }
7741   else
7742   {
7743     ostiInitiatorIOCompleted( tiRoot,
7744                               tiIORequest,
7745                               tiIOSuccess,
7746                               SCSI_STAT_GOOD,
7747                               agNULL,
7748                               satIOContext->interruptContext);
7749   }
7750 
7751   return tiSuccess;
7752 }
7753 
7754 
7755 /*****************************************************************************/
7756 /*! \brief SAT implementation for SCSI VERIFY (10).
7757  *
7758  *  SAT implementation for SCSI VERIFY (10).
7759  *
7760  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
7761  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
7762  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
7763  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
7764  *  \param   satIOContext_t:   Pointer to the SAT IO Context
7765  *
7766  *  \return If command is started successfully
7767  *    - \e tiSuccess:     I/O request successfully initiated.
7768  *    - \e tiBusy:        No resources available, try again later.
7769  *    - \e tiIONoDevice:  Invalid device handle.
7770  *    - \e tiError:       Other errors.
7771  */
7772 /*****************************************************************************/
7773 GLOBAL bit32  satVerify10(
7774                    tiRoot_t                  *tiRoot,
7775                    tiIORequest_t             *tiIORequest,
7776                    tiDeviceHandle_t          *tiDeviceHandle,
7777                    tiScsiInitiatorRequest_t *tiScsiRequest,
7778                    satIOContext_t            *satIOContext)
7779 {
7780   /*
7781     For simple implementation,
7782     no byte comparison supported as of 4/5/06
7783   */
7784   scsiRspSense_t            *pSense;
7785   tiIniScsiCmnd_t           *scsiCmnd;
7786   satDeviceData_t           *pSatDevData;
7787   agsaFisRegHostToDevice_t  *fis;
7788   bit32                     status;
7789   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7790   bit32                     lba = 0;
7791   bit32                     tl = 0;
7792   bit32                     LoopNum = 1;
7793   bit8                      LBA[4];
7794   bit8                      TL[4];
7795   bit32                     rangeChk = agFALSE; /* lba and tl range check */
7796 
7797 
7798   TI_DBG5(("satVerify10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
7799       tiDeviceHandle, tiIORequest));
7800 
7801   pSense            = satIOContext->pSense;
7802   scsiCmnd          = &tiScsiRequest->scsiCmnd;
7803   pSatDevData       = satIOContext->pSatDevData;
7804   fis               = satIOContext->pFis;
7805 
7806   /* checking BYTCHK */
7807   if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
7808   {
7809     /*
7810       should do the byte check
7811       but not supported in this version
7812      */
7813     satSetSensePayload( pSense,
7814                         SCSI_SNSKEY_ILLEGAL_REQUEST,
7815                         0,
7816                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7817                         satIOContext);
7818 
7819     ostiInitiatorIOCompleted( tiRoot,
7820                               tiIORequest,
7821                               tiIOSuccess,
7822                               SCSI_STAT_CHECK_CONDITION,
7823                               satIOContext->pTiSenseData,
7824                               satIOContext->interruptContext );
7825 
7826     TI_DBG1(("satVerify10: no byte checking \n"));
7827     return tiSuccess;
7828   }
7829 
7830   /* checking CONTROL */
7831   /* NACA == 1 or LINK == 1*/
7832   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
7833   {
7834     satSetSensePayload( pSense,
7835                         SCSI_SNSKEY_ILLEGAL_REQUEST,
7836                         0,
7837                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7838                         satIOContext);
7839 
7840     ostiInitiatorIOCompleted( tiRoot,
7841                               tiIORequest,
7842                               tiIOSuccess,
7843                               SCSI_STAT_CHECK_CONDITION,
7844                               satIOContext->pTiSenseData,
7845                               satIOContext->interruptContext );
7846 
7847     TI_DBG2(("satVerify10: return control\n"));
7848     return tiSuccess;
7849   }
7850 
7851   osti_memset(LBA, 0, sizeof(LBA));
7852   osti_memset(TL, 0, sizeof(TL));
7853 
7854   /* do not use memcpy due to indexing in LBA and TL */
7855   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
7856   LBA[1] = scsiCmnd->cdb[3];
7857   LBA[2] = scsiCmnd->cdb[4];
7858   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
7859 
7860   TL[0] = 0;
7861   TL[1] = 0;
7862   TL[2] = scsiCmnd->cdb[7];  /* MSB */
7863   TL[3] = scsiCmnd->cdb[8];  /* LSB */
7864 
7865   rangeChk = satAddNComparebit32(LBA, TL);
7866 
7867   /* cbd10; computing LBA and transfer length */
7868   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
7869     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
7870   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7871 
7872   if (pSatDevData->satNCQ != agTRUE &&
7873       pSatDevData->sat48BitSupport != agTRUE
7874       )
7875   {
7876     if (lba > SAT_TR_LBA_LIMIT - 1)
7877     {
7878       satSetSensePayload( pSense,
7879                           SCSI_SNSKEY_ILLEGAL_REQUEST,
7880                           0,
7881                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7882                           satIOContext);
7883 
7884       ostiInitiatorIOCompleted( tiRoot,
7885                                 tiIORequest,
7886                                 tiIOSuccess,
7887                                 SCSI_STAT_CHECK_CONDITION,
7888                                 satIOContext->pTiSenseData,
7889                                 satIOContext->interruptContext );
7890 
7891     TI_DBG1(("satVerify10: return LBA out of range, not EXT\n"));
7892     TI_DBG1(("satVerify10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
7893              scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
7894     TI_DBG1(("satVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
7895     return tiSuccess;
7896     }
7897 
7898     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
7899     {
7900       TI_DBG1(("satVerify10: return LBA+TL out of range, not EXT\n"));
7901       satSetSensePayload( pSense,
7902                           SCSI_SNSKEY_ILLEGAL_REQUEST,
7903                           0,
7904                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7905                           satIOContext);
7906 
7907       ostiInitiatorIOCompleted( tiRoot,
7908                                 tiIORequest,
7909                                 tiIOSuccess,
7910                                 SCSI_STAT_CHECK_CONDITION,
7911                                 satIOContext->pTiSenseData,
7912                                 satIOContext->interruptContext );
7913 
7914     return tiSuccess;
7915     }
7916   }
7917 
7918   if (pSatDevData->sat48BitSupport == agTRUE)
7919   {
7920     TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS_EXT\n"));
7921     fis->h.fisType        = 0x27;                   /* Reg host to device */
7922     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7923 
7924     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
7925     fis->h.features       = 0;                      /* FIS reserve */
7926     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7927     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7928     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7929     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
7930     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7931     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7932     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7933     fis->d.featuresExp    = 0;                      /* FIS reserve */
7934     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7935     fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
7936 
7937     fis->d.reserved4      = 0;
7938     fis->d.control        = 0;                      /* FIS HOB bit clear */
7939     fis->d.reserved5      = 0;
7940 
7941     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7942     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
7943   }
7944   else
7945   {
7946     TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS\n"));
7947     fis->h.fisType        = 0x27;                   /* Reg host to device */
7948     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7949     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
7950     fis->h.features       = 0;                      /* FIS reserve */
7951     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7952     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7953     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7954       /* FIS LBA mode set LBA (27:24) */
7955     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7956     fis->d.lbaLowExp      = 0;
7957     fis->d.lbaMidExp      = 0;
7958     fis->d.lbaHighExp     = 0;
7959     fis->d.featuresExp    = 0;
7960     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7961     fis->d.sectorCountExp = 0;
7962     fis->d.reserved4      = 0;
7963     fis->d.control        = 0;                      /* FIS HOB bit clear */
7964     fis->d.reserved5      = 0;
7965 
7966     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7967     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
7968 
7969  }
7970 
7971   satIOContext->currentLBA = lba;
7972   satIOContext->OrgTL = tl;
7973 
7974   /*
7975     computing number of loop and remainder for tl
7976     0xFF in case not ext
7977     0xFFFF in case EXT
7978   */
7979   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7980   {
7981     LoopNum = satComputeLoopNum(tl, 0xFF);
7982   }
7983   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
7984   {
7985     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7986     LoopNum = satComputeLoopNum(tl, 0xFFFF);
7987   }
7988   else
7989   {
7990     TI_DBG1(("satVerify10: error case 1!!!\n"));
7991     LoopNum = 1;
7992   }
7993 
7994   satIOContext->LoopNum = LoopNum;
7995 
7996   if (LoopNum == 1)
7997   {
7998     TI_DBG5(("satVerify10: NON CHAINED data\n"));
7999     /* Initialize CB for SATA completion.
8000      */
8001     satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8002   }
8003   else
8004   {
8005     TI_DBG1(("satVerify10: CHAINED data\n"));
8006     /* re-setting tl */
8007     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8008     {
8009        fis->d.sectorCount    = 0xFF;
8010     }
8011     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8012     {
8013       fis->d.sectorCount    = 0xFF;
8014       fis->d.sectorCountExp = 0xFF;
8015     }
8016     else
8017     {
8018       TI_DBG1(("satVerify10: error case 2!!!\n"));
8019     }
8020 
8021     /* Initialize CB for SATA completion.
8022      */
8023     satIOContext->satCompleteCB = &satChainedVerifyCB;
8024   }
8025 
8026 
8027   /*
8028    * Prepare SGL and send FIS to LL layer.
8029    */
8030   satIOContext->reqType = agRequestType;       /* Save it */
8031 
8032   status = sataLLIOStart( tiRoot,
8033                           tiIORequest,
8034                           tiDeviceHandle,
8035                           tiScsiRequest,
8036                           satIOContext);
8037   return (status);
8038 }
8039 
8040 GLOBAL bit32  satChainedVerify(
8041                    tiRoot_t                  *tiRoot,
8042                    tiIORequest_t             *tiIORequest,
8043                    tiDeviceHandle_t          *tiDeviceHandle,
8044                    tiScsiInitiatorRequest_t *tiScsiRequest,
8045                    satIOContext_t            *satIOContext)
8046 {
8047   bit32                     status;
8048   satIOContext_t            *satOrgIOContext = agNULL;
8049   agsaFisRegHostToDevice_t  *fis;
8050   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8051   bit32                     lba = 0;
8052   bit32                     DenomTL = 0xFF;
8053   bit32                     Remainder = 0;
8054   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
8055 
8056   TI_DBG2(("satChainedVerify: start\n"));
8057 
8058   fis             = satIOContext->pFis;
8059   satOrgIOContext = satIOContext->satOrgIOContext;
8060   osti_memset(LBA,0, sizeof(LBA));
8061 
8062   switch (satOrgIOContext->ATACmd)
8063   {
8064   case SAT_READ_VERIFY_SECTORS:
8065     DenomTL = 0xFF;
8066     break;
8067   case SAT_READ_VERIFY_SECTORS_EXT:
8068     DenomTL = 0xFFFF;
8069     break;
8070   default:
8071     TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8072     return tiError;
8073     break;
8074   }
8075 
8076   Remainder = satOrgIOContext->OrgTL % DenomTL;
8077   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
8078   lba = satOrgIOContext->currentLBA;
8079 
8080   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
8081   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
8082   LBA[2] = (bit8)((lba & 0xF0) >> 8);
8083   LBA[3] = (bit8)(lba & 0xF);               /* LSB */
8084 
8085   switch (satOrgIOContext->ATACmd)
8086   {
8087   case SAT_READ_VERIFY_SECTORS:
8088     fis->h.fisType        = 0x27;                   /* Reg host to device */
8089     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8090     fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
8091     fis->h.features       = 0;                      /* FIS reserve */
8092     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
8093     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
8094     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
8095 
8096     /* FIS LBA mode set LBA (27:24) */
8097     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
8098 
8099     fis->d.lbaLowExp      = 0;
8100     fis->d.lbaMidExp      = 0;
8101     fis->d.lbaHighExp     = 0;
8102     fis->d.featuresExp    = 0;
8103     if (satOrgIOContext->LoopNum == 1)
8104     {
8105       /* last loop */
8106       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
8107     }
8108     else
8109     {
8110       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
8111     }
8112     fis->d.sectorCountExp = 0;
8113     fis->d.reserved4      = 0;
8114     fis->d.control        = 0;                      /* FIS HOB bit clear */
8115     fis->d.reserved5      = 0;
8116 
8117     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8118 
8119     break;
8120   case SAT_READ_VERIFY_SECTORS_EXT:
8121     fis->h.fisType        = 0x27;                   /* Reg host to device */
8122     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8123     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
8124     fis->h.features       = 0;                      /* FIS reserve */
8125     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
8126     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
8127     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
8128     fis->d.device         = 0x40;                   /* FIS LBA mode set */
8129     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
8130     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
8131     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
8132     fis->d.featuresExp    = 0;                      /* FIS reserve */
8133     if (satOrgIOContext->LoopNum == 1)
8134     {
8135       /* last loop */
8136       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
8137       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
8138     }
8139     else
8140     {
8141       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
8142       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
8143     }
8144     fis->d.reserved4      = 0;
8145     fis->d.control        = 0;                       /* FIS HOB bit clear */
8146     fis->d.reserved5      = 0;
8147 
8148     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8149 
8150     break;
8151 
8152   default:
8153     TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8154     return tiError;
8155     break;
8156   }
8157 
8158   /* Initialize CB for SATA completion.
8159    */
8160   /* chained data */
8161   satIOContext->satCompleteCB = &satChainedVerifyCB;
8162 
8163 
8164   /*
8165    * Prepare SGL and send FIS to LL layer.
8166    */
8167   satIOContext->reqType = agRequestType;       /* Save it */
8168 
8169   status = sataLLIOStart( tiRoot,
8170                           tiIORequest,
8171                           tiDeviceHandle,
8172                           tiScsiRequest,
8173                           satIOContext);
8174 
8175   TI_DBG5(("satChainedVerify: return\n"));
8176   return (status);
8177 
8178 }
8179 
8180 
8181 /*****************************************************************************/
8182 /*! \brief SAT implementation for SCSI VERIFY (12).
8183  *
8184  *  SAT implementation for SCSI VERIFY (12).
8185  *
8186  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8187  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8188  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8189  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8190  *  \param   satIOContext_t:   Pointer to the SAT IO Context
8191  *
8192  *  \return If command is started successfully
8193  *    - \e tiSuccess:     I/O request successfully initiated.
8194  *    - \e tiBusy:        No resources available, try again later.
8195  *    - \e tiIONoDevice:  Invalid device handle.
8196  *    - \e tiError:       Other errors.
8197  */
8198 /*****************************************************************************/
8199 GLOBAL bit32  satVerify12(
8200                    tiRoot_t                  *tiRoot,
8201                    tiIORequest_t             *tiIORequest,
8202                    tiDeviceHandle_t          *tiDeviceHandle,
8203                    tiScsiInitiatorRequest_t *tiScsiRequest,
8204                    satIOContext_t            *satIOContext)
8205 {
8206   /*
8207     For simple implementation,
8208     no byte comparison supported as of 4/5/06
8209   */
8210   scsiRspSense_t            *pSense;
8211   tiIniScsiCmnd_t           *scsiCmnd;
8212   satDeviceData_t           *pSatDevData;
8213   agsaFisRegHostToDevice_t  *fis;
8214   bit32                     status;
8215   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8216   bit32                     lba = 0;
8217   bit32                     tl = 0;
8218   bit32                     LoopNum = 1;
8219   bit8                      LBA[4];
8220   bit8                      TL[4];
8221   bit32                     rangeChk = agFALSE; /* lba and tl range check */
8222 
8223   TI_DBG5(("satVerify12 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8224            tiDeviceHandle, tiIORequest));
8225 
8226   pSense            = satIOContext->pSense;
8227   scsiCmnd          = &tiScsiRequest->scsiCmnd;
8228   pSatDevData       = satIOContext->pSatDevData;
8229   fis               = satIOContext->pFis;
8230 
8231 
8232   /* checking BYTCHK */
8233   if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8234   {
8235     /*
8236       should do the byte check
8237       but not supported in this version
8238      */
8239     satSetSensePayload( pSense,
8240                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8241                         0,
8242                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8243                         satIOContext);
8244 
8245     ostiInitiatorIOCompleted( tiRoot,
8246                               tiIORequest,
8247                               tiIOSuccess,
8248                               SCSI_STAT_CHECK_CONDITION,
8249                               satIOContext->pTiSenseData,
8250                               satIOContext->interruptContext );
8251 
8252     TI_DBG1(("satVerify12: no byte checking \n"));
8253     return tiSuccess;
8254   }
8255 
8256   /* checking CONTROL */
8257   /* NACA == 1 or LINK == 1*/
8258   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
8259   {
8260     satSetSensePayload( pSense,
8261                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8262                         0,
8263                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8264                         satIOContext);
8265 
8266     ostiInitiatorIOCompleted( tiRoot,
8267                               tiIORequest,
8268                               tiIOSuccess,
8269                               SCSI_STAT_CHECK_CONDITION,
8270                               satIOContext->pTiSenseData,
8271                               satIOContext->interruptContext );
8272 
8273     TI_DBG1(("satVerify12: return control\n"));
8274     return tiSuccess;
8275   }
8276 
8277   osti_memset(LBA, 0, sizeof(LBA));
8278   osti_memset(TL, 0, sizeof(TL));
8279 
8280   /* do not use memcpy due to indexing in LBA and TL */
8281   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
8282   LBA[1] = scsiCmnd->cdb[3];
8283   LBA[2] = scsiCmnd->cdb[4];
8284   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
8285 
8286   TL[0] = scsiCmnd->cdb[6];   /* MSB */
8287   TL[1] = scsiCmnd->cdb[7];
8288   TL[2] = scsiCmnd->cdb[7];
8289   TL[3] = scsiCmnd->cdb[8];   /* LSB */
8290 
8291   rangeChk = satAddNComparebit32(LBA, TL);
8292 
8293   lba = satComputeCDB12LBA(satIOContext);
8294   tl = satComputeCDB12TL(satIOContext);
8295 
8296   if (pSatDevData->satNCQ != agTRUE &&
8297       pSatDevData->sat48BitSupport != agTRUE
8298       )
8299   {
8300     if (lba > SAT_TR_LBA_LIMIT - 1)
8301     {
8302       satSetSensePayload( pSense,
8303                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8304                           0,
8305                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8306                           satIOContext);
8307 
8308       ostiInitiatorIOCompleted( tiRoot,
8309                                 tiIORequest,
8310                                 tiIOSuccess,
8311                                 SCSI_STAT_CHECK_CONDITION,
8312                                 satIOContext->pTiSenseData,
8313                                 satIOContext->interruptContext );
8314 
8315     TI_DBG1(("satVerify12: return LBA out of range, not EXT\n"));
8316     TI_DBG1(("satVerify12: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
8317              scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
8318     TI_DBG1(("satVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
8319     return tiSuccess;
8320     }
8321 
8322     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
8323     {
8324       TI_DBG1(("satVerify12: return LBA+TL out of range, not EXT\n"));
8325       satSetSensePayload( pSense,
8326                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8327                           0,
8328                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8329                           satIOContext);
8330 
8331       ostiInitiatorIOCompleted( tiRoot,
8332                                 tiIORequest,
8333                                 tiIOSuccess,
8334                                 SCSI_STAT_CHECK_CONDITION,
8335                                 satIOContext->pTiSenseData,
8336                                 satIOContext->interruptContext );
8337 
8338     return tiSuccess;
8339     }
8340   }
8341 
8342   if (pSatDevData->sat48BitSupport == agTRUE)
8343   {
8344     TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS_EXT\n"));
8345     fis->h.fisType        = 0x27;                   /* Reg host to device */
8346     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8347 
8348     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8349     fis->h.features       = 0;                      /* FIS reserve */
8350     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8351     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8352     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8353     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8354     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
8355     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
8356     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
8357     fis->d.featuresExp    = 0;                      /* FIS reserve */
8358     fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8359     fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
8360 
8361     fis->d.reserved4      = 0;
8362     fis->d.control        = 0;                      /* FIS HOB bit clear */
8363     fis->d.reserved5      = 0;
8364 
8365     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8366     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8367   }
8368   else
8369   {
8370     TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8371     fis->h.fisType        = 0x27;                   /* Reg host to device */
8372     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8373     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8374     fis->h.features       = 0;                      /* FIS reserve */
8375     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8376     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8377     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8378       /* FIS LBA mode set LBA (27:24) */
8379     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
8380     fis->d.lbaLowExp      = 0;
8381     fis->d.lbaMidExp      = 0;
8382     fis->d.lbaHighExp     = 0;
8383     fis->d.featuresExp    = 0;
8384     fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8385     fis->d.sectorCountExp = 0;
8386     fis->d.reserved4      = 0;
8387     fis->d.control        = 0;                      /* FIS HOB bit clear */
8388     fis->d.reserved5      = 0;
8389 
8390     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8391     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8392 
8393  }
8394 
8395   satIOContext->currentLBA = lba;
8396   satIOContext->OrgTL = tl;
8397 
8398   /*
8399     computing number of loop and remainder for tl
8400     0xFF in case not ext
8401     0xFFFF in case EXT
8402   */
8403   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8404   {
8405     LoopNum = satComputeLoopNum(tl, 0xFF);
8406   }
8407   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8408   {
8409     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8410     LoopNum = satComputeLoopNum(tl, 0xFFFF);
8411   }
8412   else
8413   {
8414     TI_DBG1(("satVerify12: error case 1!!!\n"));
8415     LoopNum = 1;
8416   }
8417 
8418   satIOContext->LoopNum = LoopNum;
8419 
8420   if (LoopNum == 1)
8421   {
8422     TI_DBG5(("satVerify12: NON CHAINED data\n"));
8423     /* Initialize CB for SATA completion.
8424      */
8425     satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8426   }
8427   else
8428   {
8429     TI_DBG1(("satVerify12: CHAINED data\n"));
8430     /* re-setting tl */
8431     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8432     {
8433        fis->d.sectorCount    = 0xFF;
8434     }
8435     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8436     {
8437       fis->d.sectorCount    = 0xFF;
8438       fis->d.sectorCountExp = 0xFF;
8439     }
8440     else
8441     {
8442       TI_DBG1(("satVerify10: error case 2!!!\n"));
8443     }
8444 
8445     /* Initialize CB for SATA completion.
8446      */
8447     satIOContext->satCompleteCB = &satChainedVerifyCB;
8448   }
8449 
8450 
8451   /*
8452    * Prepare SGL and send FIS to LL layer.
8453    */
8454   satIOContext->reqType = agRequestType;       /* Save it */
8455 
8456   status = sataLLIOStart( tiRoot,
8457                           tiIORequest,
8458                           tiDeviceHandle,
8459                           tiScsiRequest,
8460                           satIOContext);
8461   return (status);
8462 }
8463 /*****************************************************************************/
8464 /*! \brief SAT implementation for SCSI VERIFY (16).
8465  *
8466  *  SAT implementation for SCSI VERIFY (16).
8467  *
8468  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8469  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8470  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8471  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8472  *  \param   satIOContext_t:   Pointer to the SAT IO Context
8473  *
8474  *  \return If command is started successfully
8475  *    - \e tiSuccess:     I/O request successfully initiated.
8476  *    - \e tiBusy:        No resources available, try again later.
8477  *    - \e tiIONoDevice:  Invalid device handle.
8478  *    - \e tiError:       Other errors.
8479  */
8480 /*****************************************************************************/
8481 GLOBAL bit32  satVerify16(
8482                    tiRoot_t                  *tiRoot,
8483                    tiIORequest_t             *tiIORequest,
8484                    tiDeviceHandle_t          *tiDeviceHandle,
8485                    tiScsiInitiatorRequest_t *tiScsiRequest,
8486                    satIOContext_t            *satIOContext)
8487 {
8488   /*
8489     For simple implementation,
8490     no byte comparison supported as of 4/5/06
8491   */
8492   scsiRspSense_t            *pSense;
8493   tiIniScsiCmnd_t           *scsiCmnd;
8494   satDeviceData_t           *pSatDevData;
8495   agsaFisRegHostToDevice_t  *fis;
8496   bit32                     status;
8497   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8498   bit32                     lba = 0;
8499   bit32                     tl = 0;
8500   bit32                     LoopNum = 1;
8501   bit8                      LBA[8];
8502   bit8                      TL[8];
8503   bit32                     rangeChk = agFALSE; /* lba and tl range check */
8504   bit32                     limitChk = agFALSE; /* lba and tl range check */
8505 
8506   TI_DBG5(("satVerify16 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8507       tiDeviceHandle, tiIORequest));
8508 
8509   pSense            = satIOContext->pSense;
8510   scsiCmnd          = &tiScsiRequest->scsiCmnd;
8511   pSatDevData       = satIOContext->pSatDevData;
8512   fis               = satIOContext->pFis;
8513 
8514   /* checking BYTCHK */
8515   if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8516   {
8517     /*
8518       should do the byte check
8519       but not supported in this version
8520      */
8521     satSetSensePayload( pSense,
8522                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8523                         0,
8524                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8525                         satIOContext);
8526 
8527     ostiInitiatorIOCompleted( tiRoot,
8528                               tiIORequest,
8529                               tiIOSuccess,
8530                               SCSI_STAT_CHECK_CONDITION,
8531                               satIOContext->pTiSenseData,
8532                               satIOContext->interruptContext );
8533 
8534     TI_DBG1(("satVerify16: no byte checking \n"));
8535     return tiSuccess;
8536   }
8537 
8538   /* checking CONTROL */
8539   /* NACA == 1 or LINK == 1*/
8540   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
8541   {
8542     satSetSensePayload( pSense,
8543                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8544                         0,
8545                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8546                         satIOContext);
8547 
8548     ostiInitiatorIOCompleted( tiRoot,
8549                               tiIORequest,
8550                               tiIOSuccess,
8551                               SCSI_STAT_CHECK_CONDITION,
8552                               satIOContext->pTiSenseData,
8553                               satIOContext->interruptContext );
8554 
8555     TI_DBG2(("satVerify16: return control\n"));
8556     return tiSuccess;
8557   }
8558 
8559   osti_memset(LBA, 0, sizeof(LBA));
8560   osti_memset(TL, 0, sizeof(TL));
8561 
8562 
8563   /* do not use memcpy due to indexing in LBA and TL */
8564   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
8565   LBA[1] = scsiCmnd->cdb[3];
8566   LBA[2] = scsiCmnd->cdb[4];
8567   LBA[3] = scsiCmnd->cdb[5];
8568   LBA[4] = scsiCmnd->cdb[6];
8569   LBA[5] = scsiCmnd->cdb[7];
8570   LBA[6] = scsiCmnd->cdb[8];
8571   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
8572 
8573   TL[0] = 0;
8574   TL[1] = 0;
8575   TL[2] = 0;
8576   TL[3] = 0;
8577   TL[4] = scsiCmnd->cdb[10];   /* MSB */
8578   TL[5] = scsiCmnd->cdb[11];
8579   TL[6] = scsiCmnd->cdb[12];
8580   TL[7] = scsiCmnd->cdb[13];   /* LSB */
8581 
8582   rangeChk = satAddNComparebit64(LBA, TL);
8583 
8584   limitChk = satCompareLBALimitbit(LBA);
8585 
8586   lba = satComputeCDB16LBA(satIOContext);
8587   tl = satComputeCDB16TL(satIOContext);
8588 
8589   if (pSatDevData->satNCQ != agTRUE &&
8590      pSatDevData->sat48BitSupport != agTRUE
8591      )
8592   {
8593     if (limitChk)
8594     {
8595       TI_DBG1(("satVerify16: return LBA out of range, not EXT\n"));
8596       satSetSensePayload( pSense,
8597                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8598                           0,
8599                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8600                           satIOContext);
8601 
8602       ostiInitiatorIOCompleted( tiRoot,
8603                                 tiIORequest,
8604                                 tiIOSuccess,
8605                                 SCSI_STAT_CHECK_CONDITION,
8606                                 satIOContext->pTiSenseData,
8607                                 satIOContext->interruptContext );
8608 
8609     return tiSuccess;
8610     }
8611     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
8612     {
8613       TI_DBG1(("satVerify16: return LBA+TL out of range, not EXT\n"));
8614       satSetSensePayload( pSense,
8615                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8616                           0,
8617                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8618                           satIOContext);
8619 
8620       ostiInitiatorIOCompleted( tiRoot,
8621                                 tiIORequest,
8622                                 tiIOSuccess,
8623                                 SCSI_STAT_CHECK_CONDITION,
8624                                 satIOContext->pTiSenseData,
8625                                 satIOContext->interruptContext );
8626 
8627     return tiSuccess;
8628     }
8629   }
8630 
8631   if (pSatDevData->sat48BitSupport == agTRUE)
8632   {
8633     TI_DBG5(("satVerify16: SAT_READ_VERIFY_SECTORS_EXT\n"));
8634     fis->h.fisType        = 0x27;                   /* Reg host to device */
8635     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8636 
8637     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8638     fis->h.features       = 0;                      /* FIS reserve */
8639     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8640     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8641     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8642     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8643     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
8644     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
8645     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
8646     fis->d.featuresExp    = 0;                      /* FIS reserve */
8647     fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8648     fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
8649 
8650     fis->d.reserved4      = 0;
8651     fis->d.control        = 0;                      /* FIS HOB bit clear */
8652     fis->d.reserved5      = 0;
8653 
8654     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8655     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8656   }
8657   else
8658   {
8659     TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8660     fis->h.fisType        = 0x27;                   /* Reg host to device */
8661     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8662     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8663     fis->h.features       = 0;                      /* FIS reserve */
8664     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8665     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8666     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8667       /* FIS LBA mode set LBA (27:24) */
8668     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
8669     fis->d.lbaLowExp      = 0;
8670     fis->d.lbaMidExp      = 0;
8671     fis->d.lbaHighExp     = 0;
8672     fis->d.featuresExp    = 0;
8673     fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8674     fis->d.sectorCountExp = 0;
8675     fis->d.reserved4      = 0;
8676     fis->d.control        = 0;                      /* FIS HOB bit clear */
8677     fis->d.reserved5      = 0;
8678 
8679     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8680     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8681 
8682  }
8683 
8684   satIOContext->currentLBA = lba;
8685   satIOContext->OrgTL = tl;
8686 
8687   /*
8688     computing number of loop and remainder for tl
8689     0xFF in case not ext
8690     0xFFFF in case EXT
8691   */
8692   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8693   {
8694     LoopNum = satComputeLoopNum(tl, 0xFF);
8695   }
8696   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8697   {
8698     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8699     LoopNum = satComputeLoopNum(tl, 0xFFFF);
8700   }
8701   else
8702   {
8703     TI_DBG1(("satVerify12: error case 1!!!\n"));
8704     LoopNum = 1;
8705   }
8706 
8707   satIOContext->LoopNum = LoopNum;
8708 
8709   if (LoopNum == 1)
8710   {
8711     TI_DBG5(("satVerify12: NON CHAINED data\n"));
8712     /* Initialize CB for SATA completion.
8713      */
8714     satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8715   }
8716   else
8717   {
8718     TI_DBG1(("satVerify12: CHAINED data\n"));
8719     /* re-setting tl */
8720     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8721     {
8722        fis->d.sectorCount    = 0xFF;
8723     }
8724     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8725     {
8726       fis->d.sectorCount    = 0xFF;
8727       fis->d.sectorCountExp = 0xFF;
8728     }
8729     else
8730     {
8731       TI_DBG1(("satVerify10: error case 2!!!\n"));
8732     }
8733 
8734     /* Initialize CB for SATA completion.
8735      */
8736     satIOContext->satCompleteCB = &satChainedVerifyCB;
8737   }
8738 
8739 
8740   /*
8741    * Prepare SGL and send FIS to LL layer.
8742    */
8743   satIOContext->reqType = agRequestType;       /* Save it */
8744 
8745   status = sataLLIOStart( tiRoot,
8746                           tiIORequest,
8747                           tiDeviceHandle,
8748                           tiScsiRequest,
8749                           satIOContext);
8750   return (status);
8751 }
8752 /*****************************************************************************/
8753 /*! \brief SAT implementation for SCSI satFormatUnit.
8754  *
8755  *  SAT implementation for SCSI satFormatUnit.
8756  *
8757  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8758  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8759  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8760  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8761  *  \param   satIOContext_t:   Pointer to the SAT IO Context
8762  *
8763  *  \return If command is started successfully
8764  *    - \e tiSuccess:     I/O request successfully initiated.
8765  *    - \e tiBusy:        No resources available, try again later.
8766  *    - \e tiIONoDevice:  Invalid device handle.
8767  *    - \e tiError:       Other errors.
8768  */
8769 /*****************************************************************************/
8770 GLOBAL bit32  satFormatUnit(
8771                    tiRoot_t                  *tiRoot,
8772                    tiIORequest_t             *tiIORequest,
8773                    tiDeviceHandle_t          *tiDeviceHandle,
8774                    tiScsiInitiatorRequest_t *tiScsiRequest,
8775                    satIOContext_t            *satIOContext)
8776 {
8777   /*
8778     note: we don't support media certification in this version and IP bit
8779     satDevData->satFormatState will be agFalse since SAT does not actually sends
8780     any ATA command
8781    */
8782 
8783   scsiRspSense_t          *pSense;
8784   tiIniScsiCmnd_t         *scsiCmnd;
8785   bit32                    index = 0;
8786 
8787   pSense        = satIOContext->pSense;
8788   scsiCmnd      = &tiScsiRequest->scsiCmnd;
8789 
8790   TI_DBG5(("satFormatUnit:start\n"));
8791 
8792   /*
8793     checking opcode
8794     1. FMTDATA bit == 0(no defect list header)
8795     2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided
8796     with DCRT bit set)
8797   */
8798   if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) ||
8799        ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8800         (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK))
8801        )
8802   {
8803     ostiInitiatorIOCompleted( tiRoot,
8804                               tiIORequest,
8805                               tiIOSuccess,
8806                               SCSI_STAT_GOOD,
8807                               agNULL,
8808                               satIOContext->interruptContext);
8809 
8810     TI_DBG2(("satFormatUnit: return opcode\n"));
8811     return tiSuccess;
8812   }
8813 
8814   /*
8815     checking DEFECT LIST FORMAT and defect list length
8816   */
8817   if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) ||
8818         ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) )
8819   {
8820     /* short parameter header */
8821     if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00)
8822     {
8823       index = 8;
8824     }
8825     /* long parameter header */
8826     if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01)
8827     {
8828       index = 10;
8829     }
8830     /* defect list length */
8831     if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0))
8832     {
8833       satSetSensePayload( pSense,
8834                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8835                           0,
8836                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8837                           satIOContext);
8838 
8839       ostiInitiatorIOCompleted( tiRoot,
8840                                 tiIORequest,
8841                                 tiIOSuccess,
8842                                 SCSI_STAT_CHECK_CONDITION,
8843                                 satIOContext->pTiSenseData,
8844                                 satIOContext->interruptContext );
8845 
8846       TI_DBG1(("satFormatUnit: return defect list format\n"));
8847       return tiSuccess;
8848     }
8849   }
8850 
8851    /* FMTDATA == 1 && CMPLIST == 1*/
8852   if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8853        (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
8854   {
8855     satSetSensePayload( pSense,
8856                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8857                         0,
8858                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8859                         satIOContext);
8860 
8861     ostiInitiatorIOCompleted( tiRoot,
8862                               tiIORequest,
8863                               tiIOSuccess,
8864                               SCSI_STAT_CHECK_CONDITION,
8865                               satIOContext->pTiSenseData,
8866                               satIOContext->interruptContext );
8867 
8868     TI_DBG1(("satFormatUnit: return cmplist\n"));
8869     return tiSuccess;
8870 
8871   }
8872 
8873  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8874   {
8875     satSetSensePayload( pSense,
8876                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8877                         0,
8878                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8879                         satIOContext);
8880 
8881     ostiInitiatorIOCompleted( tiRoot,
8882                               tiIORequest,
8883                               tiIOSuccess,
8884                               SCSI_STAT_CHECK_CONDITION,
8885                               satIOContext->pTiSenseData,
8886                               satIOContext->interruptContext );
8887 
8888     TI_DBG1(("satFormatUnit: return control\n"));
8889     return tiSuccess;
8890   }
8891 
8892   /* defect list header filed, if exists, SAT rev8, Table 37, p48 */
8893   if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK)
8894   {
8895     /* case 1,2,3 */
8896     /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */
8897     if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) ||
8898          ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) ||
8899          ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8900            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8901            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK))
8902          )
8903     {
8904       ostiInitiatorIOCompleted( tiRoot,
8905                                 tiIORequest,
8906                                 tiIOSuccess,
8907                                 SCSI_STAT_GOOD,
8908                                 agNULL,
8909                                 satIOContext->interruptContext);
8910 
8911       TI_DBG5(("satFormatUnit: return defect list case 1\n"));
8912       return tiSuccess;
8913     }
8914     /* case 4,5,6 */
8915     /*
8916         1. IMMED 0, FOV 1, DCRT 0, IP 0
8917         2. IMMED 0, FOV 1, DCRT 0, IP 1
8918         3. IMMED 0, FOV 1, DCRT 1, IP 1
8919       */
8920 
8921     if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8922             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8923            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8924            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8925          ||
8926          ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8927             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8928            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8929             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8930          ||
8931          ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8932             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8933             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8934             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8935          )
8936     {
8937 
8938       satSetSensePayload( pSense,
8939                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8940                           0,
8941                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
8942                           satIOContext);
8943 
8944       ostiInitiatorIOCompleted( tiRoot,
8945                                 tiIORequest,
8946                                 tiIOSuccess,
8947                                 SCSI_STAT_CHECK_CONDITION,
8948                                 satIOContext->pTiSenseData,
8949                                 satIOContext->interruptContext );
8950 
8951       TI_DBG5(("satFormatUnit: return defect list case 2\n"));
8952       return tiSuccess;
8953 
8954     }
8955   }
8956 
8957 
8958   /*
8959    * Send the completion response now.
8960    */
8961   ostiInitiatorIOCompleted( tiRoot,
8962                             tiIORequest,
8963                             tiIOSuccess,
8964                             SCSI_STAT_GOOD,
8965                             agNULL,
8966                             satIOContext->interruptContext);
8967 
8968   TI_DBG5(("satFormatUnit: return last\n"));
8969   return tiSuccess;
8970 }
8971 
8972 
8973 /*****************************************************************************/
8974 /*! \brief SAT implementation for SCSI satSendDiagnostic.
8975  *
8976  *  SAT implementation for SCSI satSendDiagnostic.
8977  *
8978  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8979  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8980  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8981  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8982  *  \param   satIOContext_t:   Pointer to the SAT IO Context
8983  *
8984  *  \return If command is started successfully
8985  *    - \e tiSuccess:     I/O request successfully initiated.
8986  *    - \e tiBusy:        No resources available, try again later.
8987  *    - \e tiIONoDevice:  Invalid device handle.
8988  *    - \e tiError:       Other errors.
8989  */
8990 /*****************************************************************************/
8991 GLOBAL bit32  satSendDiagnostic(
8992                    tiRoot_t                  *tiRoot,
8993                    tiIORequest_t             *tiIORequest,
8994                    tiDeviceHandle_t          *tiDeviceHandle,
8995                    tiScsiInitiatorRequest_t *tiScsiRequest,
8996                    satIOContext_t            *satIOContext)
8997 {
8998   bit32                     status;
8999   bit32                     agRequestType;
9000   satDeviceData_t           *pSatDevData;
9001   scsiRspSense_t            *pSense;
9002   tiIniScsiCmnd_t           *scsiCmnd;
9003   agsaFisRegHostToDevice_t  *fis;
9004   bit32                     parmLen;
9005 
9006   pSense        = satIOContext->pSense;
9007   pSatDevData   = satIOContext->pSatDevData;
9008   scsiCmnd      = &tiScsiRequest->scsiCmnd;
9009   fis           = satIOContext->pFis;
9010 
9011   TI_DBG5(("satSendDiagnostic:start\n"));
9012 
9013   /* reset satVerifyState */
9014   pSatDevData->satVerifyState = 0;
9015   /* no pending diagnostic in background */
9016   pSatDevData->satBGPendingDiag = agFALSE;
9017 
9018   /* table 27, 8.10 p39 SAT Rev8 */
9019   /*
9020     1. checking PF == 1
9021     2. checking DEVOFFL == 1
9022     3. checking UNITOFFL == 1
9023     4. checking PARAMETER LIST LENGTH != 0
9024 
9025   */
9026   if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) ||
9027        (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) ||
9028        (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) ||
9029        ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) )
9030        )
9031   {
9032     satSetSensePayload( pSense,
9033                         SCSI_SNSKEY_ILLEGAL_REQUEST,
9034                         0,
9035                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9036                         satIOContext);
9037 
9038     ostiInitiatorIOCompleted( tiRoot,
9039                               tiIORequest,
9040                               tiIOSuccess,
9041                               SCSI_STAT_CHECK_CONDITION,
9042                               satIOContext->pTiSenseData,
9043                               satIOContext->interruptContext );
9044 
9045     TI_DBG1(("satSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST\n"));
9046     return tiSuccess;
9047   }
9048 
9049   /* checking CONTROL */
9050   /* NACA == 1 or LINK == 1*/
9051   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9052   {
9053     satSetSensePayload( pSense,
9054                         SCSI_SNSKEY_ILLEGAL_REQUEST,
9055                         0,
9056                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9057                         satIOContext);
9058 
9059     ostiInitiatorIOCompleted( tiRoot,
9060                               tiIORequest,
9061                               tiIOSuccess,
9062                               SCSI_STAT_CHECK_CONDITION,
9063                               satIOContext->pTiSenseData,
9064                               satIOContext->interruptContext );
9065 
9066     TI_DBG2(("satSendDiagnostic: return control\n"));
9067     return tiSuccess;
9068   }
9069 
9070   parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
9071 
9072   /* checking SELFTEST bit*/
9073   /* table 29, 8.10.3, p41 SAT Rev8 */
9074   /* case 1 */
9075   if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9076        (pSatDevData->satSMARTSelfTest == agFALSE)
9077        )
9078   {
9079     satSetSensePayload( pSense,
9080                         SCSI_SNSKEY_ILLEGAL_REQUEST,
9081                         0,
9082                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9083                         satIOContext);
9084 
9085     ostiInitiatorIOCompleted( tiRoot,
9086                               tiIORequest,
9087                               tiIOSuccess,
9088                               SCSI_STAT_CHECK_CONDITION,
9089                               satIOContext->pTiSenseData,
9090                               satIOContext->interruptContext );
9091 
9092     TI_DBG1(("satSendDiagnostic: return Table 29 case 1\n"));
9093     return tiSuccess;
9094   }
9095 
9096   /* case 2 */
9097   if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9098        (pSatDevData->satSMARTSelfTest == agTRUE) &&
9099        (pSatDevData->satSMARTEnabled == agFALSE)
9100        )
9101   {
9102     satSetSensePayload( pSense,
9103                         SCSI_SNSKEY_ABORTED_COMMAND,
9104                         0,
9105                         SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
9106                         satIOContext);
9107 
9108     ostiInitiatorIOCompleted( tiRoot,
9109                               tiIORequest,
9110                               tiIOSuccess,
9111                               SCSI_STAT_CHECK_CONDITION,
9112                               satIOContext->pTiSenseData,
9113                               satIOContext->interruptContext );
9114 
9115     TI_DBG5(("satSendDiagnostic: return Table 29 case 2\n"));
9116     return tiSuccess;
9117   }
9118   /*
9119     case 3
9120      see SELF TEST CODE later
9121   */
9122 
9123 
9124 
9125   /* case 4 */
9126 
9127   /*
9128     sends three ATA verify commands
9129 
9130   */
9131   if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9132         (pSatDevData->satSMARTSelfTest == agFALSE))
9133        ||
9134        ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9135         (pSatDevData->satSMARTSelfTest == agTRUE) &&
9136         (pSatDevData->satSMARTEnabled == agFALSE))
9137        )
9138   {
9139     /*
9140       sector count 1, LBA 0
9141       sector count 1, LBA MAX
9142       sector count 1, LBA random
9143     */
9144     if (pSatDevData->sat48BitSupport == agTRUE)
9145     {
9146       /* sends READ VERIFY SECTOR(S) EXT*/
9147       fis->h.fisType        = 0x27;                   /* Reg host to device */
9148       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9149       fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9150       fis->h.features       = 0;                      /* FIS reserve */
9151       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9152       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9153       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9154       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9155       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9156       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9157       fis->d.featuresExp    = 0;                      /* FIS reserve */
9158       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9159       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9160       fis->d.reserved4      = 0;
9161       fis->d.device         = 0x40;                   /* 01000000 */
9162       fis->d.control        = 0;                      /* FIS HOB bit clear */
9163       fis->d.reserved5      = 0;
9164 
9165       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9166     }
9167     else
9168     {
9169       /* READ VERIFY SECTOR(S)*/
9170       fis->h.fisType        = 0x27;                   /* Reg host to device */
9171       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9172       fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9173       fis->h.features       = 0;                      /* FIS features NA       */
9174       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9175       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9176       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9177       fis->d.lbaLowExp      = 0;
9178       fis->d.lbaMidExp      = 0;
9179       fis->d.lbaHighExp     = 0;
9180       fis->d.featuresExp    = 0;
9181       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9182       fis->d.sectorCountExp = 0;
9183       fis->d.reserved4      = 0;
9184       fis->d.device         = 0x40;                   /* 01000000 */
9185       fis->d.control        = 0;                      /* FIS HOB bit clear */
9186       fis->d.reserved5      = 0;
9187 
9188       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9189     }
9190 
9191     /* Initialize CB for SATA completion.
9192      */
9193     satIOContext->satCompleteCB = &satSendDiagnosticCB;
9194 
9195     /*
9196      * Prepare SGL and send FIS to LL layer.
9197      */
9198     satIOContext->reqType = agRequestType;       /* Save it */
9199 
9200     status = sataLLIOStart( tiRoot,
9201                             tiIORequest,
9202                             tiDeviceHandle,
9203                             tiScsiRequest,
9204                             satIOContext);
9205 
9206 
9207     TI_DBG5(("satSendDiagnostic: return Table 29 case 4\n"));
9208     return (status);
9209   }
9210   /* case 5 */
9211   if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9212        (pSatDevData->satSMARTSelfTest == agTRUE) &&
9213        (pSatDevData->satSMARTEnabled == agTRUE)
9214        )
9215   {
9216     /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9217     fis->h.fisType        = 0x27;                   /* Reg host to device */
9218     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9219     fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0xB0 */
9220     fis->h.features       = 0xD4;                      /* FIS features NA       */
9221     fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
9222     fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9223     fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9224     fis->d.lbaLowExp      = 0;
9225     fis->d.lbaMidExp      = 0;
9226     fis->d.lbaHighExp     = 0;
9227     fis->d.featuresExp    = 0;
9228     fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9229     fis->d.sectorCountExp = 0;
9230     fis->d.reserved4      = 0;
9231     fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9232     fis->d.control        = 0;                         /* FIS HOB bit clear */
9233     fis->d.reserved5      = 0;
9234 
9235     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9236 
9237     /* Initialize CB for SATA completion.
9238      */
9239     satIOContext->satCompleteCB = &satSendDiagnosticCB;
9240 
9241     /*
9242      * Prepare SGL and send FIS to LL layer.
9243      */
9244     satIOContext->reqType = agRequestType;       /* Save it */
9245 
9246     status = sataLLIOStart( tiRoot,
9247                             tiIORequest,
9248                             tiDeviceHandle,
9249                             tiScsiRequest,
9250                             satIOContext);
9251 
9252 
9253     TI_DBG5(("satSendDiagnostic: return Table 29 case 5\n"));
9254     return (status);
9255   }
9256 
9257 
9258 
9259 
9260   /* SAT rev8 Table29 p41 case 3*/
9261   /* checking SELF TEST CODE*/
9262   if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9263        (pSatDevData->satSMARTSelfTest == agTRUE) &&
9264        (pSatDevData->satSMARTEnabled == agTRUE)
9265        )
9266   {
9267     /* SAT rev8 Table28 p40 */
9268     /* finding self-test code */
9269     switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5)
9270     {
9271     case 1:
9272       pSatDevData->satBGPendingDiag = agTRUE;
9273 
9274       ostiInitiatorIOCompleted( tiRoot,
9275                                 tiIORequest,
9276                                 tiIOSuccess,
9277                                 SCSI_STAT_GOOD,
9278                                 agNULL,
9279                                 satIOContext->interruptContext );
9280       /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9281       fis->h.fisType        = 0x27;                   /* Reg host to device */
9282       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9283       fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9284       fis->h.features       = 0xD4;                      /* FIS features NA       */
9285       fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
9286       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9287       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9288 
9289       fis->d.lbaLowExp      = 0;
9290       fis->d.lbaMidExp      = 0;
9291       fis->d.lbaHighExp     = 0;
9292       fis->d.featuresExp    = 0;
9293       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9294       fis->d.sectorCountExp = 0;
9295       fis->d.reserved4      = 0;
9296       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9297       fis->d.control        = 0;                         /* FIS HOB bit clear */
9298       fis->d.reserved5      = 0;
9299 
9300       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9301 
9302       /* Initialize CB for SATA completion.
9303        */
9304       satIOContext->satCompleteCB = &satSendDiagnosticCB;
9305 
9306       /*
9307        * Prepare SGL and send FIS to LL layer.
9308        */
9309       satIOContext->reqType = agRequestType;       /* Save it */
9310 
9311       status = sataLLIOStart( tiRoot,
9312                               tiIORequest,
9313                               tiDeviceHandle,
9314                               tiScsiRequest,
9315                               satIOContext);
9316 
9317 
9318       TI_DBG5(("satSendDiagnostic: return Table 28 case 1\n"));
9319       return (status);
9320     case 2:
9321       pSatDevData->satBGPendingDiag = agTRUE;
9322 
9323       ostiInitiatorIOCompleted( tiRoot,
9324                                 tiIORequest,
9325                                 tiIOSuccess,
9326                                 SCSI_STAT_GOOD,
9327                                 agNULL,
9328                                 satIOContext->interruptContext );
9329 
9330 
9331       /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9332       fis->h.fisType        = 0x27;                   /* Reg host to device */
9333       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9334       fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9335       fis->h.features       = 0xD4;                      /* FIS features NA       */
9336       fis->d.lbaLow         = 0x02;                      /* FIS LBA (7 :0 ) */
9337       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9338       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9339       fis->d.lbaLowExp      = 0;
9340       fis->d.lbaMidExp      = 0;
9341       fis->d.lbaHighExp     = 0;
9342       fis->d.featuresExp    = 0;
9343       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9344       fis->d.sectorCountExp = 0;
9345       fis->d.reserved4      = 0;
9346       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9347       fis->d.control        = 0;                         /* FIS HOB bit clear */
9348       fis->d.reserved5      = 0;
9349 
9350       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9351 
9352       /* Initialize CB for SATA completion.
9353        */
9354       satIOContext->satCompleteCB = &satSendDiagnosticCB;
9355 
9356       /*
9357        * Prepare SGL and send FIS to LL layer.
9358        */
9359       satIOContext->reqType = agRequestType;       /* Save it */
9360 
9361       status = sataLLIOStart( tiRoot,
9362                               tiIORequest,
9363                               tiDeviceHandle,
9364                               tiScsiRequest,
9365                               satIOContext);
9366 
9367 
9368       TI_DBG5(("satSendDiagnostic: return Table 28 case 2\n"));
9369       return (status);
9370     case 4:
9371       /* For simplicity, no abort is supported
9372          Returns good status
9373          need a flag in device data for previously sent background Send Diagnostic
9374       */
9375       if (parmLen != 0)
9376       {
9377         /* check condition */
9378         satSetSensePayload( pSense,
9379                             SCSI_SNSKEY_ILLEGAL_REQUEST,
9380                             0,
9381                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9382                             satIOContext);
9383 
9384         ostiInitiatorIOCompleted( tiRoot,
9385                                   tiIORequest,
9386                                   tiIOSuccess,
9387                                   SCSI_STAT_CHECK_CONDITION,
9388                                   satIOContext->pTiSenseData,
9389                                   satIOContext->interruptContext );
9390 
9391         TI_DBG1(("satSendDiagnostic: case 4, non zero ParmLen %d\n", parmLen));
9392         return tiSuccess;
9393       }
9394       if (pSatDevData->satBGPendingDiag == agTRUE)
9395       {
9396         /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */
9397         fis->h.fisType        = 0x27;                   /* Reg host to device */
9398         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9399         fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9400         fis->h.features       = 0xD4;                      /* FIS features NA       */
9401         fis->d.lbaLow         = 0x7F;                      /* FIS LBA (7 :0 ) */
9402         fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9403         fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9404 
9405         fis->d.lbaLowExp      = 0;
9406         fis->d.lbaMidExp      = 0;
9407         fis->d.lbaHighExp     = 0;
9408         fis->d.featuresExp    = 0;
9409         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9410         fis->d.sectorCountExp = 0;
9411         fis->d.reserved4      = 0;
9412         fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9413         fis->d.control        = 0;                         /* FIS HOB bit clear */
9414         fis->d.reserved5      = 0;
9415 
9416         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9417 
9418         /* Initialize CB for SATA completion.
9419          */
9420         satIOContext->satCompleteCB = &satSendDiagnosticCB;
9421 
9422         /*
9423          * Prepare SGL and send FIS to LL layer.
9424          */
9425         satIOContext->reqType = agRequestType;       /* Save it */
9426 
9427         status = sataLLIOStart( tiRoot,
9428                                 tiIORequest,
9429                                 tiDeviceHandle,
9430                                 tiScsiRequest,
9431                                 satIOContext);
9432 
9433 
9434         TI_DBG5(("satSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
9435         TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9436         return (status);
9437       }
9438       else
9439       {
9440         /* check condition */
9441         satSetSensePayload( pSense,
9442                             SCSI_SNSKEY_ILLEGAL_REQUEST,
9443                             0,
9444                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9445                             satIOContext);
9446 
9447         ostiInitiatorIOCompleted( tiRoot,
9448                                   tiIORequest,
9449                                   tiIOSuccess,
9450                                   SCSI_STAT_CHECK_CONDITION,
9451                                   satIOContext->pTiSenseData,
9452                                   satIOContext->interruptContext );
9453 
9454         TI_DBG1(("satSendDiagnostic: case 4, no pending diagnostic in background\n"));
9455         TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9456         return tiSuccess;
9457       }
9458       break;
9459     case 5:
9460       /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9461       fis->h.fisType        = 0x27;                   /* Reg host to device */
9462       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9463       fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9464       fis->h.features       = 0xD4;                      /* FIS features NA       */
9465       fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
9466       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9467       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9468       fis->d.lbaLowExp      = 0;
9469       fis->d.lbaMidExp      = 0;
9470       fis->d.lbaHighExp     = 0;
9471       fis->d.featuresExp    = 0;
9472       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9473       fis->d.sectorCountExp = 0;
9474       fis->d.reserved4      = 0;
9475       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9476       fis->d.control        = 0;                         /* FIS HOB bit clear */
9477       fis->d.reserved5      = 0;
9478 
9479       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9480 
9481       /* Initialize CB for SATA completion.
9482        */
9483       satIOContext->satCompleteCB = &satSendDiagnosticCB;
9484 
9485       /*
9486        * Prepare SGL and send FIS to LL layer.
9487        */
9488       satIOContext->reqType = agRequestType;       /* Save it */
9489 
9490       status = sataLLIOStart( tiRoot,
9491                               tiIORequest,
9492                               tiDeviceHandle,
9493                               tiScsiRequest,
9494                               satIOContext);
9495 
9496 
9497       TI_DBG5(("satSendDiagnostic: return Table 28 case 5\n"));
9498       return (status);
9499     case 6:
9500       /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9501       fis->h.fisType        = 0x27;                   /* Reg host to device */
9502       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9503       fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9504       fis->h.features       = 0xD4;                      /* FIS features NA       */
9505       fis->d.lbaLow         = 0x82;                      /* FIS LBA (7 :0 ) */
9506       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9507       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9508       fis->d.lbaLowExp      = 0;
9509       fis->d.lbaMidExp      = 0;
9510       fis->d.lbaHighExp     = 0;
9511       fis->d.featuresExp    = 0;
9512       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9513       fis->d.sectorCountExp = 0;
9514       fis->d.reserved4      = 0;
9515       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9516       fis->d.control        = 0;                         /* FIS HOB bit clear */
9517       fis->d.reserved5      = 0;
9518 
9519       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9520 
9521       /* Initialize CB for SATA completion.
9522        */
9523       satIOContext->satCompleteCB = &satSendDiagnosticCB;
9524 
9525       /*
9526        * Prepare SGL and send FIS to LL layer.
9527        */
9528       satIOContext->reqType = agRequestType;       /* Save it */
9529 
9530       status = sataLLIOStart( tiRoot,
9531                               tiIORequest,
9532                               tiDeviceHandle,
9533                               tiScsiRequest,
9534                               satIOContext);
9535 
9536 
9537       TI_DBG5(("satSendDiagnostic: return Table 28 case 6\n"));
9538       return (status);
9539     case 0:
9540     case 3: /* fall through */
9541     case 7: /* fall through */
9542     default:
9543       break;
9544     }/* switch */
9545 
9546     /* returns the results of default self-testing, which is good */
9547     ostiInitiatorIOCompleted( tiRoot,
9548                               tiIORequest,
9549                               tiIOSuccess,
9550                               SCSI_STAT_GOOD,
9551                               agNULL,
9552                               satIOContext->interruptContext );
9553 
9554     TI_DBG5(("satSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
9555     return tiSuccess;
9556   }
9557 
9558 
9559   ostiInitiatorIOCompleted( tiRoot,
9560                             tiIORequest,
9561                             tiIOSuccess,
9562                             SCSI_STAT_GOOD,
9563                             agNULL,
9564                             satIOContext->interruptContext );
9565 
9566 
9567   TI_DBG5(("satSendDiagnostic: return last\n"));
9568   return tiSuccess;
9569 }
9570 
9571 /*****************************************************************************/
9572 /*! \brief SAT implementation for SCSI satSendDiagnostic_1.
9573  *
9574  *  SAT implementation for SCSI satSendDiagnostic_1.
9575  *  Sub function of satSendDiagnostic.
9576  *
9577  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
9578  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
9579  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
9580  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
9581  *  \param   satIOContext_t:   Pointer to the SAT IO Context
9582  *
9583  *  \return If command is started successfully
9584  *    - \e tiSuccess:     I/O request successfully initiated.
9585  *    - \e tiBusy:        No resources available, try again later.
9586  *    - \e tiIONoDevice:  Invalid device handle.
9587  *    - \e tiError:       Other errors.
9588  */
9589 /*****************************************************************************/
9590 GLOBAL bit32  satSendDiagnostic_1(
9591                    tiRoot_t                  *tiRoot,
9592                    tiIORequest_t             *tiIORequest,
9593                    tiDeviceHandle_t          *tiDeviceHandle,
9594                    tiScsiInitiatorRequest_t *tiScsiRequest,
9595                    satIOContext_t            *satIOContext)
9596 {
9597   /*
9598     SAT Rev9, Table29, p41
9599     send 2nd SAT_READ_VERIFY_SECTORS(_EXT)
9600   */
9601   bit32                     status;
9602   bit32                     agRequestType;
9603   satDeviceData_t           *pSatDevData;
9604   agsaFisRegHostToDevice_t  *fis;
9605 
9606   TI_DBG5(("satSendDiagnostic_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9607       tiDeviceHandle, tiIORequest));
9608 
9609   pSatDevData       = satIOContext->pSatDevData;
9610   fis               = satIOContext->pFis;
9611 
9612   /*
9613     sector count 1, LBA MAX
9614   */
9615   if (pSatDevData->sat48BitSupport == agTRUE)
9616   {
9617     /* sends READ VERIFY SECTOR(S) EXT*/
9618     fis->h.fisType        = 0x27;                   /* Reg host to device */
9619     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9620     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9621     fis->h.features       = 0;                      /* FIS reserve */
9622     fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9623     fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9624     fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9625     fis->d.lbaLowExp      = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */
9626     fis->d.lbaMidExp      = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */
9627     fis->d.lbaHighExp     = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */
9628     fis->d.featuresExp    = 0;                      /* FIS reserve */
9629     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9630     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9631     fis->d.reserved4      = 0;
9632     fis->d.device         = 0x40;                   /* 01000000 */
9633     fis->d.control        = 0;                      /* FIS HOB bit clear */
9634     fis->d.reserved5      = 0;
9635 
9636   }
9637   else
9638   {
9639     /* READ VERIFY SECTOR(S)*/
9640     fis->h.fisType        = 0x27;                   /* Reg host to device */
9641     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9642     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9643     fis->h.features       = 0;                      /* FIS features NA       */
9644     fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9645     fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9646     fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9647     fis->d.lbaLowExp      = 0;
9648     fis->d.lbaMidExp      = 0;
9649     fis->d.lbaHighExp     = 0;
9650     fis->d.featuresExp    = 0;
9651     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9652     fis->d.sectorCountExp = 0;
9653     fis->d.reserved4      = 0;
9654     fis->d.device         = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF));
9655                             /* DEV and LBA 27:24 */
9656     fis->d.control        = 0;                      /* FIS HOB bit clear */
9657     fis->d.reserved5      = 0;
9658 
9659   }
9660 
9661   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9662 
9663   /* Initialize CB for SATA completion.
9664    */
9665   satIOContext->satCompleteCB = &satSendDiagnosticCB;
9666 
9667   /*
9668    * Prepare SGL and send FIS to LL layer.
9669    */
9670   satIOContext->reqType = agRequestType;       /* Save it */
9671 
9672   status = sataLLIOStart( tiRoot,
9673                           tiIORequest,
9674                           tiDeviceHandle,
9675                           tiScsiRequest,
9676                           satIOContext);
9677 
9678 
9679   return status;
9680 }
9681 
9682 /*****************************************************************************/
9683 /*! \brief SAT implementation for SCSI satSendDiagnostic_2.
9684  *
9685  *  SAT implementation for SCSI satSendDiagnostic_2.
9686  *  Sub function of satSendDiagnostic.
9687  *
9688  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
9689  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
9690  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
9691  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
9692  *  \param   satIOContext_t:   Pointer to the SAT IO Context
9693  *
9694  *  \return If command is started successfully
9695  *    - \e tiSuccess:     I/O request successfully initiated.
9696  *    - \e tiBusy:        No resources available, try again later.
9697  *    - \e tiIONoDevice:  Invalid device handle.
9698  *    - \e tiError:       Other errors.
9699  */
9700 /*****************************************************************************/
9701 GLOBAL bit32  satSendDiagnostic_2(
9702                    tiRoot_t                  *tiRoot,
9703                    tiIORequest_t             *tiIORequest,
9704                    tiDeviceHandle_t          *tiDeviceHandle,
9705                    tiScsiInitiatorRequest_t *tiScsiRequest,
9706                    satIOContext_t            *satIOContext)
9707 {
9708   /*
9709     SAT Rev9, Table29, p41
9710     send 3rd SAT_READ_VERIFY_SECTORS(_EXT)
9711   */
9712   bit32                     status;
9713   bit32                     agRequestType;
9714   satDeviceData_t           *pSatDevData;
9715   agsaFisRegHostToDevice_t  *fis;
9716 
9717   TI_DBG5(("satSendDiagnostic_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9718       tiDeviceHandle, tiIORequest));
9719 
9720   pSatDevData       = satIOContext->pSatDevData;
9721   fis               = satIOContext->pFis;
9722 
9723   /*
9724     sector count 1, LBA Random
9725   */
9726   if (pSatDevData->sat48BitSupport == agTRUE)
9727   {
9728     /* sends READ VERIFY SECTOR(S) EXT*/
9729     fis->h.fisType        = 0x27;                   /* Reg host to device */
9730     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9731     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9732     fis->h.features       = 0;                      /* FIS reserve */
9733     fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
9734     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9735     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9736     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9737     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9738     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9739     fis->d.featuresExp    = 0;                      /* FIS reserve */
9740     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9741     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9742     fis->d.reserved4      = 0;
9743     fis->d.device         = 0x40;                   /* 01000000 */
9744     fis->d.control        = 0;                      /* FIS HOB bit clear */
9745     fis->d.reserved5      = 0;
9746 
9747   }
9748   else
9749   {
9750     /* READ VERIFY SECTOR(S)*/
9751     fis->h.fisType        = 0x27;                   /* Reg host to device */
9752     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9753     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9754     fis->h.features       = 0;                      /* FIS features NA       */
9755     fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
9756     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9757     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9758     fis->d.lbaLowExp      = 0;
9759     fis->d.lbaMidExp      = 0;
9760     fis->d.lbaHighExp     = 0;
9761     fis->d.featuresExp    = 0;
9762     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9763     fis->d.sectorCountExp = 0;
9764     fis->d.reserved4      = 0;
9765     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
9766     fis->d.control        = 0;                      /* FIS HOB bit clear */
9767     fis->d.reserved5      = 0;
9768 
9769   }
9770 
9771   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9772 
9773   /* Initialize CB for SATA completion.
9774    */
9775   satIOContext->satCompleteCB = &satSendDiagnosticCB;
9776 
9777   /*
9778    * Prepare SGL and send FIS to LL layer.
9779    */
9780   satIOContext->reqType = agRequestType;       /* Save it */
9781 
9782   status = sataLLIOStart( tiRoot,
9783                           tiIORequest,
9784                           tiDeviceHandle,
9785                           tiScsiRequest,
9786                           satIOContext);
9787 
9788 
9789   return status;
9790 }
9791 /*****************************************************************************/
9792 /*! \brief SAT implementation for SCSI satStartStopUnit.
9793  *
9794  *  SAT implementation for SCSI satStartStopUnit.
9795  *
9796  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
9797  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
9798  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
9799  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
9800  *  \param   satIOContext_t:   Pointer to the SAT IO Context
9801  *
9802  *  \return If command is started successfully
9803  *    - \e tiSuccess:     I/O request successfully initiated.
9804  *    - \e tiBusy:        No resources available, try again later.
9805  *    - \e tiIONoDevice:  Invalid device handle.
9806  *    - \e tiError:       Other errors.
9807  */
9808 /*****************************************************************************/
9809 GLOBAL bit32  satStartStopUnit(
9810                    tiRoot_t                  *tiRoot,
9811                    tiIORequest_t             *tiIORequest,
9812                    tiDeviceHandle_t          *tiDeviceHandle,
9813                    tiScsiInitiatorRequest_t *tiScsiRequest,
9814                    satIOContext_t            *satIOContext)
9815 {
9816   bit32                     status;
9817   bit32                     agRequestType;
9818   satDeviceData_t           *pSatDevData;
9819   scsiRspSense_t            *pSense;
9820   tiIniScsiCmnd_t           *scsiCmnd;
9821   agsaFisRegHostToDevice_t  *fis;
9822 
9823   pSense        = satIOContext->pSense;
9824   pSatDevData   = satIOContext->pSatDevData;
9825   scsiCmnd      = &tiScsiRequest->scsiCmnd;
9826   fis           = satIOContext->pFis;
9827 
9828   TI_DBG5(("satStartStopUnit:start\n"));
9829 
9830   /* checking CONTROL */
9831   /* NACA == 1 or LINK == 1*/
9832   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9833   {
9834     satSetSensePayload( pSense,
9835                         SCSI_SNSKEY_ILLEGAL_REQUEST,
9836                         0,
9837                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9838                         satIOContext);
9839 
9840     ostiInitiatorIOCompleted( tiRoot,
9841                               tiIORequest,
9842                               tiIOSuccess,
9843                               SCSI_STAT_CHECK_CONDITION,
9844                               satIOContext->pTiSenseData,
9845                               satIOContext->interruptContext );
9846 
9847     TI_DBG1(("satStartStopUnit: return control\n"));
9848     return tiSuccess;
9849   }
9850 
9851   /* Spec p55, Table 48 checking START and LOEJ bit */
9852   /* case 1 */
9853   if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9854   {
9855     if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9856     {
9857       /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9858       ostiInitiatorIOCompleted( tiRoot,
9859                                 tiIORequest,
9860                                 tiIOSuccess,
9861                                 SCSI_STAT_GOOD,
9862                                 agNULL,
9863                                 satIOContext->interruptContext );
9864       TI_DBG5(("satStartStopUnit: return table48 case 1-1\n"));
9865       return tiSuccess;
9866     }
9867     /* sends FLUSH CACHE or FLUSH CACHE EXT */
9868     if (pSatDevData->sat48BitSupport == agTRUE)
9869     {
9870       /* FLUSH CACHE EXT */
9871       fis->h.fisType        = 0x27;                   /* Reg host to device */
9872       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9873 
9874       fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
9875       fis->h.features       = 0;                      /* FIS reserve */
9876       fis->d.featuresExp    = 0;                      /* FIS reserve */
9877       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9878       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9879       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9880       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9881       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9882       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9883       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9884       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9885       fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
9886       fis->d.control        = 0;                      /* FIS HOB bit clear */
9887       fis->d.reserved4      = 0;
9888       fis->d.reserved5      = 0;
9889 
9890       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9891     }
9892     else
9893     {
9894       /* FLUSH CACHE */
9895       fis->h.fisType        = 0x27;                   /* Reg host to device */
9896       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9897 
9898       fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
9899       fis->h.features       = 0;                      /* FIS features NA       */
9900       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9901       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9902       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9903       fis->d.lbaLowExp      = 0;
9904       fis->d.lbaMidExp      = 0;
9905       fis->d.lbaHighExp     = 0;
9906       fis->d.featuresExp    = 0;
9907       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9908       fis->d.sectorCountExp = 0;
9909       fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
9910       fis->d.control        = 0;                      /* FIS HOB bit clear */
9911       fis->d.reserved4      = 0;
9912       fis->d.reserved5      = 0;
9913 
9914       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9915     }
9916 
9917     /* Initialize CB for SATA completion.
9918      */
9919     satIOContext->satCompleteCB = &satStartStopUnitCB;
9920 
9921     /*
9922      * Prepare SGL and send FIS to LL layer.
9923      */
9924     satIOContext->reqType = agRequestType;       /* Save it */
9925 
9926     status = sataLLIOStart( tiRoot,
9927                             tiIORequest,
9928                             tiDeviceHandle,
9929                             tiScsiRequest,
9930                             satIOContext);
9931 
9932 
9933     TI_DBG5(("satStartStopUnit: return table48 case 1\n"));
9934     return (status);
9935   }
9936   /* case 2 */
9937   else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9938   {
9939     /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9940     if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9941     {
9942       ostiInitiatorIOCompleted( tiRoot,
9943                                 tiIORequest,
9944                                 tiIOSuccess,
9945                                 SCSI_STAT_GOOD,
9946                                 agNULL,
9947                                 satIOContext->interruptContext );
9948 
9949       TI_DBG5(("satStartStopUnit: return table48 case 2 1\n"));
9950       return tiSuccess;
9951     }
9952     /*
9953       sends READ_VERIFY_SECTORS(_EXT)
9954       sector count 1, any LBA between zero to Maximum
9955     */
9956     if (pSatDevData->sat48BitSupport == agTRUE)
9957     {
9958       /* READ VERIFY SECTOR(S) EXT*/
9959       fis->h.fisType        = 0x27;                   /* Reg host to device */
9960       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9961 
9962       fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9963       fis->h.features       = 0;                      /* FIS reserve */
9964       fis->d.lbaLow         = 0x01;                   /* FIS LBA (7 :0 ) */
9965       fis->d.lbaMid         = 0x00;                   /* FIS LBA (15:8 ) */
9966       fis->d.lbaHigh        = 0x00;                   /* FIS LBA (23:16) */
9967       fis->d.lbaLowExp      = 0x00;                   /* FIS LBA (31:24) */
9968       fis->d.lbaMidExp      = 0x00;                   /* FIS LBA (39:32) */
9969       fis->d.lbaHighExp     = 0x00;                   /* FIS LBA (47:40) */
9970       fis->d.featuresExp    = 0;                      /* FIS reserve */
9971       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9972       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9973       fis->d.reserved4      = 0;
9974       fis->d.device         = 0x40;                   /* 01000000 */
9975       fis->d.control        = 0;                      /* FIS HOB bit clear */
9976       fis->d.reserved5      = 0;
9977 
9978     }
9979     else
9980     {
9981       /* READ VERIFY SECTOR(S)*/
9982       fis->h.fisType        = 0x27;                   /* Reg host to device */
9983       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9984 
9985       fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9986       fis->h.features       = 0;                      /* FIS features NA       */
9987       fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
9988       fis->d.lbaMid         = 0x00;                      /* FIS LBA (15:8 ) */
9989       fis->d.lbaHigh        = 0x00;                      /* FIS LBA (23:16) */
9990       fis->d.lbaLowExp      = 0;
9991       fis->d.lbaMidExp      = 0;
9992       fis->d.lbaHighExp     = 0;
9993       fis->d.featuresExp    = 0;
9994       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9995       fis->d.sectorCountExp = 0;
9996       fis->d.reserved4      = 0;
9997       fis->d.device         = 0x40;                   /* 01000000 */
9998       fis->d.control        = 0;                      /* FIS HOB bit clear */
9999       fis->d.reserved5      = 0;
10000 
10001     }
10002 
10003     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10004 
10005     /* Initialize CB for SATA completion.
10006      */
10007     satIOContext->satCompleteCB = &satStartStopUnitCB;
10008 
10009     /*
10010      * Prepare SGL and send FIS to LL layer.
10011      */
10012     satIOContext->reqType = agRequestType;       /* Save it */
10013 
10014     status = sataLLIOStart( tiRoot,
10015                             tiIORequest,
10016                             tiDeviceHandle,
10017                             tiScsiRequest,
10018                             satIOContext);
10019 
10020     TI_DBG5(("satStartStopUnit: return table48 case 2 2\n"));
10021     return status;
10022   }
10023   /* case 3 */
10024   else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
10025   {
10026     if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
10027     {
10028       /* support for removal media */
10029       /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
10030       if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
10031       {
10032         ostiInitiatorIOCompleted( tiRoot,
10033                                   tiIORequest,
10034                                   tiIOSuccess,
10035                                   SCSI_STAT_GOOD,
10036                                   agNULL,
10037                                   satIOContext->interruptContext );
10038 
10039         TI_DBG5(("satStartStopUnit: return table48 case 3 1\n"));
10040         return tiSuccess;
10041       }
10042       /*
10043         sends MEDIA EJECT
10044       */
10045       /* Media Eject fis */
10046       fis->h.fisType        = 0x27;                   /* Reg host to device */
10047       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10048 
10049       fis->h.command        = SAT_MEDIA_EJECT;        /* 0xED */
10050       fis->h.features       = 0;                      /* FIS features NA       */
10051       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
10052       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
10053       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
10054       fis->d.lbaLowExp      = 0;
10055       fis->d.lbaMidExp      = 0;
10056       fis->d.lbaHighExp     = 0;
10057       fis->d.featuresExp    = 0;
10058       /* sector count zero */
10059       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
10060       fis->d.sectorCountExp = 0;
10061       fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
10062       fis->d.control        = 0;                      /* FIS HOB bit clear */
10063       fis->d.reserved4      = 0;
10064       fis->d.reserved5      = 0;
10065 
10066       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10067 
10068       /* Initialize CB for SATA completion.
10069        */
10070       satIOContext->satCompleteCB = &satStartStopUnitCB;
10071 
10072       /*
10073        * Prepare SGL and send FIS to LL layer.
10074        */
10075       satIOContext->reqType = agRequestType;       /* Save it */
10076 
10077       status = sataLLIOStart( tiRoot,
10078                               tiIORequest,
10079                               tiDeviceHandle,
10080                               tiScsiRequest,
10081                               satIOContext);
10082 
10083       return status;
10084     }
10085     else
10086     {
10087       /* no support for removal media */
10088       satSetSensePayload( pSense,
10089                           SCSI_SNSKEY_ILLEGAL_REQUEST,
10090                           0,
10091                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10092                           satIOContext);
10093 
10094       ostiInitiatorIOCompleted( tiRoot,
10095                                 tiIORequest,
10096                                 tiIOSuccess,
10097                                 SCSI_STAT_CHECK_CONDITION,
10098                                 satIOContext->pTiSenseData,
10099                                 satIOContext->interruptContext );
10100 
10101       TI_DBG5(("satStartStopUnit: return Table 29 case 3 2\n"));
10102       return tiSuccess;
10103     }
10104 
10105   }
10106   /* case 4 */
10107   else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */
10108   {
10109     satSetSensePayload( pSense,
10110                         SCSI_SNSKEY_ILLEGAL_REQUEST,
10111                         0,
10112                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10113                         satIOContext);
10114 
10115     ostiInitiatorIOCompleted( tiRoot,
10116                               tiIORequest,
10117                               tiIOSuccess,
10118                               SCSI_STAT_CHECK_CONDITION,
10119                               satIOContext->pTiSenseData,
10120                               satIOContext->interruptContext );
10121 
10122     TI_DBG5(("satStartStopUnit: return Table 29 case 4\n"));
10123     return tiSuccess;
10124   }
10125 
10126 
10127 }
10128 
10129 
10130 /*****************************************************************************/
10131 /*! \brief SAT implementation for SCSI satStartStopUnit_1.
10132  *
10133  *  SAT implementation for SCSI satStartStopUnit_1.
10134  *  Sub function of satStartStopUnit
10135  *
10136  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10137  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10138  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10139  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10140  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10141  *
10142  *  \return If command is started successfully
10143  *    - \e tiSuccess:     I/O request successfully initiated.
10144  *    - \e tiBusy:        No resources available, try again later.
10145  *    - \e tiIONoDevice:  Invalid device handle.
10146  *    - \e tiError:       Other errors.
10147  */
10148 /*****************************************************************************/
10149 GLOBAL bit32  satStartStopUnit_1(
10150                    tiRoot_t                  *tiRoot,
10151                    tiIORequest_t             *tiIORequest,
10152                    tiDeviceHandle_t          *tiDeviceHandle,
10153                    tiScsiInitiatorRequest_t *tiScsiRequest,
10154                    satIOContext_t            *satIOContext)
10155 {
10156   /*
10157     SAT Rev 8, Table 48, 9.11.3 p55
10158     sends STANDBY
10159   */
10160   bit32                     status;
10161   bit32                     agRequestType;
10162   agsaFisRegHostToDevice_t  *fis;
10163 
10164   TI_DBG5(("satStartStopUnit_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10165       tiDeviceHandle, tiIORequest));
10166 
10167   fis               = satIOContext->pFis;
10168 
10169   /* STANDBY */
10170   fis->h.fisType        = 0x27;                   /* Reg host to device */
10171   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10172 
10173   fis->h.command        = SAT_STANDBY;            /* 0xE2 */
10174   fis->h.features       = 0;                      /* FIS features NA       */
10175   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
10176   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
10177   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
10178   fis->d.lbaLowExp      = 0;
10179   fis->d.lbaMidExp      = 0;
10180   fis->d.lbaHighExp     = 0;
10181   fis->d.featuresExp    = 0;
10182   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
10183   fis->d.sectorCountExp = 0;
10184   fis->d.reserved4      = 0;
10185   fis->d.device         = 0;                      /* 0 */
10186   fis->d.control        = 0;                      /* FIS HOB bit clear */
10187   fis->d.reserved5      = 0;
10188 
10189   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10190 
10191   /* Initialize CB for SATA completion.
10192    */
10193   satIOContext->satCompleteCB = &satStartStopUnitCB;
10194 
10195   /*
10196    * Prepare SGL and send FIS to LL layer.
10197    */
10198   satIOContext->reqType = agRequestType;       /* Save it */
10199 
10200   status = sataLLIOStart( tiRoot,
10201                           tiIORequest,
10202                           tiDeviceHandle,
10203                           tiScsiRequest,
10204                           satIOContext);
10205 
10206   TI_DBG5(("satStartStopUnit_1 return status %d\n", status));
10207   return status;
10208 }
10209 
10210 /*****************************************************************************/
10211 /*! \brief SAT implementation for SCSI satRead10_2.
10212  *
10213  *  SAT implementation for SCSI satRead10_2
10214  *  Sub function of satRead10
10215  *
10216  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10217  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10218  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10219  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10220  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10221  *
10222  *  \return If command is started successfully
10223  *    - \e tiSuccess:     I/O request successfully initiated.
10224  *    - \e tiBusy:        No resources available, try again later.
10225  *    - \e tiIONoDevice:  Invalid device handle.
10226  *    - \e tiError:       Other errors.
10227  */
10228 /*****************************************************************************/
10229 GLOBAL bit32  satRead10_2(
10230                           tiRoot_t                  *tiRoot,
10231                           tiIORequest_t             *tiIORequest,
10232                           tiDeviceHandle_t          *tiDeviceHandle,
10233                           tiScsiInitiatorRequest_t *tiScsiRequest,
10234                           satIOContext_t            *satIOContext)
10235 {
10236   /*
10237     externally generated ATA cmd, there is corresponding scsi cmnd
10238     called by satStartStopUnit() or maybe satRead10()
10239    */
10240 
10241   bit32                     status;
10242   bit32                     agRequestType;
10243   satDeviceData_t           *pSatDevData;
10244   agsaFisRegHostToDevice_t  *fis;
10245 
10246   pSatDevData   = satIOContext->pSatDevData;
10247   fis           = satIOContext->pFis;
10248 
10249   TI_DBG5(("satReadVerifySectorsNoChain: start\n"));
10250 
10251   /* specifying ReadVerifySectors has no chain */
10252   pSatDevData->satVerifyState = 0xFFFFFFFF;
10253 
10254   if (pSatDevData->sat48BitSupport == agTRUE)
10255   {
10256     /* READ VERIFY SECTOR(S) EXT*/
10257     fis->h.fisType        = 0x27;                   /* Reg host to device */
10258     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10259     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
10260     fis->h.features       = 0;                      /* FIS reserve */
10261     fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
10262     fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
10263     fis->d.lbaHigh        = 0x00;                   /* FIS LBA (23:16) */
10264     fis->d.lbaLowExp      = 0xF1;                   /* FIS LBA (31:24) */
10265     fis->d.lbaMidExp      = 0x5F;                   /* FIS LBA (39:32) */
10266     fis->d.lbaHighExp     = 0xFF;                   /* FIS LBA (47:40) */
10267     fis->d.featuresExp    = 0;                      /* FIS reserve */
10268     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10269     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10270     fis->d.reserved4      = 0;
10271     fis->d.device         = 0x4E;                   /* 01001110 */
10272     fis->d.control        = 0;                      /* FIS HOB bit clear */
10273     fis->d.reserved5      = 0;
10274 
10275     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10276   }
10277   else
10278   {
10279     /* READ VERIFY SECTOR(S)*/
10280     fis->h.fisType        = 0x27;                   /* Reg host to device */
10281     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10282     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
10283     fis->h.features       = 0;                      /* FIS features NA       */
10284     fis->d.lbaLow         = 0x7F;                      /* FIS LBA (7 :0 ) */
10285     fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
10286     fis->d.lbaHigh        = 0x00;                      /* FIS LBA (23:16) */
10287     fis->d.lbaLowExp      = 0;
10288     fis->d.lbaMidExp      = 0;
10289     fis->d.lbaHighExp     = 0;
10290     fis->d.featuresExp    = 0;
10291     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10292     fis->d.sectorCountExp = 0;
10293     fis->d.reserved4      = 0;
10294     fis->d.device         = 0x4E;                   /* 01001110 */
10295     fis->d.control        = 0;                      /* FIS HOB bit clear */
10296     fis->d.reserved5      = 0;
10297 
10298     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10299   }
10300 
10301   /* Initialize CB for SATA completion.
10302    */
10303   satIOContext->satCompleteCB = &satNonDataIOCB;
10304 
10305   /*
10306    * Prepare SGL and send FIS to LL layer.
10307    */
10308   satIOContext->reqType = agRequestType;       /* Save it */
10309 
10310   status = sataLLIOStart( tiRoot,
10311                           tiIORequest,
10312                           tiDeviceHandle,
10313                           tiScsiRequest,
10314                           satIOContext);
10315 
10316   TI_DBG5(("satReadVerifySectorsNoChain: return last\n"));
10317 
10318   return status;
10319 }
10320 
10321 
10322 /*****************************************************************************/
10323 /*! \brief SAT implementation for SCSI satWriteSame10.
10324  *
10325  *  SAT implementation for SCSI satWriteSame10.
10326  *
10327  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10328  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10329  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10330  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10331  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10332  *
10333  *  \return If command is started successfully
10334  *    - \e tiSuccess:     I/O request successfully initiated.
10335  *    - \e tiBusy:        No resources available, try again later.
10336  *    - \e tiIONoDevice:  Invalid device handle.
10337  *    - \e tiError:       Other errors.
10338  */
10339 /*****************************************************************************/
10340 GLOBAL bit32  satWriteSame10(
10341                    tiRoot_t                  *tiRoot,
10342                    tiIORequest_t             *tiIORequest,
10343                    tiDeviceHandle_t          *tiDeviceHandle,
10344                    tiScsiInitiatorRequest_t *tiScsiRequest,
10345                    satIOContext_t            *satIOContext)
10346 {
10347   bit32                     status;
10348   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10349   satDeviceData_t           *pSatDevData;
10350   scsiRspSense_t            *pSense;
10351   tiIniScsiCmnd_t           *scsiCmnd;
10352   agsaFisRegHostToDevice_t  *fis;
10353   bit32                     lba = 0;
10354   bit32                     tl = 0;
10355 
10356   pSense        = satIOContext->pSense;
10357   pSatDevData   = satIOContext->pSatDevData;
10358   scsiCmnd      = &tiScsiRequest->scsiCmnd;
10359   fis           = satIOContext->pFis;
10360 
10361   TI_DBG5(("satWriteSame10: start\n"));
10362 
10363   /* checking CONTROL */
10364     /* NACA == 1 or LINK == 1*/
10365   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
10366   {
10367     satSetSensePayload( pSense,
10368                         SCSI_SNSKEY_ILLEGAL_REQUEST,
10369                         0,
10370                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10371                         satIOContext);
10372 
10373     ostiInitiatorIOCompleted( tiRoot,
10374                               tiIORequest,
10375                               tiIOSuccess,
10376                               SCSI_STAT_CHECK_CONDITION,
10377                               satIOContext->pTiSenseData,
10378                               satIOContext->interruptContext );
10379 
10380     TI_DBG1(("satWriteSame10: return control\n"));
10381     return tiSuccess;
10382   }
10383 
10384 
10385   /* checking LBDATA and PBDATA */
10386   /* case 1 */
10387   if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10388        !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10389   {
10390     TI_DBG5(("satWriteSame10: case 1\n"));
10391     /* spec 9.26.2, Table 62, p64, case 1*/
10392     /*
10393       normal case
10394       just like write in 9.17.1
10395     */
10396 
10397     if ( pSatDevData->sat48BitSupport != agTRUE )
10398     {
10399       /*
10400         writeSame10 but no support for 48 bit addressing
10401         -> problem in transfer length. Therefore, return check condition
10402       */
10403       satSetSensePayload( pSense,
10404                           SCSI_SNSKEY_ILLEGAL_REQUEST,
10405                           0,
10406                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10407                           satIOContext);
10408 
10409       ostiInitiatorIOCompleted( tiRoot,
10410                                 tiIORequest,
10411                                 tiIOSuccess,
10412                                 SCSI_STAT_CHECK_CONDITION,
10413                                 satIOContext->pTiSenseData,
10414                                 satIOContext->interruptContext );
10415 
10416       TI_DBG1(("satWriteSame10: return internal checking\n"));
10417       return tiSuccess;
10418     }
10419 
10420     /* cdb10; computing LBA and transfer length */
10421     lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
10422       + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
10423     tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
10424 
10425 
10426     /* Table 34, 9.1, p 46 */
10427     /*
10428       note: As of 2/10/2006, no support for DMA QUEUED
10429     */
10430 
10431     /*
10432       Table 34, 9.1, p 46, b (footnote)
10433       When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
10434       return check condition
10435     */
10436     if (pSatDevData->satNCQ != agTRUE &&
10437         pSatDevData->sat48BitSupport != agTRUE
10438           )
10439     {
10440       if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */
10441       {
10442         satSetSensePayload( pSense,
10443                             SCSI_SNSKEY_ILLEGAL_REQUEST,
10444                             0,
10445                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
10446                             satIOContext);
10447 
10448         ostiInitiatorIOCompleted( tiRoot,
10449                                   tiIORequest,
10450                                   tiIOSuccess,
10451                                   SCSI_STAT_CHECK_CONDITION,
10452                                   satIOContext->pTiSenseData,
10453                                   satIOContext->interruptContext );
10454 
10455         TI_DBG1(("satWriteSame10: return LBA out of range\n"));
10456           return tiSuccess;
10457       }
10458     }
10459 
10460     if (lba + tl <= SAT_TR_LBA_LIMIT)
10461     {
10462       if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10463       {
10464         /* case 2 */
10465         /* WRITE DMA */
10466         /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10467         TI_DBG5(("satWriteSame10: case 1-2 !!! error due to writeSame10\n"));
10468         satSetSensePayload( pSense,
10469                             SCSI_SNSKEY_ILLEGAL_REQUEST,
10470                             0,
10471                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10472                             satIOContext);
10473 
10474         ostiInitiatorIOCompleted( tiRoot,
10475                                   tiIORequest,
10476                                   tiIOSuccess,
10477                                   SCSI_STAT_CHECK_CONDITION,
10478                                   satIOContext->pTiSenseData,
10479                                   satIOContext->interruptContext );
10480         return tiSuccess;
10481       }
10482       else
10483       {
10484         /* case 1 */
10485         /* WRITE MULTIPLE or WRITE SECTOR(S) */
10486         /* WRITE SECTORS is chosen for easier implemetation */
10487         /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10488         TI_DBG5(("satWriteSame10: case 1-1 !!! error due to writesame10\n"));
10489         satSetSensePayload( pSense,
10490                             SCSI_SNSKEY_ILLEGAL_REQUEST,
10491                             0,
10492                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10493                             satIOContext);
10494 
10495         ostiInitiatorIOCompleted( tiRoot,
10496                                   tiIORequest,
10497                                   tiIOSuccess,
10498                                   SCSI_STAT_CHECK_CONDITION,
10499                                   satIOContext->pTiSenseData,
10500                                   satIOContext->interruptContext );
10501         return tiSuccess;
10502       }
10503     } /* end of case 1 and 2 */
10504 
10505     /* case 3 and 4 */
10506     if (pSatDevData->sat48BitSupport == agTRUE)
10507     {
10508       if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10509       {
10510         /* case 3 */
10511         /* WRITE DMA EXT or WRITE DMA FUA EXT */
10512         /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */
10513         TI_DBG5(("satWriteSame10: case 1-3\n"));
10514         fis->h.fisType        = 0x27;                   /* Reg host to device */
10515         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10516 
10517         fis->h.command        = SAT_WRITE_DMA_EXT;          /* 0x35 */
10518 
10519         fis->h.features       = 0;                      /* FIS reserve */
10520         fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
10521         fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
10522         fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
10523         fis->d.device         = 0x40;                   /* FIS LBA mode set */
10524         fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
10525         fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10526         fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10527         fis->d.featuresExp    = 0;                      /* FIS reserve */
10528         if (tl == 0)
10529         {
10530           /* error check
10531              ATA spec, p125, 6.17.29
10532              pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10533              and allowed value is 0x0FFFFFFF - 1
10534           */
10535           if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10536           {
10537             TI_DBG5(("satWriteSame10: case 3 !!! warning can't fit sectors\n"));
10538             satSetSensePayload( pSense,
10539                                 SCSI_SNSKEY_ILLEGAL_REQUEST,
10540                                 0,
10541                                 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10542                                 satIOContext);
10543 
10544             ostiInitiatorIOCompleted( tiRoot,
10545                                       tiIORequest,
10546                                       tiIOSuccess,
10547                                       SCSI_STAT_CHECK_CONDITION,
10548                                       satIOContext->pTiSenseData,
10549                                       satIOContext->interruptContext );
10550             return tiSuccess;
10551           }
10552         }
10553         /* one sector at a time */
10554         fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10555         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10556         fis->d.reserved4      = 0;
10557         fis->d.control        = 0;                      /* FIS HOB bit clear */
10558         fis->d.reserved5      = 0;
10559 
10560         agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10561       }
10562       else
10563       {
10564         /* case 4 */
10565         /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
10566         /* WRITE SECTORS EXT is chosen for easier implemetation */
10567         TI_DBG5(("satWriteSame10: case 1-4\n"));
10568         fis->h.fisType        = 0x27;                   /* Reg host to device */
10569         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10570 
10571         fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
10572         fis->h.features       = 0;                      /* FIS reserve */
10573         fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
10574         fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
10575         fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
10576         fis->d.device         = 0x40;                   /* FIS LBA mode set */
10577         fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
10578         fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10579         fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10580         fis->d.featuresExp    = 0;                      /* FIS reserve */
10581         if (tl == 0)
10582         {
10583           /* error check
10584              ATA spec, p125, 6.17.29
10585              pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10586              and allowed value is 0x0FFFFFFF - 1
10587           */
10588           if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10589           {
10590             TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10591             satSetSensePayload( pSense,
10592                                 SCSI_SNSKEY_ILLEGAL_REQUEST,
10593                                 0,
10594                                 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10595                                 satIOContext);
10596 
10597             ostiInitiatorIOCompleted( tiRoot,
10598                                       tiIORequest,
10599                                       tiIOSuccess,
10600                                       SCSI_STAT_CHECK_CONDITION,
10601                                       satIOContext->pTiSenseData,
10602                                       satIOContext->interruptContext );
10603             return tiSuccess;
10604           }
10605         }
10606         /* one sector at a time */
10607         fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10608         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10609         fis->d.reserved4      = 0;
10610         fis->d.control        = 0;                      /* FIS HOB bit clear */
10611         fis->d.reserved5      = 0;
10612 
10613         agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10614       }
10615     }
10616 
10617     /* case 5 */
10618     if (pSatDevData->satNCQ == agTRUE)
10619     {
10620       /* WRITE FPDMA QUEUED */
10621       if (pSatDevData->sat48BitSupport != agTRUE)
10622       {
10623         TI_DBG5(("satWriteSame10: case 1-5 !!! error NCQ but 28 bit address support \n"));
10624         satSetSensePayload( pSense,
10625                             SCSI_SNSKEY_ILLEGAL_REQUEST,
10626                             0,
10627                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10628                             satIOContext);
10629 
10630         ostiInitiatorIOCompleted( tiRoot,
10631                                   tiIORequest,
10632                                   tiIOSuccess,
10633                                   SCSI_STAT_CHECK_CONDITION,
10634                                   satIOContext->pTiSenseData,
10635                                   satIOContext->interruptContext );
10636         return tiSuccess;
10637       }
10638       TI_DBG5(("satWriteSame10: case 1-5\n"));
10639 
10640       /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
10641 
10642       fis->h.fisType        = 0x27;                   /* Reg host to device */
10643       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10644       fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
10645 
10646       if (tl == 0)
10647       {
10648         /* error check
10649            ATA spec, p125, 6.17.29
10650            pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10651            and allowed value is 0x0FFFFFFF - 1
10652         */
10653         if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10654         {
10655           TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10656           satSetSensePayload( pSense,
10657                               SCSI_SNSKEY_ILLEGAL_REQUEST,
10658                               0,
10659                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10660                               satIOContext);
10661 
10662           ostiInitiatorIOCompleted( tiRoot,
10663                                     tiIORequest,
10664                                     tiIOSuccess,
10665                                     SCSI_STAT_CHECK_CONDITION,
10666                                     satIOContext->pTiSenseData,
10667                                     satIOContext->interruptContext );
10668           return tiSuccess;
10669         }
10670       }
10671       /* one sector at a time */
10672       fis->h.features       = 1;            /* FIS sector count (7:0) */
10673       fis->d.featuresExp    = 0;            /* FIS sector count (15:8) */
10674 
10675 
10676       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
10677       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
10678       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
10679 
10680       /* NO FUA bit in the WRITE SAME 10 */
10681       fis->d.device       = 0x40;                     /* FIS FUA clear */
10682 
10683       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
10684       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10685       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10686       fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
10687       fis->d.sectorCountExp = 0;
10688       fis->d.reserved4      = 0;
10689       fis->d.control        = 0;                      /* FIS HOB bit clear */
10690       fis->d.reserved5      = 0;
10691 
10692       agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
10693     }
10694     /* Initialize CB for SATA completion.
10695      */
10696     satIOContext->satCompleteCB = &satWriteSame10CB;
10697 
10698     /*
10699      * Prepare SGL and send FIS to LL layer.
10700      */
10701     satIOContext->reqType = agRequestType;       /* Save it */
10702 
10703     status = sataLLIOStart( tiRoot,
10704                             tiIORequest,
10705                             tiDeviceHandle,
10706                             tiScsiRequest,
10707                             satIOContext);
10708     return (status);
10709 
10710 
10711   } /* end of case 1 */
10712   else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10713              (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10714   {
10715     /* spec 9.26.2, Table 62, p64, case 2*/
10716     satSetSensePayload( pSense,
10717                         SCSI_SNSKEY_ILLEGAL_REQUEST,
10718                         0,
10719                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10720                         satIOContext);
10721 
10722     ostiInitiatorIOCompleted( tiRoot,
10723                               tiIORequest,
10724                               tiIOSuccess,
10725                               SCSI_STAT_CHECK_CONDITION,
10726                               satIOContext->pTiSenseData,
10727                               satIOContext->interruptContext );
10728 
10729     TI_DBG5(("satWriteSame10: return Table 62 case 2\n"));
10730     return tiSuccess;
10731   }
10732   else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10733            !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10734   {
10735     TI_DBG5(("satWriteSame10: Table 62 case 3\n"));
10736 
10737   }
10738   else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10739             (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */
10740   {
10741 
10742     /* spec 9.26.2, Table 62, p64, case 4*/
10743     satSetSensePayload( pSense,
10744                         SCSI_SNSKEY_ILLEGAL_REQUEST,
10745                         0,
10746                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10747                         satIOContext);
10748 
10749     ostiInitiatorIOCompleted( tiRoot,
10750                               tiIORequest,
10751                               tiIOSuccess,
10752                               SCSI_STAT_CHECK_CONDITION,
10753                               satIOContext->pTiSenseData,
10754                               satIOContext->interruptContext );
10755 
10756     TI_DBG5(("satWriteSame10: return Table 62 case 4\n"));
10757     return tiSuccess;
10758   }
10759 
10760 
10761   return tiSuccess;
10762 }
10763 
10764 /*****************************************************************************/
10765 /*! \brief SAT implementation for SCSI satWriteSame10_1.
10766  *
10767  *  SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10768  *  This is used when WRITESAME10 is divided into multiple ATA commands
10769  *
10770  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10771  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10772  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10773  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10774  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10775  *  \param   lba:              LBA
10776  *
10777  *  \return If command is started successfully
10778  *    - \e tiSuccess:     I/O request successfully initiated.
10779  *    - \e tiBusy:        No resources available, try again later.
10780  *    - \e tiIONoDevice:  Invalid device handle.
10781  *    - \e tiError:       Other errors.
10782  */
10783 /*****************************************************************************/
10784 GLOBAL bit32  satWriteSame10_1(
10785                    tiRoot_t                  *tiRoot,
10786                    tiIORequest_t             *tiIORequest,
10787                    tiDeviceHandle_t          *tiDeviceHandle,
10788                    tiScsiInitiatorRequest_t *tiScsiRequest,
10789                    satIOContext_t            *satIOContext,
10790                    bit32                     lba
10791                    )
10792 {
10793   /*
10794     sends SAT_WRITE_DMA_EXT
10795   */
10796 
10797   bit32                     status;
10798   bit32                     agRequestType;
10799   agsaFisRegHostToDevice_t  *fis;
10800   bit8                      lba1, lba2 ,lba3, lba4;
10801 
10802   TI_DBG5(("satWriteSame10_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10803            tiDeviceHandle, tiIORequest));
10804 
10805   fis               = satIOContext->pFis;
10806 
10807   /* MSB */
10808   lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10809   lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10810   lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10811   /* LSB */
10812   lba4 = (bit8)(lba & 0x000000FF);
10813 
10814   /* SAT_WRITE_DMA_EXT */
10815   fis->h.fisType        = 0x27;                   /* Reg host to device */
10816   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10817 
10818   fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
10819 
10820   fis->h.features       = 0;                      /* FIS reserve */
10821   fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
10822   fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
10823   fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
10824   fis->d.device         = 0x40;                   /* FIS LBA mode set */
10825   fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
10826   fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10827   fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10828   fis->d.featuresExp    = 0;                      /* FIS reserve */
10829   /* one sector at a time */
10830   fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10831   fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10832 
10833   fis->d.reserved4      = 0;
10834   fis->d.control        = 0;                      /* FIS HOB bit clear */
10835   fis->d.reserved5      = 0;
10836 
10837 
10838   agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10839 
10840   /* Initialize CB for SATA completion.
10841    */
10842   satIOContext->satCompleteCB = &satWriteSame10CB;
10843 
10844   /*
10845    * Prepare SGL and send FIS to LL layer.
10846    */
10847   satIOContext->reqType = agRequestType;       /* Save it */
10848 
10849   status = sataLLIOStart( tiRoot,
10850                           tiIORequest,
10851                           tiDeviceHandle,
10852                           tiScsiRequest,
10853                           satIOContext);
10854 
10855   TI_DBG5(("satWriteSame10_1 return status %d\n", status));
10856   return status;
10857 }
10858 
10859 /*****************************************************************************/
10860 /*! \brief SAT implementation for SCSI satWriteSame10_2.
10861  *
10862  *  SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10863  *  This is used when WRITESAME10 is divided into multiple ATA commands
10864  *
10865  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10866  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10867  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10868  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10869  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10870  *  \param   lba:              LBA
10871  *
10872  *  \return If command is started successfully
10873  *    - \e tiSuccess:     I/O request successfully initiated.
10874  *    - \e tiBusy:        No resources available, try again later.
10875  *    - \e tiIONoDevice:  Invalid device handle.
10876  *    - \e tiError:       Other errors.
10877  */
10878 /*****************************************************************************/
10879 GLOBAL bit32  satWriteSame10_2(
10880                    tiRoot_t                  *tiRoot,
10881                    tiIORequest_t             *tiIORequest,
10882                    tiDeviceHandle_t          *tiDeviceHandle,
10883                    tiScsiInitiatorRequest_t *tiScsiRequest,
10884                    satIOContext_t            *satIOContext,
10885                    bit32                     lba
10886                    )
10887 {
10888   /*
10889     sends SAT_WRITE_SECTORS_EXT
10890   */
10891 
10892   bit32                     status;
10893   bit32                     agRequestType;
10894   agsaFisRegHostToDevice_t  *fis;
10895   bit8                      lba1, lba2 ,lba3, lba4;
10896 
10897   TI_DBG5(("satWriteSame10_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10898            tiDeviceHandle, tiIORequest));
10899 
10900   fis               = satIOContext->pFis;
10901 
10902   /* MSB */
10903   lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10904   lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10905   lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10906   /* LSB */
10907   lba4 = (bit8)(lba & 0x000000FF);
10908 
10909 
10910   /* SAT_WRITE_SECTORS_EXT */
10911   fis->h.fisType        = 0x27;                   /* Reg host to device */
10912   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10913 
10914   fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
10915   fis->h.features       = 0;                      /* FIS reserve */
10916   fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
10917   fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
10918   fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
10919   fis->d.device         = 0x40;                   /* FIS LBA mode set */
10920   fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
10921   fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10922   fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10923   fis->d.featuresExp    = 0;                      /* FIS reserve */
10924   /* one sector at a time */
10925   fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10926   fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10927 
10928   fis->d.reserved4      = 0;
10929   fis->d.control        = 0;                      /* FIS HOB bit clear */
10930   fis->d.reserved5      = 0;
10931 
10932 
10933   agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10934 
10935   /* Initialize CB for SATA completion.
10936    */
10937   satIOContext->satCompleteCB = &satWriteSame10CB;
10938 
10939   /*
10940    * Prepare SGL and send FIS to LL layer.
10941    */
10942   satIOContext->reqType = agRequestType;       /* Save it */
10943 
10944   status = sataLLIOStart( tiRoot,
10945                           tiIORequest,
10946                           tiDeviceHandle,
10947                           tiScsiRequest,
10948                           satIOContext);
10949 
10950   TI_DBG5(("satWriteSame10_2 return status %d\n", status));
10951   return status;
10952 }
10953 
10954 /*****************************************************************************/
10955 /*! \brief SAT implementation for SCSI satWriteSame10_3.
10956  *
10957  *  SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10958  *  This is used when WRITESAME10 is divided into multiple ATA commands
10959  *
10960  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10961  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10962  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10963  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10964  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10965  *  \param   lba:              LBA
10966  *
10967  *  \return If command is started successfully
10968  *    - \e tiSuccess:     I/O request successfully initiated.
10969  *    - \e tiBusy:        No resources available, try again later.
10970  *    - \e tiIONoDevice:  Invalid device handle.
10971  *    - \e tiError:       Other errors.
10972  */
10973 /*****************************************************************************/
10974 GLOBAL bit32  satWriteSame10_3(
10975                    tiRoot_t                  *tiRoot,
10976                    tiIORequest_t             *tiIORequest,
10977                    tiDeviceHandle_t          *tiDeviceHandle,
10978                    tiScsiInitiatorRequest_t *tiScsiRequest,
10979                    satIOContext_t            *satIOContext,
10980                    bit32                     lba
10981                    )
10982 {
10983   /*
10984     sends SAT_WRITE_FPDMA_QUEUED
10985   */
10986 
10987   bit32                     status;
10988   bit32                     agRequestType;
10989   agsaFisRegHostToDevice_t  *fis;
10990   bit8                      lba1, lba2 ,lba3, lba4;
10991 
10992   TI_DBG5(("satWriteSame10_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10993            tiDeviceHandle, tiIORequest));
10994 
10995   fis               = satIOContext->pFis;
10996 
10997   /* MSB */
10998   lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10999   lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
11000   lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
11001   /* LSB */
11002   lba4 = (bit8)(lba & 0x000000FF);
11003 
11004   /* SAT_WRITE_FPDMA_QUEUED */
11005   fis->h.fisType        = 0x27;                   /* Reg host to device */
11006   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11007   fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
11008 
11009 
11010   /* one sector at a time */
11011   fis->h.features       = 1;                      /* FIS sector count (7:0) */
11012   fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
11013 
11014 
11015   fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
11016   fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
11017   fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
11018 
11019   /* NO FUA bit in the WRITE SAME 10 */
11020   fis->d.device         = 0x40;                   /* FIS FUA clear */
11021 
11022   fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
11023   fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
11024   fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
11025   fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
11026   fis->d.sectorCountExp = 0;
11027   fis->d.reserved4      = 0;
11028   fis->d.control        = 0;                      /* FIS HOB bit clear */
11029   fis->d.reserved5      = 0;
11030 
11031   agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
11032 
11033   /* Initialize CB for SATA completion.
11034    */
11035   satIOContext->satCompleteCB = &satWriteSame10CB;
11036 
11037   /*
11038    * Prepare SGL and send FIS to LL layer.
11039    */
11040   satIOContext->reqType = agRequestType;       /* Save it */
11041 
11042   status = sataLLIOStart( tiRoot,
11043                           tiIORequest,
11044                           tiDeviceHandle,
11045                           tiScsiRequest,
11046                           satIOContext);
11047 
11048   TI_DBG5(("satWriteSame10_2 return status %d\n", status));
11049   return status;
11050 }
11051 /*****************************************************************************/
11052 /*! \brief SAT implementation for SCSI satWriteSame16.
11053  *
11054  *  SAT implementation for SCSI satWriteSame16.
11055  *
11056  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11057  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11058  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11059  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11060  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11061  *
11062  *  \return If command is started successfully
11063  *    - \e tiSuccess:     I/O request successfully initiated.
11064  *    - \e tiBusy:        No resources available, try again later.
11065  *    - \e tiIONoDevice:  Invalid device handle.
11066  *    - \e tiError:       Other errors.
11067  */
11068 /*****************************************************************************/
11069 GLOBAL bit32  satWriteSame16(
11070                    tiRoot_t                  *tiRoot,
11071                    tiIORequest_t             *tiIORequest,
11072                    tiDeviceHandle_t          *tiDeviceHandle,
11073                    tiScsiInitiatorRequest_t *tiScsiRequest,
11074                    satIOContext_t            *satIOContext)
11075 {
11076   scsiRspSense_t            *pSense;
11077 
11078   pSense        = satIOContext->pSense;
11079 
11080   TI_DBG5(("satWriteSame16:start\n"));
11081 
11082 
11083   satSetSensePayload( pSense,
11084                       SCSI_SNSKEY_NO_SENSE,
11085                       0,
11086                       SCSI_SNSCODE_NO_ADDITIONAL_INFO,
11087                       satIOContext);
11088 
11089   ostiInitiatorIOCompleted( tiRoot,
11090                             tiIORequest, /* == &satIntIo->satOrgTiIORequest */
11091                             tiIOSuccess,
11092                             SCSI_STAT_CHECK_CONDITION,
11093                             satIOContext->pTiSenseData,
11094                             satIOContext->interruptContext );
11095   TI_DBG5(("satWriteSame16: return internal checking\n"));
11096   return tiSuccess;
11097 }
11098 
11099 /*****************************************************************************/
11100 /*! \brief SAT implementation for SCSI satLogSense_1.
11101  *
11102  *  Part of SAT implementation for SCSI satLogSense.
11103  *
11104  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11105  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11106  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11107  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11108  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11109  *
11110  *  \return If command is started successfully
11111  *    - \e tiSuccess:     I/O request successfully initiated.
11112  *    - \e tiBusy:        No resources available, try again later.
11113  *    - \e tiIONoDevice:  Invalid device handle.
11114  *    - \e tiError:       Other errors.
11115  */
11116 /*****************************************************************************/
11117 GLOBAL bit32  satLogSense_1(
11118                    tiRoot_t                  *tiRoot,
11119                    tiIORequest_t             *tiIORequest,
11120                    tiDeviceHandle_t          *tiDeviceHandle,
11121                    tiScsiInitiatorRequest_t *tiScsiRequest,
11122                    satIOContext_t            *satIOContext)
11123 {
11124   bit32                     status;
11125   bit32                     agRequestType;
11126   satDeviceData_t           *pSatDevData;
11127   agsaFisRegHostToDevice_t  *fis;
11128 
11129   pSatDevData   = satIOContext->pSatDevData;
11130   fis           = satIOContext->pFis;
11131 
11132   TI_DBG5(("satLogSense_1: start\n"));
11133 
11134 
11135   /* SAT Rev 8, 10.2.4 p74 */
11136   if ( pSatDevData->sat48BitSupport == agTRUE )
11137   {
11138     TI_DBG5(("satLogSense_1: case 2-1 sends READ LOG EXT\n"));
11139     /* sends READ LOG EXT */
11140     fis->h.fisType        = 0x27;                   /* Reg host to device */
11141     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11142 
11143     fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
11144     fis->h.features       = 0;                      /* FIS reserve */
11145     fis->d.lbaLow         = 0x07;                   /* 0x07 */
11146     fis->d.lbaMid         = 0;                      /*  */
11147     fis->d.lbaHigh        = 0;                      /*  */
11148     fis->d.device         = 0;                      /*  */
11149     fis->d.lbaLowExp      = 0;                      /*  */
11150     fis->d.lbaMidExp      = 0;                      /*  */
11151     fis->d.lbaHighExp     = 0;                      /*  */
11152     fis->d.featuresExp    = 0;                      /* FIS reserve */
11153     fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
11154     fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
11155     fis->d.reserved4      = 0;
11156     fis->d.control        = 0;                      /* FIS HOB bit clear */
11157     fis->d.reserved5      = 0;
11158 
11159     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11160 
11161     /* Initialize CB for SATA completion.
11162      */
11163     satIOContext->satCompleteCB = &satLogSenseCB;
11164 
11165     /*
11166      * Prepare SGL and send FIS to LL layer.
11167      */
11168     satIOContext->reqType = agRequestType;       /* Save it */
11169 
11170     status = sataLLIOStart( tiRoot,
11171                             tiIORequest,
11172                             tiDeviceHandle,
11173                             tiScsiRequest,
11174                             satIOContext);
11175     return status;
11176 
11177   }
11178   else
11179   {
11180     TI_DBG5(("satLogSense_1: case 2-2 sends SMART READ LOG\n"));
11181     /* sends SMART READ LOG */
11182     fis->h.fisType        = 0x27;                   /* Reg host to device */
11183     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11184 
11185     fis->h.command        = SAT_SMART_READ_LOG;     /* 0x2F */
11186     fis->h.features       = 0x00;                   /* 0xd5 */
11187     fis->d.lbaLow         = 0x06;                   /* 0x06 */
11188     fis->d.lbaMid         = 0x00;                   /* 0x4f */
11189     fis->d.lbaHigh        = 0x00;                   /* 0xc2 */
11190     fis->d.device         = 0;                      /*  */
11191     fis->d.lbaLowExp      = 0;                      /*  */
11192     fis->d.lbaMidExp      = 0;                      /*  */
11193     fis->d.lbaHighExp     = 0;                      /*  */
11194     fis->d.featuresExp    = 0;                      /* FIS reserve */
11195     fis->d.sectorCount    = 0x01;                      /*  */
11196     fis->d.sectorCountExp = 0x00;                      /*  */
11197     fis->d.reserved4      = 0;
11198     fis->d.control        = 0;                      /* FIS HOB bit clear */
11199     fis->d.reserved5      = 0;
11200 
11201     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11202 
11203     /* Initialize CB for SATA completion.
11204      */
11205     satIOContext->satCompleteCB = &satLogSenseCB;
11206 
11207     /*
11208      * Prepare SGL and send FIS to LL layer.
11209      */
11210     satIOContext->reqType = agRequestType;       /* Save it */
11211 
11212     status = sataLLIOStart( tiRoot,
11213                             tiIORequest,
11214                             tiDeviceHandle,
11215                             tiScsiRequest,
11216                             satIOContext);
11217     return status;
11218 
11219   }
11220 }
11221 
11222 /*****************************************************************************/
11223 /*! \brief SAT implementation for SCSI satSMARTEnable.
11224  *
11225  *  Part of SAT implementation for SCSI satLogSense.
11226  *
11227  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11228  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11229  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11230  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11231  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11232  *
11233  *  \return If command is started successfully
11234  *    - \e tiSuccess:     I/O request successfully initiated.
11235  *    - \e tiBusy:        No resources available, try again later.
11236  *    - \e tiIONoDevice:  Invalid device handle.
11237  *    - \e tiError:       Other errors.
11238  */
11239 /*****************************************************************************/
11240 GLOBAL bit32  satSMARTEnable(
11241                    tiRoot_t                  *tiRoot,
11242                    tiIORequest_t             *tiIORequest,
11243                    tiDeviceHandle_t          *tiDeviceHandle,
11244                    tiScsiInitiatorRequest_t *tiScsiRequest,
11245                    satIOContext_t            *satIOContext)
11246 {
11247   bit32                     status;
11248   bit32                     agRequestType;
11249   agsaFisRegHostToDevice_t  *fis;
11250 
11251   TI_DBG4(("satSMARTEnable entry: tiDeviceHandle=%p tiIORequest=%p\n",
11252       tiDeviceHandle, tiIORequest));
11253 
11254   fis               = satIOContext->pFis;
11255 
11256   /*
11257    * Send the SAT_SMART_ENABLE_OPERATIONS command.
11258    */
11259   fis->h.fisType        = 0x27;                   /* Reg host to device */
11260   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11261 
11262   fis->h.command        = SAT_SMART_ENABLE_OPERATIONS;   /* 0xB0 */
11263   fis->h.features       = 0xD8;
11264   fis->d.lbaLow         = 0;
11265   fis->d.lbaMid         = 0x4F;
11266   fis->d.lbaHigh        = 0xC2;
11267   fis->d.device         = 0;
11268   fis->d.lbaLowExp      = 0;
11269   fis->d.lbaMidExp      = 0;
11270   fis->d.lbaHighExp     = 0;
11271   fis->d.featuresExp    = 0;
11272   fis->d.sectorCount    = 0;
11273   fis->d.sectorCountExp = 0;
11274   fis->d.reserved4      = 0;
11275   fis->d.control        = 0;                      /* FIS HOB bit clear */
11276   fis->d.reserved5      = 0;
11277 
11278   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11279 
11280   /* Initialize CB for SATA completion.
11281    */
11282   satIOContext->satCompleteCB = &satSMARTEnableCB;
11283 
11284   /*
11285    * Prepare SGL and send FIS to LL layer.
11286    */
11287   satIOContext->reqType = agRequestType;       /* Save it */
11288 
11289   status = sataLLIOStart( tiRoot,
11290                           tiIORequest,
11291                           tiDeviceHandle,
11292                           tiScsiRequest,
11293                           satIOContext);
11294 
11295 
11296   return status;
11297 }
11298 
11299 /*****************************************************************************/
11300 /*! \brief SAT implementation for SCSI satLogSense_3.
11301  *
11302  *  Part of SAT implementation for SCSI satLogSense.
11303  *
11304  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11305  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11306  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11307  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11308  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11309  *
11310  *  \return If command is started successfully
11311  *    - \e tiSuccess:     I/O request successfully initiated.
11312  *    - \e tiBusy:        No resources available, try again later.
11313  *    - \e tiIONoDevice:  Invalid device handle.
11314  *    - \e tiError:       Other errors.
11315  */
11316 /*****************************************************************************/
11317 GLOBAL bit32  satLogSense_3(
11318                    tiRoot_t                  *tiRoot,
11319                    tiIORequest_t             *tiIORequest,
11320                    tiDeviceHandle_t          *tiDeviceHandle,
11321                    tiScsiInitiatorRequest_t *tiScsiRequest,
11322                    satIOContext_t            *satIOContext)
11323 {
11324   bit32                     status;
11325   bit32                     agRequestType;
11326   agsaFisRegHostToDevice_t  *fis;
11327 
11328   TI_DBG4(("satLogSense_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11329       tiDeviceHandle, tiIORequest));
11330 
11331   fis               = satIOContext->pFis;
11332   /* sends READ LOG EXT */
11333   fis->h.fisType        = 0x27;                   /* Reg host to device */
11334   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11335 
11336   fis->h.command        = SAT_SMART_READ_LOG;     /* 0x2F */
11337   fis->h.features       = 0xD5;                   /* 0xd5 */
11338   fis->d.lbaLow         = 0x06;                   /* 0x06 */
11339   fis->d.lbaMid         = 0x4F;                   /* 0x4f */
11340   fis->d.lbaHigh        = 0xC2;                   /* 0xc2 */
11341   fis->d.device         = 0;                      /*  */
11342   fis->d.lbaLowExp      = 0;                      /*  */
11343   fis->d.lbaMidExp      = 0;                      /*  */
11344   fis->d.lbaHighExp     = 0;                      /*  */
11345   fis->d.featuresExp    = 0;                      /* FIS reserve */
11346   fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
11347   fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
11348   fis->d.reserved4      = 0;
11349   fis->d.control        = 0;                      /* FIS HOB bit clear */
11350   fis->d.reserved5      = 0;
11351 
11352   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11353 
11354   /* Initialize CB for SATA completion.
11355    */
11356   satIOContext->satCompleteCB = &satLogSenseCB;
11357 
11358   /*
11359    * Prepare SGL and send FIS to LL layer.
11360    */
11361   satIOContext->reqType = agRequestType;       /* Save it */
11362 
11363   status = sataLLIOStart( tiRoot,
11364                           tiIORequest,
11365                           tiDeviceHandle,
11366                           tiScsiRequest,
11367                           satIOContext);
11368   return status;
11369 }
11370 
11371 /*****************************************************************************/
11372 /*! \brief SAT implementation for SCSI satLogSense_2.
11373  *
11374  *  Part of SAT implementation for SCSI satLogSense.
11375  *
11376  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11377  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11378  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11379  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11380  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11381  *
11382  *  \return If command is started successfully
11383  *    - \e tiSuccess:     I/O request successfully initiated.
11384  *    - \e tiBusy:        No resources available, try again later.
11385  *    - \e tiIONoDevice:  Invalid device handle.
11386  *    - \e tiError:       Other errors.
11387  */
11388 /*****************************************************************************/
11389 GLOBAL bit32  satLogSense_2(
11390                    tiRoot_t                  *tiRoot,
11391                    tiIORequest_t             *tiIORequest,
11392                    tiDeviceHandle_t          *tiDeviceHandle,
11393                    tiScsiInitiatorRequest_t *tiScsiRequest,
11394                    satIOContext_t            *satIOContext)
11395 {
11396   bit32                     status;
11397   bit32                     agRequestType;
11398   agsaFisRegHostToDevice_t  *fis;
11399 
11400   TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11401       tiDeviceHandle, tiIORequest));
11402 
11403   fis               = satIOContext->pFis;
11404   /* sends READ LOG EXT */
11405   fis->h.fisType        = 0x27;                   /* Reg host to device */
11406   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11407 
11408   fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
11409   fis->h.features       = 0;                      /* FIS reserve */
11410   fis->d.lbaLow         = 0x07;                   /* 0x07 */
11411   fis->d.lbaMid         = 0;                      /*  */
11412   fis->d.lbaHigh        = 0;                      /*  */
11413   fis->d.device         = 0;                      /*  */
11414   fis->d.lbaLowExp      = 0;                      /*  */
11415   fis->d.lbaMidExp      = 0;                      /*  */
11416   fis->d.lbaHighExp     = 0;                      /*  */
11417   fis->d.featuresExp    = 0;                      /* FIS reserve */
11418   fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
11419   fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
11420   fis->d.reserved4      = 0;
11421   fis->d.control        = 0;                      /* FIS HOB bit clear */
11422   fis->d.reserved5      = 0;
11423 
11424   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11425 
11426   /* Initialize CB for SATA completion.
11427    */
11428   satIOContext->satCompleteCB = &satLogSenseCB;
11429 
11430   /*
11431    * Prepare SGL and send FIS to LL layer.
11432    */
11433   satIOContext->reqType = agRequestType;       /* Save it */
11434 
11435   status = sataLLIOStart( tiRoot,
11436                           tiIORequest,
11437                           tiDeviceHandle,
11438                           tiScsiRequest,
11439                           satIOContext);
11440   return status;
11441 }
11442 
11443 /*****************************************************************************/
11444 /*! \brief SAT implementation for SCSI satLogSenseAllocate.
11445  *
11446  *  Part of SAT implementation for SCSI satLogSense.
11447  *
11448  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11449  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11450  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11451  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11452  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11453  *  \param   payloadSize:      size of payload to be allocated.
11454  *  \param   flag:             flag value
11455  *
11456  *  \return If command is started successfully
11457  *    - \e tiSuccess:     I/O request successfully initiated.
11458  *    - \e tiBusy:        No resources available, try again later.
11459  *    - \e tiIONoDevice:  Invalid device handle.
11460  *    - \e tiError:       Other errors.
11461  *  \note
11462  *    - flag values: LOG_SENSE_0, LOG_SENSE_1, LOG_SENSE_2
11463  */
11464 /*****************************************************************************/
11465 GLOBAL bit32  satLogSenseAllocate(
11466                    tiRoot_t                  *tiRoot,
11467                    tiIORequest_t             *tiIORequest,
11468                    tiDeviceHandle_t          *tiDeviceHandle,
11469                    tiScsiInitiatorRequest_t *tiScsiRequest,
11470                    satIOContext_t            *satIOContext,
11471                    bit32                      payloadSize,
11472                    bit32                      flag
11473                    )
11474 {
11475   satDeviceData_t           *pSatDevData;
11476   tdIORequestBody_t         *tdIORequestBody;
11477   satInternalIo_t           *satIntIo = agNULL;
11478   satIOContext_t            *satIOContext2;
11479   bit32                     status;
11480 
11481   TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11482       tiDeviceHandle, tiIORequest));
11483 
11484   pSatDevData       = satIOContext->pSatDevData;
11485 
11486   /* create internal satIOContext */
11487   satIntIo = satAllocIntIoResource( tiRoot,
11488                                     tiIORequest, /* original request */
11489                                     pSatDevData,
11490                                     payloadSize,
11491                                     satIntIo);
11492 
11493   if (satIntIo == agNULL)
11494   {
11495     /* memory allocation failure */
11496     satFreeIntIoResource( tiRoot,
11497                           pSatDevData,
11498                           satIntIo);
11499 
11500     ostiInitiatorIOCompleted( tiRoot,
11501                               tiIORequest,
11502                               tiIOFailed,
11503                               tiDetailOtherError,
11504                               agNULL,
11505                               satIOContext->interruptContext );
11506 
11507     TI_DBG4(("satLogSense_2: fail in allocation\n"));
11508     return tiSuccess;
11509   } /* end of memory allocation failure */
11510 
11511   satIntIo->satOrgTiIORequest = tiIORequest;
11512   tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
11513   satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
11514 
11515   satIOContext2->pSatDevData   = pSatDevData;
11516   satIOContext2->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
11517   satIOContext2->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
11518   satIOContext2->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
11519   satIOContext2->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
11520   satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
11521   satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
11522   satIOContext2->interruptContext = satIOContext->interruptContext;
11523   satIOContext2->satIntIoContext  = satIntIo;
11524   satIOContext2->ptiDeviceHandle = tiDeviceHandle;
11525   satIOContext2->satOrgIOContext = satIOContext;
11526 
11527   if (flag == LOG_SENSE_0)
11528   {
11529     /* SAT_SMART_ENABLE_OPERATIONS */
11530     status = satSMARTEnable( tiRoot,
11531                          &(satIntIo->satIntTiIORequest),
11532                          tiDeviceHandle,
11533                          &(satIntIo->satIntTiScsiXchg),
11534                          satIOContext2);
11535   }
11536   else if (flag == LOG_SENSE_1)
11537   {
11538     /* SAT_READ_LOG_EXT */
11539     status = satLogSense_2( tiRoot,
11540                          &(satIntIo->satIntTiIORequest),
11541                          tiDeviceHandle,
11542                          &(satIntIo->satIntTiScsiXchg),
11543                          satIOContext2);
11544   }
11545   else
11546   {
11547     /* SAT_SMART_READ_LOG */
11548     /* SAT_READ_LOG_EXT */
11549     status = satLogSense_3( tiRoot,
11550                          &(satIntIo->satIntTiIORequest),
11551                          tiDeviceHandle,
11552                          &(satIntIo->satIntTiScsiXchg),
11553                          satIOContext2);
11554 
11555   }
11556   if (status != tiSuccess)
11557   {
11558     satFreeIntIoResource( tiRoot,
11559                           pSatDevData,
11560                           satIntIo);
11561 
11562     ostiInitiatorIOCompleted( tiRoot,
11563                               tiIORequest,
11564                               tiIOFailed,
11565                               tiDetailOtherError,
11566                               agNULL,
11567                               satIOContext->interruptContext );
11568     return tiSuccess;
11569   }
11570 
11571 
11572   return tiSuccess;
11573 }
11574 
11575 
11576 /*****************************************************************************/
11577 /*! \brief SAT implementation for SCSI satLogSense.
11578  *
11579  *  SAT implementation for SCSI satLogSense.
11580  *
11581  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11582  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11583  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11584  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11585  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11586  *
11587  *  \return If command is started successfully
11588  *    - \e tiSuccess:     I/O request successfully initiated.
11589  *    - \e tiBusy:        No resources available, try again later.
11590  *    - \e tiIONoDevice:  Invalid device handle.
11591  *    - \e tiError:       Other errors.
11592  */
11593 /*****************************************************************************/
11594 GLOBAL bit32  satLogSense(
11595                    tiRoot_t                  *tiRoot,
11596                    tiIORequest_t             *tiIORequest,
11597                    tiDeviceHandle_t          *tiDeviceHandle,
11598                    tiScsiInitiatorRequest_t *tiScsiRequest,
11599                    satIOContext_t            *satIOContext)
11600 {
11601   bit32                     status;
11602   bit32                     agRequestType;
11603   satDeviceData_t           *pSatDevData;
11604   scsiRspSense_t            *pSense;
11605   tiIniScsiCmnd_t           *scsiCmnd;
11606   agsaFisRegHostToDevice_t  *fis;
11607   bit8                      *pLogPage;    /* Log Page data buffer */
11608   bit32                     flag = 0;
11609   bit16                     AllocLen = 0;       /* allocation length */
11610   bit8                      AllLogPages[8];
11611   bit16                     lenRead = 0;
11612 
11613   pSense        = satIOContext->pSense;
11614   pSatDevData   = satIOContext->pSatDevData;
11615   scsiCmnd      = &tiScsiRequest->scsiCmnd;
11616   fis           = satIOContext->pFis;
11617   pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
11618 
11619   TI_DBG5(("satLogSense: start\n"));
11620 
11621   osti_memset(&AllLogPages, 0, 8);
11622   /* checking CONTROL */
11623   /* NACA == 1 or LINK == 1*/
11624   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
11625   {
11626     satSetSensePayload( pSense,
11627                         SCSI_SNSKEY_ILLEGAL_REQUEST,
11628                         0,
11629                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11630                         satIOContext);
11631 
11632     ostiInitiatorIOCompleted( tiRoot,
11633                               tiIORequest,
11634                               tiIOSuccess,
11635                               SCSI_STAT_CHECK_CONDITION,
11636                               satIOContext->pTiSenseData,
11637                               satIOContext->interruptContext );
11638 
11639     TI_DBG2(("satLogSense: return control\n"));
11640     return tiSuccess;
11641   }
11642 
11643 
11644   AllocLen = (bit8)((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
11645 
11646   /* checking PC (Page Control) */
11647   /* nothing */
11648 
11649   /* special cases */
11650   if (AllocLen == 4)
11651   {
11652     TI_DBG1(("satLogSense: AllocLen is 4\n"));
11653     switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11654     {
11655       case LOGSENSE_SUPPORTED_LOG_PAGES:
11656         TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11657 
11658         /* SAT Rev 8, 10.2.5 p76 */
11659         if (pSatDevData->satSMARTFeatureSet == agTRUE)
11660         {
11661           /* add informational exception log */
11662           flag = 1;
11663           if (pSatDevData->satSMARTSelfTest == agTRUE)
11664           {
11665             /* add Self-Test results log page */
11666             flag = 2;
11667           }
11668         }
11669         else
11670         {
11671           /* only supported, no informational exception log, no  Self-Test results log page */
11672           flag = 0;
11673         }
11674         lenRead = 4;
11675         AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES;          /* page code */
11676         AllLogPages[1] = 0;          /* reserved  */
11677         switch (flag)
11678         {
11679           case 0:
11680             /* only supported */
11681             AllLogPages[2] = 0;          /* page length */
11682             AllLogPages[3] = 1;          /* page length */
11683             break;
11684           case 1:
11685             /* supported and informational exception log */
11686             AllLogPages[2] = 0;          /* page length */
11687             AllLogPages[3] = 2;          /* page length */
11688             break;
11689           case 2:
11690             /* supported and informational exception log */
11691             AllLogPages[2] = 0;          /* page length */
11692             AllLogPages[3] = 3;          /* page length */
11693             break;
11694           default:
11695             TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11696             break;
11697         }
11698         osti_memcpy(pLogPage, &AllLogPages, lenRead);
11699         break;
11700       case LOGSENSE_SELFTEST_RESULTS_PAGE:
11701         TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11702         lenRead = 4;
11703         AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE;          /* page code */
11704         AllLogPages[1] = 0;          /* reserved  */
11705         /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */
11706         AllLogPages[2] = 0x01;
11707         AllLogPages[3] = 0x90;       /* page length */
11708         osti_memcpy(pLogPage, &AllLogPages, lenRead);
11709 
11710         break;
11711       case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11712         TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11713         lenRead = 4;
11714         AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE;          /* page code */
11715         AllLogPages[1] = 0;          /* reserved  */
11716         AllLogPages[2] = 0;          /* page length */
11717         AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3;       /* page length */
11718         osti_memcpy(pLogPage, &AllLogPages, lenRead);
11719         break;
11720       default:
11721         TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11722         satSetSensePayload( pSense,
11723                             SCSI_SNSKEY_ILLEGAL_REQUEST,
11724                             0,
11725                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11726                             satIOContext);
11727 
11728         ostiInitiatorIOCompleted( tiRoot,
11729                                   tiIORequest,
11730                                   tiIOSuccess,
11731                                   SCSI_STAT_CHECK_CONDITION,
11732                                   satIOContext->pTiSenseData,
11733                                   satIOContext->interruptContext );
11734         return tiSuccess;
11735     }
11736     ostiInitiatorIOCompleted( tiRoot,
11737                                 tiIORequest,
11738                                 tiIOSuccess,
11739                                 SCSI_STAT_GOOD,
11740                                 agNULL,
11741                                 satIOContext->interruptContext);
11742     return tiSuccess;
11743 
11744   } /* if */
11745 
11746   /* SAT rev8 Table 11  p30*/
11747   /* checking Page Code */
11748   switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11749   {
11750     case LOGSENSE_SUPPORTED_LOG_PAGES:
11751       TI_DBG5(("satLogSense: case 1\n"));
11752 
11753       /* SAT Rev 8, 10.2.5 p76 */
11754 
11755       if (pSatDevData->satSMARTFeatureSet == agTRUE)
11756       {
11757         /* add informational exception log */
11758         flag = 1;
11759         if (pSatDevData->satSMARTSelfTest == agTRUE)
11760         {
11761           /* add Self-Test results log page */
11762           flag = 2;
11763         }
11764       }
11765       else
11766       {
11767         /* only supported, no informational exception log, no  Self-Test results log page */
11768         flag = 0;
11769       }
11770       AllLogPages[0] = 0;          /* page code */
11771       AllLogPages[1] = 0;          /* reserved  */
11772       switch (flag)
11773       {
11774       case 0:
11775         /* only supported */
11776         AllLogPages[2] = 0;          /* page length */
11777         AllLogPages[3] = 1;          /* page length */
11778         AllLogPages[4] = 0x00;       /* supported page list */
11779         lenRead = (bit8)(MIN(AllocLen, 5));
11780         break;
11781       case 1:
11782         /* supported and informational exception log */
11783         AllLogPages[2] = 0;          /* page length */
11784         AllLogPages[3] = 2;          /* page length */
11785         AllLogPages[4] = 0x00;       /* supported page list */
11786         AllLogPages[5] = 0x10;       /* supported page list */
11787         lenRead = (bit8)(MIN(AllocLen, 6));
11788         break;
11789       case 2:
11790         /* supported and informational exception log */
11791         AllLogPages[2] = 0;          /* page length */
11792         AllLogPages[3] = 3;          /* page length */
11793         AllLogPages[4] = 0x00;       /* supported page list */
11794         AllLogPages[5] = 0x10;       /* supported page list */
11795         AllLogPages[6] = 0x2F;       /* supported page list */
11796        lenRead = (bit8)(MIN(AllocLen, 7));
11797        break;
11798       default:
11799         TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11800         break;
11801       }
11802 
11803       osti_memcpy(pLogPage, &AllLogPages, lenRead);
11804       /* comparing allocation length to Log Page byte size */
11805       /* SPC-4, 4.3.4.6, p28 */
11806       if (AllocLen > lenRead )
11807       {
11808         TI_DBG1(("satLogSense reporting underrun lenRead=0x%x AllocLen=0x%x tiIORequest=%p\n", lenRead, AllocLen, tiIORequest));
11809        ostiInitiatorIOCompleted( tiRoot,
11810                                   tiIORequest,
11811                                   tiIOUnderRun,
11812                                   AllocLen - lenRead,
11813                                   agNULL,
11814                                   satIOContext->interruptContext );
11815       }
11816       else
11817       {
11818         ostiInitiatorIOCompleted( tiRoot,
11819                                   tiIORequest,
11820                                   tiIOSuccess,
11821                                   SCSI_STAT_GOOD,
11822                                   agNULL,
11823                                   satIOContext->interruptContext);
11824       }
11825       break;
11826     case LOGSENSE_SELFTEST_RESULTS_PAGE:
11827       TI_DBG5(("satLogSense: case 2\n"));
11828       /* checking SMART self-test */
11829       if (pSatDevData->satSMARTSelfTest == agFALSE)
11830       {
11831         TI_DBG5(("satLogSense: case 2 no SMART Self Test\n"));
11832         satSetSensePayload( pSense,
11833                             SCSI_SNSKEY_ILLEGAL_REQUEST,
11834                             0,
11835                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11836                             satIOContext);
11837 
11838         ostiInitiatorIOCompleted( tiRoot,
11839                                   tiIORequest,
11840                                   tiIOSuccess,
11841                                   SCSI_STAT_CHECK_CONDITION,
11842                                   satIOContext->pTiSenseData,
11843                                   satIOContext->interruptContext );
11844       }
11845       else
11846       {
11847         /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */
11848         if (pSatDevData->satSMARTEnabled == agFALSE)
11849         {
11850           TI_DBG5(("satLogSense: case 2 calling satSMARTEnable\n"));
11851           status = satLogSenseAllocate(tiRoot,
11852                                        tiIORequest,
11853                                        tiDeviceHandle,
11854                                        tiScsiRequest,
11855                                        satIOContext,
11856                                        0,
11857                                        LOG_SENSE_0
11858                                        );
11859 
11860           return status;
11861 
11862         }
11863         else
11864         {
11865         /* SAT Rev 8, 10.2.4 p74 */
11866         if ( pSatDevData->sat48BitSupport == agTRUE )
11867         {
11868           TI_DBG5(("satLogSense: case 2-1 sends READ LOG EXT\n"));
11869           status = satLogSenseAllocate(tiRoot,
11870                                        tiIORequest,
11871                                        tiDeviceHandle,
11872                                        tiScsiRequest,
11873                                        satIOContext,
11874                                        512,
11875                                        LOG_SENSE_1
11876                                        );
11877 
11878           return status;
11879         }
11880         else
11881         {
11882           TI_DBG5(("satLogSense: case 2-2 sends SMART READ LOG\n"));
11883           status = satLogSenseAllocate(tiRoot,
11884                                        tiIORequest,
11885                                        tiDeviceHandle,
11886                                        tiScsiRequest,
11887                                        satIOContext,
11888                                        512,
11889                                        LOG_SENSE_2
11890                                        );
11891 
11892           return status;
11893         }
11894       }
11895       }
11896       break;
11897     case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11898       TI_DBG5(("satLogSense: case 3\n"));
11899       /* checking SMART feature set */
11900       if (pSatDevData->satSMARTFeatureSet == agFALSE)
11901       {
11902         satSetSensePayload( pSense,
11903                             SCSI_SNSKEY_ILLEGAL_REQUEST,
11904                             0,
11905                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11906                             satIOContext);
11907 
11908         ostiInitiatorIOCompleted( tiRoot,
11909                                   tiIORequest,
11910                                   tiIOSuccess,
11911                                   SCSI_STAT_CHECK_CONDITION,
11912                                   satIOContext->pTiSenseData,
11913                                   satIOContext->interruptContext );
11914       }
11915       else
11916       {
11917         /* checking SMART feature enabled */
11918         if (pSatDevData->satSMARTEnabled == agFALSE)
11919         {
11920           satSetSensePayload( pSense,
11921                               SCSI_SNSKEY_ABORTED_COMMAND,
11922                               0,
11923                               SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
11924                               satIOContext);
11925 
11926           ostiInitiatorIOCompleted( tiRoot,
11927                                     tiIORequest,
11928                                     tiIOSuccess,
11929                                     SCSI_STAT_CHECK_CONDITION,
11930                                     satIOContext->pTiSenseData,
11931                                     satIOContext->interruptContext );
11932         }
11933         else
11934         {
11935           /* SAT Rev 8, 10.2.3 p72 */
11936           TI_DBG5(("satLogSense: case 3 sends SMART RETURN STATUS\n"));
11937 
11938           /* sends SMART RETURN STATUS */
11939           fis->h.fisType        = 0x27;                   /* Reg host to device */
11940           fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11941 
11942           fis->h.command        = SAT_SMART_RETURN_STATUS;/* 0xB0 */
11943           fis->h.features       = 0xDA;                   /* FIS features */
11944           fis->d.featuresExp    = 0;                      /* FIS reserve */
11945           fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
11946           fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
11947           fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
11948           fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
11949           fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
11950           fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
11951           fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
11952           fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
11953           fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
11954           fis->d.control        = 0;                      /* FIS HOB bit clear */
11955           fis->d.reserved4      = 0;
11956           fis->d.reserved5      = 0;
11957 
11958           agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11959           /* Initialize CB for SATA completion.
11960            */
11961           satIOContext->satCompleteCB = &satLogSenseCB;
11962 
11963           /*
11964            * Prepare SGL and send FIS to LL layer.
11965            */
11966           satIOContext->reqType = agRequestType;       /* Save it */
11967 
11968           status = sataLLIOStart( tiRoot,
11969                                   tiIORequest,
11970                                   tiDeviceHandle,
11971                                   tiScsiRequest,
11972                                   satIOContext);
11973 
11974 
11975           return status;
11976         }
11977       }
11978       break;
11979     default:
11980       TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11981       satSetSensePayload( pSense,
11982                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11983                           0,
11984                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11985                           satIOContext);
11986 
11987       ostiInitiatorIOCompleted( tiRoot,
11988                                 tiIORequest,
11989                                 tiIOSuccess,
11990                                 SCSI_STAT_CHECK_CONDITION,
11991                                 satIOContext->pTiSenseData,
11992                                 satIOContext->interruptContext );
11993 
11994       break;
11995   } /* end switch */
11996 
11997   return tiSuccess;
11998 
11999 
12000 }
12001 
12002 /*****************************************************************************/
12003 /*! \brief SAT implementation for SCSI satModeSelect6.
12004  *
12005  *  SAT implementation for SCSI satModeSelect6.
12006  *
12007  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
12008  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
12009  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
12010  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
12011  *  \param   satIOContext_t:   Pointer to the SAT IO Context
12012  *
12013  *  \return If command is started successfully
12014  *    - \e tiSuccess:     I/O request successfully initiated.
12015  *    - \e tiBusy:        No resources available, try again later.
12016  *    - \e tiIONoDevice:  Invalid device handle.
12017  *    - \e tiError:       Other errors.
12018  */
12019 /*****************************************************************************/
12020 GLOBAL bit32  satModeSelect6(
12021                    tiRoot_t                  *tiRoot,
12022                    tiIORequest_t             *tiIORequest,
12023                    tiDeviceHandle_t          *tiDeviceHandle,
12024                    tiScsiInitiatorRequest_t *tiScsiRequest,
12025                    satIOContext_t            *satIOContext)
12026 {
12027   bit32                     status;
12028   bit32                     agRequestType;
12029   satDeviceData_t           *pSatDevData;
12030   scsiRspSense_t            *pSense;
12031   tiIniScsiCmnd_t           *scsiCmnd;
12032   agsaFisRegHostToDevice_t  *fis;
12033   bit8                      *pLogPage;    /* Log Page data buffer */
12034   bit32                     StartingIndex = 0;
12035   bit8                      PageCode = 0;
12036   bit32                     chkCnd = agFALSE;
12037 
12038   pSense        = satIOContext->pSense;
12039   pSatDevData   = satIOContext->pSatDevData;
12040   scsiCmnd      = &tiScsiRequest->scsiCmnd;
12041   fis           = satIOContext->pFis;
12042   pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
12043 
12044   TI_DBG5(("satModeSelect6: start\n"));
12045 
12046   /* checking CONTROL */
12047   /* NACA == 1 or LINK == 1*/
12048   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
12049   {
12050     satSetSensePayload( pSense,
12051                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12052                         0,
12053                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12054                         satIOContext);
12055 
12056     ostiInitiatorIOCompleted( tiRoot,
12057                               tiIORequest,
12058                               tiIOSuccess,
12059                               SCSI_STAT_CHECK_CONDITION,
12060                               satIOContext->pTiSenseData,
12061                               satIOContext->interruptContext );
12062 
12063     TI_DBG2(("satModeSelect6: return control\n"));
12064     return tiSuccess;
12065   }
12066 
12067   /* checking PF bit */
12068   if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
12069   {
12070     satSetSensePayload( pSense,
12071                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12072                         0,
12073                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12074                         satIOContext);
12075 
12076     ostiInitiatorIOCompleted( tiRoot,
12077                               tiIORequest,
12078                               tiIOSuccess,
12079                               SCSI_STAT_CHECK_CONDITION,
12080                               satIOContext->pTiSenseData,
12081                               satIOContext->interruptContext );
12082 
12083     TI_DBG1(("satModeSelect6: PF bit check \n"));
12084     return tiSuccess;
12085 
12086   }
12087 
12088   /* checking Block Descriptor Length on Mode parameter header(6)*/
12089   if (pLogPage[3] == 8)
12090   {
12091     /* mode parameter block descriptor exists */
12092     PageCode = (bit8)(pLogPage[12] & 0x3F);   /* page code and index is 4 + 8 */
12093     StartingIndex = 12;
12094   }
12095   else if (pLogPage[3] == 0)
12096   {
12097     /* mode parameter block descriptor does not exist */
12098     PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */
12099     StartingIndex = 4;
12100     ostiInitiatorIOCompleted( tiRoot,
12101                               tiIORequest,
12102                               tiIOSuccess,
12103                               SCSI_STAT_GOOD,
12104                               agNULL,
12105                               satIOContext->interruptContext);
12106     return tiSuccess;
12107   }
12108   else
12109   {
12110     TI_DBG1(("satModeSelect6: return mode parameter block descriptor 0x%x\n", pLogPage[3]));
12111     /* no more than one mode parameter block descriptor shall be supported */
12112     satSetSensePayload( pSense,
12113                         SCSI_SNSKEY_NO_SENSE,
12114                         0,
12115                         SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12116                         satIOContext);
12117 
12118     ostiInitiatorIOCompleted( tiRoot,
12119                               tiIORequest,
12120                               tiIOSuccess,
12121                               SCSI_STAT_CHECK_CONDITION,
12122                               satIOContext->pTiSenseData,
12123                               satIOContext->interruptContext );
12124     return tiSuccess;
12125   }
12126 
12127 
12128 
12129   switch (PageCode) /* page code */
12130   {
12131   case MODESELECT_CONTROL_PAGE:
12132     TI_DBG1(("satModeSelect6: Control mode page\n"));
12133     /*
12134       compare pLogPage to expected value (SAT Table 65, p67)
12135       If not match, return check condition
12136      */
12137     if ( pLogPage[StartingIndex+1] != 0x0A ||
12138          pLogPage[StartingIndex+2] != 0x02 ||
12139          (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12140          (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12141          (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12142          (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12143          (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12144 
12145          (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12146          (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12147          (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12148          (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12149 
12150          pLogPage[StartingIndex+8] != 0xFF ||
12151          pLogPage[StartingIndex+9] != 0xFF ||
12152          pLogPage[StartingIndex+10] != 0x00 ||
12153          pLogPage[StartingIndex+11] != 0x00
12154        )
12155     {
12156       chkCnd = agTRUE;
12157     }
12158     if (chkCnd == agTRUE)
12159     {
12160       satSetSensePayload( pSense,
12161                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12162                         0,
12163                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12164                         satIOContext);
12165 
12166       ostiInitiatorIOCompleted( tiRoot,
12167                               tiIORequest,
12168                               tiIOSuccess,
12169                               SCSI_STAT_CHECK_CONDITION,
12170                               satIOContext->pTiSenseData,
12171                               satIOContext->interruptContext );
12172 
12173       TI_DBG1(("satModeSelect10: unexpected values\n"));
12174     }
12175     else
12176     {
12177       ostiInitiatorIOCompleted( tiRoot,
12178                                 tiIORequest,
12179                                 tiIOSuccess,
12180                                 SCSI_STAT_GOOD,
12181                                 agNULL,
12182                                 satIOContext->interruptContext);
12183     }
12184     return tiSuccess;
12185     break;
12186   case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12187     TI_DBG1(("satModeSelect6: Read-Write Error Recovery mode page\n"));
12188 
12189     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) ||
12190          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) ||
12191          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) ||
12192          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) ||
12193          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) ||
12194          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) ||
12195          (pLogPage[StartingIndex + 10]) ||
12196          (pLogPage[StartingIndex + 11])
12197          )
12198     {
12199       TI_DBG5(("satModeSelect6: return check condition \n"));
12200 
12201       satSetSensePayload( pSense,
12202                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12203                           0,
12204                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12205                           satIOContext);
12206 
12207       ostiInitiatorIOCompleted( tiRoot,
12208                                 tiIORequest,
12209                                 tiIOSuccess,
12210                                 SCSI_STAT_CHECK_CONDITION,
12211                                 satIOContext->pTiSenseData,
12212                                 satIOContext->interruptContext );
12213       return tiSuccess;
12214     }
12215     else
12216     {
12217       TI_DBG5(("satModeSelect6: return GOOD \n"));
12218       ostiInitiatorIOCompleted( tiRoot,
12219                                 tiIORequest,
12220                                 tiIOSuccess,
12221                                 SCSI_STAT_GOOD,
12222                                 agNULL,
12223                                 satIOContext->interruptContext);
12224       return tiSuccess;
12225     }
12226 
12227     break;
12228   case MODESELECT_CACHING:
12229     /* SAT rev8 Table67, p69*/
12230     TI_DBG5(("satModeSelect6: Caching mode page\n"));
12231     if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12232          (pLogPage[StartingIndex + 3]) ||
12233          (pLogPage[StartingIndex + 4]) ||
12234          (pLogPage[StartingIndex + 5]) ||
12235          (pLogPage[StartingIndex + 6]) ||
12236          (pLogPage[StartingIndex + 7]) ||
12237          (pLogPage[StartingIndex + 8]) ||
12238          (pLogPage[StartingIndex + 9]) ||
12239          (pLogPage[StartingIndex + 10]) ||
12240          (pLogPage[StartingIndex + 11]) ||
12241 
12242          (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12243          (pLogPage[StartingIndex + 13]) ||
12244          (pLogPage[StartingIndex + 14]) ||
12245          (pLogPage[StartingIndex + 15])
12246          )
12247     {
12248       TI_DBG1(("satModeSelect6: return check condition \n"));
12249 
12250       satSetSensePayload( pSense,
12251                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12252                           0,
12253                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12254                           satIOContext);
12255 
12256       ostiInitiatorIOCompleted( tiRoot,
12257                                 tiIORequest,
12258                                 tiIOSuccess,
12259                                 SCSI_STAT_CHECK_CONDITION,
12260                                 satIOContext->pTiSenseData,
12261                                 satIOContext->interruptContext );
12262       return tiSuccess;
12263 
12264     }
12265     else
12266     {
12267       /* sends ATA SET FEATURES based on WCE bit */
12268       if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
12269       {
12270         TI_DBG5(("satModeSelect6: disable write cache\n"));
12271         /* sends SET FEATURES */
12272         fis->h.fisType        = 0x27;                   /* Reg host to device */
12273         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12274 
12275         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12276         fis->h.features       = 0x82;                   /* disable write cache */
12277         fis->d.lbaLow         = 0;                      /* */
12278         fis->d.lbaMid         = 0;                      /* */
12279         fis->d.lbaHigh        = 0;                      /* */
12280         fis->d.device         = 0;                      /* */
12281         fis->d.lbaLowExp      = 0;                      /* */
12282         fis->d.lbaMidExp      = 0;                      /* */
12283         fis->d.lbaHighExp     = 0;                      /* */
12284         fis->d.featuresExp    = 0;                      /* */
12285         fis->d.sectorCount    = 0;                      /* */
12286         fis->d.sectorCountExp = 0;                      /* */
12287         fis->d.reserved4      = 0;
12288         fis->d.control        = 0;                      /* FIS HOB bit clear */
12289         fis->d.reserved5      = 0;
12290 
12291         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12292 
12293         /* Initialize CB for SATA completion.
12294          */
12295         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12296 
12297         /*
12298          * Prepare SGL and send FIS to LL layer.
12299          */
12300         satIOContext->reqType = agRequestType;       /* Save it */
12301 
12302         status = sataLLIOStart( tiRoot,
12303                                 tiIORequest,
12304                                 tiDeviceHandle,
12305                                 tiScsiRequest,
12306                                 satIOContext);
12307         return status;
12308       }
12309       else
12310       {
12311         TI_DBG5(("satModeSelect6: enable write cache\n"));
12312         /* sends SET FEATURES */
12313         fis->h.fisType        = 0x27;                   /* Reg host to device */
12314         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12315 
12316         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12317         fis->h.features       = 0x02;                   /* enable write cache */
12318         fis->d.lbaLow         = 0;                      /* */
12319         fis->d.lbaMid         = 0;                      /* */
12320         fis->d.lbaHigh        = 0;                      /* */
12321         fis->d.device         = 0;                      /* */
12322         fis->d.lbaLowExp      = 0;                      /* */
12323         fis->d.lbaMidExp      = 0;                      /* */
12324         fis->d.lbaHighExp     = 0;                      /* */
12325         fis->d.featuresExp    = 0;                      /* */
12326         fis->d.sectorCount    = 0;                      /* */
12327         fis->d.sectorCountExp = 0;                      /* */
12328         fis->d.reserved4      = 0;
12329         fis->d.control        = 0;                      /* FIS HOB bit clear */
12330         fis->d.reserved5      = 0;
12331 
12332         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12333 
12334         /* Initialize CB for SATA completion.
12335          */
12336         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12337 
12338         /*
12339          * Prepare SGL and send FIS to LL layer.
12340          */
12341         satIOContext->reqType = agRequestType;       /* Save it */
12342 
12343         status = sataLLIOStart( tiRoot,
12344                                 tiIORequest,
12345                                 tiDeviceHandle,
12346                                 tiScsiRequest,
12347                                 satIOContext);
12348         return status;
12349 
12350       }
12351     }
12352     break;
12353   case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
12354     TI_DBG5(("satModeSelect6: Informational Exception Control mode page\n"));
12355     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
12356          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
12357          )
12358     {
12359       TI_DBG1(("satModeSelect6: return check condition \n"));
12360 
12361       satSetSensePayload( pSense,
12362                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12363                           0,
12364                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12365                           satIOContext);
12366 
12367       ostiInitiatorIOCompleted( tiRoot,
12368                                 tiIORequest,
12369                                 tiIOSuccess,
12370                                 SCSI_STAT_CHECK_CONDITION,
12371                                 satIOContext->pTiSenseData,
12372                                 satIOContext->interruptContext );
12373       return tiSuccess;
12374     }
12375     else
12376     {
12377       /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
12378       if ( !(pLogPage[StartingIndex + 2] & 0x08) )
12379       {
12380         TI_DBG5(("satModeSelect6: enable information exceptions reporting\n"));
12381         /* sends SMART ENABLE OPERATIONS */
12382         fis->h.fisType        = 0x27;                   /* Reg host to device */
12383         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12384 
12385         fis->h.command        = SAT_SMART_ENABLE_OPERATIONS;       /* 0xB0 */
12386         fis->h.features       = 0xD8;                   /* enable */
12387         fis->d.lbaLow         = 0;                      /* */
12388         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
12389         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
12390         fis->d.device         = 0;                      /* */
12391         fis->d.lbaLowExp      = 0;                      /* */
12392         fis->d.lbaMidExp      = 0;                      /* */
12393         fis->d.lbaHighExp     = 0;                      /* */
12394         fis->d.featuresExp    = 0;                      /* */
12395         fis->d.sectorCount    = 0;                      /* */
12396         fis->d.sectorCountExp = 0;                      /* */
12397         fis->d.reserved4      = 0;
12398         fis->d.control        = 0;                      /* FIS HOB bit clear */
12399         fis->d.reserved5      = 0;
12400 
12401         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12402 
12403         /* Initialize CB for SATA completion.
12404          */
12405         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12406 
12407         /*
12408          * Prepare SGL and send FIS to LL layer.
12409          */
12410         satIOContext->reqType = agRequestType;       /* Save it */
12411 
12412         status = sataLLIOStart( tiRoot,
12413                                 tiIORequest,
12414                                 tiDeviceHandle,
12415                                 tiScsiRequest,
12416                                 satIOContext);
12417         return status;
12418       }
12419       else
12420       {
12421         TI_DBG5(("satModeSelect6: disable information exceptions reporting\n"));
12422         /* sends SMART DISABLE OPERATIONS */
12423         fis->h.fisType        = 0x27;                   /* Reg host to device */
12424         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12425 
12426         fis->h.command        = SAT_SMART_DISABLE_OPERATIONS;       /* 0xB0 */
12427         fis->h.features       = 0xD9;                   /* disable */
12428         fis->d.lbaLow         = 0;                      /* */
12429         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
12430         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
12431         fis->d.device         = 0;                      /* */
12432         fis->d.lbaLowExp      = 0;                      /* */
12433         fis->d.lbaMidExp      = 0;                      /* */
12434         fis->d.lbaHighExp     = 0;                      /* */
12435         fis->d.featuresExp    = 0;                      /* */
12436         fis->d.sectorCount    = 0;                      /* */
12437         fis->d.sectorCountExp = 0;                      /* */
12438         fis->d.reserved4      = 0;
12439         fis->d.control        = 0;                      /* FIS HOB bit clear */
12440         fis->d.reserved5      = 0;
12441 
12442         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12443 
12444         /* Initialize CB for SATA completion.
12445          */
12446         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12447 
12448         /*
12449          * Prepare SGL and send FIS to LL layer.
12450          */
12451         satIOContext->reqType = agRequestType;       /* Save it */
12452 
12453         status = sataLLIOStart( tiRoot,
12454                                 tiIORequest,
12455                                 tiDeviceHandle,
12456                                 tiScsiRequest,
12457                                 satIOContext);
12458         return status;
12459 
12460       }
12461     }
12462     break;
12463   default:
12464     TI_DBG1(("satModeSelect6: Error unknown page code 0x%x\n", pLogPage[12]));
12465     satSetSensePayload( pSense,
12466                         SCSI_SNSKEY_NO_SENSE,
12467                         0,
12468                         SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12469                         satIOContext);
12470 
12471     ostiInitiatorIOCompleted( tiRoot,
12472                               tiIORequest,
12473                               tiIOSuccess,
12474                               SCSI_STAT_CHECK_CONDITION,
12475                               satIOContext->pTiSenseData,
12476                               satIOContext->interruptContext );
12477     return tiSuccess;
12478   }
12479 
12480 }
12481 
12482 /*****************************************************************************/
12483 /*! \brief SAT implementation for SCSI satModeSelect6n10_1.
12484  *
12485  *  This function is part of implementation of ModeSelect6 and ModeSelect10.
12486  *  When ModeSelect6 or ModeSelect10 is coverted into multiple ATA commands,
12487  *  this function is used.
12488  *
12489  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
12490  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
12491  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
12492  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
12493  *  \param   satIOContext_t:   Pointer to the SAT IO Context
12494  *
12495  *  \return If command is started successfully
12496  *    - \e tiSuccess:     I/O request successfully initiated.
12497  *    - \e tiBusy:        No resources available, try again later.
12498  *    - \e tiIONoDevice:  Invalid device handle.
12499  *    - \e tiError:       Other errors.
12500  */
12501 /*****************************************************************************/
12502 GLOBAL bit32  satModeSelect6n10_1(
12503                    tiRoot_t                  *tiRoot,
12504                    tiIORequest_t             *tiIORequest,
12505                    tiDeviceHandle_t          *tiDeviceHandle,
12506                    tiScsiInitiatorRequest_t *tiScsiRequest,
12507                    satIOContext_t            *satIOContext)
12508 {
12509   /* sends either ATA SET FEATURES based on DRA bit */
12510   bit32                     status;
12511   bit32                     agRequestType;
12512   agsaFisRegHostToDevice_t  *fis;
12513   bit8                      *pLogPage;    /* Log Page data buffer */
12514   bit32                     StartingIndex = 0;
12515 
12516   fis           = satIOContext->pFis;
12517   pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
12518   TI_DBG5(("satModeSelect6_1: start\n"));
12519   /* checking Block Descriptor Length on Mode parameter header(6)*/
12520   if (pLogPage[3] == 8)
12521   {
12522     /* mode parameter block descriptor exists */
12523     StartingIndex = 12;
12524   }
12525   else
12526   {
12527     /* mode parameter block descriptor does not exist */
12528     StartingIndex = 4;
12529   }
12530 
12531   /* sends ATA SET FEATURES based on DRA bit */
12532   if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
12533   {
12534     TI_DBG5(("satModeSelect6_1: enable read look-ahead feature\n"));
12535     /* sends SET FEATURES */
12536     fis->h.fisType        = 0x27;                   /* Reg host to device */
12537     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12538 
12539     fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12540     fis->h.features       = 0xAA;                   /* enable read look-ahead */
12541     fis->d.lbaLow         = 0;                      /* */
12542     fis->d.lbaMid         = 0;                      /* */
12543     fis->d.lbaHigh        = 0;                      /* */
12544     fis->d.device         = 0;                      /* */
12545     fis->d.lbaLowExp      = 0;                      /* */
12546     fis->d.lbaMidExp      = 0;                      /* */
12547     fis->d.lbaHighExp     = 0;                      /* */
12548     fis->d.featuresExp    = 0;                      /* */
12549     fis->d.sectorCount    = 0;                      /* */
12550     fis->d.sectorCountExp = 0;                      /* */
12551     fis->d.reserved4      = 0;
12552     fis->d.control        = 0;                      /* FIS HOB bit clear */
12553     fis->d.reserved5      = 0;
12554 
12555     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12556 
12557     /* Initialize CB for SATA completion.
12558      */
12559     satIOContext->satCompleteCB = &satModeSelect6n10CB;
12560 
12561     /*
12562      * Prepare SGL and send FIS to LL layer.
12563      */
12564     satIOContext->reqType = agRequestType;       /* Save it */
12565 
12566     status = sataLLIOStart( tiRoot,
12567                             tiIORequest,
12568                             tiDeviceHandle,
12569                             tiScsiRequest,
12570                             satIOContext);
12571     return status;
12572   }
12573   else
12574   {
12575     TI_DBG5(("satModeSelect6_1: disable read look-ahead feature\n"));
12576         /* sends SET FEATURES */
12577     fis->h.fisType        = 0x27;                   /* Reg host to device */
12578     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12579 
12580     fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12581     fis->h.features       = 0x55;                   /* disable read look-ahead */
12582     fis->d.lbaLow         = 0;                      /* */
12583     fis->d.lbaMid         = 0;                      /* */
12584     fis->d.lbaHigh        = 0;                      /* */
12585     fis->d.device         = 0;                      /* */
12586     fis->d.lbaLowExp      = 0;                      /* */
12587     fis->d.lbaMidExp      = 0;                      /* */
12588     fis->d.lbaHighExp     = 0;                      /* */
12589     fis->d.featuresExp    = 0;                      /* */
12590     fis->d.sectorCount    = 0;                      /* */
12591     fis->d.sectorCountExp = 0;                      /* */
12592     fis->d.reserved4      = 0;
12593     fis->d.control        = 0;                      /* FIS HOB bit clear */
12594     fis->d.reserved5      = 0;
12595 
12596     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12597 
12598     /* Initialize CB for SATA completion.
12599      */
12600     satIOContext->satCompleteCB = &satModeSelect6n10CB;
12601 
12602     /*
12603      * Prepare SGL and send FIS to LL layer.
12604      */
12605     satIOContext->reqType = agRequestType;       /* Save it */
12606 
12607     status = sataLLIOStart( tiRoot,
12608                             tiIORequest,
12609                             tiDeviceHandle,
12610                             tiScsiRequest,
12611                             satIOContext);
12612     return status;
12613   }
12614 
12615 }
12616 
12617 
12618 /*****************************************************************************/
12619 /*! \brief SAT implementation for SCSI satModeSelect10.
12620  *
12621  *  SAT implementation for SCSI satModeSelect10.
12622  *
12623  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
12624  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
12625  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
12626  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
12627  *  \param   satIOContext_t:   Pointer to the SAT IO Context
12628  *
12629  *  \return If command is started successfully
12630  *    - \e tiSuccess:     I/O request successfully initiated.
12631  *    - \e tiBusy:        No resources available, try again later.
12632  *    - \e tiIONoDevice:  Invalid device handle.
12633  *    - \e tiError:       Other errors.
12634  */
12635 /*****************************************************************************/
12636 GLOBAL bit32  satModeSelect10(
12637                    tiRoot_t                  *tiRoot,
12638                    tiIORequest_t             *tiIORequest,
12639                    tiDeviceHandle_t          *tiDeviceHandle,
12640                    tiScsiInitiatorRequest_t *tiScsiRequest,
12641                    satIOContext_t            *satIOContext)
12642 {
12643   bit32                     status;
12644   bit32                     agRequestType;
12645   satDeviceData_t           *pSatDevData;
12646   scsiRspSense_t            *pSense;
12647   tiIniScsiCmnd_t           *scsiCmnd;
12648   agsaFisRegHostToDevice_t  *fis;
12649   bit8                      *pLogPage;    /* Log Page data buffer */
12650   bit16                     BlkDescLen = 0;     /* Block Descriptor Length */
12651   bit32                     StartingIndex = 0;
12652   bit8                      PageCode = 0;
12653   bit32                     chkCnd = agFALSE;
12654 
12655   pSense        = satIOContext->pSense;
12656   pSatDevData   = satIOContext->pSatDevData;
12657   scsiCmnd      = &tiScsiRequest->scsiCmnd;
12658   fis           = satIOContext->pFis;
12659   pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
12660 
12661   TI_DBG5(("satModeSelect10: start\n"));
12662 
12663   /* checking CONTROL */
12664   /* NACA == 1 or LINK == 1*/
12665   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
12666   {
12667     satSetSensePayload( pSense,
12668                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12669                         0,
12670                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12671                         satIOContext);
12672 
12673     ostiInitiatorIOCompleted( tiRoot,
12674                               tiIORequest,
12675                               tiIOSuccess,
12676                               SCSI_STAT_CHECK_CONDITION,
12677                               satIOContext->pTiSenseData,
12678                               satIOContext->interruptContext );
12679 
12680     TI_DBG2(("satModeSelect10: return control\n"));
12681     return tiSuccess;
12682   }
12683 
12684   /* checking PF bit */
12685   if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
12686   {
12687     satSetSensePayload( pSense,
12688                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12689                         0,
12690                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12691                         satIOContext);
12692 
12693     ostiInitiatorIOCompleted( tiRoot,
12694                               tiIORequest,
12695                               tiIOSuccess,
12696                               SCSI_STAT_CHECK_CONDITION,
12697                               satIOContext->pTiSenseData,
12698                               satIOContext->interruptContext );
12699 
12700     TI_DBG1(("satModeSelect10: PF bit check \n"));
12701     return tiSuccess;
12702 
12703   }
12704 
12705   BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]);
12706 
12707   /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/
12708   if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12709   {
12710     /* mode parameter block descriptor exists and length is 8 byte */
12711     PageCode = (bit8)(pLogPage[16] & 0x3F);   /* page code and index is 8 + 8 */
12712     StartingIndex = 16;
12713   }
12714   else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12715   {
12716     /* mode parameter block descriptor exists and length is 16 byte */
12717     PageCode = (bit8)(pLogPage[24] & 0x3F);   /* page code and index is 8 + 16 */
12718     StartingIndex = 24;
12719   }
12720   else if (BlkDescLen == 0)
12721   {
12722     /*
12723       mode parameter block descriptor does not exist
12724       */
12725     PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */
12726     StartingIndex = 8;
12727     ostiInitiatorIOCompleted( tiRoot,
12728                               tiIORequest,
12729                               tiIOSuccess,
12730                               SCSI_STAT_GOOD,
12731                               agNULL,
12732                               satIOContext->interruptContext);
12733     return tiSuccess;
12734   }
12735   else
12736   {
12737     TI_DBG1(("satModeSelect10: return mode parameter block descriptor 0x%x\n",  BlkDescLen));
12738     /* no more than one mode parameter block descriptor shall be supported */
12739     satSetSensePayload( pSense,
12740                         SCSI_SNSKEY_NO_SENSE,
12741                         0,
12742                         SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12743                         satIOContext);
12744 
12745     ostiInitiatorIOCompleted( tiRoot,
12746                               tiIORequest,
12747                               tiIOSuccess,
12748                               SCSI_STAT_CHECK_CONDITION,
12749                               satIOContext->pTiSenseData,
12750                               satIOContext->interruptContext );
12751     return tiSuccess;
12752   }
12753   /*
12754     for debugging only
12755   */
12756   if (StartingIndex == 8)
12757   {
12758     tdhexdump("startingindex 8", (bit8 *)pLogPage, 8);
12759   }
12760   else if(StartingIndex == 16)
12761   {
12762     if (PageCode == MODESELECT_CACHING)
12763     {
12764       tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
12765     }
12766     else
12767     {
12768       tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
12769     }
12770   }
12771   else
12772   {
12773     if (PageCode == MODESELECT_CACHING)
12774     {
12775       tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
12776     }
12777     else
12778     {
12779       tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
12780     }
12781   }
12782   switch (PageCode) /* page code */
12783   {
12784   case MODESELECT_CONTROL_PAGE:
12785     TI_DBG5(("satModeSelect10: Control mode page\n"));
12786     /*
12787       compare pLogPage to expected value (SAT Table 65, p67)
12788       If not match, return check condition
12789      */
12790     if ( pLogPage[StartingIndex+1] != 0x0A ||
12791          pLogPage[StartingIndex+2] != 0x02 ||
12792          (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12793          (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12794          (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12795          (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12796          (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12797 
12798          (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12799          (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12800          (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12801          (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12802 
12803          pLogPage[StartingIndex+8] != 0xFF ||
12804          pLogPage[StartingIndex+9] != 0xFF ||
12805          pLogPage[StartingIndex+10] != 0x00 ||
12806          pLogPage[StartingIndex+11] != 0x00
12807        )
12808     {
12809       chkCnd = agTRUE;
12810     }
12811     if (chkCnd == agTRUE)
12812     {
12813       satSetSensePayload( pSense,
12814                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12815                         0,
12816                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12817                         satIOContext);
12818 
12819       ostiInitiatorIOCompleted( tiRoot,
12820                               tiIORequest,
12821                               tiIOSuccess,
12822                               SCSI_STAT_CHECK_CONDITION,
12823                               satIOContext->pTiSenseData,
12824                               satIOContext->interruptContext );
12825 
12826       TI_DBG1(("satModeSelect10: unexpected values\n"));
12827     }
12828     else
12829     {
12830       ostiInitiatorIOCompleted( tiRoot,
12831                               tiIORequest,
12832                               tiIOSuccess,
12833                               SCSI_STAT_GOOD,
12834                               agNULL,
12835                               satIOContext->interruptContext);
12836     }
12837     return tiSuccess;
12838     break;
12839   case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12840     TI_DBG5(("satModeSelect10: Read-Write Error Recovery mode page\n"));
12841     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) ||
12842          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) ||
12843          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) ||
12844          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) ||
12845          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) ||
12846          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) ||
12847          (pLogPage[StartingIndex + 10]) ||
12848          (pLogPage[StartingIndex + 11])
12849          )
12850     {
12851       TI_DBG1(("satModeSelect10: return check condition \n"));
12852 
12853       satSetSensePayload( pSense,
12854                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12855                           0,
12856                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12857                           satIOContext);
12858 
12859       ostiInitiatorIOCompleted( tiRoot,
12860                                 tiIORequest,
12861                                 tiIOSuccess,
12862                                 SCSI_STAT_CHECK_CONDITION,
12863                                 satIOContext->pTiSenseData,
12864                                 satIOContext->interruptContext );
12865       return tiSuccess;
12866     }
12867     else
12868     {
12869       TI_DBG2(("satModeSelect10: return GOOD \n"));
12870       ostiInitiatorIOCompleted( tiRoot,
12871                                 tiIORequest,
12872                                 tiIOSuccess,
12873                                 SCSI_STAT_GOOD,
12874                                 agNULL,
12875                                 satIOContext->interruptContext);
12876       return tiSuccess;
12877     }
12878 
12879     break;
12880   case MODESELECT_CACHING:
12881     /* SAT rev8 Table67, p69*/
12882     TI_DBG5(("satModeSelect10: Caching mode page\n"));
12883     if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12884          (pLogPage[StartingIndex + 3]) ||
12885          (pLogPage[StartingIndex + 4]) ||
12886          (pLogPage[StartingIndex + 5]) ||
12887          (pLogPage[StartingIndex + 6]) ||
12888          (pLogPage[StartingIndex + 7]) ||
12889          (pLogPage[StartingIndex + 8]) ||
12890          (pLogPage[StartingIndex + 9]) ||
12891          (pLogPage[StartingIndex + 10]) ||
12892          (pLogPage[StartingIndex + 11]) ||
12893 
12894          (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12895          (pLogPage[StartingIndex + 13]) ||
12896          (pLogPage[StartingIndex + 14]) ||
12897          (pLogPage[StartingIndex + 15])
12898          )
12899     {
12900       TI_DBG1(("satModeSelect10: return check condition \n"));
12901 
12902       satSetSensePayload( pSense,
12903                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12904                           0,
12905                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12906                           satIOContext);
12907 
12908       ostiInitiatorIOCompleted( tiRoot,
12909                                 tiIORequest,
12910                                 tiIOSuccess,
12911                                 SCSI_STAT_CHECK_CONDITION,
12912                                 satIOContext->pTiSenseData,
12913                                 satIOContext->interruptContext );
12914       return tiSuccess;
12915 
12916     }
12917     else
12918     {
12919       /* sends ATA SET FEATURES based on WCE bit */
12920       if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
12921       {
12922         TI_DBG5(("satModeSelect10: disable write cache\n"));
12923         /* sends SET FEATURES */
12924         fis->h.fisType        = 0x27;                   /* Reg host to device */
12925         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12926 
12927         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12928         fis->h.features       = 0x82;                   /* disable write cache */
12929         fis->d.lbaLow         = 0;                      /* */
12930         fis->d.lbaMid         = 0;                      /* */
12931         fis->d.lbaHigh        = 0;                      /* */
12932         fis->d.device         = 0;                      /* */
12933         fis->d.lbaLowExp      = 0;                      /* */
12934         fis->d.lbaMidExp      = 0;                      /* */
12935         fis->d.lbaHighExp     = 0;                      /* */
12936         fis->d.featuresExp    = 0;                      /* */
12937         fis->d.sectorCount    = 0;                      /* */
12938         fis->d.sectorCountExp = 0;                      /* */
12939         fis->d.reserved4      = 0;
12940         fis->d.control        = 0;                      /* FIS HOB bit clear */
12941         fis->d.reserved5      = 0;
12942 
12943         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12944 
12945         /* Initialize CB for SATA completion.
12946          */
12947         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12948 
12949         /*
12950          * Prepare SGL and send FIS to LL layer.
12951          */
12952         satIOContext->reqType = agRequestType;       /* Save it */
12953 
12954         status = sataLLIOStart( tiRoot,
12955                                 tiIORequest,
12956                                 tiDeviceHandle,
12957                                 tiScsiRequest,
12958                                 satIOContext);
12959         return status;
12960       }
12961       else
12962       {
12963         TI_DBG5(("satModeSelect10: enable write cache\n"));
12964         /* sends SET FEATURES */
12965         fis->h.fisType        = 0x27;                   /* Reg host to device */
12966         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12967 
12968         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12969         fis->h.features       = 0x02;                   /* enable write cache */
12970         fis->d.lbaLow         = 0;                      /* */
12971         fis->d.lbaMid         = 0;                      /* */
12972         fis->d.lbaHigh        = 0;                      /* */
12973         fis->d.device         = 0;                      /* */
12974         fis->d.lbaLowExp      = 0;                      /* */
12975         fis->d.lbaMidExp      = 0;                      /* */
12976         fis->d.lbaHighExp     = 0;                      /* */
12977         fis->d.featuresExp    = 0;                      /* */
12978         fis->d.sectorCount    = 0;                      /* */
12979         fis->d.sectorCountExp = 0;                      /* */
12980         fis->d.reserved4      = 0;
12981         fis->d.control        = 0;                      /* FIS HOB bit clear */
12982         fis->d.reserved5      = 0;
12983 
12984         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12985 
12986         /* Initialize CB for SATA completion.
12987          */
12988         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12989 
12990         /*
12991          * Prepare SGL and send FIS to LL layer.
12992          */
12993         satIOContext->reqType = agRequestType;       /* Save it */
12994 
12995         status = sataLLIOStart( tiRoot,
12996                                 tiIORequest,
12997                                 tiDeviceHandle,
12998                                 tiScsiRequest,
12999                                 satIOContext);
13000         return status;
13001 
13002       }
13003     }
13004     break;
13005   case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
13006     TI_DBG5(("satModeSelect10: Informational Exception Control mode page\n"));
13007 
13008     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
13009          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
13010          )
13011     {
13012       TI_DBG1(("satModeSelect10: return check condition \n"));
13013 
13014       satSetSensePayload( pSense,
13015                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13016                           0,
13017                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13018                           satIOContext);
13019 
13020       ostiInitiatorIOCompleted( tiRoot,
13021                                 tiIORequest,
13022                                 tiIOSuccess,
13023                                 SCSI_STAT_CHECK_CONDITION,
13024                                 satIOContext->pTiSenseData,
13025                                 satIOContext->interruptContext );
13026       return tiSuccess;
13027     }
13028     else
13029     {
13030       /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
13031       if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
13032       {
13033         TI_DBG5(("satModeSelect10: enable information exceptions reporting\n"));
13034         /* sends SMART ENABLE OPERATIONS */
13035         fis->h.fisType        = 0x27;                   /* Reg host to device */
13036         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13037 
13038         fis->h.command        = SAT_SMART_ENABLE_OPERATIONS;       /* 0xB0 */
13039         fis->h.features       = 0xD8;                   /* enable */
13040         fis->d.lbaLow         = 0;                      /* */
13041         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
13042         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
13043         fis->d.device         = 0;                      /* */
13044         fis->d.lbaLowExp      = 0;                      /* */
13045         fis->d.lbaMidExp      = 0;                      /* */
13046         fis->d.lbaHighExp     = 0;                      /* */
13047         fis->d.featuresExp    = 0;                      /* */
13048         fis->d.sectorCount    = 0;                      /* */
13049         fis->d.sectorCountExp = 0;                      /* */
13050         fis->d.reserved4      = 0;
13051         fis->d.control        = 0;                      /* FIS HOB bit clear */
13052         fis->d.reserved5      = 0;
13053 
13054         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13055 
13056         /* Initialize CB for SATA completion.
13057          */
13058         satIOContext->satCompleteCB = &satModeSelect6n10CB;
13059 
13060         /*
13061          * Prepare SGL and send FIS to LL layer.
13062          */
13063         satIOContext->reqType = agRequestType;       /* Save it */
13064 
13065         status = sataLLIOStart( tiRoot,
13066                                 tiIORequest,
13067                                 tiDeviceHandle,
13068                                 tiScsiRequest,
13069                                 satIOContext);
13070         return status;
13071       }
13072       else
13073       {
13074         TI_DBG5(("satModeSelect10: disable information exceptions reporting\n"));
13075         /* sends SMART DISABLE OPERATIONS */
13076         fis->h.fisType        = 0x27;                   /* Reg host to device */
13077         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13078 
13079         fis->h.command        = SAT_SMART_DISABLE_OPERATIONS;       /* 0xB0 */
13080         fis->h.features       = 0xD9;                   /* disable */
13081         fis->d.lbaLow         = 0;                      /* */
13082         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
13083         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
13084         fis->d.device         = 0;                      /* */
13085         fis->d.lbaLowExp      = 0;                      /* */
13086         fis->d.lbaMidExp      = 0;                      /* */
13087         fis->d.lbaHighExp     = 0;                      /* */
13088         fis->d.featuresExp    = 0;                      /* */
13089         fis->d.sectorCount    = 0;                      /* */
13090         fis->d.sectorCountExp = 0;                      /* */
13091         fis->d.reserved4      = 0;
13092         fis->d.control        = 0;                      /* FIS HOB bit clear */
13093         fis->d.reserved5      = 0;
13094 
13095         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13096 
13097         /* Initialize CB for SATA completion.
13098          */
13099         satIOContext->satCompleteCB = &satModeSelect6n10CB;
13100 
13101         /*
13102          * Prepare SGL and send FIS to LL layer.
13103          */
13104         satIOContext->reqType = agRequestType;       /* Save it */
13105 
13106         status = sataLLIOStart( tiRoot,
13107                                 tiIORequest,
13108                                 tiDeviceHandle,
13109                                 tiScsiRequest,
13110                                 satIOContext);
13111         return status;
13112 
13113       }
13114     }
13115     break;
13116   default:
13117     TI_DBG1(("satModeSelect10: Error unknown page code 0x%x\n", pLogPage[12]));
13118     satSetSensePayload( pSense,
13119                         SCSI_SNSKEY_NO_SENSE,
13120                         0,
13121                         SCSI_SNSCODE_NO_ADDITIONAL_INFO,
13122                         satIOContext);
13123 
13124     ostiInitiatorIOCompleted( tiRoot,
13125                               tiIORequest,
13126                               tiIOSuccess,
13127                               SCSI_STAT_CHECK_CONDITION,
13128                               satIOContext->pTiSenseData,
13129                               satIOContext->interruptContext );
13130     return tiSuccess;
13131   }
13132 
13133 }
13134 
13135 
13136 /*****************************************************************************/
13137 /*! \brief SAT implementation for SCSI satSynchronizeCache10.
13138  *
13139  *  SAT implementation for SCSI satSynchronizeCache10.
13140  *
13141  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
13142  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
13143  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
13144  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
13145  *  \param   satIOContext_t:   Pointer to the SAT IO Context
13146  *
13147  *  \return If command is started successfully
13148  *    - \e tiSuccess:     I/O request successfully initiated.
13149  *    - \e tiBusy:        No resources available, try again later.
13150  *    - \e tiIONoDevice:  Invalid device handle.
13151  *    - \e tiError:       Other errors.
13152  */
13153 /*****************************************************************************/
13154 GLOBAL bit32  satSynchronizeCache10(
13155                    tiRoot_t                  *tiRoot,
13156                    tiIORequest_t             *tiIORequest,
13157                    tiDeviceHandle_t          *tiDeviceHandle,
13158                    tiScsiInitiatorRequest_t *tiScsiRequest,
13159                    satIOContext_t            *satIOContext)
13160 {
13161   bit32                     status;
13162   bit32                     agRequestType;
13163   satDeviceData_t           *pSatDevData;
13164   scsiRspSense_t            *pSense;
13165   tiIniScsiCmnd_t           *scsiCmnd;
13166   agsaFisRegHostToDevice_t  *fis;
13167 
13168   pSense        = satIOContext->pSense;
13169   pSatDevData   = satIOContext->pSatDevData;
13170   scsiCmnd      = &tiScsiRequest->scsiCmnd;
13171   fis           = satIOContext->pFis;
13172 
13173   TI_DBG5(("satSynchronizeCache10: start\n"));
13174 
13175   /* checking CONTROL */
13176   /* NACA == 1 or LINK == 1*/
13177   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13178   {
13179     satSetSensePayload( pSense,
13180                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13181                         0,
13182                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13183                         satIOContext);
13184 
13185     ostiInitiatorIOCompleted( tiRoot,
13186                               tiIORequest,
13187                               tiIOSuccess,
13188                               SCSI_STAT_CHECK_CONDITION,
13189                               satIOContext->pTiSenseData,
13190                               satIOContext->interruptContext );
13191 
13192     TI_DBG2(("satSynchronizeCache10: return control\n"));
13193     return tiSuccess;
13194   }
13195 
13196   /* checking IMMED bit */
13197   if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13198   {
13199     TI_DBG1(("satSynchronizeCache10: GOOD status due to IMMED bit\n"));
13200 
13201     /* return GOOD status first here */
13202     ostiInitiatorIOCompleted( tiRoot,
13203                               tiIORequest,
13204                               tiIOSuccess,
13205                               SCSI_STAT_GOOD,
13206                               agNULL,
13207                               satIOContext->interruptContext);
13208   }
13209 
13210   /* sends FLUSH CACHE or FLUSH CACHE EXT */
13211   if (pSatDevData->sat48BitSupport == agTRUE)
13212   {
13213     TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE EXT\n"));
13214     /* FLUSH CACHE EXT */
13215     fis->h.fisType        = 0x27;                   /* Reg host to device */
13216     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13217 
13218     fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
13219     fis->h.features       = 0;                      /* FIS reserve */
13220     fis->d.featuresExp    = 0;                      /* FIS reserve */
13221     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13222     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
13223     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13224     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
13225     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13226     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13227     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13228     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13229     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13230     fis->d.control        = 0;                      /* FIS HOB bit clear */
13231     fis->d.reserved4      = 0;
13232     fis->d.reserved5      = 0;
13233 
13234   }
13235   else
13236   {
13237     TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE\n"));
13238     /* FLUSH CACHE */
13239     fis->h.fisType        = 0x27;                   /* Reg host to device */
13240     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13241 
13242     fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
13243     fis->h.features       = 0;                      /* FIS features NA       */
13244     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13245     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13246     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13247     fis->d.lbaLowExp      = 0;
13248     fis->d.lbaMidExp      = 0;
13249     fis->d.lbaHighExp     = 0;
13250     fis->d.featuresExp    = 0;
13251     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13252     fis->d.sectorCountExp = 0;
13253     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13254     fis->d.control        = 0;                      /* FIS HOB bit clear */
13255     fis->d.reserved4      = 0;
13256     fis->d.reserved5      = 0;
13257 
13258   }
13259 
13260   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13261 
13262   /* Initialize CB for SATA completion.
13263    */
13264   satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13265 
13266   /*
13267    * Prepare SGL and send FIS to LL layer.
13268    */
13269   satIOContext->reqType = agRequestType;       /* Save it */
13270 
13271   status = sataLLIOStart( tiRoot,
13272                           tiIORequest,
13273                           tiDeviceHandle,
13274                           tiScsiRequest,
13275                           satIOContext);
13276 
13277 
13278   return (status);
13279 }
13280 
13281 /*****************************************************************************/
13282 /*! \brief SAT implementation for SCSI satSynchronizeCache16.
13283  *
13284  *  SAT implementation for SCSI satSynchronizeCache16.
13285  *
13286  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
13287  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
13288  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
13289  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
13290  *  \param   satIOContext_t:   Pointer to the SAT IO Context
13291  *
13292  *  \return If command is started successfully
13293  *    - \e tiSuccess:     I/O request successfully initiated.
13294  *    - \e tiBusy:        No resources available, try again later.
13295  *    - \e tiIONoDevice:  Invalid device handle.
13296  *    - \e tiError:       Other errors.
13297  */
13298 /*****************************************************************************/
13299 GLOBAL bit32  satSynchronizeCache16(
13300                    tiRoot_t                  *tiRoot,
13301                    tiIORequest_t             *tiIORequest,
13302                    tiDeviceHandle_t          *tiDeviceHandle,
13303                    tiScsiInitiatorRequest_t *tiScsiRequest,
13304                    satIOContext_t            *satIOContext)
13305 {
13306   bit32                     status;
13307   bit32                     agRequestType;
13308   satDeviceData_t           *pSatDevData;
13309   scsiRspSense_t            *pSense;
13310   tiIniScsiCmnd_t           *scsiCmnd;
13311   agsaFisRegHostToDevice_t  *fis;
13312 
13313   pSense        = satIOContext->pSense;
13314   pSatDevData   = satIOContext->pSatDevData;
13315   scsiCmnd      = &tiScsiRequest->scsiCmnd;
13316   fis           = satIOContext->pFis;
13317 
13318   TI_DBG5(("satSynchronizeCache16: start\n"));
13319 
13320   /* checking CONTROL */
13321   /* NACA == 1 or LINK == 1*/
13322   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
13323   {
13324     satSetSensePayload( pSense,
13325                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13326                         0,
13327                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13328                         satIOContext);
13329 
13330     ostiInitiatorIOCompleted( tiRoot,
13331                               tiIORequest,
13332                               tiIOSuccess,
13333                               SCSI_STAT_CHECK_CONDITION,
13334                               satIOContext->pTiSenseData,
13335                               satIOContext->interruptContext );
13336 
13337     TI_DBG1(("satSynchronizeCache16: return control\n"));
13338     return tiSuccess;
13339   }
13340 
13341 
13342   /* checking IMMED bit */
13343   if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13344   {
13345     TI_DBG1(("satSynchronizeCache16: GOOD status due to IMMED bit\n"));
13346 
13347     /* return GOOD status first here */
13348     ostiInitiatorIOCompleted( tiRoot,
13349                               tiIORequest,
13350                               tiIOSuccess,
13351                               SCSI_STAT_GOOD,
13352                               agNULL,
13353                               satIOContext->interruptContext);
13354   }
13355 
13356   /* sends FLUSH CACHE or FLUSH CACHE EXT */
13357   if (pSatDevData->sat48BitSupport == agTRUE)
13358   {
13359     TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE EXT\n"));
13360     /* FLUSH CACHE EXT */
13361     fis->h.fisType        = 0x27;                   /* Reg host to device */
13362     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13363 
13364     fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
13365     fis->h.features       = 0;                      /* FIS reserve */
13366     fis->d.featuresExp    = 0;                      /* FIS reserve */
13367     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13368     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
13369     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13370     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
13371     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13372     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13373     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13374     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13375     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13376     fis->d.control        = 0;                      /* FIS HOB bit clear */
13377     fis->d.reserved4      = 0;
13378     fis->d.reserved5      = 0;
13379 
13380   }
13381   else
13382   {
13383     TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE\n"));
13384     /* FLUSH CACHE */
13385     fis->h.fisType        = 0x27;                   /* Reg host to device */
13386     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13387 
13388     fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
13389     fis->h.features       = 0;                      /* FIS features NA       */
13390     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13391     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13392     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13393     fis->d.lbaLowExp      = 0;
13394     fis->d.lbaMidExp      = 0;
13395     fis->d.lbaHighExp     = 0;
13396     fis->d.featuresExp    = 0;
13397     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13398     fis->d.sectorCountExp = 0;
13399     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13400     fis->d.control        = 0;                      /* FIS HOB bit clear */
13401     fis->d.reserved4      = 0;
13402     fis->d.reserved5      = 0;
13403 
13404   }
13405 
13406   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13407 
13408   /* Initialize CB for SATA completion.
13409    */
13410   satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13411 
13412   /*
13413    * Prepare SGL and send FIS to LL layer.
13414    */
13415   satIOContext->reqType = agRequestType;       /* Save it */
13416 
13417   status = sataLLIOStart( tiRoot,
13418                           tiIORequest,
13419                           tiDeviceHandle,
13420                           tiScsiRequest,
13421                           satIOContext);
13422 
13423 
13424   return (status);
13425 }
13426 
13427 
13428 /*****************************************************************************/
13429 /*! \brief SAT implementation for SCSI satWriteAndVerify10.
13430  *
13431  *  SAT implementation for SCSI satWriteAndVerify10.
13432  *
13433  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
13434  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
13435  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
13436  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
13437  *  \param   satIOContext_t:   Pointer to the SAT IO Context
13438  *
13439  *  \return If command is started successfully
13440  *    - \e tiSuccess:     I/O request successfully initiated.
13441  *    - \e tiBusy:        No resources available, try again later.
13442  *    - \e tiIONoDevice:  Invalid device handle.
13443  *    - \e tiError:       Other errors.
13444  */
13445 /*****************************************************************************/
13446 GLOBAL bit32  satWriteAndVerify10(
13447                    tiRoot_t                  *tiRoot,
13448                    tiIORequest_t             *tiIORequest,
13449                    tiDeviceHandle_t          *tiDeviceHandle,
13450                    tiScsiInitiatorRequest_t *tiScsiRequest,
13451                    satIOContext_t            *satIOContext)
13452 {
13453   /*
13454     combination of write10 and verify10
13455   */
13456 
13457   bit32                     status;
13458   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13459   satDeviceData_t           *pSatDevData;
13460   scsiRspSense_t            *pSense;
13461   tiIniScsiCmnd_t           *scsiCmnd;
13462   agsaFisRegHostToDevice_t  *fis;
13463   bit32                     lba = 0;
13464   bit32                     tl = 0;
13465   bit32                     LoopNum = 1;
13466   bit8                      LBA[4];
13467   bit8                      TL[4];
13468   bit32                     rangeChk = agFALSE; /* lba and tl range check */
13469 
13470   pSense        = satIOContext->pSense;
13471   pSatDevData   = satIOContext->pSatDevData;
13472   scsiCmnd      = &tiScsiRequest->scsiCmnd;
13473   fis           = satIOContext->pFis;
13474 
13475   TI_DBG5(("satWriteAndVerify10: start\n"));
13476 
13477 
13478   /* checking BYTCHK bit */
13479   if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13480   {
13481     satSetSensePayload( pSense,
13482                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13483                         0,
13484                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13485                         satIOContext);
13486 
13487     ostiInitiatorIOCompleted( tiRoot,
13488                               tiIORequest,
13489                               tiIOSuccess,
13490                               SCSI_STAT_CHECK_CONDITION,
13491                               satIOContext->pTiSenseData,
13492                               satIOContext->interruptContext );
13493 
13494     TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13495     return tiSuccess;
13496   }
13497 
13498 
13499   /* checking CONTROL */
13500   /* NACA == 1 or LINK == 1*/
13501   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13502   {
13503     satSetSensePayload( pSense,
13504                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13505                         0,
13506                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13507                         satIOContext);
13508 
13509     ostiInitiatorIOCompleted( tiRoot,
13510                               tiIORequest,
13511                               tiIOSuccess,
13512                               SCSI_STAT_CHECK_CONDITION,
13513                               satIOContext->pTiSenseData,
13514                               satIOContext->interruptContext );
13515 
13516     TI_DBG1(("satWriteAndVerify10: return control\n"));
13517     return tiSuccess;
13518   }
13519 
13520   osti_memset(LBA, 0, sizeof(LBA));
13521   osti_memset(TL, 0, sizeof(TL));
13522 
13523   /* do not use memcpy due to indexing in LBA and TL */
13524   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
13525   LBA[1] = scsiCmnd->cdb[3];
13526   LBA[2] = scsiCmnd->cdb[4];
13527   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
13528 
13529   TL[0] = 0;
13530   TL[1] = 0;
13531   TL[2] = scsiCmnd->cdb[7];  /* MSB */
13532   TL[3] = scsiCmnd->cdb[8];  /* LSB */
13533 
13534   rangeChk = satAddNComparebit32(LBA, TL);
13535 
13536   /* cbd10; computing LBA and transfer length */
13537   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13538     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13539   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13540 
13541 
13542   /* Table 34, 9.1, p 46 */
13543   /*
13544     note: As of 2/10/2006, no support for DMA QUEUED
13545    */
13546 
13547   /*
13548     Table 34, 9.1, p 46, b
13549     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13550     return check condition
13551   */
13552   if (pSatDevData->satNCQ != agTRUE &&
13553       pSatDevData->sat48BitSupport != agTRUE
13554       )
13555   {
13556     if (lba > SAT_TR_LBA_LIMIT - 1)
13557     {
13558       satSetSensePayload( pSense,
13559                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13560                           0,
13561                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13562                           satIOContext);
13563 
13564       ostiInitiatorIOCompleted( tiRoot,
13565                                 tiIORequest,
13566                                 tiIOSuccess,
13567                                 SCSI_STAT_CHECK_CONDITION,
13568                                 satIOContext->pTiSenseData,
13569                                 satIOContext->interruptContext );
13570 
13571     TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13572     return tiSuccess;
13573     }
13574 
13575     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
13576     {
13577       TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
13578       satSetSensePayload( pSense,
13579                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13580                           0,
13581                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13582                           satIOContext);
13583 
13584       ostiInitiatorIOCompleted( tiRoot,
13585                                 tiIORequest,
13586                                 tiIOSuccess,
13587                                 SCSI_STAT_CHECK_CONDITION,
13588                                 satIOContext->pTiSenseData,
13589                                 satIOContext->interruptContext );
13590 
13591     return tiSuccess;
13592     }
13593   }
13594 
13595 
13596   /* case 1 and 2 */
13597   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
13598   {
13599     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13600     {
13601       /* case 2 */
13602       /* WRITE DMA*/
13603       /* can't fit the transfer length */
13604       TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
13605       fis->h.fisType        = 0x27;                   /* Reg host to device */
13606       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
13607       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
13608       fis->h.features       = 0;                      /* FIS reserve */
13609       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13610       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13611       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13612 
13613       /* FIS LBA mode set LBA (27:24) */
13614       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13615 
13616       fis->d.lbaLowExp      = 0;
13617       fis->d.lbaMidExp      = 0;
13618       fis->d.lbaHighExp     = 0;
13619       fis->d.featuresExp    = 0;
13620       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13621       fis->d.sectorCountExp = 0;
13622       fis->d.reserved4      = 0;
13623       fis->d.control        = 0;                      /* FIS HOB bit clear */
13624       fis->d.reserved5      = 0;
13625 
13626       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13627       satIOContext->ATACmd = SAT_WRITE_DMA;
13628     }
13629     else
13630     {
13631       /* case 1 */
13632       /* WRITE MULTIPLE or WRITE SECTOR(S) */
13633       /* WRITE SECTORS for easier implemetation */
13634       /* can't fit the transfer length */
13635       TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
13636       fis->h.fisType        = 0x27;                   /* Reg host to device */
13637       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
13638       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
13639       fis->h.features       = 0;                      /* FIS reserve */
13640       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13641       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13642       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13643 
13644       /* FIS LBA mode set LBA (27:24) */
13645       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13646 
13647       fis->d.lbaLowExp      = 0;
13648       fis->d.lbaMidExp      = 0;
13649       fis->d.lbaHighExp     = 0;
13650       fis->d.featuresExp    = 0;
13651       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13652       fis->d.sectorCountExp = 0;
13653       fis->d.reserved4      = 0;
13654       fis->d.control        = 0;                      /* FIS HOB bit clear */
13655       fis->d.reserved5      = 0;
13656 
13657       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13658       satIOContext->ATACmd = SAT_WRITE_SECTORS;
13659 
13660     }
13661   }
13662 
13663   /* case 3 and 4 */
13664   if (pSatDevData->sat48BitSupport == agTRUE)
13665   {
13666     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13667     {
13668       /* case 3 */
13669       /* WRITE DMA EXT or WRITE DMA FUA EXT */
13670       TI_DBG5(("satWriteAndVerify10: case 3\n"));
13671       fis->h.fisType        = 0x27;                   /* Reg host to device */
13672       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13673 
13674       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
13675       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
13676 
13677       fis->h.features       = 0;                      /* FIS reserve */
13678       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13679       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13680       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13681       fis->d.device         = 0x40;                   /* FIS LBA mode set */
13682       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
13683       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13684       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13685       fis->d.featuresExp    = 0;                      /* FIS reserve */
13686       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13687       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
13688       fis->d.reserved4      = 0;
13689       fis->d.control        = 0;                      /* FIS HOB bit clear */
13690       fis->d.reserved5      = 0;
13691 
13692       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13693       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
13694     }
13695     else
13696     {
13697       /* case 4 */
13698       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
13699       /* WRITE SECTORS EXT for easier implemetation */
13700       TI_DBG5(("satWriteAndVerify10: case 4\n"));
13701       fis->h.fisType        = 0x27;                   /* Reg host to device */
13702       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13703       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
13704 
13705       fis->h.features       = 0;                      /* FIS reserve */
13706       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13707       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13708       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13709       fis->d.device         = 0x40;                   /* FIS LBA mode set */
13710       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
13711       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13712       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13713       fis->d.featuresExp    = 0;                      /* FIS reserve */
13714       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13715       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
13716       fis->d.reserved4      = 0;
13717       fis->d.control        = 0;                      /* FIS HOB bit clear */
13718       fis->d.reserved5      = 0;
13719 
13720       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13721       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
13722     }
13723   }
13724   /* case 5 */
13725   if (pSatDevData->satNCQ == agTRUE)
13726   {
13727     /* WRITE FPDMA QUEUED */
13728     if (pSatDevData->sat48BitSupport != agTRUE)
13729     {
13730       TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
13731       satSetSensePayload( pSense,
13732                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13733                           0,
13734                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13735                           satIOContext);
13736 
13737       ostiInitiatorIOCompleted( tiRoot,
13738                                 tiIORequest,
13739                                 tiIOSuccess,
13740                                 SCSI_STAT_CHECK_CONDITION,
13741                                 satIOContext->pTiSenseData,
13742                                 satIOContext->interruptContext );
13743       return tiSuccess;
13744     }
13745     TI_DBG5(("satWriteAndVerify10: case 5\n"));
13746 
13747     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
13748 
13749     fis->h.fisType        = 0x27;                   /* Reg host to device */
13750     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13751     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
13752     fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13753     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13754     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13755     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13756 
13757     /* Check FUA bit */
13758     if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
13759       fis->d.device       = 0xC0;                   /* FIS FUA set */
13760     else
13761       fis->d.device       = 0x40;                   /* FIS FUA clear */
13762 
13763     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
13764     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13765     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13766     fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
13767     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
13768     fis->d.sectorCountExp = 0;
13769     fis->d.reserved4      = 0;
13770     fis->d.control        = 0;                      /* FIS HOB bit clear */
13771     fis->d.reserved5      = 0;
13772 
13773     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
13774     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
13775   }
13776 
13777   satIOContext->currentLBA = lba;
13778   satIOContext->OrgTL = tl;
13779 
13780   /*
13781     computing number of loop and remainder for tl
13782     0xFF in case not ext
13783     0xFFFF in case EXT
13784   */
13785   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13786   {
13787     LoopNum = satComputeLoopNum(tl, 0xFF);
13788   }
13789   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13790            fis->h.command == SAT_WRITE_DMA_EXT     ||
13791            fis->h.command == SAT_WRITE_DMA_FUA_EXT
13792            )
13793   {
13794     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
13795     LoopNum = satComputeLoopNum(tl, 0xFFFF);
13796   }
13797   else
13798   {
13799     /* SAT_WRITE_FPDMA_QUEUED */
13800     LoopNum = satComputeLoopNum(tl, 0xFFFF);
13801   }
13802 
13803   satIOContext->LoopNum = LoopNum;
13804 
13805 
13806   if (LoopNum == 1)
13807   {
13808     TI_DBG5(("satWriteAndVerify10: NON CHAINED data\n"));
13809     /* Initialize CB for SATA completion.
13810      */
13811     satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
13812   }
13813   else
13814   {
13815     TI_DBG1(("satWriteAndVerify10: CHAINED data\n"));
13816     /* re-setting tl */
13817     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13818     {
13819        fis->d.sectorCount    = 0xFF;
13820     }
13821     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13822              fis->h.command == SAT_WRITE_DMA_EXT ||
13823              fis->h.command == SAT_WRITE_DMA_FUA_EXT
13824              )
13825     {
13826       fis->d.sectorCount    = 0xFF;
13827       fis->d.sectorCountExp = 0xFF;
13828     }
13829     else
13830     {
13831       /* SAT_WRITE_FPDMA_QUEUED */
13832       fis->h.features       = 0xFF;
13833       fis->d.featuresExp    = 0xFF;
13834     }
13835 
13836     /* Initialize CB for SATA completion.
13837      */
13838     satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
13839   }
13840 
13841 
13842   /*
13843    * Prepare SGL and send FIS to LL layer.
13844    */
13845   satIOContext->reqType = agRequestType;       /* Save it */
13846 
13847   status = sataLLIOStart( tiRoot,
13848                           tiIORequest,
13849                           tiDeviceHandle,
13850                           tiScsiRequest,
13851                           satIOContext);
13852   return (status);
13853 
13854 }
13855 
13856 
13857 
13858 
13859 
13860 
13861 #ifdef REMOVED
13862 GLOBAL bit32  satWriteAndVerify10(
13863                    tiRoot_t                  *tiRoot,
13864                    tiIORequest_t             *tiIORequest,
13865                    tiDeviceHandle_t          *tiDeviceHandle,
13866                    tiScsiInitiatorRequest_t *tiScsiRequest,
13867                    satIOContext_t            *satIOContext)
13868 {
13869   /*
13870     combination of write10 and verify10
13871   */
13872 
13873   bit32                     status;
13874   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13875   satDeviceData_t           *pSatDevData;
13876   scsiRspSense_t            *pSense;
13877   tiIniScsiCmnd_t           *scsiCmnd;
13878   agsaFisRegHostToDevice_t  *fis;
13879   bit32                     lba = 0;
13880   bit32                     tl = 0;
13881 
13882   pSense        = satIOContext->pSense;
13883   pSatDevData   = satIOContext->pSatDevData;
13884   scsiCmnd      = &tiScsiRequest->scsiCmnd;
13885   fis           = satIOContext->pFis;
13886 
13887   TI_DBG5(("satWriteAndVerify10: start\n"));
13888 
13889 
13890   /* checking BYTCHK bit */
13891   if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13892   {
13893     satSetSensePayload( pSense,
13894                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13895                         0,
13896                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13897                         satIOContext);
13898 
13899     ostiInitiatorIOCompleted( tiRoot,
13900                               tiIORequest,
13901                               tiIOSuccess,
13902                               SCSI_STAT_CHECK_CONDITION,
13903                               satIOContext->pTiSenseData,
13904                               satIOContext->interruptContext );
13905 
13906     TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13907     return tiSuccess;
13908   }
13909 
13910 
13911   /* checking CONTROL */
13912   /* NACA == 1 or LINK == 1*/
13913   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13914   {
13915     satSetSensePayload( pSense,
13916                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13917                         0,
13918                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13919                         satIOContext);
13920 
13921     ostiInitiatorIOCompleted( tiRoot,
13922                               tiIORequest,
13923                               tiIOSuccess,
13924                               SCSI_STAT_CHECK_CONDITION,
13925                               satIOContext->pTiSenseData,
13926                               satIOContext->interruptContext );
13927 
13928     TI_DBG2(("satWriteAndVerify10: return control\n"));
13929     return tiSuccess;
13930   }
13931 
13932   /* let's do write10 */
13933   if ( pSatDevData->sat48BitSupport != agTRUE )
13934   {
13935     /*
13936       writeandverify10 but no support for 48 bit addressing -> problem in transfer
13937       length(sector count)
13938     */
13939     satSetSensePayload( pSense,
13940                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13941                         0,
13942                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13943                         satIOContext);
13944 
13945     ostiInitiatorIOCompleted( tiRoot,
13946                               tiIORequest,
13947                               tiIOSuccess,
13948                               SCSI_STAT_CHECK_CONDITION,
13949                               satIOContext->pTiSenseData,
13950                               satIOContext->interruptContext );
13951 
13952     TI_DBG1(("satWriteAndVerify10: return internal checking\n"));
13953     return tiSuccess;
13954   }
13955 
13956   /* cbd10; computing LBA and transfer length */
13957   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13958     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13959   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13960 
13961 
13962   /* Table 34, 9.1, p 46 */
13963   /*
13964     note: As of 2/10/2006, no support for DMA QUEUED
13965    */
13966 
13967   /*
13968     Table 34, 9.1, p 46, b
13969     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13970     return check condition
13971   */
13972   if (pSatDevData->satNCQ != agTRUE &&
13973       pSatDevData->sat48BitSupport != agTRUE
13974       )
13975   {
13976     if (lba > SAT_TR_LBA_LIMIT - 1)
13977     {
13978       satSetSensePayload( pSense,
13979                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13980                           0,
13981                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13982                           satIOContext);
13983 
13984       ostiInitiatorIOCompleted( tiRoot,
13985                                 tiIORequest,
13986                                 tiIOSuccess,
13987                                 SCSI_STAT_CHECK_CONDITION,
13988                                 satIOContext->pTiSenseData,
13989                                 satIOContext->interruptContext );
13990 
13991     TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13992     return tiSuccess;
13993     }
13994   }
13995 
13996 
13997   /* case 1 and 2 */
13998   if (lba + tl <= SAT_TR_LBA_LIMIT)
13999   {
14000     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14001     {
14002       /* case 2 */
14003       /* WRITE DMA*/
14004       /* can't fit the transfer length */
14005       TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
14006       fis->h.fisType        = 0x27;                   /* Reg host to device */
14007       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14008       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
14009       fis->h.features       = 0;                      /* FIS reserve */
14010       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14011       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14012       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14013 
14014       /* FIS LBA mode set LBA (27:24) */
14015       fis->d.device         = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14016 
14017       fis->d.lbaLowExp      = 0;
14018       fis->d.lbaMidExp      = 0;
14019       fis->d.lbaHighExp     = 0;
14020       fis->d.featuresExp    = 0;
14021       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14022       fis->d.sectorCountExp = 0;
14023       fis->d.reserved4      = 0;
14024       fis->d.control        = 0;                      /* FIS HOB bit clear */
14025       fis->d.reserved5      = 0;
14026 
14027       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14028       satIOContext->ATACmd = SAT_WRITE_DMA;
14029     }
14030     else
14031     {
14032       /* case 1 */
14033       /* WRITE MULTIPLE or WRITE SECTOR(S) */
14034       /* WRITE SECTORS for easier implemetation */
14035       /* can't fit the transfer length */
14036       TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
14037       fis->h.fisType        = 0x27;                   /* Reg host to device */
14038       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14039       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
14040       fis->h.features       = 0;                      /* FIS reserve */
14041       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14042       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14043       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14044 
14045       /* FIS LBA mode set LBA (27:24) */
14046       fis->d.device         = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14047 
14048       fis->d.lbaLowExp      = 0;
14049       fis->d.lbaMidExp      = 0;
14050       fis->d.lbaHighExp     = 0;
14051       fis->d.featuresExp    = 0;
14052       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14053       fis->d.sectorCountExp = 0;
14054       fis->d.reserved4      = 0;
14055       fis->d.control        = 0;                      /* FIS HOB bit clear */
14056       fis->d.reserved5      = 0;
14057 
14058       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14059       satIOContext->ATACmd = SAT_WRITE_SECTORS;
14060 
14061     }
14062   }
14063 
14064   /* case 3 and 4 */
14065   if (pSatDevData->sat48BitSupport == agTRUE)
14066   {
14067     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14068     {
14069       /* case 3 */
14070       /* WRITE DMA EXT or WRITE DMA FUA EXT */
14071       TI_DBG5(("satWriteAndVerify10: case 3\n"));
14072       fis->h.fisType        = 0x27;                   /* Reg host to device */
14073       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14074 
14075       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14076       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
14077 
14078       fis->h.features       = 0;                      /* FIS reserve */
14079       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14080       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14081       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14082       fis->d.device         = 0x40;                   /* FIS LBA mode set */
14083       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14084       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14085       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14086       fis->d.featuresExp    = 0;                      /* FIS reserve */
14087       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14088       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14089       fis->d.reserved4      = 0;
14090       fis->d.control        = 0;                      /* FIS HOB bit clear */
14091       fis->d.reserved5      = 0;
14092 
14093       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14094     }
14095     else
14096     {
14097       /* case 4 */
14098       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14099       /* WRITE SECTORS EXT for easier implemetation */
14100       TI_DBG5(("satWriteAndVerify10: case 4\n"));
14101       fis->h.fisType        = 0x27;                   /* Reg host to device */
14102       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14103       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
14104 
14105       fis->h.features       = 0;                      /* FIS reserve */
14106       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14107       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14108       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14109       fis->d.device         = 0x40;                   /* FIS LBA mode set */
14110       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14111       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14112       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14113       fis->d.featuresExp    = 0;                      /* FIS reserve */
14114       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14115       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14116       fis->d.reserved4      = 0;
14117       fis->d.control        = 0;                      /* FIS HOB bit clear */
14118       fis->d.reserved5      = 0;
14119 
14120       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14121     }
14122   }
14123   /* case 5 */
14124   if (pSatDevData->satNCQ == agTRUE)
14125   {
14126     /* WRITE FPDMA QUEUED */
14127     if (pSatDevData->sat48BitSupport != agTRUE)
14128     {
14129       TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
14130       satSetSensePayload( pSense,
14131                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14132                           0,
14133                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14134                           satIOContext);
14135 
14136       ostiInitiatorIOCompleted( tiRoot,
14137                                 tiIORequest,
14138                                 tiIOSuccess,
14139                                 SCSI_STAT_CHECK_CONDITION,
14140                                 satIOContext->pTiSenseData,
14141                                 satIOContext->interruptContext );
14142       return tiSuccess;
14143     }
14144     TI_DBG5(("satWriteAndVerify10: case 5\n"));
14145 
14146     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14147 
14148     fis->h.fisType        = 0x27;                   /* Reg host to device */
14149     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14150     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14151     fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14152     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14153     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14154     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14155 
14156     /* Check FUA bit */
14157     if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
14158       fis->d.device       = 0xC0;                   /* FIS FUA set */
14159     else
14160       fis->d.device       = 0x40;                   /* FIS FUA clear */
14161 
14162     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14163     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14164     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14165     fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14166     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
14167     fis->d.sectorCountExp = 0;
14168     fis->d.reserved4      = 0;
14169     fis->d.control        = 0;                      /* FIS HOB bit clear */
14170     fis->d.reserved5      = 0;
14171 
14172     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14173   }
14174 
14175   /* Initialize CB for SATA completion.
14176    */
14177   satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14178 
14179   /*
14180    * Prepare SGL and send FIS to LL layer.
14181    */
14182   satIOContext->reqType = agRequestType;       /* Save it */
14183 
14184   status = sataLLIOStart( tiRoot,
14185                           tiIORequest,
14186                           tiDeviceHandle,
14187                           tiScsiRequest,
14188                           satIOContext);
14189   return (status);
14190 
14191 }
14192 #endif /* REMOVED */
14193 
14194 #ifdef REMOVED
14195 /*****************************************************************************/
14196 /*! \brief SAT implementation for SCSI satWriteAndVerify10_1.
14197  *
14198  *  SAT implementation for SCSI satWriteAndVerify10_1.
14199  *  Sub function of satWriteAndVerify10
14200  *
14201  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
14202  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
14203  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
14204  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
14205  *  \param   satIOContext_t:   Pointer to the SAT IO Context
14206  *
14207  *  \return If command is started successfully
14208  *    - \e tiSuccess:     I/O request successfully initiated.
14209  *    - \e tiBusy:        No resources available, try again later.
14210  *    - \e tiIONoDevice:  Invalid device handle.
14211  *    - \e tiError:       Other errors.
14212  */
14213 /*****************************************************************************/
14214 GLOBAL bit32  satWriteAndVerify10_1(
14215                    tiRoot_t                  *tiRoot,
14216                    tiIORequest_t             *tiIORequest,
14217                    tiDeviceHandle_t          *tiDeviceHandle,
14218                    tiScsiInitiatorRequest_t *tiScsiRequest,
14219                    satIOContext_t            *satIOContext)
14220 {
14221   bit32                     status;
14222   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14223   satDeviceData_t           *pSatDevData;
14224   scsiRspSense_t            *pSense;
14225   tiIniScsiCmnd_t           *scsiCmnd;
14226   agsaFisRegHostToDevice_t  *fis;
14227 
14228   pSense        = satIOContext->pSense;
14229   pSatDevData   = satIOContext->pSatDevData;
14230   scsiCmnd      = &tiScsiRequest->scsiCmnd;
14231   fis           = satIOContext->pFis;
14232 
14233   TI_DBG5(("satWriteAndVerify10_1: start\n"));
14234 
14235   if (pSatDevData->sat48BitSupport == agTRUE)
14236   {
14237     fis->h.fisType        = 0x27;                   /* Reg host to device */
14238     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14239 
14240     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14241     fis->h.features       = 0;                      /* FIS reserve */
14242     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14243     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14244     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14245     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
14246     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14247     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14248     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14249     fis->d.featuresExp    = 0;                      /* FIS reserve */
14250     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14251     fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14252 
14253     fis->d.reserved4      = 0;
14254     fis->d.control        = 0;                      /* FIS HOB bit clear */
14255     fis->d.reserved5      = 0;
14256 
14257     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14258 
14259     /* Initialize CB for SATA completion.
14260      */
14261     satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14262 
14263     /*
14264      * Prepare SGL and send FIS to LL layer.
14265      */
14266     satIOContext->reqType = agRequestType;       /* Save it */
14267 
14268     status = sataLLIOStart( tiRoot,
14269                             tiIORequest,
14270                             tiDeviceHandle,
14271                             tiScsiRequest,
14272                             satIOContext);
14273 
14274 
14275     TI_DBG1(("satWriteAndVerify10_1: return status %d\n", status));
14276     return (status);
14277   }
14278   else
14279   {
14280     /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14281     TI_DBG1(("satWriteAndVerify10_1: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14282     return tiError;
14283   }
14284 
14285 
14286   return tiSuccess;
14287 }
14288 #endif /* REMOVED */
14289 
14290 /*****************************************************************************/
14291 /*! \brief SAT implementation for SCSI satWriteAndVerify12.
14292  *
14293  *  SAT implementation for SCSI satWriteAndVerify12.
14294  *
14295  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
14296  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
14297  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
14298  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
14299  *  \param   satIOContext_t:   Pointer to the SAT IO Context
14300  *
14301  *  \return If command is started successfully
14302  *    - \e tiSuccess:     I/O request successfully initiated.
14303  *    - \e tiBusy:        No resources available, try again later.
14304  *    - \e tiIONoDevice:  Invalid device handle.
14305  *    - \e tiError:       Other errors.
14306  */
14307 /*****************************************************************************/
14308 GLOBAL bit32  satWriteAndVerify12(
14309                    tiRoot_t                  *tiRoot,
14310                    tiIORequest_t             *tiIORequest,
14311                    tiDeviceHandle_t          *tiDeviceHandle,
14312                    tiScsiInitiatorRequest_t *tiScsiRequest,
14313                    satIOContext_t            *satIOContext)
14314 {
14315   /*
14316     combination of write12 and verify12
14317     temp: since write12 is not support (due to internal checking), no support
14318   */
14319   bit32                     status;
14320   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14321   satDeviceData_t           *pSatDevData;
14322   scsiRspSense_t            *pSense;
14323   tiIniScsiCmnd_t           *scsiCmnd;
14324   agsaFisRegHostToDevice_t  *fis;
14325   bit32                     lba = 0;
14326   bit32                     tl = 0;
14327   bit32                     LoopNum = 1;
14328   bit8                      LBA[4];
14329   bit8                      TL[4];
14330   bit32                     rangeChk = agFALSE; /* lba and tl range check */
14331 
14332   pSense        = satIOContext->pSense;
14333   pSatDevData   = satIOContext->pSatDevData;
14334   scsiCmnd      = &tiScsiRequest->scsiCmnd;
14335   fis           = satIOContext->pFis;
14336 
14337   TI_DBG5(("satWriteAndVerify12: start\n"));
14338 
14339   /* checking BYTCHK bit */
14340   if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
14341   {
14342     satSetSensePayload( pSense,
14343                         SCSI_SNSKEY_ILLEGAL_REQUEST,
14344                         0,
14345                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14346                         satIOContext);
14347 
14348     ostiInitiatorIOCompleted( tiRoot,
14349                               tiIORequest,
14350                               tiIOSuccess,
14351                               SCSI_STAT_CHECK_CONDITION,
14352                               satIOContext->pTiSenseData,
14353                               satIOContext->interruptContext );
14354 
14355     TI_DBG1(("satWriteAndVerify12: BYTCHK bit checking \n"));
14356     return tiSuccess;
14357   }
14358 
14359   /* checking CONTROL */
14360   /* NACA == 1 or LINK == 1*/
14361   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
14362   {
14363     satSetSensePayload( pSense,
14364                         SCSI_SNSKEY_ILLEGAL_REQUEST,
14365                         0,
14366                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14367                         satIOContext);
14368 
14369     ostiInitiatorIOCompleted( tiRoot,
14370                               tiIORequest,
14371                               tiIOSuccess,
14372                               SCSI_STAT_CHECK_CONDITION,
14373                               satIOContext->pTiSenseData,
14374                               satIOContext->interruptContext );
14375 
14376     TI_DBG2(("satWriteAndVerify12: return control\n"));
14377     return tiSuccess;
14378   }
14379 
14380   osti_memset(LBA, 0, sizeof(LBA));
14381   osti_memset(TL, 0, sizeof(TL));
14382 
14383   /* do not use memcpy due to indexing in LBA and TL */
14384   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
14385   LBA[1] = scsiCmnd->cdb[3];
14386   LBA[2] = scsiCmnd->cdb[4];
14387   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
14388 
14389   TL[0] = scsiCmnd->cdb[6];   /* MSB */
14390   TL[1] = scsiCmnd->cdb[7];
14391   TL[2] = scsiCmnd->cdb[7];
14392   TL[3] = scsiCmnd->cdb[8];   /* LSB */
14393 
14394   rangeChk = satAddNComparebit32(LBA, TL);
14395 
14396   lba = satComputeCDB12LBA(satIOContext);
14397   tl = satComputeCDB12TL(satIOContext);
14398 
14399 
14400   /* Table 34, 9.1, p 46 */
14401   /*
14402     note: As of 2/10/2006, no support for DMA QUEUED
14403    */
14404 
14405   /*
14406     Table 34, 9.1, p 46, b
14407     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
14408     return check condition
14409   */
14410   if (pSatDevData->satNCQ != agTRUE &&
14411       pSatDevData->sat48BitSupport != agTRUE
14412       )
14413   {
14414     if (lba > SAT_TR_LBA_LIMIT - 1)
14415     {
14416       satSetSensePayload( pSense,
14417                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14418                           0,
14419                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14420                           satIOContext);
14421 
14422       ostiInitiatorIOCompleted( tiRoot,
14423                                 tiIORequest,
14424                                 tiIOSuccess,
14425                                 SCSI_STAT_CHECK_CONDITION,
14426                                 satIOContext->pTiSenseData,
14427                                 satIOContext->interruptContext );
14428 
14429     TI_DBG1(("satWriteAndVerify12: return LBA out of range, not EXT\n"));
14430     return tiSuccess;
14431     }
14432 
14433     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
14434     {
14435       TI_DBG1(("satWriteAndVerify12: return LBA+TL out of range, not EXT\n"));
14436       satSetSensePayload( pSense,
14437                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14438                           0,
14439                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14440                           satIOContext);
14441 
14442       ostiInitiatorIOCompleted( tiRoot,
14443                                 tiIORequest,
14444                                 tiIOSuccess,
14445                                 SCSI_STAT_CHECK_CONDITION,
14446                                 satIOContext->pTiSenseData,
14447                                 satIOContext->interruptContext );
14448 
14449     return tiSuccess;
14450     }
14451   }
14452 
14453   /* case 1 and 2 */
14454   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
14455   {
14456     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14457     {
14458       /* case 2 */
14459       /* WRITE DMA*/
14460       /* In case that we can't fit the transfer length, we loop */
14461       TI_DBG5(("satWriteAndVerify12: case 2\n"));
14462       fis->h.fisType        = 0x27;                   /* Reg host to device */
14463       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14464       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
14465       fis->h.features       = 0;                      /* FIS reserve */
14466       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14467       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14468       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14469 
14470       /* FIS LBA mode set LBA (27:24) */
14471       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14472 
14473       fis->d.lbaLowExp      = 0;
14474       fis->d.lbaMidExp      = 0;
14475       fis->d.lbaHighExp     = 0;
14476       fis->d.featuresExp    = 0;
14477       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14478       fis->d.sectorCountExp = 0;
14479       fis->d.reserved4      = 0;
14480       fis->d.control        = 0;                      /* FIS HOB bit clear */
14481       fis->d.reserved5      = 0;
14482 
14483       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14484       satIOContext->ATACmd = SAT_WRITE_DMA;
14485     }
14486     else
14487     {
14488       /* case 1 */
14489       /* WRITE MULTIPLE or WRITE SECTOR(S) */
14490       /* WRITE SECTORS for easier implemetation */
14491       /* In case that we can't fit the transfer length, we loop */
14492       TI_DBG5(("satWriteAndVerify12: case 1\n"));
14493       fis->h.fisType        = 0x27;                   /* Reg host to device */
14494       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14495       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
14496       fis->h.features       = 0;                      /* FIS reserve */
14497       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14498       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14499       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14500 
14501       /* FIS LBA mode set LBA (27:24) */
14502       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14503 
14504       fis->d.lbaLowExp      = 0;
14505       fis->d.lbaMidExp      = 0;
14506       fis->d.lbaHighExp     = 0;
14507       fis->d.featuresExp    = 0;
14508       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14509       fis->d.sectorCountExp = 0;
14510       fis->d.reserved4      = 0;
14511       fis->d.control        = 0;                      /* FIS HOB bit clear */
14512       fis->d.reserved5      = 0;
14513 
14514       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14515       satIOContext->ATACmd = SAT_WRITE_SECTORS;
14516     }
14517   }
14518 
14519   /* case 3 and 4 */
14520   if (pSatDevData->sat48BitSupport == agTRUE)
14521   {
14522     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14523     {
14524       /* case 3 */
14525       /* WRITE DMA EXT or WRITE DMA FUA EXT */
14526       TI_DBG5(("satWriteAndVerify12: case 3\n"));
14527       fis->h.fisType        = 0x27;                   /* Reg host to device */
14528       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14529 
14530       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14531       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
14532 
14533       fis->h.features       = 0;                      /* FIS reserve */
14534       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14535       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14536       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14537       fis->d.device         = 0x40;                   /* FIS LBA mode set */
14538       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14539       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14540       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14541       fis->d.featuresExp    = 0;                      /* FIS reserve */
14542       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14543       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
14544       fis->d.reserved4      = 0;
14545       fis->d.control        = 0;                      /* FIS HOB bit clear */
14546       fis->d.reserved5      = 0;
14547 
14548       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14549       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
14550     }
14551     else
14552     {
14553       /* case 4 */
14554       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14555       /* WRITE SECTORS EXT for easier implemetation */
14556       TI_DBG5(("satWriteAndVerify12: case 4\n"));
14557       fis->h.fisType        = 0x27;                   /* Reg host to device */
14558       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14559       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
14560 
14561       fis->h.features       = 0;                      /* FIS reserve */
14562       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14563       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14564       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14565       fis->d.device         = 0x40;                   /* FIS LBA mode set */
14566       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14567       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14568       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14569       fis->d.featuresExp    = 0;                      /* FIS reserve */
14570       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14571       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
14572       fis->d.reserved4      = 0;
14573       fis->d.control        = 0;                      /* FIS HOB bit clear */
14574       fis->d.reserved5      = 0;
14575 
14576       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14577       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
14578     }
14579   }
14580 
14581   /* case 5 */
14582   if (pSatDevData->satNCQ == agTRUE)
14583   {
14584     /* WRITE FPDMA QUEUED */
14585     if (pSatDevData->sat48BitSupport != agTRUE)
14586     {
14587       TI_DBG5(("satWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support \n"));
14588        satSetSensePayload( pSense,
14589                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14590                           0,
14591                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14592                           satIOContext);
14593 
14594       ostiInitiatorIOCompleted( tiRoot,
14595                                 tiIORequest,
14596                                 tiIOSuccess,
14597                                 SCSI_STAT_CHECK_CONDITION,
14598                                 satIOContext->pTiSenseData,
14599                                 satIOContext->interruptContext );
14600       return tiSuccess;
14601     }
14602     TI_DBG6(("satWriteAndVerify12: case 5\n"));
14603 
14604     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14605 
14606     fis->h.fisType        = 0x27;                   /* Reg host to device */
14607     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14608     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14609     fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14610     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14611     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14612     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14613 
14614     /* Check FUA bit */
14615     if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
14616       fis->d.device       = 0xC0;                   /* FIS FUA set */
14617     else
14618       fis->d.device       = 0x40;                   /* FIS FUA clear */
14619 
14620     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14621     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14622     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14623     fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
14624     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
14625     fis->d.sectorCountExp = 0;
14626     fis->d.reserved4      = 0;
14627     fis->d.control        = 0;                      /* FIS HOB bit clear */
14628     fis->d.reserved5      = 0;
14629 
14630     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14631     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
14632   }
14633 
14634   satIOContext->currentLBA = lba;
14635 //  satIOContext->OrgLBA = lba;
14636   satIOContext->OrgTL = tl;
14637 
14638   /*
14639     computing number of loop and remainder for tl
14640     0xFF in case not ext
14641     0xFFFF in case EXT
14642   */
14643   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14644   {
14645     LoopNum = satComputeLoopNum(tl, 0xFF);
14646   }
14647   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14648            fis->h.command == SAT_WRITE_DMA_EXT     ||
14649            fis->h.command == SAT_WRITE_DMA_FUA_EXT
14650            )
14651   {
14652     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
14653     LoopNum = satComputeLoopNum(tl, 0xFFFF);
14654   }
14655   else
14656   {
14657     /* SAT_WRITE_FPDMA_QUEUEDK */
14658     LoopNum = satComputeLoopNum(tl, 0xFFFF);
14659   }
14660 
14661   satIOContext->LoopNum = LoopNum;
14662   satIOContext->LoopNum2 = LoopNum;
14663 
14664 
14665   if (LoopNum == 1)
14666   {
14667     TI_DBG5(("satWriteAndVerify12: NON CHAINED data\n"));
14668     /* Initialize CB for SATA completion.
14669      */
14670     satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14671   }
14672   else
14673   {
14674     TI_DBG1(("satWriteAndVerify12: CHAINED data\n"));
14675     /* re-setting tl */
14676     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14677     {
14678        fis->d.sectorCount    = 0xFF;
14679     }
14680     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14681              fis->h.command == SAT_WRITE_DMA_EXT ||
14682              fis->h.command == SAT_WRITE_DMA_FUA_EXT
14683              )
14684     {
14685       fis->d.sectorCount    = 0xFF;
14686       fis->d.sectorCountExp = 0xFF;
14687     }
14688     else
14689     {
14690       /* SAT_WRITE_FPDMA_QUEUED */
14691       fis->h.features       = 0xFF;
14692       fis->d.featuresExp    = 0xFF;
14693     }
14694 
14695     /* Initialize CB for SATA completion.
14696      */
14697     satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
14698   }
14699 
14700 
14701   /*
14702    * Prepare SGL and send FIS to LL layer.
14703    */
14704   satIOContext->reqType = agRequestType;       /* Save it */
14705 
14706   status = sataLLIOStart( tiRoot,
14707                           tiIORequest,
14708                           tiDeviceHandle,
14709                           tiScsiRequest,
14710                           satIOContext);
14711   return (status);
14712 }
14713 
14714 GLOBAL bit32  satNonChainedWriteNVerify_Verify(
14715                    tiRoot_t                  *tiRoot,
14716                    tiIORequest_t             *tiIORequest,
14717                    tiDeviceHandle_t          *tiDeviceHandle,
14718                    tiScsiInitiatorRequest_t *tiScsiRequest,
14719                    satIOContext_t            *satIOContext)
14720 {
14721   bit32                     status;
14722   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14723   satDeviceData_t           *pSatDevData;
14724   tiIniScsiCmnd_t           *scsiCmnd;
14725   agsaFisRegHostToDevice_t  *fis;
14726 
14727   pSatDevData   = satIOContext->pSatDevData;
14728   scsiCmnd      = &tiScsiRequest->scsiCmnd;
14729   fis           = satIOContext->pFis;
14730 
14731   TI_DBG5(("satNonChainedWriteNVerify_Verify: start\n"));
14732 
14733   if (pSatDevData->sat48BitSupport == agTRUE)
14734   {
14735     fis->h.fisType        = 0x27;                   /* Reg host to device */
14736     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14737 
14738     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14739     fis->h.features       = 0;                      /* FIS reserve */
14740     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14741     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14742     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14743     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
14744     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14745     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14746     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14747     fis->d.featuresExp    = 0;                      /* FIS reserve */
14748     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14749     fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14750 
14751     fis->d.reserved4      = 0;
14752     fis->d.control        = 0;                      /* FIS HOB bit clear */
14753     fis->d.reserved5      = 0;
14754 
14755     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14756 
14757     /* Initialize CB for SATA completion.
14758      */
14759     satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14760 
14761     /*
14762      * Prepare SGL and send FIS to LL layer.
14763      */
14764     satIOContext->reqType = agRequestType;       /* Save it */
14765 
14766     status = sataLLIOStart( tiRoot,
14767                             tiIORequest,
14768                             tiDeviceHandle,
14769                             tiScsiRequest,
14770                             satIOContext);
14771 
14772 
14773     TI_DBG1(("satNonChainedWriteNVerify_Verify: return status %d\n", status));
14774     return (status);
14775   }
14776   else
14777   {
14778     /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14779     TI_DBG1(("satNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14780     return tiError;
14781   }
14782 
14783 }
14784 
14785 GLOBAL bit32  satChainedWriteNVerify_Write(
14786                    tiRoot_t                  *tiRoot,
14787                    tiIORequest_t             *tiIORequest,
14788                    tiDeviceHandle_t          *tiDeviceHandle,
14789                    tiScsiInitiatorRequest_t *tiScsiRequest,
14790                    satIOContext_t            *satIOContext)
14791 {
14792   /*
14793     Assumption: error check on lba and tl has been done in satWrite*()
14794     lba = lba + tl;
14795   */
14796   bit32                     status;
14797   satIOContext_t            *satOrgIOContext = agNULL;
14798   tiIniScsiCmnd_t           *scsiCmnd;
14799   agsaFisRegHostToDevice_t  *fis;
14800   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14801   bit32                     lba = 0;
14802   bit32                     DenomTL = 0xFF;
14803   bit32                     Remainder = 0;
14804   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
14805 
14806   TI_DBG1(("satChainedWriteNVerify_Write: start\n"));
14807 
14808   fis             = satIOContext->pFis;
14809   satOrgIOContext = satIOContext->satOrgIOContext;
14810   scsiCmnd        = satOrgIOContext->pScsiCmnd;
14811 
14812   osti_memset(LBA,0, sizeof(LBA));
14813 
14814   switch (satOrgIOContext->ATACmd)
14815   {
14816   case SAT_WRITE_DMA:
14817     DenomTL = 0xFF;
14818     break;
14819   case SAT_WRITE_SECTORS:
14820     DenomTL = 0xFF;
14821     break;
14822   case SAT_WRITE_DMA_EXT:
14823     DenomTL = 0xFFFF;
14824     break;
14825   case SAT_WRITE_DMA_FUA_EXT:
14826     DenomTL = 0xFFFF;
14827     break;
14828   case SAT_WRITE_SECTORS_EXT:
14829     DenomTL = 0xFFFF;
14830     break;
14831   case SAT_WRITE_FPDMA_QUEUED:
14832     DenomTL = 0xFFFF;
14833     break;
14834   default:
14835     TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
14836     return tiError;
14837     break;
14838   }
14839 
14840   Remainder = satOrgIOContext->OrgTL % DenomTL;
14841   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
14842   lba = satOrgIOContext->currentLBA;
14843 
14844   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
14845   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
14846   LBA[2] = (bit8)((lba & 0xF0) >> 8);
14847   LBA[3] = (bit8)(lba & 0xF);               /* LSB */
14848 
14849   switch (satOrgIOContext->ATACmd)
14850   {
14851   case SAT_WRITE_DMA:
14852     fis->h.fisType        = 0x27;                   /* Reg host to device */
14853     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14854     fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
14855     fis->h.features       = 0;                      /* FIS reserve */
14856     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14857     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14858     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14859 
14860     /* FIS LBA mode set LBA (27:24) */
14861     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14862 
14863     fis->d.lbaLowExp      = 0;
14864     fis->d.lbaMidExp      = 0;
14865     fis->d.lbaHighExp     = 0;
14866     fis->d.featuresExp    = 0;
14867     if (satOrgIOContext->LoopNum == 1)
14868     {
14869       /* last loop */
14870       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
14871     }
14872     else
14873     {
14874       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
14875     }
14876     fis->d.sectorCountExp = 0;
14877     fis->d.reserved4      = 0;
14878     fis->d.control        = 0;                      /* FIS HOB bit clear */
14879     fis->d.reserved5      = 0;
14880 
14881     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14882 
14883     break;
14884   case SAT_WRITE_SECTORS:
14885     fis->h.fisType        = 0x27;                   /* Reg host to device */
14886     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14887     fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
14888     fis->h.features       = 0;                      /* FIS reserve */
14889     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14890     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14891     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14892 
14893     /* FIS LBA mode set LBA (27:24) */
14894     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14895 
14896     fis->d.lbaLowExp      = 0;
14897     fis->d.lbaMidExp      = 0;
14898     fis->d.lbaHighExp     = 0;
14899     fis->d.featuresExp    = 0;
14900     if (satOrgIOContext->LoopNum == 1)
14901     {
14902       /* last loop */
14903       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
14904     }
14905     else
14906     {
14907       fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
14908     }
14909     fis->d.sectorCountExp = 0;
14910     fis->d.reserved4      = 0;
14911     fis->d.control        = 0;                      /* FIS HOB bit clear */
14912     fis->d.reserved5      = 0;
14913 
14914     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14915 
14916     break;
14917   case SAT_WRITE_DMA_EXT:
14918     fis->h.fisType        = 0x27;                   /* Reg host to device */
14919     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14920     fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
14921     fis->h.features       = 0;                      /* FIS reserve */
14922     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14923     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14924     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14925     fis->d.device         = 0x40;                   /* FIS LBA mode set */
14926     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
14927     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14928     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14929     fis->d.featuresExp    = 0;                      /* FIS reserve */
14930     if (satOrgIOContext->LoopNum == 1)
14931     {
14932       /* last loop */
14933       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
14934       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
14935     }
14936     else
14937     {
14938       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
14939       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
14940     }
14941     fis->d.reserved4      = 0;
14942     fis->d.control        = 0;                       /* FIS HOB bit clear */
14943     fis->d.reserved5      = 0;
14944 
14945     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14946 
14947     break;
14948   case SAT_WRITE_SECTORS_EXT:
14949     fis->h.fisType        = 0x27;                   /* Reg host to device */
14950     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14951     fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
14952 
14953     fis->h.features       = 0;                      /* FIS reserve */
14954     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14955     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14956     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14957     fis->d.device         = 0x40;                   /* FIS LBA mode set */
14958     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
14959     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14960     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14961     fis->d.featuresExp    = 0;                      /* FIS reserve */
14962     if (satOrgIOContext->LoopNum == 1)
14963     {
14964       /* last loop */
14965       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
14966       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
14967     }
14968     else
14969     {
14970       fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
14971       fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
14972     }
14973     fis->d.reserved4      = 0;
14974     fis->d.control        = 0;                      /* FIS HOB bit clear */
14975     fis->d.reserved5      = 0;
14976 
14977     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14978 
14979     break;
14980   case SAT_WRITE_FPDMA_QUEUED:
14981     fis->h.fisType        = 0x27;                   /* Reg host to device */
14982     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14983     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14984     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14985     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14986     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14987 
14988     /* Check FUA bit */
14989     if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
14990       fis->d.device       = 0xC0;                   /* FIS FUA set */
14991     else
14992       fis->d.device       = 0x40;                   /* FIS FUA clear */
14993 
14994     fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
14995     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14996     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14997     if (satOrgIOContext->LoopNum == 1)
14998     {
14999       /* last loop */
15000       fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
15001       fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
15002     }
15003     else
15004     {
15005       fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
15006       fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
15007     }
15008     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15009     fis->d.sectorCountExp = 0;
15010     fis->d.reserved4      = 0;
15011     fis->d.control        = 0;                      /* FIS HOB bit clear */
15012     fis->d.reserved5      = 0;
15013 
15014     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15015     break;
15016 
15017   default:
15018     TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15019     return tiError;
15020     break;
15021   }
15022 
15023   /* Initialize CB for SATA completion.
15024    */
15025   /* chained data */
15026   satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15027 
15028 
15029   /*
15030    * Prepare SGL and send FIS to LL layer.
15031    */
15032   satIOContext->reqType = agRequestType;       /* Save it */
15033 
15034   status = sataLLIOStart( tiRoot,
15035                           tiIORequest,
15036                           tiDeviceHandle,
15037                           tiScsiRequest,
15038                           satIOContext);
15039 
15040   TI_DBG5(("satChainedWriteNVerify_Write: return\n"));
15041   return (status);
15042 
15043 }
15044 
15045 /*
15046   similar to write12 and verify10;
15047   this will be similar to verify12
15048   */
15049 GLOBAL bit32  satChainedWriteNVerify_Start_Verify(
15050                    tiRoot_t                  *tiRoot,
15051                    tiIORequest_t             *tiIORequest,
15052                    tiDeviceHandle_t          *tiDeviceHandle,
15053                    tiScsiInitiatorRequest_t *tiScsiRequest,
15054                    satIOContext_t            *satIOContext)
15055 {
15056   /*
15057     deal with transfer length; others have been handled previously at this point;
15058     no LBA check; no range check;
15059   */
15060   bit32                     status;
15061   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15062   satDeviceData_t           *pSatDevData;
15063   tiIniScsiCmnd_t           *scsiCmnd;
15064   agsaFisRegHostToDevice_t  *fis;
15065   bit32                     lba = 0;
15066   bit32                     tl = 0;
15067   bit32                     LoopNum = 1;
15068   bit8                      LBA[4];
15069   bit8                      TL[4];
15070 
15071   pSatDevData   = satIOContext->pSatDevData;
15072   scsiCmnd      = &tiScsiRequest->scsiCmnd;
15073   fis           = satIOContext->pFis;
15074 
15075   TI_DBG5(("satChainedWriteNVerify_Start_Verify: start\n"));
15076 
15077   osti_memset(LBA, 0, sizeof(LBA));
15078   osti_memset(TL, 0, sizeof(TL));
15079 
15080   /* do not use memcpy due to indexing in LBA and TL */
15081   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
15082   LBA[1] = scsiCmnd->cdb[3];
15083   LBA[2] = scsiCmnd->cdb[4];
15084   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
15085 
15086   TL[0] = scsiCmnd->cdb[6];   /* MSB */
15087   TL[1] = scsiCmnd->cdb[7];
15088   TL[2] = scsiCmnd->cdb[7];
15089   TL[3] = scsiCmnd->cdb[8];   /* LSB */
15090 
15091   lba = satComputeCDB12LBA(satIOContext);
15092   tl = satComputeCDB12TL(satIOContext);
15093 
15094   if (pSatDevData->sat48BitSupport == agTRUE)
15095   {
15096     TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n"));
15097     fis->h.fisType        = 0x27;                   /* Reg host to device */
15098     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15099 
15100     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
15101     fis->h.features       = 0;                      /* FIS reserve */
15102     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15103     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15104     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15105     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
15106     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15107     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15108     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15109     fis->d.featuresExp    = 0;                      /* FIS reserve */
15110     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15111     fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15112 
15113     fis->d.reserved4      = 0;
15114     fis->d.control        = 0;                      /* FIS HOB bit clear */
15115     fis->d.reserved5      = 0;
15116 
15117     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15118     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
15119   }
15120   else
15121   {
15122     TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n"));
15123     fis->h.fisType        = 0x27;                   /* Reg host to device */
15124     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15125     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
15126     fis->h.features       = 0;                      /* FIS reserve */
15127     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15128     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15129     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15130       /* FIS LBA mode set LBA (27:24) */
15131     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15132     fis->d.lbaLowExp      = 0;
15133     fis->d.lbaMidExp      = 0;
15134     fis->d.lbaHighExp     = 0;
15135     fis->d.featuresExp    = 0;
15136     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15137     fis->d.sectorCountExp = 0;
15138     fis->d.reserved4      = 0;
15139     fis->d.control        = 0;                      /* FIS HOB bit clear */
15140     fis->d.reserved5      = 0;
15141 
15142     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15143     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
15144 
15145  }
15146 
15147   satIOContext->currentLBA = lba;
15148   satIOContext->OrgTL = tl;
15149 
15150   /*
15151     computing number of loop and remainder for tl
15152     0xFF in case not ext
15153     0xFFFF in case EXT
15154   */
15155   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15156   {
15157     LoopNum = satComputeLoopNum(tl, 0xFF);
15158   }
15159   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15160   {
15161     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15162     LoopNum = satComputeLoopNum(tl, 0xFFFF);
15163   }
15164   else
15165   {
15166     TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
15167     LoopNum = 1;
15168   }
15169 
15170   satIOContext->LoopNum = LoopNum;
15171 
15172   if (LoopNum == 1)
15173   {
15174     TI_DBG5(("satChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
15175     /* Initialize CB for SATA completion.
15176      */
15177     satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15178   }
15179   else
15180   {
15181     TI_DBG1(("satChainedWriteNVerify_Start_Verify: CHAINED data\n"));
15182     /* re-setting tl */
15183     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15184     {
15185        fis->d.sectorCount    = 0xFF;
15186     }
15187     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15188     {
15189       fis->d.sectorCount    = 0xFF;
15190       fis->d.sectorCountExp = 0xFF;
15191     }
15192     else
15193     {
15194       TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
15195     }
15196 
15197     /* Initialize CB for SATA completion.
15198      */
15199     satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15200   }
15201 
15202 
15203   /*
15204    * Prepare SGL and send FIS to LL layer.
15205    */
15206   satIOContext->reqType = agRequestType;       /* Save it */
15207 
15208   status = sataLLIOStart( tiRoot,
15209                           tiIORequest,
15210                           tiDeviceHandle,
15211                           tiScsiRequest,
15212                           satIOContext);
15213   return (status);
15214 }
15215 
15216 GLOBAL bit32  satChainedWriteNVerify_Verify(
15217                    tiRoot_t                  *tiRoot,
15218                    tiIORequest_t             *tiIORequest,
15219                    tiDeviceHandle_t          *tiDeviceHandle,
15220                    tiScsiInitiatorRequest_t *tiScsiRequest,
15221                    satIOContext_t            *satIOContext)
15222 {
15223   bit32                     status;
15224   satIOContext_t            *satOrgIOContext = agNULL;
15225   agsaFisRegHostToDevice_t  *fis;
15226   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15227   bit32                     lba = 0;
15228   bit32                     DenomTL = 0xFF;
15229   bit32                     Remainder = 0;
15230   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
15231 
15232   TI_DBG2(("satChainedWriteNVerify_Verify: start\n"));
15233 
15234   fis             = satIOContext->pFis;
15235   satOrgIOContext = satIOContext->satOrgIOContext;
15236 
15237   osti_memset(LBA,0, sizeof(LBA));
15238 
15239   switch (satOrgIOContext->ATACmd)
15240   {
15241   case SAT_READ_VERIFY_SECTORS:
15242     DenomTL = 0xFF;
15243     break;
15244   case SAT_READ_VERIFY_SECTORS_EXT:
15245     DenomTL = 0xFFFF;
15246     break;
15247   default:
15248     TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15249     return tiError;
15250     break;
15251   }
15252 
15253   Remainder = satOrgIOContext->OrgTL % DenomTL;
15254   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
15255   lba = satOrgIOContext->currentLBA;
15256 
15257   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
15258   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
15259   LBA[2] = (bit8)((lba & 0xF0) >> 8);
15260   LBA[3] = (bit8)(lba & 0xF);               /* LSB */
15261 
15262   switch (satOrgIOContext->ATACmd)
15263   {
15264   case SAT_READ_VERIFY_SECTORS:
15265     fis->h.fisType        = 0x27;                   /* Reg host to device */
15266     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15267     fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
15268     fis->h.features       = 0;                      /* FIS reserve */
15269     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
15270     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
15271     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
15272 
15273     /* FIS LBA mode set LBA (27:24) */
15274     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
15275 
15276     fis->d.lbaLowExp      = 0;
15277     fis->d.lbaMidExp      = 0;
15278     fis->d.lbaHighExp     = 0;
15279     fis->d.featuresExp    = 0;
15280     if (satOrgIOContext->LoopNum == 1)
15281     {
15282       /* last loop */
15283       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
15284     }
15285     else
15286     {
15287       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
15288     }
15289     fis->d.sectorCountExp = 0;
15290     fis->d.reserved4      = 0;
15291     fis->d.control        = 0;                      /* FIS HOB bit clear */
15292     fis->d.reserved5      = 0;
15293 
15294     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15295 
15296     break;
15297   case SAT_READ_VERIFY_SECTORS_EXT:
15298     fis->h.fisType        = 0x27;                   /* Reg host to device */
15299     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15300     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
15301     fis->h.features       = 0;                      /* FIS reserve */
15302     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
15303     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
15304     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
15305     fis->d.device         = 0x40;                   /* FIS LBA mode set */
15306     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
15307     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15308     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15309     fis->d.featuresExp    = 0;                      /* FIS reserve */
15310     if (satOrgIOContext->LoopNum == 1)
15311     {
15312       /* last loop */
15313       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
15314       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
15315     }
15316     else
15317     {
15318       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
15319       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
15320     }
15321     fis->d.reserved4      = 0;
15322     fis->d.control        = 0;                       /* FIS HOB bit clear */
15323     fis->d.reserved5      = 0;
15324 
15325     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15326 
15327     break;
15328 
15329   default:
15330     TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15331     return tiError;
15332     break;
15333   }
15334 
15335   /* Initialize CB for SATA completion.
15336    */
15337   /* chained data */
15338   satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15339 
15340 
15341   /*
15342    * Prepare SGL and send FIS to LL layer.
15343    */
15344   satIOContext->reqType = agRequestType;       /* Save it */
15345 
15346   status = sataLLIOStart( tiRoot,
15347                           tiIORequest,
15348                           tiDeviceHandle,
15349                           tiScsiRequest,
15350                           satIOContext);
15351 
15352   TI_DBG5(("satChainedWriteNVerify_Verify: return\n"));
15353   return (status);
15354 
15355 }
15356 
15357 
15358 /*****************************************************************************/
15359 /*! \brief SAT implementation for SCSI satWriteAndVerify16.
15360  *
15361  *  SAT implementation for SCSI satWriteAndVerify16.
15362  *
15363  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
15364  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
15365  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
15366  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
15367  *  \param   satIOContext_t:   Pointer to the SAT IO Context
15368  *
15369  *  \return If command is started successfully
15370  *    - \e tiSuccess:     I/O request successfully initiated.
15371  *    - \e tiBusy:        No resources available, try again later.
15372  *    - \e tiIONoDevice:  Invalid device handle.
15373  *    - \e tiError:       Other errors.
15374  */
15375 /*****************************************************************************/
15376 GLOBAL bit32  satWriteAndVerify16(
15377                    tiRoot_t                  *tiRoot,
15378                    tiIORequest_t             *tiIORequest,
15379                    tiDeviceHandle_t          *tiDeviceHandle,
15380                    tiScsiInitiatorRequest_t *tiScsiRequest,
15381                    satIOContext_t            *satIOContext)
15382 {
15383   /*
15384     combination of write16 and verify16
15385     since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support
15386   */
15387   bit32                     status;
15388   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15389   satDeviceData_t           *pSatDevData;
15390   scsiRspSense_t            *pSense;
15391   tiIniScsiCmnd_t           *scsiCmnd;
15392   agsaFisRegHostToDevice_t  *fis;
15393   bit32                     lba = 0;
15394   bit32                     tl = 0;
15395   bit32                     LoopNum = 1;
15396   bit8                      LBA[8];
15397   bit8                      TL[8];
15398   bit32                     rangeChk = agFALSE; /* lba and tl range check */
15399   bit32                     limitChk = agFALSE; /* lba and tl range check */
15400 
15401   pSense        = satIOContext->pSense;
15402   pSatDevData   = satIOContext->pSatDevData;
15403   scsiCmnd      = &tiScsiRequest->scsiCmnd;
15404   fis           = satIOContext->pFis;
15405   TI_DBG5(("satWriteAndVerify16:start\n"));
15406 
15407   /* checking BYTCHK bit */
15408   if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15409   {
15410     satSetSensePayload( pSense,
15411                         SCSI_SNSKEY_ILLEGAL_REQUEST,
15412                         0,
15413                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15414                         satIOContext);
15415 
15416     ostiInitiatorIOCompleted( tiRoot,
15417                               tiIORequest,
15418                               tiIOSuccess,
15419                               SCSI_STAT_CHECK_CONDITION,
15420                               satIOContext->pTiSenseData,
15421                               satIOContext->interruptContext );
15422 
15423     TI_DBG1(("satWriteAndVerify16: BYTCHK bit checking \n"));
15424     return tiSuccess;
15425   }
15426 
15427 
15428   /* checking CONTROL */
15429   /* NACA == 1 or LINK == 1*/
15430   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
15431   {
15432     satSetSensePayload( pSense,
15433                         SCSI_SNSKEY_ILLEGAL_REQUEST,
15434                         0,
15435                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15436                         satIOContext);
15437 
15438     ostiInitiatorIOCompleted( tiRoot,
15439                               tiIORequest,
15440                               tiIOSuccess,
15441                               SCSI_STAT_CHECK_CONDITION,
15442                               satIOContext->pTiSenseData,
15443                               satIOContext->interruptContext );
15444 
15445     TI_DBG2(("satWriteAndVerify16: return control\n"));
15446     return tiSuccess;
15447   }
15448 
15449   osti_memset(LBA, 0, sizeof(LBA));
15450   osti_memset(TL, 0, sizeof(TL));
15451 
15452 
15453   /* do not use memcpy due to indexing in LBA and TL */
15454   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
15455   LBA[1] = scsiCmnd->cdb[3];
15456   LBA[2] = scsiCmnd->cdb[4];
15457   LBA[3] = scsiCmnd->cdb[5];
15458   LBA[4] = scsiCmnd->cdb[6];
15459   LBA[5] = scsiCmnd->cdb[7];
15460   LBA[6] = scsiCmnd->cdb[8];
15461   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
15462 
15463   TL[0] = 0;
15464   TL[1] = 0;
15465   TL[2] = 0;
15466   TL[3] = 0;
15467   TL[4] = scsiCmnd->cdb[10];   /* MSB */
15468   TL[5] = scsiCmnd->cdb[11];
15469   TL[6] = scsiCmnd->cdb[12];
15470   TL[7] = scsiCmnd->cdb[13];   /* LSB */
15471 
15472   rangeChk = satAddNComparebit64(LBA, TL);
15473 
15474   limitChk = satCompareLBALimitbit(LBA);
15475 
15476   lba = satComputeCDB16LBA(satIOContext);
15477   tl = satComputeCDB16TL(satIOContext);
15478 
15479 
15480   /* Table 34, 9.1, p 46 */
15481   /*
15482     note: As of 2/10/2006, no support for DMA QUEUED
15483   */
15484 
15485   /*
15486     Table 34, 9.1, p 46, b
15487     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15488     return check condition
15489   */
15490   if (pSatDevData->satNCQ != agTRUE &&
15491      pSatDevData->sat48BitSupport != agTRUE
15492      )
15493   {
15494     if (limitChk)
15495     {
15496       TI_DBG1(("satWriteAndVerify16: return LBA out of range, not EXT\n"));
15497       satSetSensePayload( pSense,
15498                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15499                           0,
15500                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15501                           satIOContext);
15502 
15503       ostiInitiatorIOCompleted( tiRoot,
15504                                 tiIORequest,
15505                                 tiIOSuccess,
15506                                 SCSI_STAT_CHECK_CONDITION,
15507                                 satIOContext->pTiSenseData,
15508                                 satIOContext->interruptContext );
15509 
15510     return tiSuccess;
15511     }
15512     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
15513     {
15514       TI_DBG1(("satWriteAndVerify16: return LBA+TL out of range, not EXT\n"));
15515       satSetSensePayload( pSense,
15516                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15517                           0,
15518                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15519                           satIOContext);
15520 
15521       ostiInitiatorIOCompleted( tiRoot,
15522                                 tiIORequest,
15523                                 tiIOSuccess,
15524                                 SCSI_STAT_CHECK_CONDITION,
15525                                 satIOContext->pTiSenseData,
15526                                 satIOContext->interruptContext );
15527 
15528     return tiSuccess;
15529     }
15530   }
15531 
15532 
15533   /* case 1 and 2 */
15534   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
15535   {
15536     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15537     {
15538       /* case 2 */
15539       /* WRITE DMA*/
15540       /* In case that we can't fit the transfer length, we loop */
15541       TI_DBG5(("satWriteAndVerify16: case 2\n"));
15542       fis->h.fisType        = 0x27;                   /* Reg host to device */
15543       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15544       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
15545       fis->h.features       = 0;                      /* FIS reserve */
15546       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15547       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15548       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15549 
15550       /* FIS LBA mode set LBA (27:24) */
15551       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15552 
15553       fis->d.lbaLowExp      = 0;
15554       fis->d.lbaMidExp      = 0;
15555       fis->d.lbaHighExp     = 0;
15556       fis->d.featuresExp    = 0;
15557       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15558       fis->d.sectorCountExp = 0;
15559       fis->d.reserved4      = 0;
15560       fis->d.control        = 0;                      /* FIS HOB bit clear */
15561       fis->d.reserved5      = 0;
15562 
15563       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15564       satIOContext->ATACmd = SAT_WRITE_DMA;
15565     }
15566     else
15567     {
15568       /* case 1 */
15569       /* WRITE MULTIPLE or WRITE SECTOR(S) */
15570       /* WRITE SECTORS for easier implemetation */
15571       /* In case that we can't fit the transfer length, we loop */
15572       TI_DBG5(("satWriteAndVerify16: case 1\n"));
15573       fis->h.fisType        = 0x27;                   /* Reg host to device */
15574       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15575       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
15576       fis->h.features       = 0;                      /* FIS reserve */
15577       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15578       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15579       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15580 
15581       /* FIS LBA mode set LBA (27:24) */
15582       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15583 
15584       fis->d.lbaLowExp      = 0;
15585       fis->d.lbaMidExp      = 0;
15586       fis->d.lbaHighExp     = 0;
15587       fis->d.featuresExp    = 0;
15588       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15589       fis->d.sectorCountExp = 0;
15590       fis->d.reserved4      = 0;
15591       fis->d.control        = 0;                      /* FIS HOB bit clear */
15592       fis->d.reserved5      = 0;
15593 
15594       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15595       satIOContext->ATACmd = SAT_WRITE_SECTORS;
15596     }
15597   }
15598 
15599   /* case 3 and 4 */
15600   if (pSatDevData->sat48BitSupport == agTRUE)
15601   {
15602     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15603     {
15604       /* case 3 */
15605       /* WRITE DMA EXT or WRITE DMA FUA EXT */
15606       TI_DBG5(("satWriteAndVerify16: case 3\n"));
15607       fis->h.fisType        = 0x27;                   /* Reg host to device */
15608       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15609 
15610       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15611       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
15612 
15613       fis->h.features       = 0;                      /* FIS reserve */
15614       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15615       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15616       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15617       fis->d.device         = 0x40;                   /* FIS LBA mode set */
15618       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
15619       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
15620       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
15621       fis->d.featuresExp    = 0;                      /* FIS reserve */
15622       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15623       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
15624       fis->d.reserved4      = 0;
15625       fis->d.control        = 0;                      /* FIS HOB bit clear */
15626       fis->d.reserved5      = 0;
15627 
15628       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15629       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15630     }
15631     else
15632     {
15633       /* case 4 */
15634       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15635       /* WRITE SECTORS EXT for easier implemetation */
15636       TI_DBG5(("satWriteAndVerify16: case 4\n"));
15637       fis->h.fisType        = 0x27;                   /* Reg host to device */
15638       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15639       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
15640 
15641       fis->h.features       = 0;                      /* FIS reserve */
15642       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15643       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15644       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15645       fis->d.device         = 0x40;                   /* FIS LBA mode set */
15646       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
15647       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
15648       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
15649       fis->d.featuresExp    = 0;                      /* FIS reserve */
15650       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15651       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
15652       fis->d.reserved4      = 0;
15653       fis->d.control        = 0;                      /* FIS HOB bit clear */
15654       fis->d.reserved5      = 0;
15655 
15656       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15657       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15658     }
15659   }
15660 
15661   /* case 5 */
15662   if (pSatDevData->satNCQ == agTRUE)
15663   {
15664     /* WRITE FPDMA QUEUED */
15665     if (pSatDevData->sat48BitSupport != agTRUE)
15666     {
15667       TI_DBG5(("satWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support \n"));
15668       satSetSensePayload( pSense,
15669                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15670                           0,
15671                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15672                           satIOContext);
15673 
15674       ostiInitiatorIOCompleted( tiRoot,
15675                                 tiIORequest,
15676                                 tiIOSuccess,
15677                                 SCSI_STAT_CHECK_CONDITION,
15678                                 satIOContext->pTiSenseData,
15679                                 satIOContext->interruptContext );
15680       return tiSuccess;
15681     }
15682     TI_DBG6(("satWriteAndVerify16: case 5\n"));
15683 
15684     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15685 
15686     fis->h.fisType        = 0x27;                   /* Reg host to device */
15687     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15688     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15689     fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15690     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15691     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15692     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15693 
15694     /* Check FUA bit */
15695     if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
15696       fis->d.device       = 0xC0;                   /* FIS FUA set */
15697     else
15698       fis->d.device       = 0x40;                   /* FIS FUA clear */
15699 
15700     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
15701     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
15702     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
15703     fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
15704     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15705     fis->d.sectorCountExp = 0;
15706     fis->d.reserved4      = 0;
15707     fis->d.control        = 0;                      /* FIS HOB bit clear */
15708     fis->d.reserved5      = 0;
15709 
15710     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15711     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15712   }
15713 
15714   satIOContext->currentLBA = lba;
15715   satIOContext->OrgTL = tl;
15716 
15717   /*
15718     computing number of loop and remainder for tl
15719     0xFF in case not ext
15720     0xFFFF in case EXT
15721   */
15722   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15723   {
15724     LoopNum = satComputeLoopNum(tl, 0xFF);
15725   }
15726   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15727            fis->h.command == SAT_WRITE_DMA_EXT     ||
15728            fis->h.command == SAT_WRITE_DMA_FUA_EXT
15729            )
15730   {
15731     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15732     LoopNum = satComputeLoopNum(tl, 0xFFFF);
15733   }
15734   else
15735   {
15736     /* SAT_WRITE_FPDMA_QUEUEDK */
15737     LoopNum = satComputeLoopNum(tl, 0xFFFF);
15738   }
15739 
15740   satIOContext->LoopNum = LoopNum;
15741 
15742 
15743   if (LoopNum == 1)
15744   {
15745     TI_DBG5(("satWriteAndVerify16: NON CHAINED data\n"));
15746     /* Initialize CB for SATA completion.
15747      */
15748     satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15749   }
15750   else
15751   {
15752     TI_DBG1(("satWriteAndVerify16: CHAINED data\n"));
15753     /* re-setting tl */
15754     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15755     {
15756        fis->d.sectorCount    = 0xFF;
15757     }
15758     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15759              fis->h.command == SAT_WRITE_DMA_EXT ||
15760              fis->h.command == SAT_WRITE_DMA_FUA_EXT
15761              )
15762     {
15763       fis->d.sectorCount    = 0xFF;
15764       fis->d.sectorCountExp = 0xFF;
15765     }
15766     else
15767     {
15768       /* SAT_WRITE_FPDMA_QUEUED */
15769       fis->h.features       = 0xFF;
15770       fis->d.featuresExp    = 0xFF;
15771     }
15772 
15773     /* Initialize CB for SATA completion.
15774      */
15775     satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15776   }
15777 
15778 
15779   /*
15780    * Prepare SGL and send FIS to LL layer.
15781    */
15782   satIOContext->reqType = agRequestType;       /* Save it */
15783 
15784   status = sataLLIOStart( tiRoot,
15785                           tiIORequest,
15786                           tiDeviceHandle,
15787                           tiScsiRequest,
15788                           satIOContext);
15789   return (status);
15790 }
15791 
15792 /*****************************************************************************/
15793 /*! \brief SAT implementation for SCSI satReadMediaSerialNumber.
15794  *
15795  *  SAT implementation for SCSI Read Media Serial Number.
15796  *
15797  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
15798  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
15799  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
15800  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
15801  *  \param   satIOContext_t:   Pointer to the SAT IO Context
15802  *
15803  *  \return If command is started successfully
15804  *    - \e tiSuccess:     I/O request successfully initiated.
15805  *    - \e tiBusy:        No resources available, try again later.
15806  *    - \e tiIONoDevice:  Invalid device handle.
15807  *    - \e tiError:       Other errors.
15808  */
15809 /*****************************************************************************/
15810 GLOBAL bit32  satReadMediaSerialNumber(
15811                    tiRoot_t                  *tiRoot,
15812                    tiIORequest_t             *tiIORequest,
15813                    tiDeviceHandle_t          *tiDeviceHandle,
15814                    tiScsiInitiatorRequest_t  *tiScsiRequest,
15815                    satIOContext_t            *satIOContext)
15816 {
15817   bit32                     status;
15818   bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15819   satDeviceData_t           *pSatDevData;
15820   scsiRspSense_t            *pSense;
15821   tiIniScsiCmnd_t           *scsiCmnd;
15822   agsaFisRegHostToDevice_t  *fis;
15823   agsaSATAIdentifyData_t    *pSATAIdData;
15824   bit8                      *pSerialNumber;
15825 
15826   pSense        = satIOContext->pSense;
15827   pSatDevData   = satIOContext->pSatDevData;
15828   scsiCmnd      = &tiScsiRequest->scsiCmnd;
15829   fis           = satIOContext->pFis;
15830   pSATAIdData   = &(pSatDevData->satIdentifyData);
15831   pSerialNumber = (bit8 *) tiScsiRequest->sglVirtualAddr;
15832 
15833 
15834   TI_DBG1(("satReadMediaSerialNumber: start\n"));
15835 
15836   /* checking CONTROL */
15837   /* NACA == 1 or LINK == 1*/
15838   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
15839   {
15840     satSetSensePayload( pSense,
15841                         SCSI_SNSKEY_ILLEGAL_REQUEST,
15842                         0,
15843                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15844                         satIOContext);
15845 
15846     ostiInitiatorIOCompleted( tiRoot,
15847                               tiIORequest,
15848                               tiIOSuccess,
15849                               SCSI_STAT_CHECK_CONDITION,
15850                               satIOContext->pTiSenseData,
15851                               satIOContext->interruptContext );
15852 
15853     TI_DBG1(("satReadMediaSerialNumber: return control\n"));
15854     return tiSuccess;
15855   }
15856 
15857   if (tiScsiRequest->scsiCmnd.expDataLength == 4)
15858   {
15859     if (pSATAIdData->commandSetFeatureDefault & 0x4)
15860     {
15861       TI_DBG1(("satReadMediaSerialNumber: Media serial number returning only length\n"));
15862       /* SPC-3 6.16 p192; filling in length */
15863       pSerialNumber[0] = 0;
15864       pSerialNumber[1] = 0;
15865       pSerialNumber[2] = 0;
15866       pSerialNumber[3] = 0x3C;
15867     }
15868     else
15869     {
15870       /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/
15871       pSerialNumber[0] = 0;
15872       pSerialNumber[1] = 0;
15873       pSerialNumber[2] = 0x1;
15874       pSerialNumber[3] = 0xfc;
15875     }
15876 
15877     ostiInitiatorIOCompleted( tiRoot,
15878                               tiIORequest,
15879                               tiIOSuccess,
15880                               SCSI_STAT_GOOD,
15881                               agNULL,
15882                               satIOContext->interruptContext);
15883 
15884     return tiSuccess;
15885   }
15886 
15887   if ( pSatDevData->IDDeviceValid == agTRUE)
15888   {
15889     if (pSATAIdData->commandSetFeatureDefault & 0x4)
15890     {
15891       /* word87 bit2 Media serial number is valid */
15892       /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/
15893       tdhexdump("ID satReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
15894       /* SPC-3 6.16 p192; filling in length */
15895       pSerialNumber[0] = 0;
15896       pSerialNumber[1] = 0;
15897       pSerialNumber[2] = 0;
15898       pSerialNumber[3] = 0x3C;
15899       osti_memcpy(&pSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
15900       tdhexdump("satReadMediaSerialNumber", (bit8*)pSerialNumber, 2*30 + 4);
15901 
15902       ostiInitiatorIOCompleted( tiRoot,
15903                                 tiIORequest,
15904                                 tiIOSuccess,
15905                                 SCSI_STAT_GOOD,
15906                                 agNULL,
15907                                 satIOContext->interruptContext);
15908       return tiSuccess;
15909 
15910 
15911     }
15912     else
15913     {
15914      /* word87 bit2 Media serial number is NOT valid */
15915       TI_DBG1(("satReadMediaSerialNumber: Media serial number is NOT valid \n"));
15916 
15917       if (pSatDevData->sat48BitSupport == agTRUE)
15918       {
15919         /* READ VERIFY SECTORS EXT */
15920         fis->h.fisType        = 0x27;                   /* Reg host to device */
15921         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15922         fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
15923 
15924         fis->h.features       = 0;                      /* FIS reserve */
15925         fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
15926         fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
15927         fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
15928         fis->d.device         = 0x40;                   /* FIS LBA mode set */
15929         fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
15930         fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15931         fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15932         fis->d.featuresExp    = 0;                      /* FIS reserve */
15933         fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
15934         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
15935         fis->d.reserved4      = 0;
15936         fis->d.control        = 0;                      /* FIS HOB bit clear */
15937         fis->d.reserved5      = 0;
15938 
15939         agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15940       }
15941       else
15942       {
15943         /* READ VERIFY SECTORS */
15944         fis->h.fisType        = 0x27;                   /* Reg host to device */
15945         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15946         fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
15947         fis->h.features       = 0;                      /* FIS reserve */
15948         fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
15949         fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
15950         fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
15951         fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
15952         fis->d.lbaLowExp      = 0;
15953         fis->d.lbaMidExp      = 0;
15954         fis->d.lbaHighExp     = 0;
15955         fis->d.featuresExp    = 0;
15956         fis->d.sectorCount    = 1;                       /* FIS sector count (7:0) */
15957         fis->d.sectorCountExp = 0;
15958         fis->d.reserved4      = 0;
15959         fis->d.control        = 0;                      /* FIS HOB bit clear */
15960         fis->d.reserved5      = 0;
15961 
15962 
15963         agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15964       }
15965       satIOContext->satCompleteCB = &satReadMediaSerialNumberCB;
15966       satIOContext->reqType = agRequestType;       /* Save it */
15967       status = sataLLIOStart( tiRoot,
15968                              tiIORequest,
15969                              tiDeviceHandle,
15970                              tiScsiRequest,
15971                              satIOContext);
15972 
15973       return status;
15974     }
15975   }
15976   else
15977   {
15978      /* temporary failure */
15979     ostiInitiatorIOCompleted( tiRoot,
15980                               tiIORequest,
15981                               tiIOFailed,
15982                               tiDetailOtherError,
15983                               agNULL,
15984                               satIOContext->interruptContext);
15985 
15986     return tiSuccess;
15987 
15988   }
15989 
15990 }
15991 
15992 /*****************************************************************************/
15993 /*! \brief SAT implementation for SCSI satReadBuffer.
15994  *
15995  *  SAT implementation for SCSI Read Buffer.
15996  *
15997  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
15998  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
15999  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16000  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16001  *  \param   satIOContext_t:   Pointer to the SAT IO Context
16002  *
16003  *  \return If command is started successfully
16004  *    - \e tiSuccess:     I/O request successfully initiated.
16005  *    - \e tiBusy:        No resources available, try again later.
16006  *    - \e tiIONoDevice:  Invalid device handle.
16007  *    - \e tiError:       Other errors.
16008  */
16009 /*****************************************************************************/
16010 /* SAT-2, Revision 00*/
16011 GLOBAL bit32  satReadBuffer(
16012                    tiRoot_t                  *tiRoot,
16013                    tiIORequest_t             *tiIORequest,
16014                    tiDeviceHandle_t          *tiDeviceHandle,
16015                    tiScsiInitiatorRequest_t *tiScsiRequest,
16016                    satIOContext_t            *satIOContext)
16017 {
16018   bit32                     status = tiSuccess;
16019   bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16020   scsiRspSense_t            *pSense;
16021   tiIniScsiCmnd_t           *scsiCmnd;
16022   agsaFisRegHostToDevice_t  *fis;
16023   bit32                     bufferOffset;
16024   bit32                     tl;
16025   bit8                      mode;
16026   bit8                      bufferID;
16027   bit8                      *pBuff;
16028 
16029   pSense        = satIOContext->pSense;
16030   scsiCmnd      = &tiScsiRequest->scsiCmnd;
16031   fis           = satIOContext->pFis;
16032   pBuff         = (bit8 *) tiScsiRequest->sglVirtualAddr;
16033 
16034   TI_DBG2(("satReadBuffer: start\n"));
16035   /* checking CONTROL */
16036   /* NACA == 1 or LINK == 1*/
16037   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16038   {
16039     satSetSensePayload( pSense,
16040                         SCSI_SNSKEY_ILLEGAL_REQUEST,
16041                         0,
16042                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16043                         satIOContext);
16044     ostiInitiatorIOCompleted( tiRoot,
16045                               tiIORequest,
16046                               tiIOSuccess,
16047                               SCSI_STAT_CHECK_CONDITION,
16048                               satIOContext->pTiSenseData,
16049                               satIOContext->interruptContext );
16050     TI_DBG1(("satReadBuffer: return control\n"));
16051     return tiSuccess;
16052   }
16053 
16054   bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16055   tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16056 
16057   mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16058   bufferID = scsiCmnd->cdb[2];
16059 
16060   if (mode == READ_BUFFER_DATA_MODE) /* 2 */
16061   {
16062     if (bufferID == 0 && bufferOffset == 0 && tl == 512)
16063     {
16064       /* send ATA READ BUFFER */
16065       fis->h.fisType        = 0x27;                   /* Reg host to device */
16066       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16067       fis->h.command        = SAT_READ_BUFFER;        /* 0xE4 */
16068       fis->h.features       = 0;                      /* FIS reserve */
16069       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16070       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16071       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16072       fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16073       fis->d.lbaLowExp      = 0;
16074       fis->d.lbaMidExp      = 0;
16075       fis->d.lbaHighExp     = 0;
16076       fis->d.featuresExp    = 0;
16077       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16078       fis->d.sectorCountExp = 0;
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_PIO_READ;
16084       satIOContext->satCompleteCB = &satReadBufferCB;
16085       satIOContext->reqType = agRequestType;       /* Save it */
16086 
16087       status = sataLLIOStart( tiRoot,
16088                               tiIORequest,
16089                               tiDeviceHandle,
16090                               tiScsiRequest,
16091                               satIOContext);
16092       return status;
16093     }
16094     if (bufferID == 0 && bufferOffset == 0 && tl != 512)
16095     {
16096       satSetSensePayload( pSense,
16097                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16098                           0,
16099                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16100                           satIOContext);
16101       ostiInitiatorIOCompleted( tiRoot,
16102                                 tiIORequest,
16103                                 tiIOSuccess,
16104                                 SCSI_STAT_CHECK_CONDITION,
16105                                 satIOContext->pTiSenseData,
16106                                 satIOContext->interruptContext );
16107       TI_DBG1(("satReadBuffer: allocation length is not 512; it is %d\n", tl));
16108       return tiSuccess;
16109     }
16110     if (bufferID == 0 && bufferOffset != 0)
16111     {
16112       satSetSensePayload( pSense,
16113                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16114                           0,
16115                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16116                           satIOContext);
16117       ostiInitiatorIOCompleted( tiRoot,
16118                                 tiIORequest,
16119                                 tiIOSuccess,
16120                                 SCSI_STAT_CHECK_CONDITION,
16121                                 satIOContext->pTiSenseData,
16122                                 satIOContext->interruptContext );
16123       TI_DBG1(("satReadBuffer: buffer offset is not 0; it is %d\n", bufferOffset));
16124       return tiSuccess;
16125     }
16126     /* all other cases unsupported */
16127     TI_DBG1(("satReadBuffer: unsupported case 1\n"));
16128     satSetSensePayload( pSense,
16129                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16130                           0,
16131                           SCSI_SNSCODE_INVALID_COMMAND,
16132                           satIOContext);
16133 
16134     ostiInitiatorIOCompleted( tiRoot,
16135                                 tiIORequest,
16136                                 tiIOSuccess,
16137                                 SCSI_STAT_CHECK_CONDITION,
16138                                 satIOContext->pTiSenseData,
16139                                 satIOContext->interruptContext );
16140     return tiSuccess;
16141   }
16142   else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */
16143   {
16144     if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */
16145     {
16146       satSetSensePayload( pSense,
16147                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16148                           0,
16149                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16150                           satIOContext);
16151       ostiInitiatorIOCompleted( tiRoot,
16152                                 tiIORequest,
16153                                 tiIOSuccess,
16154                                 SCSI_STAT_CHECK_CONDITION,
16155                                 satIOContext->pTiSenseData,
16156                                 satIOContext->interruptContext );
16157       TI_DBG1(("satReadBuffer: tl < 4; tl is %d\n", tl));
16158       return tiSuccess;
16159     }
16160     if (bufferID == 0)
16161     {
16162       /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/
16163       pBuff[0] = 0xFF;
16164       pBuff[1] = 0x00;
16165       pBuff[2] = 0x02;
16166       pBuff[3] = 0x00;
16167       if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
16168       {
16169         /* underrrun */
16170         TI_DBG1(("satReadBuffer: underrun tl %d data %d\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
16171         ostiInitiatorIOCompleted( tiRoot,
16172                                 tiIORequest,
16173                                 tiIOUnderRun,
16174                                 tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
16175                                 agNULL,
16176                                 satIOContext->interruptContext );
16177         return tiSuccess;
16178       }
16179       else
16180       {
16181         ostiInitiatorIOCompleted( tiRoot,
16182                                   tiIORequest,
16183                                   tiIOSuccess,
16184                                   SCSI_STAT_GOOD,
16185                                   agNULL,
16186                                   satIOContext->interruptContext);
16187         return tiSuccess;
16188       }
16189     }
16190     else
16191     {
16192       /* We don't support other than bufferID 0 */
16193       satSetSensePayload( pSense,
16194                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16195                           0,
16196                           SCSI_SNSCODE_INVALID_COMMAND,
16197                           satIOContext);
16198 
16199       ostiInitiatorIOCompleted( tiRoot,
16200                                 tiIORequest,
16201                                 tiIOSuccess,
16202                                 SCSI_STAT_CHECK_CONDITION,
16203                                 satIOContext->pTiSenseData,
16204                                 satIOContext->interruptContext );
16205       return tiSuccess;
16206     }
16207   }
16208   else
16209   {
16210     /* We don't support any other mode */
16211     TI_DBG1(("satReadBuffer: unsupported mode %d\n", mode));
16212     satSetSensePayload( pSense,
16213                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16214                           0,
16215                           SCSI_SNSCODE_INVALID_COMMAND,
16216                           satIOContext);
16217 
16218     ostiInitiatorIOCompleted( tiRoot,
16219                                 tiIORequest,
16220                                 tiIOSuccess,
16221                                 SCSI_STAT_CHECK_CONDITION,
16222                                 satIOContext->pTiSenseData,
16223                                 satIOContext->interruptContext );
16224     return tiSuccess;
16225   }
16226 }
16227 
16228 /*****************************************************************************/
16229 /*! \brief SAT implementation for SCSI satWriteBuffer.
16230  *
16231  *  SAT implementation for SCSI Write Buffer.
16232  *
16233  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16234  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16235  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16236  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16237  *  \param   satIOContext_t:   Pointer to the SAT IO Context
16238  *
16239  *  \return If command is started successfully
16240  *    - \e tiSuccess:     I/O request successfully initiated.
16241  *    - \e tiBusy:        No resources available, try again later.
16242  *    - \e tiIONoDevice:  Invalid device handle.
16243  *    - \e tiError:       Other errors.
16244  */
16245 /*****************************************************************************/
16246 /* SAT-2, Revision 00*/
16247 GLOBAL bit32  satWriteBuffer(
16248                    tiRoot_t                  *tiRoot,
16249                    tiIORequest_t             *tiIORequest,
16250                    tiDeviceHandle_t          *tiDeviceHandle,
16251                    tiScsiInitiatorRequest_t *tiScsiRequest,
16252                    satIOContext_t            *satIOContext)
16253 {
16254 #ifdef NOT_YET
16255   bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16256 #endif
16257   scsiRspSense_t            *pSense;
16258   tiIniScsiCmnd_t           *scsiCmnd;
16259   bit32                     bufferOffset;
16260   bit32                     parmLen;
16261   bit8                      mode;
16262   bit8                      bufferID;
16263   bit8                      *pBuff;
16264 
16265   pSense        = satIOContext->pSense;
16266   scsiCmnd      = &tiScsiRequest->scsiCmnd;
16267   pBuff         = (bit8 *) tiScsiRequest->sglVirtualAddr;
16268 
16269   TI_DBG2(("satWriteBuffer: start\n"));
16270 
16271   /* checking CONTROL */
16272   /* NACA == 1 or LINK == 1*/
16273   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16274   {
16275     satSetSensePayload( pSense,
16276                         SCSI_SNSKEY_ILLEGAL_REQUEST,
16277                         0,
16278                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16279                         satIOContext);
16280 
16281     ostiInitiatorIOCompleted( tiRoot,
16282                               tiIORequest,
16283                               tiIOSuccess,
16284                               SCSI_STAT_CHECK_CONDITION,
16285                               satIOContext->pTiSenseData,
16286                               satIOContext->interruptContext );
16287 
16288     TI_DBG1(("satWriteBuffer: return control\n"));
16289     return tiSuccess;
16290   }
16291 
16292   bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16293   parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16294 
16295   mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16296   bufferID = scsiCmnd->cdb[2];
16297 
16298   /* for debugging only */
16299   tdhexdump("satWriteBuffer pBuff", (bit8 *)pBuff, 24);
16300 
16301   if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */
16302   {
16303     if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
16304     {
16305       TI_DBG1(("satWriteBuffer: sending ATA WRITE BUFFER\n"));
16306       /* send ATA WRITE BUFFER */
16307 #ifdef NOT_YET
16308       fis->h.fisType        = 0x27;                   /* Reg host to device */
16309       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16310       fis->h.command        = SAT_WRITE_BUFFER;       /* 0xE8 */
16311       fis->h.features       = 0;                      /* FIS reserve */
16312       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16313       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16314       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16315       fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16316       fis->d.lbaLowExp      = 0;
16317       fis->d.lbaMidExp      = 0;
16318       fis->d.lbaHighExp     = 0;
16319       fis->d.featuresExp    = 0;
16320       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16321       fis->d.sectorCountExp = 0;
16322       fis->d.reserved4      = 0;
16323       fis->d.control        = 0;                      /* FIS HOB bit clear */
16324       fis->d.reserved5      = 0;
16325 
16326 
16327       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16328 
16329       satIOContext->satCompleteCB = &satWriteBufferCB;
16330 
16331       satIOContext->reqType = agRequestType;       /* Save it */
16332 
16333       status = sataLLIOStart( tiRoot,
16334                               tiIORequest,
16335                               tiDeviceHandle,
16336                               tiScsiRequest,
16337                               satIOContext);
16338       return status;
16339 #endif
16340       /* temp */
16341       ostiInitiatorIOCompleted( tiRoot,
16342                                   tiIORequest,
16343                                   tiIOSuccess,
16344                                   SCSI_STAT_GOOD,
16345                                   agNULL,
16346                                   satIOContext->interruptContext);
16347       return tiSuccess;
16348     }
16349     if ( (bufferID == 0 && bufferOffset != 0) ||
16350          (bufferID == 0 && parmLen != 512)
16351         )
16352     {
16353       satSetSensePayload( pSense,
16354                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16355                           0,
16356                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16357                           satIOContext);
16358 
16359       ostiInitiatorIOCompleted( tiRoot,
16360                                 tiIORequest,
16361                                 tiIOSuccess,
16362                                 SCSI_STAT_CHECK_CONDITION,
16363                                 satIOContext->pTiSenseData,
16364                                 satIOContext->interruptContext );
16365 
16366       TI_DBG1(("satWriteBuffer: wrong buffer offset %d or parameter length parmLen %d\n", bufferOffset, parmLen));
16367       return tiSuccess;
16368     }
16369 
16370     /* all other cases unsupported */
16371     TI_DBG1(("satWriteBuffer: unsupported case 1\n"));
16372     satSetSensePayload( pSense,
16373                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16374                           0,
16375                           SCSI_SNSCODE_INVALID_COMMAND,
16376                           satIOContext);
16377 
16378     ostiInitiatorIOCompleted( tiRoot,
16379                                 tiIORequest,
16380                                 tiIOSuccess,
16381                                 SCSI_STAT_CHECK_CONDITION,
16382                                 satIOContext->pTiSenseData,
16383                                 satIOContext->interruptContext );
16384 
16385     return tiSuccess;
16386 
16387   }
16388   else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */
16389   {
16390     TI_DBG1(("satWriteBuffer: not yet supported mode %d\n", mode));
16391     satSetSensePayload( pSense,
16392                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16393                           0,
16394                           SCSI_SNSCODE_INVALID_COMMAND,
16395                           satIOContext);
16396 
16397     ostiInitiatorIOCompleted( tiRoot,
16398                                 tiIORequest,
16399                                 tiIOSuccess,
16400                                 SCSI_STAT_CHECK_CONDITION,
16401                                 satIOContext->pTiSenseData,
16402                                 satIOContext->interruptContext );
16403 
16404     return tiSuccess;
16405   }
16406   else
16407   {
16408     /* We don't support any other mode */
16409     TI_DBG1(("satWriteBuffer: unsupported mode %d\n", mode));
16410     satSetSensePayload( pSense,
16411                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16412                           0,
16413                           SCSI_SNSCODE_INVALID_COMMAND,
16414                           satIOContext);
16415 
16416     ostiInitiatorIOCompleted( tiRoot,
16417                                 tiIORequest,
16418                                 tiIOSuccess,
16419                                 SCSI_STAT_CHECK_CONDITION,
16420                                 satIOContext->pTiSenseData,
16421                                 satIOContext->interruptContext );
16422 
16423     return tiSuccess;
16424   }
16425 
16426 }
16427 
16428 /*****************************************************************************/
16429 /*! \brief SAT implementation for SCSI satReassignBlocks.
16430  *
16431  *  SAT implementation for SCSI Reassign Blocks.
16432  *
16433  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16434  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16435  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16436  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16437  *  \param   satIOContext_t:   Pointer to the SAT IO Context
16438  *
16439  *  \return If command is started successfully
16440  *    - \e tiSuccess:     I/O request successfully initiated.
16441  *    - \e tiBusy:        No resources available, try again later.
16442  *    - \e tiIONoDevice:  Invalid device handle.
16443  *    - \e tiError:       Other errors.
16444  */
16445 /*****************************************************************************/
16446 GLOBAL bit32  satReassignBlocks(
16447                    tiRoot_t                  *tiRoot,
16448                    tiIORequest_t             *tiIORequest,
16449                    tiDeviceHandle_t          *tiDeviceHandle,
16450                    tiScsiInitiatorRequest_t *tiScsiRequest,
16451                    satIOContext_t            *satIOContext)
16452 {
16453   /*
16454     assumes all LBA fits in ATA command; no boundary condition is checked here yet
16455   */
16456   bit32                     status;
16457   bit32                     agRequestType;
16458   satDeviceData_t           *pSatDevData;
16459   scsiRspSense_t            *pSense;
16460   tiIniScsiCmnd_t           *scsiCmnd;
16461   agsaFisRegHostToDevice_t  *fis;
16462   bit8                      *pParmList;    /* Log Page data buffer */
16463   bit8                      LongLBA;
16464   bit8                      LongList;
16465   bit32                     defectListLen;
16466   bit8                      LBA[8];
16467   bit32                     startingIndex;
16468 
16469   pSense        = satIOContext->pSense;
16470   pSatDevData   = satIOContext->pSatDevData;
16471   scsiCmnd      = &tiScsiRequest->scsiCmnd;
16472   fis           = satIOContext->pFis;
16473   pParmList     = (bit8 *) tiScsiRequest->sglVirtualAddr;
16474 
16475   TI_DBG5(("satReassignBlocks: start\n"));
16476 
16477   /* checking CONTROL */
16478   /* NACA == 1 or LINK == 1*/
16479   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
16480   {
16481     satSetSensePayload( pSense,
16482                         SCSI_SNSKEY_ILLEGAL_REQUEST,
16483                         0,
16484                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16485                         satIOContext);
16486 
16487     ostiInitiatorIOCompleted( tiRoot,
16488                               tiIORequest,
16489                               tiIOSuccess,
16490                               SCSI_STAT_CHECK_CONDITION,
16491                               satIOContext->pTiSenseData,
16492                               satIOContext->interruptContext );
16493 
16494     TI_DBG1(("satReassignBlocks: return control\n"));
16495     return tiSuccess;
16496   }
16497 
16498   osti_memset(satIOContext->LBA, 0, 8);
16499   satIOContext->ParmIndex = 0;
16500   satIOContext->ParmLen = 0;
16501 
16502   LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK);
16503   LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16504   osti_memset(LBA, 0, sizeof(LBA));
16505 
16506   if (LongList == 0)
16507   {
16508     defectListLen = (pParmList[2] << 8) + pParmList[3];
16509   }
16510   else
16511   {
16512     defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2))
16513                   + (pParmList[2] << 8) + pParmList[3];
16514   }
16515   /* SBC 5.16.2, p61*/
16516   satIOContext->ParmLen = defectListLen + 4 /* header size */;
16517 
16518   startingIndex = 4;
16519 
16520   if (LongLBA == 0)
16521   {
16522     LBA[4] = pParmList[startingIndex];   /* MSB */
16523     LBA[5] = pParmList[startingIndex+1];
16524     LBA[6] = pParmList[startingIndex+2];
16525     LBA[7] = pParmList[startingIndex+3];  /* LSB */
16526     startingIndex = startingIndex + 4;
16527   }
16528   else
16529   {
16530     LBA[0] = pParmList[startingIndex];    /* MSB */
16531     LBA[1] = pParmList[startingIndex+1];
16532     LBA[2] = pParmList[startingIndex+2];
16533     LBA[3] = pParmList[startingIndex+3];
16534     LBA[4] = pParmList[startingIndex+4];
16535     LBA[5] = pParmList[startingIndex+5];
16536     LBA[6] = pParmList[startingIndex+6];
16537     LBA[7] = pParmList[startingIndex+7];  /* LSB */
16538     startingIndex = startingIndex + 8;
16539   }
16540 
16541   tdhexdump("satReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen);
16542 
16543   if (pSatDevData->sat48BitSupport == agTRUE)
16544   {
16545     /* sends READ VERIFY SECTOR(S) EXT*/
16546     fis->h.fisType        = 0x27;                   /* Reg host to device */
16547     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16548     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16549     fis->h.features       = 0;                      /* FIS reserve */
16550     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16551     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16552     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16553     fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16554     fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16555     fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16556     fis->d.featuresExp    = 0;                      /* FIS reserve */
16557     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16558     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16559     fis->d.reserved4      = 0;
16560     fis->d.device         = 0x40;                   /* 01000000 */
16561     fis->d.control        = 0;                      /* FIS HOB bit clear */
16562     fis->d.reserved5      = 0;
16563   }
16564   else
16565   {
16566     /* READ VERIFY SECTOR(S)*/
16567     fis->h.fisType        = 0x27;                   /* Reg host to device */
16568     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16569     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16570     fis->h.features       = 0;                      /* FIS features NA       */
16571     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16572     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16573     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16574     fis->d.lbaLowExp      = 0;
16575     fis->d.lbaMidExp      = 0;
16576     fis->d.lbaHighExp     = 0;
16577     fis->d.featuresExp    = 0;
16578     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16579     fis->d.sectorCountExp = 0;
16580     fis->d.reserved4      = 0;
16581     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16582                             /* DEV and LBA 27:24 */
16583     fis->d.control        = 0;                      /* FIS HOB bit clear */
16584     fis->d.reserved5      = 0;
16585   }
16586 
16587   osti_memcpy(satIOContext->LBA, LBA, 8);
16588   satIOContext->ParmIndex = startingIndex;
16589 
16590   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16591 
16592   /* Initialize CB for SATA completion.
16593    */
16594   satIOContext->satCompleteCB = &satReassignBlocksCB;
16595 
16596   /*
16597    * Prepare SGL and send FIS to LL layer.
16598    */
16599   satIOContext->reqType = agRequestType;       /* Save it */
16600 
16601   status = sataLLIOStart( tiRoot,
16602                           tiIORequest,
16603                           tiDeviceHandle,
16604                           tiScsiRequest,
16605                           satIOContext);
16606 
16607   return status;
16608 }
16609 
16610 /*****************************************************************************/
16611 /*! \brief SAT implementation for SCSI satReassignBlocks_1.
16612  *
16613  *  SAT implementation for SCSI Reassign Blocks. This is helper function for
16614  *  satReassignBlocks and satReassignBlocksCB. This sends ATA verify command.
16615  *
16616  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16617  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16618  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16619  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16620  *  \param   satIOContext_t:   Pointer to the SAT IO Context
16621  *
16622  *  \return If command is started successfully
16623  *    - \e tiSuccess:     I/O request successfully initiated.
16624  *    - \e tiBusy:        No resources available, try again later.
16625  *    - \e tiIONoDevice:  Invalid device handle.
16626  *    - \e tiError:       Other errors.
16627  */
16628 /*****************************************************************************/
16629 /* next LBA; sends READ VERIFY SECTOR; update LBA and ParmIdx */
16630 GLOBAL bit32  satReassignBlocks_1(
16631                    tiRoot_t                  *tiRoot,
16632                    tiIORequest_t             *tiIORequest,
16633                    tiDeviceHandle_t          *tiDeviceHandle,
16634                    tiScsiInitiatorRequest_t *tiScsiRequest,
16635                    satIOContext_t            *satIOContext,
16636                    satIOContext_t            *satOrgIOContext
16637                    )
16638 {
16639   /*
16640     assumes all LBA fits in ATA command; no boundary condition is checked here yet
16641     tiScsiRequest is OS generated; needs for accessing parameter list
16642   */
16643   bit32                     agRequestType;
16644   satDeviceData_t           *pSatDevData;
16645   tiIniScsiCmnd_t           *scsiCmnd;
16646   agsaFisRegHostToDevice_t  *fis;
16647   bit8                      *pParmList;    /* Log Page data buffer */
16648   bit8                      LongLBA;
16649   bit8                      LBA[8];
16650   bit32                     startingIndex;
16651 
16652   pSatDevData   = satIOContext->pSatDevData;
16653   scsiCmnd      = &tiScsiRequest->scsiCmnd;
16654   fis           = satIOContext->pFis;
16655   pParmList     = (bit8 *) tiScsiRequest->sglVirtualAddr;
16656 
16657   TI_DBG5(("satReassignBlocks_1: start\n"));
16658 
16659   LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16660   osti_memset(LBA, 0, sizeof(LBA));
16661 
16662   startingIndex = satOrgIOContext->ParmIndex;
16663 
16664   if (LongLBA == 0)
16665   {
16666     LBA[4] = pParmList[startingIndex];
16667     LBA[5] = pParmList[startingIndex+1];
16668     LBA[6] = pParmList[startingIndex+2];
16669     LBA[7] = pParmList[startingIndex+3];
16670     startingIndex = startingIndex + 4;
16671   }
16672   else
16673   {
16674     LBA[0] = pParmList[startingIndex];
16675     LBA[1] = pParmList[startingIndex+1];
16676     LBA[2] = pParmList[startingIndex+2];
16677     LBA[3] = pParmList[startingIndex+3];
16678     LBA[4] = pParmList[startingIndex+4];
16679     LBA[5] = pParmList[startingIndex+5];
16680     LBA[6] = pParmList[startingIndex+6];
16681     LBA[7] = pParmList[startingIndex+7];
16682     startingIndex = startingIndex + 8;
16683   }
16684 
16685   if (pSatDevData->sat48BitSupport == agTRUE)
16686   {
16687     /* sends READ VERIFY SECTOR(S) EXT*/
16688     fis->h.fisType        = 0x27;                   /* Reg host to device */
16689     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16690     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16691     fis->h.features       = 0;                      /* FIS reserve */
16692     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16693     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16694     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16695     fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16696     fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16697     fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16698     fis->d.featuresExp    = 0;                      /* FIS reserve */
16699     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16700     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16701     fis->d.reserved4      = 0;
16702     fis->d.device         = 0x40;                   /* 01000000 */
16703     fis->d.control        = 0;                      /* FIS HOB bit clear */
16704     fis->d.reserved5      = 0;
16705   }
16706   else
16707   {
16708     /* READ VERIFY SECTOR(S)*/
16709     fis->h.fisType        = 0x27;                   /* Reg host to device */
16710     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16711     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16712     fis->h.features       = 0;                      /* FIS features NA       */
16713     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16714     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16715     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16716     fis->d.lbaLowExp      = 0;
16717     fis->d.lbaMidExp      = 0;
16718     fis->d.lbaHighExp     = 0;
16719     fis->d.featuresExp    = 0;
16720     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16721     fis->d.sectorCountExp = 0;
16722     fis->d.reserved4      = 0;
16723     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16724                             /* DEV and LBA 27:24 */
16725     fis->d.control        = 0;                      /* FIS HOB bit clear */
16726     fis->d.reserved5      = 0;
16727   }
16728   osti_memcpy(satOrgIOContext->LBA, LBA, 8);
16729   satOrgIOContext->ParmIndex = startingIndex;
16730   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16731   /* Initialize CB for SATA completion.
16732    */
16733   satIOContext->satCompleteCB = &satReassignBlocksCB;
16734   /*
16735    * Prepare SGL and send FIS to LL layer.
16736    */
16737   satIOContext->reqType = agRequestType;       /* Save it */
16738 
16739   sataLLIOStart( tiRoot,
16740                  tiIORequest,
16741                  tiDeviceHandle,
16742                  tiScsiRequest,
16743                  satIOContext );
16744   return tiSuccess;
16745 }
16746 
16747 /*****************************************************************************/
16748 /*! \brief SAT implementation for SCSI satReassignBlocks_2.
16749  *
16750  *  SAT implementation for SCSI Reassign Blocks. This is helper function for
16751  *  satReassignBlocks and satReassignBlocksCB. This sends ATA write command.
16752  *
16753  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16754  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16755  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16756  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16757  *  \param   satIOContext_t:   Pointer to the SAT IO Context
16758  *  \param   LBA:              Pointer to the LBA to be processed
16759  *
16760  *  \return If command is started successfully
16761  *    - \e tiSuccess:     I/O request successfully initiated.
16762  *    - \e tiBusy:        No resources available, try again later.
16763  *    - \e tiIONoDevice:  Invalid device handle.
16764  *    - \e tiError:       Other errors.
16765  */
16766 /*****************************************************************************/
16767 /* current LBA; sends WRITE */
16768 GLOBAL bit32  satReassignBlocks_2(
16769                    tiRoot_t                  *tiRoot,
16770                    tiIORequest_t             *tiIORequest,
16771                    tiDeviceHandle_t          *tiDeviceHandle,
16772                    tiScsiInitiatorRequest_t *tiScsiRequest,
16773                    satIOContext_t            *satIOContext,
16774                    bit8                      *LBA
16775                    )
16776 {
16777   /*
16778     assumes all LBA fits in ATA command; no boundary condition is checked here yet
16779     tiScsiRequest is TD generated for writing
16780   */
16781   bit32                     status;
16782   bit32                     agRequestType;
16783   satDeviceData_t           *pSatDevData;
16784   scsiRspSense_t            *pSense;
16785   agsaFisRegHostToDevice_t  *fis;
16786 
16787   pSense        = satIOContext->pSense;
16788   pSatDevData   = satIOContext->pSatDevData;
16789   fis           = satIOContext->pFis;
16790 
16791   if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16792   {
16793     /* case 2 */
16794     /* WRITE DMA*/
16795     /* can't fit the transfer length */
16796     TI_DBG5(("satReassignBlocks_2: case 2\n"));
16797     fis->h.fisType        = 0x27;                   /* Reg host to device */
16798     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16799     fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
16800     fis->h.features       = 0;                      /* FIS reserve */
16801     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16802     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16803     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16804 
16805     /* FIS LBA mode set LBA (27:24) */
16806     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16807 
16808     fis->d.lbaLowExp      = 0;
16809     fis->d.lbaMidExp      = 0;
16810     fis->d.lbaHighExp     = 0;
16811     fis->d.featuresExp    = 0;
16812     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16813     fis->d.sectorCountExp = 0;
16814     fis->d.reserved4      = 0;
16815     fis->d.control        = 0;                      /* FIS HOB bit clear */
16816     fis->d.reserved5      = 0;
16817 
16818     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16819     satIOContext->ATACmd = SAT_WRITE_DMA;
16820   }
16821   else
16822   {
16823     /* case 1 */
16824     /* WRITE MULTIPLE or WRITE SECTOR(S) */
16825     /* WRITE SECTORS for easier implemetation */
16826     /* can't fit the transfer length */
16827     TI_DBG5(("satReassignBlocks_2: case 1\n"));
16828     fis->h.fisType        = 0x27;                   /* Reg host to device */
16829     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16830     fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
16831     fis->h.features       = 0;                      /* FIS reserve */
16832     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16833     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16834     fis->d.lbaHigh        = LBA[7];                 /* FIS LBA (23:16) */
16835 
16836     /* FIS LBA mode set LBA (27:24) */
16837     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16838 
16839     fis->d.lbaLowExp      = 0;
16840     fis->d.lbaMidExp      = 0;
16841     fis->d.lbaHighExp     = 0;
16842     fis->d.featuresExp    = 0;
16843     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16844     fis->d.sectorCountExp = 0;
16845     fis->d.reserved4      = 0;
16846     fis->d.control        = 0;                      /* FIS HOB bit clear */
16847     fis->d.reserved5      = 0;
16848 
16849     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16850     satIOContext->ATACmd = SAT_WRITE_SECTORS;
16851   }
16852 
16853   /* case 3 and 4 */
16854   if (pSatDevData->sat48BitSupport == agTRUE)
16855   {
16856     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16857     {
16858       /* case 3 */
16859       /* WRITE DMA EXT or WRITE DMA FUA EXT */
16860       TI_DBG5(("satReassignBlocks_2: case 3\n"));
16861       fis->h.fisType        = 0x27;                   /* Reg host to device */
16862       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16863 
16864       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
16865       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
16866       satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
16867 
16868       fis->h.features       = 0;                      /* FIS reserve */
16869       fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16870       fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16871       fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16872       fis->d.device         = 0x40;                   /* FIS LBA mode set */
16873       fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16874       fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16875       fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16876       fis->d.featuresExp    = 0;                      /* FIS reserve */
16877       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16878       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16879       fis->d.reserved4      = 0;
16880       fis->d.control        = 0;                      /* FIS HOB bit clear */
16881       fis->d.reserved5      = 0;
16882 
16883       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16884     }
16885     else
16886     {
16887       /* case 4 */
16888       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
16889       /* WRITE SECTORS EXT for easier implemetation */
16890       TI_DBG5(("satReassignBlocks_2: case 4\n"));
16891       fis->h.fisType        = 0x27;                   /* Reg host to device */
16892       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16893       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
16894 
16895       fis->h.features       = 0;                      /* FIS reserve */
16896       fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16897       fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16898       fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16899       fis->d.device         = 0x40;                   /* FIS LBA mode set */
16900       fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16901       fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16902       fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16903       fis->d.featuresExp    = 0;                      /* FIS reserve */
16904       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16905       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16906       fis->d.reserved4      = 0;
16907       fis->d.control        = 0;                      /* FIS HOB bit clear */
16908       fis->d.reserved5      = 0;
16909 
16910       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16911       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
16912     }
16913   }
16914   /* case 5 */
16915   if (pSatDevData->satNCQ == agTRUE)
16916   {
16917     /* WRITE FPDMA QUEUED */
16918     if (pSatDevData->sat48BitSupport != agTRUE)
16919     {
16920       TI_DBG5(("satReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
16921       satSetSensePayload( pSense,
16922                           SCSI_SNSKEY_HARDWARE_ERROR,
16923                           0,
16924                           SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
16925                           satIOContext);
16926 
16927       ostiInitiatorIOCompleted( tiRoot,
16928                                 tiIORequest,
16929                                 tiIOSuccess,
16930                                 SCSI_STAT_CHECK_CONDITION,
16931                                 satIOContext->pTiSenseData,
16932                                 satIOContext->interruptContext );
16933       return tiSuccess;
16934     }
16935     TI_DBG6(("satWrite10: case 5\n"));
16936 
16937     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
16938 
16939     fis->h.fisType        = 0x27;                   /* Reg host to device */
16940     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16941     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
16942     fis->h.features       = 1;                      /* FIS sector count (7:0) */
16943     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16944     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16945     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16946 
16947     /* Check FUA bit */
16948     fis->d.device       = 0x40;                     /* FIS FUA clear */
16949 
16950     fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16951     fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16952     fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16953     fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
16954     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
16955     fis->d.sectorCountExp = 0;
16956     fis->d.reserved4      = 0;
16957     fis->d.control        = 0;                      /* FIS HOB bit clear */
16958     fis->d.reserved5      = 0;
16959 
16960     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
16961     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
16962   }
16963 
16964   satIOContext->satCompleteCB = &satReassignBlocksCB;
16965 
16966   /*
16967    * Prepare SGL and send FIS to LL layer.
16968    */
16969   satIOContext->reqType = agRequestType;       /* Save it */
16970 
16971   status = sataLLIOStart( tiRoot,
16972                           tiIORequest,
16973                           tiDeviceHandle,
16974                           /* not the original, should be the TD generated one */
16975                           tiScsiRequest,
16976                           satIOContext);
16977   return (status);
16978 }
16979 
16980 
16981 /*****************************************************************************/
16982 /*! \brief SAT implementation for SCSI satPrepareNewIO.
16983  *
16984  *  This function fills in the fields of internal IO generated by TD layer.
16985  *  This is mostly used in the callback functions.
16986  *
16987  *  \param   satNewIntIo:      Pointer to the internal IO structure.
16988  *  \param   tiOrgIORequest:   Pointer to the original tiIOrequest sent by OS layer
16989  *  \param   satDevData:       Pointer to the device data.
16990  *  \param   scsiCmnd:         Pointer to SCSI command.
16991  *  \param   satOrgIOContext:  Pointer to the original SAT IO Context
16992  *
16993  *  \return
16994  *    - \e Pointer to the new SAT IO Context
16995  */
16996 /*****************************************************************************/
16997 GLOBAL satIOContext_t *satPrepareNewIO(
16998                             satInternalIo_t         *satNewIntIo,
16999                             tiIORequest_t           *tiOrgIORequest,
17000                             satDeviceData_t         *satDevData,
17001                             tiIniScsiCmnd_t         *scsiCmnd,
17002                             satIOContext_t          *satOrgIOContext
17003                             )
17004 {
17005   satIOContext_t          *satNewIOContext;
17006   tdIORequestBody_t       *tdNewIORequestBody;
17007 
17008   TI_DBG2(("satPrepareNewIO: start\n"));
17009 
17010   /* the one to be used; good 8/2/07 */
17011   satNewIntIo->satOrgTiIORequest = tiOrgIORequest; /* this is already done in
17012                                                         satAllocIntIoResource() */
17013 
17014   tdNewIORequestBody = (tdIORequestBody_t *)satNewIntIo->satIntRequestBody;
17015   satNewIOContext = &(tdNewIORequestBody->transport.SATA.satIOContext);
17016 
17017   satNewIOContext->pSatDevData   = satDevData;
17018   satNewIOContext->pFis          = &(tdNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
17019   satNewIOContext->pScsiCmnd     = &(satNewIntIo->satIntTiScsiXchg.scsiCmnd);
17020   if (scsiCmnd != agNULL)
17021   {
17022     /* saves only CBD; not scsi command for LBA and number of blocks */
17023     osti_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
17024   }
17025   satNewIOContext->pSense        = &(tdNewIORequestBody->transport.SATA.sensePayload);
17026   satNewIOContext->pTiSenseData  = &(tdNewIORequestBody->transport.SATA.tiSenseData);
17027   satNewIOContext->pTiSenseData->senseData = satNewIOContext->pSense;
17028   satNewIOContext->tiRequestBody = satNewIntIo->satIntRequestBody;
17029   satNewIOContext->interruptContext = satNewIOContext->interruptContext;
17030   satNewIOContext->satIntIoContext  = satNewIntIo;
17031   satNewIOContext->ptiDeviceHandle = satOrgIOContext->ptiDeviceHandle;
17032   satNewIOContext->satOrgIOContext = satOrgIOContext;
17033   /* saves tiScsiXchg; only for writesame10() */
17034   satNewIOContext->tiScsiXchg = satOrgIOContext->tiScsiXchg;
17035 
17036   return satNewIOContext;
17037 }
17038 /*****************************************************************************
17039  *! \brief  satIOAbort
17040  *
17041  *   This routine is called to initiate a I/O abort to SATL.
17042  *   This routine is independent of HW/LL API.
17043  *
17044  *  \param  tiRoot:     Pointer to TISA initiator driver/port instance.
17045  *  \param  taskTag:    Pointer to TISA I/O request context/tag to be aborted.
17046  *
17047  *  \return:
17048  *
17049  *  \e tiSuccess:     I/O request successfully initiated.
17050  *  \e tiBusy:        No resources available, try again later.
17051  *  \e tiError:       Other errors that prevent the I/O request to be started.
17052  *
17053  *
17054  *****************************************************************************/
17055 GLOBAL bit32 satIOAbort(
17056                           tiRoot_t      *tiRoot,
17057                           tiIORequest_t *taskTag )
17058 {
17059 
17060   tdsaRoot_t          *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
17061   tdsaContext_t       *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
17062   agsaRoot_t          *agRoot;
17063   tdIORequestBody_t   *tdIORequestBody;
17064   tdIORequestBody_t   *tdIONewRequestBody;
17065   agsaIORequest_t     *agIORequest;
17066   bit32               status;
17067   agsaIORequest_t     *agAbortIORequest;
17068   tdIORequestBody_t   *tdAbortIORequestBody;
17069   bit32               PhysUpper32;
17070   bit32               PhysLower32;
17071   bit32               memAllocStatus;
17072   void                *osMemHandle;
17073   satIOContext_t      *satIOContext;
17074   satInternalIo_t     *satIntIo;
17075 
17076   TI_DBG2(("satIOAbort: start\n"));
17077 
17078   agRoot          = &(tdsaAllShared->agRootNonInt);
17079   tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData;
17080 
17081   /* needs to distinguish internally generated or externally generated */
17082   satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17083   satIntIo     = satIOContext->satIntIoContext;
17084   if (satIntIo == agNULL)
17085   {
17086     TI_DBG1(("satIOAbort: External, OS generated\n"));
17087     agIORequest     = &(tdIORequestBody->agIORequest);
17088   }
17089   else
17090   {
17091     TI_DBG1(("satIOAbort: Internal, TD generated\n"));
17092     tdIONewRequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
17093     agIORequest     = &(tdIONewRequestBody->agIORequest);
17094   }
17095 
17096   /* allocating agIORequest for abort itself */
17097   memAllocStatus = ostiAllocMemory(
17098                                    tiRoot,
17099                                    &osMemHandle,
17100                                    (void **)&tdAbortIORequestBody,
17101                                    &PhysUpper32,
17102                                    &PhysLower32,
17103                                    8,
17104                                    sizeof(tdIORequestBody_t),
17105                                    agTRUE
17106                                    );
17107   if (memAllocStatus != tiSuccess)
17108   {
17109     /* let os process IO */
17110     TI_DBG1(("satIOAbort: ostiAllocMemory failed...\n"));
17111     return tiError;
17112   }
17113 
17114   if (tdAbortIORequestBody == agNULL)
17115   {
17116     /* let os process IO */
17117     TI_DBG1(("satIOAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17118     return tiError;
17119   }
17120 
17121   /* setup task management structure */
17122   tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17123   tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
17124 
17125   /* initialize agIORequest */
17126   agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17127   agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17128   agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17129 
17130   /* remember IO to be aborted */
17131   tdAbortIORequestBody->tiIOToBeAbortedRequest = taskTag;
17132 
17133   status = saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, agNULL );
17134 
17135   TI_DBG5(("satIOAbort: return status=0x%x\n", status));
17136 
17137   if (status == AGSA_RC_SUCCESS)
17138     return tiSuccess;
17139   else
17140     return tiError;
17141 
17142 }
17143 
17144 
17145 /*****************************************************************************
17146  *! \brief  satTM
17147  *
17148  *   This routine is called to initiate a TM request to SATL.
17149  *   This routine is independent of HW/LL API.
17150  *
17151  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17152  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17153  *  \param  task:             SAM-3 task management request.
17154  *  \param  lun:              Pointer to LUN.
17155  *  \param  taskTag:          Pointer to the associated task where the TM
17156  *                            command is to be applied.
17157  *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17158  *
17159  *  \return:
17160  *
17161  *  \e tiSuccess:     I/O request successfully initiated.
17162  *  \e tiBusy:        No resources available, try again later.
17163  *  \e tiIONoDevice:  Invalid device handle.
17164  *  \e tiError:       Other errors that prevent the I/O request to be started.
17165  *
17166  *
17167  *****************************************************************************/
17168  /* save task in satIOContext */
17169 osGLOBAL bit32 satTM(
17170                         tiRoot_t          *tiRoot,
17171                         tiDeviceHandle_t  *tiDeviceHandle,
17172                         bit32             task,
17173                         tiLUN_t           *lun,
17174                         tiIORequest_t     *taskTag,
17175                         tiIORequest_t     *currentTaskTag,
17176                         tdIORequestBody_t *tiRequestBody,
17177                         bit32              NotifyOS
17178                         )
17179 {
17180   tdIORequestBody_t           *tdIORequestBody = agNULL;
17181   satIOContext_t              *satIOContext = agNULL;
17182   tdsaDeviceData_t            *oneDeviceData = agNULL;
17183   bit32                       status;
17184 
17185   TI_DBG3(("satTM: tiDeviceHandle=%p task=0x%x\n", tiDeviceHandle, task ));
17186 
17187   /* set satIOContext fields and etc */
17188   oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17189 
17190 
17191   tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
17192   satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17193 
17194   satIOContext->pSatDevData   = &oneDeviceData->satDevData;
17195   satIOContext->pFis          =
17196     &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
17197 
17198 
17199   satIOContext->tiRequestBody = tiRequestBody;
17200   satIOContext->ptiDeviceHandle = tiDeviceHandle;
17201   satIOContext->satIntIoContext  = agNULL;
17202   satIOContext->satOrgIOContext  = agNULL;
17203 
17204   /* followings are used only for internal IO */
17205   satIOContext->currentLBA = 0;
17206   satIOContext->OrgTL = 0;
17207 
17208   /* saving task in satIOContext */
17209   satIOContext->TMF = task;
17210 
17211   satIOContext->satToBeAbortedIOContext = agNULL;
17212 
17213   if (NotifyOS == agTRUE)
17214   {
17215     satIOContext->NotifyOS = agTRUE;
17216   }
17217   else
17218   {
17219     satIOContext->NotifyOS = agFALSE;
17220   }
17221   /*
17222    * Our SAT supports RESET LUN and partially support ABORT TASK (only if there
17223    * is no more than one I/O pending on the drive.
17224    */
17225 
17226   if (task == AG_LOGICAL_UNIT_RESET)
17227   {
17228     status = satTmResetLUN( tiRoot,
17229                             currentTaskTag,
17230                             tiDeviceHandle,
17231                             agNULL,
17232                             satIOContext,
17233                             lun);
17234     return status;
17235   }
17236 #ifdef TO_BE_REMOVED
17237   else if (task == AG_TARGET_WARM_RESET)
17238   {
17239     status = satTmWarmReset( tiRoot,
17240                              currentTaskTag,
17241                              tiDeviceHandle,
17242                              agNULL,
17243                              satIOContext);
17244 
17245     return status;
17246   }
17247 #endif
17248   else if (task == AG_ABORT_TASK)
17249   {
17250     status = satTmAbortTask( tiRoot,
17251                              currentTaskTag,
17252                              tiDeviceHandle,
17253                              agNULL,
17254                              satIOContext,
17255                              taskTag);
17256 
17257     return status;
17258   }
17259   else if (task == TD_INTERNAL_TM_RESET)
17260   {
17261     status = satTDInternalTmReset( tiRoot,
17262                                    currentTaskTag,
17263                                    tiDeviceHandle,
17264                                    agNULL,
17265                                    satIOContext);
17266    return status;
17267   }
17268   else
17269   {
17270     TI_DBG1(("satTM: tiDeviceHandle=%p UNSUPPORTED TM task=0x%x\n",
17271         tiDeviceHandle, task ));
17272 
17273     /* clean up TD layer's IORequestBody */
17274     ostiFreeMemory(
17275                    tiRoot,
17276                    tiRequestBody->IOType.InitiatorTMIO.osMemHandle,
17277                    sizeof(tdIORequestBody_t)
17278                    );
17279     return tiError;
17280   }
17281 
17282 }
17283 
17284 
17285 /*****************************************************************************
17286  *! \brief  satTmResetLUN
17287  *
17288  *   This routine is called to initiate a TM RESET LUN request to SATL.
17289  *   This routine is independent of HW/LL API.
17290  *
17291  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17292  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17293  *  \param  lun:              Pointer to LUN.
17294  *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17295  *
17296  *  \return:
17297  *
17298  *  \e tiSuccess:     I/O request successfully initiated.
17299  *  \e tiBusy:        No resources available, try again later.
17300  *  \e tiIONoDevice:  Invalid device handle.
17301  *  \e tiError:       Other errors that prevent the I/O request to be started.
17302  *
17303  *
17304  *****************************************************************************/
17305 osGLOBAL bit32 satTmResetLUN(
17306                             tiRoot_t                  *tiRoot,
17307                             tiIORequest_t             *tiIORequest, /* current task tag */
17308                             tiDeviceHandle_t          *tiDeviceHandle,
17309                             tiScsiInitiatorRequest_t *tiScsiRequest,
17310                             satIOContext_t            *satIOContext,
17311                             tiLUN_t                   *lun)
17312 {
17313 
17314   tdsaDeviceData_t        *tdsaDeviceData;
17315   satDeviceData_t         *satDevData;
17316 
17317   tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17318   satDevData      = &tdsaDeviceData->satDevData;
17319 
17320   TI_DBG1(("satTmResetLUN: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17321 
17322   /*
17323    * Only support LUN 0
17324    */
17325   if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
17326         lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
17327   {
17328     TI_DBG1(("satTmResetLUN: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n",
17329                 tiDeviceHandle));
17330     return tiError;
17331   }
17332 
17333   /*
17334    * Check if there is other TM request pending
17335    */
17336   if (satDevData->satTmTaskTag != agNULL)
17337   {
17338     TI_DBG1(("satTmResetLUN: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17339                 tiDeviceHandle));
17340     return tiError;
17341   }
17342 
17343   /*
17344    * Save tiIORequest, will be returned at device reset completion to return
17345    * the TM completion.
17346    */
17347    satDevData->satTmTaskTag = tiIORequest;
17348 
17349   /*
17350    * Set flag to indicate device in recovery mode.
17351    */
17352   satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17353 
17354   /*
17355    * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17356    * at the completion of SATA device reset.
17357    */
17358   satDevData->satAbortAfterReset = agFALSE;
17359 
17360   /* SAT rev8 6.3.6 p22 */
17361   satStartResetDevice(
17362                       tiRoot,
17363                       tiIORequest, /* currentTaskTag */
17364                       tiDeviceHandle,
17365                       tiScsiRequest,
17366                       satIOContext
17367                       );
17368 
17369 
17370   return tiSuccess;
17371 
17372 }
17373 
17374 /*****************************************************************************
17375  *! \brief  satTmWarmReset
17376  *
17377  *   This routine is called to initiate a TM warm RESET request to SATL.
17378  *   This routine is independent of HW/LL API.
17379  *
17380  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17381  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17382  *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17383  *
17384  *  \return:
17385  *
17386  *  \e tiSuccess:     I/O request successfully initiated.
17387  *  \e tiBusy:        No resources available, try again later.
17388  *  \e tiIONoDevice:  Invalid device handle.
17389  *  \e tiError:       Other errors that prevent the I/O request to be started.
17390  *
17391  *
17392  *****************************************************************************/
17393 osGLOBAL bit32 satTmWarmReset(
17394                             tiRoot_t                  *tiRoot,
17395                             tiIORequest_t             *tiIORequest, /* current task tag */
17396                             tiDeviceHandle_t          *tiDeviceHandle,
17397                             tiScsiInitiatorRequest_t *tiScsiRequest,
17398                             satIOContext_t            *satIOContext)
17399 {
17400 
17401   tdsaDeviceData_t        *tdsaDeviceData;
17402   satDeviceData_t         *satDevData;
17403 
17404   tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17405   satDevData      = &tdsaDeviceData->satDevData;
17406 
17407   TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17408 
17409   /*
17410    * Check if there is other TM request pending
17411    */
17412   if (satDevData->satTmTaskTag != agNULL)
17413   {
17414     TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17415                 tiDeviceHandle));
17416     return tiError;
17417   }
17418 
17419   /*
17420    * Save tiIORequest, will be returned at device reset completion to return
17421    * the TM completion.
17422    */
17423    satDevData->satTmTaskTag = tiIORequest;
17424 
17425   /*
17426    * Set flag to indicate device in recovery mode.
17427    */
17428   satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17429 
17430   /*
17431    * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17432    * at the completion of SATA device reset.
17433    */
17434   satDevData->satAbortAfterReset = agFALSE;
17435 
17436   /* SAT rev8 6.3.6 p22 */
17437   satStartResetDevice(
17438                       tiRoot,
17439                       tiIORequest, /* currentTaskTag */
17440                       tiDeviceHandle,
17441                       tiScsiRequest,
17442                       satIOContext
17443                       );
17444 
17445   return tiSuccess;
17446 
17447 }
17448 
17449 osGLOBAL bit32 satTDInternalTmReset(
17450                             tiRoot_t                  *tiRoot,
17451                             tiIORequest_t             *tiIORequest, /* current task tag */
17452                             tiDeviceHandle_t          *tiDeviceHandle,
17453                             tiScsiInitiatorRequest_t *tiScsiRequest,
17454                             satIOContext_t            *satIOContext)
17455 {
17456 
17457   tdsaDeviceData_t        *tdsaDeviceData;
17458   satDeviceData_t         *satDevData;
17459 
17460   tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17461   satDevData      = &tdsaDeviceData->satDevData;
17462 
17463   TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17464 
17465   /*
17466    * Check if there is other TM request pending
17467    */
17468   if (satDevData->satTmTaskTag != agNULL)
17469   {
17470     TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17471                 tiDeviceHandle));
17472     return tiError;
17473   }
17474 
17475   /*
17476    * Save tiIORequest, will be returned at device reset completion to return
17477    * the TM completion.
17478    */
17479    satDevData->satTmTaskTag = tiIORequest;
17480 
17481   /*
17482    * Set flag to indicate device in recovery mode.
17483    */
17484   satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17485 
17486   /*
17487    * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17488    * at the completion of SATA device reset.
17489    */
17490   satDevData->satAbortAfterReset = agFALSE;
17491 
17492   /* SAT rev8 6.3.6 p22 */
17493   satStartResetDevice(
17494                       tiRoot,
17495                       tiIORequest, /* currentTaskTag */
17496                       tiDeviceHandle,
17497                       tiScsiRequest,
17498                       satIOContext
17499                       );
17500 
17501   return tiSuccess;
17502 
17503 }
17504 
17505 /*****************************************************************************
17506  *! \brief  satTmAbortTask
17507  *
17508  *   This routine is called to initiate a TM ABORT TASK request to SATL.
17509  *   This routine is independent of HW/LL API.
17510  *
17511  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17512  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17513  *  \param  taskTag:          Pointer to the associated task where the TM
17514  *                            command is to be applied.
17515  *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17516  *
17517  *  \return:
17518  *
17519  *  \e tiSuccess:     I/O request successfully initiated.
17520  *  \e tiBusy:        No resources available, try again later.
17521  *  \e tiIONoDevice:  Invalid device handle.
17522  *  \e tiError:       Other errors that prevent the I/O request to be started.
17523  *
17524  *
17525  *****************************************************************************/
17526 osGLOBAL bit32 satTmAbortTask(
17527                             tiRoot_t                  *tiRoot,
17528                             tiIORequest_t             *tiIORequest,  /* current task tag */
17529                             tiDeviceHandle_t          *tiDeviceHandle,
17530                             tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */
17531                             satIOContext_t            *satIOContext,
17532                             tiIORequest_t             *taskTag)
17533 {
17534 
17535   tdsaDeviceData_t        *tdsaDeviceData;
17536   satDeviceData_t         *satDevData;
17537   satIOContext_t          *satTempIOContext = agNULL;
17538   tdIORequestBody_t       *tdIORequestBody;
17539   tdIORequestBody_t       *TMtdIORequestBody;
17540   tdList_t                *elementHdr;
17541   bit32                   found = agFALSE;
17542   tiIORequest_t           *tiIOReq;
17543 
17544   tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17545   satDevData      = &tdsaDeviceData->satDevData;
17546   TMtdIORequestBody = (tdIORequestBody_t *)tiIORequest->tdData;
17547 
17548   TI_DBG1(("satTmAbortTask: tiDeviceHandle=%p taskTag=%p.\n", tiDeviceHandle, taskTag ));
17549   /*
17550    * Check if there is other TM request pending
17551    */
17552   if (satDevData->satTmTaskTag != agNULL)
17553   {
17554     TI_DBG1(("satTmAbortTask: REJECT other TM pending, tiDeviceHandle=%p\n",
17555                 tiDeviceHandle));
17556     /* clean up TD layer's IORequestBody */
17557     ostiFreeMemory(
17558                    tiRoot,
17559                    TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17560                    sizeof(tdIORequestBody_t)
17561                    );
17562     return tiError;
17563   }
17564 
17565 #ifdef REMOVED
17566   /*
17567    * Check if there is only one I/O pending.
17568    */
17569   if (satDevData->satPendingIO > 0)
17570   {
17571     TI_DBG1(("satTmAbortTask: REJECT num pending I/O, tiDeviceHandle=%p, satPendingIO=0x%x\n",
17572                 tiDeviceHandle, satDevData->satPendingIO));
17573     /* clean up TD layer's IORequestBody */
17574     ostiFreeMemory(
17575                    tiRoot,
17576                    TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17577                    sizeof(tdIORequestBody_t)
17578                    );
17579 
17580     return tiError;
17581   }
17582 #endif
17583 
17584   /*
17585    * Check that the only pending I/O matches taskTag. If not return tiError.
17586    */
17587   elementHdr = satDevData->satIoLinkList.flink;
17588 
17589   while (elementHdr != &satDevData->satIoLinkList)
17590   {
17591     satTempIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17592                                            satIoContextLink,
17593                                            elementHdr );
17594 
17595     tdIORequestBody = (tdIORequestBody_t *) satTempIOContext->tiRequestBody;
17596     tiIOReq = tdIORequestBody->tiIORequest;
17597 
17598     elementHdr = elementHdr->flink;   /* for the next while loop  */
17599 
17600     /*
17601      * Check if the tag matches
17602      */
17603     if ( tiIOReq == taskTag)
17604     {
17605       found = agTRUE;
17606       satIOContext->satToBeAbortedIOContext = satTempIOContext;
17607       TI_DBG1(("satTmAbortTask: found matching tag.\n"));
17608 
17609       break;
17610 
17611     } /* if matching tag */
17612 
17613   } /* while loop */
17614 
17615 
17616   if (found == agFALSE )
17617   {
17618     TI_DBG1(("satTmAbortTask: *** REJECT *** no match, tiDeviceHandle=%p\n",
17619                 tiDeviceHandle ));
17620 
17621     /* clean up TD layer's IORequestBody */
17622     ostiFreeMemory(
17623                    tiRoot,
17624                    TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17625                    sizeof(tdIORequestBody_t)
17626                    );
17627 
17628     return tiError;
17629   }
17630 
17631   /*
17632    * Save tiIORequest, will be returned at device reset completion to return
17633    * the TM completion.
17634    */
17635    satDevData->satTmTaskTag = tiIORequest;
17636 
17637   /*
17638    * Set flag to indicate device in recovery mode.
17639    */
17640   satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17641 
17642 
17643   /*
17644    * Issue SATA device reset or check power mode. Set flag to to automatically abort
17645    * at the completion of SATA device reset.
17646    * SAT r09 p25
17647    */
17648   satDevData->satAbortAfterReset = agTRUE;
17649 
17650   if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
17651        (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
17652       )
17653   {
17654     TI_DBG1(("satTmAbortTask: calling satStartCheckPowerMode\n"));
17655     /* send check power mode */
17656     satStartCheckPowerMode(
17657                       tiRoot,
17658                       tiIORequest, /* currentTaskTag */
17659                       tiDeviceHandle,
17660                       tiScsiRequest,
17661                       satIOContext
17662                       );
17663   }
17664   else
17665   {
17666     TI_DBG1(("satTmAbortTask: calling satStartResetDevice\n"));
17667     /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */
17668     satStartResetDevice(
17669                       tiRoot,
17670                       tiIORequest, /* currentTaskTag */
17671                       tiDeviceHandle,
17672                       tiScsiRequest,
17673                       satIOContext
17674                       );
17675   }
17676 
17677 
17678   return tiSuccess;
17679 }
17680 
17681 /*****************************************************************************
17682  *! \brief  osSatResetCB
17683  *
17684  *   This routine is called to notify the completion of SATA device reset
17685  *   which was initiated previously through the call to sataLLReset().
17686  *   This routine is independent of HW/LL API.
17687  *
17688  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17689  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17690  *  \param  resetStatus:      Reset status either tiSuccess or tiError.
17691  *  \param  respFis:          Pointer to the Register Device-To-Host FIS
17692  *                            received from the device.
17693  *
17694  *  \return: None
17695  *
17696  *****************************************************************************/
17697 osGLOBAL void osSatResetCB(
17698                 tiRoot_t          *tiRoot,
17699                 tiDeviceHandle_t  *tiDeviceHandle,
17700                 bit32             resetStatus,
17701                 void              *respFis)
17702 {
17703 
17704   agsaRoot_t              *agRoot;
17705   tdsaDeviceData_t        *tdsaDeviceData;
17706   satDeviceData_t         *satDevData;
17707   satIOContext_t          *satIOContext;
17708   tdIORequestBody_t       *tdIORequestBodyTmp;
17709   tdList_t                *elementHdr;
17710   agsaIORequest_t         *agAbortIORequest;
17711   tdIORequestBody_t       *tdAbortIORequestBody;
17712   bit32                   PhysUpper32;
17713   bit32                   PhysLower32;
17714   bit32                   memAllocStatus;
17715   void                    *osMemHandle;
17716 
17717   tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17718   agRoot          = tdsaDeviceData->agRoot;
17719   satDevData      = &tdsaDeviceData->satDevData;
17720 
17721   TI_DBG5(("osSatResetCB: tiDeviceHandle=%p resetStatus=0x%x\n",
17722       tiDeviceHandle, resetStatus ));
17723 
17724   /* We may need to check FIS to check device operating condition */
17725 
17726 
17727   /*
17728    * Check if need to abort all pending I/Os
17729    */
17730   if ( satDevData->satAbortAfterReset == agTRUE )
17731   {
17732     /*
17733      * Issue abort to LL layer to all other pending I/Os for the same SATA drive
17734      */
17735     elementHdr = satDevData->satIoLinkList.flink;
17736     while (elementHdr != &satDevData->satIoLinkList)
17737     {
17738       satIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17739                                          satIoContextLink,
17740                                          elementHdr );
17741 
17742       tdIORequestBodyTmp = (tdIORequestBody_t *)satIOContext->tiRequestBody;
17743 
17744       /*
17745        * Issue abort
17746        */
17747       TI_DBG5(("osSatResetCB: issuing ABORT tiDeviceHandle=%p agIORequest=%p\n",
17748       tiDeviceHandle, &tdIORequestBodyTmp->agIORequest ));
17749 
17750       /* allocating agIORequest for abort itself */
17751       memAllocStatus = ostiAllocMemory(
17752                                        tiRoot,
17753                                        &osMemHandle,
17754                                        (void **)&tdAbortIORequestBody,
17755                                        &PhysUpper32,
17756                                        &PhysLower32,
17757                                        8,
17758                                        sizeof(tdIORequestBody_t),
17759                                        agTRUE
17760                                        );
17761 
17762       if (memAllocStatus != tiSuccess)
17763       {
17764         /* let os process IO */
17765         TI_DBG1(("osSatResetCB: ostiAllocMemory failed...\n"));
17766         return;
17767       }
17768 
17769       if (tdAbortIORequestBody == agNULL)
17770       {
17771         /* let os process IO */
17772         TI_DBG1(("osSatResetCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17773         return;
17774       }
17775       /* setup task management structure */
17776       tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17777       tdAbortIORequestBody->tiDevHandle = tiDeviceHandle;
17778 
17779       /* initialize agIORequest */
17780       agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17781       agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17782       agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17783 
17784       saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, &(tdIORequestBodyTmp->agIORequest), agNULL );
17785       elementHdr = elementHdr->flink;   /* for the next while loop  */
17786 
17787     } /* while */
17788 
17789     /* Reset flag */
17790     satDevData->satAbortAfterReset = agFALSE;
17791 
17792   }
17793 
17794 
17795   /*
17796    * Check if the device reset if the result of TM request.
17797    */
17798   if ( satDevData->satTmTaskTag != agNULL )
17799   {
17800     TI_DBG5(("osSatResetCB: calling TM completion tiDeviceHandle=%p satTmTaskTag=%p\n",
17801     tiDeviceHandle, satDevData->satTmTaskTag ));
17802 
17803     ostiInitiatorEvent( tiRoot,
17804                         agNULL,               /* portalContext not used */
17805                         tiDeviceHandle,
17806                         tiIntrEventTypeTaskManagement,
17807                         tiTMOK,
17808                         satDevData->satTmTaskTag);
17809     /*
17810      * Reset flag
17811      */
17812     satDevData->satTmTaskTag = agNULL;
17813   }
17814 
17815 }
17816 
17817 
17818 /*****************************************************************************
17819  *! \brief  osSatIOCompleted
17820  *
17821  *   This routine is a callback for SATA completion that required FIS status
17822  *   translation to SCSI status.
17823  *
17824  *  \param   tiRoot:          Pointer to TISA initiator driver/port instance.
17825  *  \param   tiIORequest:     Pointer to TISA I/O request context for this I/O.
17826  *  \param   respFis:         Pointer to status FIS to read.
17827  *  \param   respFisLen:      Length of response FIS to read.
17828  *  \param   satIOContext:    Pointer to SAT context.
17829  *  \param   interruptContext:      Interrupt context
17830  *
17831  *  \return: None
17832  *
17833  *****************************************************************************/
17834 osGLOBAL void osSatIOCompleted(
17835                           tiRoot_t           *tiRoot,
17836                           tiIORequest_t      *tiIORequest,
17837                           agsaFisHeader_t    *agFirstDword,
17838                           bit32              respFisLen,
17839                           agsaFrameHandle_t  agFrameHandle,
17840                           satIOContext_t     *satIOContext,
17841                           bit32              interruptContext)
17842 
17843 {
17844   satDeviceData_t           *pSatDevData;
17845   scsiRspSense_t            *pSense;
17846 #ifdef  TD_DEBUG_ENABLE
17847   tiIniScsiCmnd_t           *pScsiCmnd;
17848 #endif
17849   agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
17850   bit32                     ataStatus = 0;
17851   bit32                     ataError;
17852   satInternalIo_t           *satIntIo = agNULL;
17853   bit32                     status;
17854   tiDeviceHandle_t          *tiDeviceHandle;
17855   satIOContext_t            *satIOContext2;
17856   tdIORequestBody_t         *tdIORequestBody;
17857   agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
17858   agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL;
17859   tiIORequest_t             tiIORequestTMP;
17860 
17861   pSense          = satIOContext->pSense;
17862   pSatDevData     = satIOContext->pSatDevData;
17863 #ifdef  TD_DEBUG_ENABLE
17864   pScsiCmnd       = satIOContext->pScsiCmnd;
17865 #endif
17866   hostToDevFis    = satIOContext->pFis;
17867 
17868   tiDeviceHandle  = &((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->tiDeviceHandle;
17869   /*
17870    * Find out the type of response FIS:
17871    * Set Device Bit FIS or Reg Device To Host FIS.
17872    */
17873 
17874   /* First assume it is Reg Device to Host FIS */
17875   statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
17876   ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
17877   ataError      = statDevToHostFisHeader->error;    /* ATA Eror register   */
17878 
17879   /* for debugging */
17880   TI_DBG1(("osSatIOCompleted: H to D command 0x%x\n", hostToDevFis->h.command));
17881   TI_DBG1(("osSatIOCompleted: D to H fistype 0x%x\n", statDevToHostFisHeader->fisType));
17882 
17883 
17884   if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS)
17885   {
17886     /* It is Set Device Bits FIS */
17887     statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H);
17888     /* Get ATA Status register */
17889     ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70);               /* bits 4,5,6 */
17890     ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07);   /* bits 0,1,2 */
17891 
17892     /* ATA Eror register   */
17893     ataError  = statSetDevBitFisHeader->error;
17894 
17895     statDevToHostFisHeader = agNULL;
17896   }
17897 
17898   else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
17899   {
17900     TI_DBG1(("osSatIOCompleted: *** UNEXPECTED RESP FIS TYPE 0x%x *** tiIORequest=%p\n",
17901                  statDevToHostFisHeader->fisType, tiIORequest));
17902 
17903     satSetSensePayload( pSense,
17904                         SCSI_SNSKEY_HARDWARE_ERROR,
17905                         0,
17906                         SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
17907                         satIOContext);
17908 
17909     ostiInitiatorIOCompleted( tiRoot,
17910                               tiIORequest,
17911                               tiIOSuccess,
17912                               SCSI_STAT_CHECK_CONDITION,
17913                               satIOContext->pTiSenseData,
17914                               interruptContext );
17915     return;
17916 
17917   }
17918 
17919   if ( ataStatus & DF_ATA_STATUS_MASK )
17920   {
17921     pSatDevData->satDeviceFaultState = agTRUE;
17922   }
17923   else
17924   {
17925     pSatDevData->satDeviceFaultState = agFALSE;
17926   }
17927 
17928   TI_DBG5(("osSatIOCompleted: tiIORequest=%p  CDB=0x%x ATA CMD =0x%x\n",
17929     tiIORequest, pScsiCmnd->cdb[0], hostToDevFis->h.command));
17930 
17931   /*
17932    * Decide which ATA command is the translation needed
17933    */
17934   switch(hostToDevFis->h.command)
17935   {
17936     case SAT_READ_FPDMA_QUEUED:
17937     case SAT_WRITE_FPDMA_QUEUED:
17938 
17939       /************************************************************************
17940        *
17941        * !!!! See Section 13.5.2.4 of SATA 2.5 specs.                      !!!!
17942        * !!!! If the NCQ error ends up here, it means that the device sent !!!!
17943        * !!!! Set Device Bit FIS (which has SActive register) instead of   !!!!
17944        * !!!! Register Device To Host FIS (which does not have SActive     !!!!
17945        * !!!! register). The callback ossaSATAEvent() deals with the case  !!!!
17946        * !!!! where Register Device To Host FIS was sent by the device.    !!!!
17947        *
17948        * For NCQ we need to issue READ LOG EXT command with log page 10h
17949        * to get the error and to allow other I/Os to continue.
17950        *
17951        * Here is the basic flow or sequence of error recovery, note that due
17952        * to the SATA HW assist that we have, this sequence is slighly different
17953        * from the one described in SATA 2.5:
17954        *
17955        * 1. Set SATA device flag to indicate error condition and returning busy
17956        *    for all new request.
17957        *   return tiSuccess;
17958 
17959        * 2. Because the HW/LL layer received Set Device Bit FIS, it can get the
17960        *    tag or I/O context for NCQ request, SATL would translate the ATA error
17961        *    to SCSI status and return the original NCQ I/O with the appopriate
17962        *    SCSI status.
17963        *
17964        * 3. Prepare READ LOG EXT page 10h command. Set flag to indicate that
17965        *    the failed I/O has been returned to the OS Layer. Send command.
17966        *
17967        * 4. When the device receives READ LOG EXT page 10h request all other
17968        *    pending I/O are implicitly aborted. No completion (aborted) status
17969        *    will be sent to the host for these aborted commands.
17970        *
17971        * 5. SATL receives the completion for READ LOG EXT command in
17972        *    satReadLogExtCB(). Steps 6,7,8,9 below are the step 1,2,3,4 in
17973        *    satReadLogExtCB().
17974        *
17975        * 6. Check flag that indicates whether the failed I/O has been returned
17976        *    to the OS Layer. If not, search the I/O context in device data
17977        *    looking for a matched tag. Then return the completion of the failed
17978        *    NCQ command with the appopriate/trasnlated SCSI status.
17979        *
17980        * 7. Issue abort to LL layer to all other pending I/Os for the same SATA
17981        *    drive.
17982        *
17983        * 8. Free resource allocated for the internally generated READ LOG EXT.
17984        *
17985        * 9. At the completion of abort, in the context of ossaSATACompleted(),
17986        *    return the I/O with error status to the OS-App Specific layer.
17987        *    When all I/O aborts are completed, clear SATA device flag to
17988        *    indicate ready to process new request.
17989        *
17990        ***********************************************************************/
17991 
17992       TI_DBG1(("osSatIOCompleted: NCQ ERROR tiIORequest=%p ataStatus=0x%x ataError=0x%x\n",
17993           tiIORequest, ataStatus, ataError ));
17994 
17995       /* Set flag to indicate we are in recovery */
17996       pSatDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17997 
17998       /* Return the failed NCQ I/O to OS-Apps Specifiic layer */
17999       osSatDefaultTranslation( tiRoot,
18000                                tiIORequest,
18001                                satIOContext,
18002                                pSense,
18003                                (bit8)ataStatus,
18004                                (bit8)ataError,
18005                                interruptContext );
18006 
18007       /*
18008        * Allocate resource for READ LOG EXT page 10h
18009        */
18010       satIntIo = satAllocIntIoResource( tiRoot,
18011                                         &(tiIORequestTMP), /* anything but NULL */
18012                                         pSatDevData,
18013                                         sizeof (satReadLogExtPage10h_t),
18014                                         satIntIo);
18015 
18016       if (satIntIo == agNULL)
18017       {
18018         TI_DBG1(("osSatIOCompleted: can't send RLE due to resource lack\n"));
18019 
18020         /* Abort I/O after completion of device reset */
18021         pSatDevData->satAbortAfterReset = agTRUE;
18022 #ifdef NOT_YET
18023         /* needs further investigation */
18024         /* no report to OS layer */
18025         satSubTM(tiRoot,
18026                  tiDeviceHandle,
18027                  TD_INTERNAL_TM_RESET,
18028                  agNULL,
18029                  agNULL,
18030                  agNULL,
18031                  agFALSE);
18032 #endif
18033 
18034 
18035         TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 1\n"));
18036         return;
18037       }
18038 
18039 
18040       /*
18041        * Set flag to indicate that the failed I/O has been returned to the
18042        * OS-App specific Layer.
18043        */
18044       satIntIo->satIntFlag = AG_SAT_INT_IO_FLAG_ORG_IO_COMPLETED;
18045 
18046       /* compare to satPrepareNewIO() */
18047       /* Send READ LOG EXIT page 10h command */
18048 
18049       /*
18050        * Need to initialize all the fields within satIOContext except
18051        * reqType and satCompleteCB which will be set depending on cmd.
18052        */
18053 
18054       tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
18055       satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
18056 
18057       satIOContext2->pSatDevData   = pSatDevData;
18058       satIOContext2->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
18059       satIOContext2->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
18060       satIOContext2->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
18061       satIOContext2->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
18062       satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
18063 
18064       satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
18065       satIOContext2->interruptContext = interruptContext;
18066       satIOContext2->satIntIoContext  = satIntIo;
18067 
18068       satIOContext2->ptiDeviceHandle = tiDeviceHandle;
18069       satIOContext2->satOrgIOContext = agNULL;
18070       satIOContext2->tiScsiXchg = agNULL;
18071 
18072       status = satSendReadLogExt( tiRoot,
18073                                   &satIntIo->satIntTiIORequest,
18074                                   tiDeviceHandle,
18075                                   &satIntIo->satIntTiScsiXchg,
18076                                   satIOContext2);
18077 
18078       if (status != tiSuccess)
18079       {
18080         TI_DBG1(("osSatIOCompleted: can't send RLE due to LL api failure\n"));
18081         satFreeIntIoResource( tiRoot,
18082                               pSatDevData,
18083                               satIntIo);
18084 
18085         /* Abort I/O after completion of device reset */
18086         pSatDevData->satAbortAfterReset = agTRUE;
18087 #ifdef NOT_YET
18088         /* needs further investigation */
18089         /* no report to OS layer */
18090         satSubTM(tiRoot,
18091                  tiDeviceHandle,
18092                  TD_INTERNAL_TM_RESET,
18093                  agNULL,
18094                  agNULL,
18095                  agNULL,
18096                  agFALSE);
18097 #endif
18098 
18099         TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 2\n"));
18100         return;
18101       }
18102 
18103       break;
18104 
18105     case SAT_READ_DMA_EXT:
18106       /* fall through */
18107       /* Use default status/error translation */
18108 
18109     case SAT_READ_DMA:
18110       /* fall through */
18111       /* Use default status/error translation */
18112 
18113     default:
18114       osSatDefaultTranslation( tiRoot,
18115                                tiIORequest,
18116                                satIOContext,
18117                                pSense,
18118                                (bit8)ataStatus,
18119                                (bit8)ataError,
18120                                interruptContext );
18121       break;
18122 
18123   }  /* end switch  */
18124 }
18125 
18126 
18127 /*****************************************************************************/
18128 /*! \brief SAT implementation for SCSI STANDARD INQUIRY.
18129  *
18130  *  SAT implementation for SCSI STANDARD INQUIRY.
18131  *
18132  *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18133  *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18134  *
18135  *  \return None.
18136  */
18137 /*****************************************************************************/
18138 GLOBAL void  satInquiryStandard(
18139                                 bit8                    *pInquiry,
18140                                 agsaSATAIdentifyData_t  *pSATAIdData,
18141                                 tiIniScsiCmnd_t          *scsiCmnd
18142                                 )
18143 {
18144   tiLUN_t       *pLun;
18145   pLun          = &scsiCmnd->lun;
18146 
18147   /*
18148     Assumption: Basic Task Mangement is supported
18149     -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147
18150   */
18151  /*
18152     See SPC-4, 6.4.2, p 143
18153     and SAT revision 8, 8.1.2, p 28
18154    */
18155 
18156   TI_DBG5(("satInquiryStandard: start\n"));
18157 
18158   if (pInquiry == agNULL)
18159   {
18160     TI_DBG1(("satInquiryStandard: pInquiry is NULL, wrong\n"));
18161     return;
18162   }
18163   else
18164   {
18165     TI_DBG5(("satInquiryStandard: pInquiry is NOT NULL\n"));
18166   }
18167   /*
18168    * Reject all other LUN other than LUN 0.
18169    */
18170   if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
18171          pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) )
18172   {
18173     /* SAT Spec Table 8, p27, footnote 'a' */
18174     pInquiry[0] = 0x7F;
18175 
18176   }
18177   else
18178   {
18179     pInquiry[0] = 0x00;
18180   }
18181 
18182   if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
18183   {
18184     pInquiry[1] = 0x80;
18185   }
18186   else
18187   {
18188     pInquiry[1] = 0x00;
18189   }
18190   pInquiry[2] = 0x05;   /* SPC-3 */
18191   pInquiry[3] = 0x12;   /* set HiSup 1; resp data format set to 2 */
18192   pInquiry[4] = 0x1F;   /* 35 - 4 = 31; Additional length */
18193   pInquiry[5] = 0x00;
18194   /* The following two are for task management. SAT Rev8, p20 */
18195   if (pSATAIdData->sataCapabilities & 0x100)
18196   {
18197     /* NCQ supported; multiple outstanding SCSI IO are supported */
18198     pInquiry[6] = 0x00;   /* BQUE bit is not set */
18199     pInquiry[7] = 0x02;   /* CMDQUE bit is set */
18200   }
18201   else
18202   {
18203     pInquiry[6] = 0x80;   /* BQUE bit is set */
18204     pInquiry[7] = 0x00;   /* CMDQUE bit is not set */
18205   }
18206   /*
18207    * Vendor ID.
18208    */
18209   osti_strncpy((char*)&pInquiry[8],  AG_SAT_VENDOR_ID_STRING,8);   /* 8 bytes   */
18210 
18211   /*
18212    * Product ID
18213    */
18214   /* when flipped by LL */
18215   pInquiry[16] = pSATAIdData->modelNumber[1];
18216   pInquiry[17] = pSATAIdData->modelNumber[0];
18217   pInquiry[18] = pSATAIdData->modelNumber[3];
18218   pInquiry[19] = pSATAIdData->modelNumber[2];
18219   pInquiry[20] = pSATAIdData->modelNumber[5];
18220   pInquiry[21] = pSATAIdData->modelNumber[4];
18221   pInquiry[22] = pSATAIdData->modelNumber[7];
18222   pInquiry[23] = pSATAIdData->modelNumber[6];
18223   pInquiry[24] = pSATAIdData->modelNumber[9];
18224   pInquiry[25] = pSATAIdData->modelNumber[8];
18225   pInquiry[26] = pSATAIdData->modelNumber[11];
18226   pInquiry[27] = pSATAIdData->modelNumber[10];
18227   pInquiry[28] = pSATAIdData->modelNumber[13];
18228   pInquiry[29] = pSATAIdData->modelNumber[12];
18229   pInquiry[30] = pSATAIdData->modelNumber[15];
18230   pInquiry[31] = pSATAIdData->modelNumber[14];
18231 
18232   /* when flipped */
18233   /*
18234    * Product Revision level.
18235    */
18236 
18237   /*
18238    * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18239    * device are ASCII spaces (20h), do this translation.
18240    */
18241   if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18242        (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18243        (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18244        (pSATAIdData->firmwareVersion[7] == 0x00 )
18245        )
18246   {
18247     pInquiry[32] = pSATAIdData->firmwareVersion[1];
18248     pInquiry[33] = pSATAIdData->firmwareVersion[0];
18249     pInquiry[34] = pSATAIdData->firmwareVersion[3];
18250     pInquiry[35] = pSATAIdData->firmwareVersion[2];
18251   }
18252   else
18253   {
18254     pInquiry[32] = pSATAIdData->firmwareVersion[5];
18255     pInquiry[33] = pSATAIdData->firmwareVersion[4];
18256     pInquiry[34] = pSATAIdData->firmwareVersion[7];
18257     pInquiry[35] = pSATAIdData->firmwareVersion[6];
18258   }
18259 
18260 
18261 #ifdef REMOVED
18262   /*
18263    * Product ID
18264    */
18265   /* when flipped by LL */
18266   pInquiry[16] = pSATAIdData->modelNumber[0];
18267   pInquiry[17] = pSATAIdData->modelNumber[1];
18268   pInquiry[18] = pSATAIdData->modelNumber[2];
18269   pInquiry[19] = pSATAIdData->modelNumber[3];
18270   pInquiry[20] = pSATAIdData->modelNumber[4];
18271   pInquiry[21] = pSATAIdData->modelNumber[5];
18272   pInquiry[22] = pSATAIdData->modelNumber[6];
18273   pInquiry[23] = pSATAIdData->modelNumber[7];
18274   pInquiry[24] = pSATAIdData->modelNumber[8];
18275   pInquiry[25] = pSATAIdData->modelNumber[9];
18276   pInquiry[26] = pSATAIdData->modelNumber[10];
18277   pInquiry[27] = pSATAIdData->modelNumber[11];
18278   pInquiry[28] = pSATAIdData->modelNumber[12];
18279   pInquiry[29] = pSATAIdData->modelNumber[13];
18280   pInquiry[30] = pSATAIdData->modelNumber[14];
18281   pInquiry[31] = pSATAIdData->modelNumber[15];
18282 
18283   /* when flipped */
18284   /*
18285    * Product Revision level.
18286    */
18287 
18288   /*
18289    * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18290    * device are ASCII spaces (20h), do this translation.
18291    */
18292   if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18293        (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18294        (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18295        (pSATAIdData->firmwareVersion[7] == 0x00 )
18296        )
18297   {
18298     pInquiry[32] = pSATAIdData->firmwareVersion[0];
18299     pInquiry[33] = pSATAIdData->firmwareVersion[1];
18300     pInquiry[34] = pSATAIdData->firmwareVersion[2];
18301     pInquiry[35] = pSATAIdData->firmwareVersion[3];
18302   }
18303   else
18304   {
18305     pInquiry[32] = pSATAIdData->firmwareVersion[4];
18306     pInquiry[33] = pSATAIdData->firmwareVersion[5];
18307     pInquiry[34] = pSATAIdData->firmwareVersion[6];
18308     pInquiry[35] = pSATAIdData->firmwareVersion[7];
18309   }
18310 #endif
18311 
18312   TI_DBG5(("satInquiryStandard: end\n"));
18313 
18314 }
18315 
18316 
18317 /*****************************************************************************/
18318 /*! \brief SAT implementation for SCSI INQUIRY page 0.
18319  *
18320  *  SAT implementation for SCSI INQUIRY page 0.
18321  *
18322  *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18323  *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18324  *
18325  *  \return None.
18326  */
18327 /*****************************************************************************/
18328 GLOBAL void  satInquiryPage0(
18329                     bit8                    *pInquiry,
18330                     agsaSATAIdentifyData_t  *pSATAIdData)
18331 {
18332 
18333   TI_DBG5(("satInquiryPage0: entry\n"));
18334 
18335   /*
18336     See SPC-4, 7.6.9, p 345
18337     and SAT revision 8, 10.3.2, p 77
18338    */
18339   pInquiry[0] = 0x00;
18340   pInquiry[1] = 0x00; /* page code */
18341   pInquiry[2] = 0x00; /* reserved */
18342   pInquiry[3] = 7 - 3; /* last index(in this case, 6) - 3; page length */
18343 
18344   /* supported vpd page list */
18345   pInquiry[4] = 0x00; /* page 0x00 supported */
18346   pInquiry[5] = 0x80; /* page 0x80 supported */
18347   pInquiry[6] = 0x83; /* page 0x83 supported */
18348   pInquiry[7] = 0x89; /* page 0x89 supported */
18349 
18350 }
18351 
18352 
18353 /*****************************************************************************/
18354 /*! \brief SAT implementation for SCSI INQUIRY page 83.
18355  *
18356  *  SAT implementation for SCSI INQUIRY page 83.
18357  *
18358  *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18359  *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18360  *
18361  *  \return None.
18362  */
18363 /*****************************************************************************/
18364 GLOBAL void  satInquiryPage83(
18365                     bit8                    *pInquiry,
18366                     agsaSATAIdentifyData_t  *pSATAIdData,
18367                     satDeviceData_t         *pSatDevData)
18368 {
18369 
18370   satSimpleSATAIdentifyData_t   *pSimpleData;
18371 
18372   /*
18373    * When translating the fields, in some cases using the simple form of SATA
18374    * Identify Device Data is easier. So we define it here.
18375    * Both pSimpleData and pSATAIdData points to the same data.
18376    */
18377   pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18378 
18379   TI_DBG5(("satInquiryPage83: entry\n"));
18380 
18381   pInquiry[0] = 0x00;
18382   pInquiry[1] = 0x83; /* page code */
18383   pInquiry[2] = 0;    /* Reserved */
18384 
18385   /*
18386    * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE
18387    * data indicating that it supports the WORLD WIDE NAME field
18388    * (i.e., words 108-111), the SATL shall include an identification descriptor
18389    * containing a logical unit name.
18390    */
18391   if ( pSatDevData->satWWNSupport)
18392   {
18393     /* Fill in SAT Rev8 Table85 */
18394     /*
18395      * Logical unit name derived from the world wide name.
18396      */
18397     pInquiry[3] = 12;         /* 15-3; page length, no addition ID descriptor assumed*/
18398 
18399     /*
18400      * Identifier descriptor
18401      */
18402     pInquiry[4]  = 0x01;                        /* Code set: binary codes */
18403     pInquiry[5]  = 0x03;                        /* Identifier type : NAA  */
18404     pInquiry[6]  = 0x00;                        /* Reserved               */
18405     pInquiry[7]  = 0x08;                        /* Identifier length      */
18406 
18407     /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
18408     pInquiry[8]  = (bit8)((pSATAIdData->namingAuthority) >> 8);
18409     pInquiry[9]  = (bit8)((pSATAIdData->namingAuthority) & 0xFF);           /* IEEE Company ID */
18410     pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8);            /* IEEE Company ID */
18411     /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
18412     pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
18413     pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8);       /* Vendor Specific ID  */
18414     pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF);     /* Vendor Specific ID  */
18415     pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8);        /* Vendor Specific ID  */
18416     pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF);      /* Vendor Specific ID  */
18417 
18418   }
18419   else
18420   {
18421     /* Fill in SAT Rev8 Table86 */
18422     /*
18423      * Logical unit name derived from the model number and serial number.
18424      */
18425     pInquiry[3] = 72;    /* 75 - 3; page length */
18426 
18427     /*
18428      * Identifier descriptor
18429      */
18430     pInquiry[4] = 0x02;             /* Code set: ASCII codes */
18431     pInquiry[5] = 0x01;             /* Identifier type : T10 vendor ID based */
18432     pInquiry[6] = 0x00;             /* Reserved */
18433     pInquiry[7] = 0x44;               /* 0x44, 68 Identifier length */
18434 
18435     /* Byte 8 to 15 is the vendor id string 'ATA     '. */
18436     osti_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
18437 
18438 
18439         /*
18440      * Byte 16 to 75 is vendor specific id
18441      */
18442     pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
18443     pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
18444     pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
18445     pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
18446     pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
18447     pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
18448     pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
18449     pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
18450     pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
18451     pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
18452     pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
18453     pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
18454     pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
18455     pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
18456     pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
18457     pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
18458     pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
18459     pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
18460     pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
18461     pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
18462     pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
18463     pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
18464     pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
18465     pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
18466     pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
18467     pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
18468     pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
18469     pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
18470     pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
18471     pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
18472     pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
18473     pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
18474     pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
18475     pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
18476     pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
18477     pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
18478     pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
18479     pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
18480     pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
18481     pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
18482 
18483     pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
18484     pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
18485     pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
18486     pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
18487     pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
18488     pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
18489     pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
18490     pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
18491     pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
18492     pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
18493     pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
18494     pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
18495     pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
18496     pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
18497     pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
18498     pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
18499     pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
18500     pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
18501     pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
18502     pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
18503   }
18504 
18505 }
18506 
18507 /*****************************************************************************/
18508 /*! \brief SAT implementation for SCSI INQUIRY page 89.
18509  *
18510  *  SAT implementation for SCSI INQUIRY page 89.
18511  *
18512  *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18513  *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18514  *  \param   pSatDevData       Pointer to internal device data structure
18515  *
18516  *  \return None.
18517  */
18518 /*****************************************************************************/
18519 GLOBAL void  satInquiryPage89(
18520                     bit8                    *pInquiry,
18521                     agsaSATAIdentifyData_t  *pSATAIdData,
18522                     satDeviceData_t         *pSatDevData)
18523 {
18524   /*
18525     SAT revision 8, 10.3.5, p 83
18526    */
18527   satSimpleSATAIdentifyData_t   *pSimpleData;
18528 
18529   /*
18530    * When translating the fields, in some cases using the simple form of SATA
18531    * Identify Device Data is easier. So we define it here.
18532    * Both pSimpleData and pSATAIdData points to the same data.
18533    */
18534   pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18535 
18536   TI_DBG5(("satInquiryPage89: start\n"));
18537 
18538   pInquiry[0] = 0x00;   /* Peripheral Qualifier and Peripheral Device Type */
18539   pInquiry[1] = 0x89;   /* page code */
18540 
18541   /* Page length 0x238 */
18542   pInquiry[2] = 0x02;
18543   pInquiry[3] = 0x38;
18544 
18545   pInquiry[4] = 0x0;    /* reserved */
18546   pInquiry[5] = 0x0;    /* reserved */
18547   pInquiry[6] = 0x0;    /* reserved */
18548   pInquiry[7] = 0x0;    /* reserved */
18549 
18550   /* SAT Vendor Identification */
18551   osti_strncpy((char*)&pInquiry[8],  "PMC-SIERRA", 8);   /* 8 bytes   */
18552 
18553   /* SAT Product Idetification */
18554   osti_strncpy((char*)&pInquiry[16],  "Tachyon-SPC    ", 16);   /* 16 bytes   */
18555 
18556   /* SAT Product Revision Level */
18557   osti_strncpy((char*)&pInquiry[32],  "01", 4);   /* 4 bytes   */
18558 
18559   /* Signature, SAT revision8, Table88, p85 */
18560 
18561 
18562   pInquiry[36] = 0x34;    /* FIS type */
18563   if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18564   {
18565     /* interrupt assume to be 0 */
18566     pInquiry[37] = (bit8)((pSatDevData->satPMField) >> (4 * 7)); /* first four bits of PM field */
18567   }
18568   else
18569   {
18570     /* interrupt assume to be 1 */
18571     pInquiry[37] = (bit8)(0x40 + (bit8)(((pSatDevData->satPMField) >> (4 * 7)))); /* first four bits of PM field */
18572   }
18573   pInquiry[38] = 0;
18574   pInquiry[39] = 0;
18575 
18576   if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18577   {
18578     pInquiry[40] = 0x01; /* LBA Low          */
18579     pInquiry[41] = 0x00; /* LBA Mid          */
18580     pInquiry[42] = 0x00; /* LBA High         */
18581     pInquiry[43] = 0x00; /* Device           */
18582     pInquiry[44] = 0x00; /* LBA Low Exp      */
18583     pInquiry[45] = 0x00; /* LBA Mid Exp      */
18584     pInquiry[46] = 0x00; /* LBA High Exp     */
18585     pInquiry[47] = 0x00; /* Reserved         */
18586     pInquiry[48] = 0x01; /* Sector Count     */
18587     pInquiry[49] = 0x00; /* Sector Count Exp */
18588   }
18589   else
18590   {
18591     pInquiry[40] = 0x01; /* LBA Low          */
18592     pInquiry[41] = 0x00; /* LBA Mid          */
18593     pInquiry[42] = 0x00; /* LBA High         */
18594     pInquiry[43] = 0x00; /* Device           */
18595     pInquiry[44] = 0x00; /* LBA Low Exp      */
18596     pInquiry[45] = 0x00; /* LBA Mid Exp      */
18597     pInquiry[46] = 0x00; /* LBA High Exp     */
18598     pInquiry[47] = 0x00; /* Reserved         */
18599     pInquiry[48] = 0x01; /* Sector Count     */
18600     pInquiry[49] = 0x00; /* Sector Count Exp */
18601   }
18602 
18603   /* Reserved */
18604   pInquiry[50] = 0x00;
18605   pInquiry[51] = 0x00;
18606   pInquiry[52] = 0x00;
18607   pInquiry[53] = 0x00;
18608   pInquiry[54] = 0x00;
18609   pInquiry[55] = 0x00;
18610 
18611   /* Command Code */
18612   if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18613   {
18614     pInquiry[56] = 0xEC;    /* IDENTIFY DEVICE */
18615   }
18616   else
18617   {
18618     pInquiry[56] = 0xA1;    /* IDENTIFY PACKET DEVICE */
18619   }
18620   /* Reserved */
18621   pInquiry[57] = 0x0;
18622   pInquiry[58] = 0x0;
18623   pInquiry[59] = 0x0;
18624 
18625   /* Identify Device */
18626   osti_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
18627   return;
18628 }
18629 
18630 /*****************************************************************************/
18631 /*! \brief SAT implementation for SCSI INQUIRY page 0.
18632  *
18633  *  SAT implementation for SCSI INQUIRY page 0.
18634  *
18635  *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18636  *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18637  *
18638  *  \return None.
18639  */
18640 /*****************************************************************************/
18641 GLOBAL void  satInquiryPage80(
18642                     bit8                    *pInquiry,
18643                     agsaSATAIdentifyData_t  *pSATAIdData)
18644 {
18645 
18646   TI_DBG5(("satInquiryPage80: entry\n"));
18647 
18648   /*
18649     See SPC-4, 7.6.9, p 345
18650     and SAT revision 8, 10.3.3, p 77
18651    */
18652   pInquiry[0] = 0x00;
18653   pInquiry[1] = 0x80; /* page code */
18654   pInquiry[2] = 0x00; /* reserved */
18655   pInquiry[3] = 0x14; /* page length */
18656 
18657   /* supported vpd page list */
18658   pInquiry[4] = pSATAIdData->serialNumber[1];
18659   pInquiry[5] = pSATAIdData->serialNumber[0];
18660   pInquiry[6] = pSATAIdData->serialNumber[3];
18661   pInquiry[7] = pSATAIdData->serialNumber[2];
18662   pInquiry[8] = pSATAIdData->serialNumber[5];
18663   pInquiry[9] = pSATAIdData->serialNumber[4];
18664   pInquiry[10] = pSATAIdData->serialNumber[7];
18665   pInquiry[11] = pSATAIdData->serialNumber[6];
18666   pInquiry[12] = pSATAIdData->serialNumber[9];
18667   pInquiry[13] = pSATAIdData->serialNumber[8];
18668   pInquiry[14] = pSATAIdData->serialNumber[11];
18669   pInquiry[15] = pSATAIdData->serialNumber[10];
18670   pInquiry[16] = pSATAIdData->serialNumber[13];
18671   pInquiry[17] = pSATAIdData->serialNumber[12];
18672   pInquiry[18] = pSATAIdData->serialNumber[15];
18673   pInquiry[19] = pSATAIdData->serialNumber[14];
18674   pInquiry[20] = pSATAIdData->serialNumber[17];
18675   pInquiry[21] = pSATAIdData->serialNumber[16];
18676   pInquiry[22] = pSATAIdData->serialNumber[19];
18677   pInquiry[23] = pSATAIdData->serialNumber[18];
18678 
18679 
18680 }
18681 
18682 
18683 
18684 /*****************************************************************************/
18685 /*! \brief  Send READ LOG EXT ATA PAGE 10h command to sata drive.
18686  *
18687  *  Send READ LOG EXT ATA command PAGE 10h request to LL layer.
18688  *
18689  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
18690  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
18691  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
18692  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
18693  *  \param   satIOContext_t:   Pointer to the SAT IO Context
18694  *
18695  *  \return If command is started successfully
18696  *    - \e tiSuccess:     I/O request successfully initiated.
18697  *    - \e tiBusy:        No resources available, try again later.
18698  *    - \e tiIONoDevice:  Invalid device handle.
18699  *    - \e tiError:       Other errors.
18700  */
18701 /*****************************************************************************/
18702 GLOBAL bit32  satSendReadLogExt(
18703                    tiRoot_t                  *tiRoot,
18704                    tiIORequest_t             *tiIORequest,
18705                    tiDeviceHandle_t          *tiDeviceHandle,
18706                    tiScsiInitiatorRequest_t *tiScsiRequest,
18707                    satIOContext_t            *satIOContext)
18708 
18709 {
18710 
18711   bit32                     status;
18712   bit32                     agRequestType;
18713   agsaFisRegHostToDevice_t  *fis;
18714 
18715   fis           = satIOContext->pFis;
18716 
18717   TI_DBG1(("satSendReadLogExt: tiDeviceHandle=%p tiIORequest=%p\n",
18718       tiDeviceHandle, tiIORequest));
18719 
18720   fis->h.fisType        = 0x27;                   /* Reg host to device */
18721   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18722   fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
18723   fis->h.features       = 0;                      /* FIS reserve */
18724   fis->d.lbaLow         = 0x10;                   /* Page number */
18725   fis->d.lbaMid         = 0;                      /*  */
18726   fis->d.lbaHigh        = 0;                      /*  */
18727   fis->d.device         = 0;                      /* DEV is ignored in SATA */
18728   fis->d.lbaLowExp      = 0;                      /*  */
18729   fis->d.lbaMidExp      = 0;                      /*  */
18730   fis->d.lbaHighExp     = 0;                      /*  */
18731   fis->d.featuresExp    = 0;                      /* FIS reserve */
18732   fis->d.sectorCount    = 0x01;                   /*  1 sector counts*/
18733   fis->d.sectorCountExp = 0x00;                   /*  1 sector counts */
18734   fis->d.reserved4      = 0;
18735   fis->d.control        = 0;                      /* FIS HOB bit clear */
18736   fis->d.reserved5      = 0;
18737 
18738   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
18739 
18740   /* Initialize CB for SATA completion.
18741    */
18742   satIOContext->satCompleteCB = &satReadLogExtCB;
18743 
18744   /*
18745    * Prepare SGL and send FIS to LL layer.
18746    */
18747   satIOContext->reqType = agRequestType;       /* Save it */
18748 
18749   status = sataLLIOStart( tiRoot,
18750                           tiIORequest,
18751                           tiDeviceHandle,
18752                           tiScsiRequest,
18753                           satIOContext);
18754 
18755   TI_DBG1(("satSendReadLogExt: end status %d\n", status));
18756 
18757   return (status);
18758 
18759 }
18760 
18761 
18762 /*****************************************************************************/
18763 /*! \brief  SAT default ATA status and ATA error translation to SCSI.
18764  *
18765  *  SSAT default ATA status and ATA error translation to SCSI.
18766  *
18767  *  \param   tiRoot:        Pointer to TISA initiator driver/port instance.
18768  *  \param   tiIORequest:   Pointer to TISA I/O request context for this I/O.
18769  *  \param   satIOContext:  Pointer to the SAT IO Context
18770  *  \param   pSense:        Pointer to scsiRspSense_t
18771  *  \param   ataStatus:     ATA status register
18772  *  \param   ataError:      ATA error register
18773  *  \param   interruptContext:    Interrupt context
18774  *
18775  *  \return  None
18776  */
18777 /*****************************************************************************/
18778 GLOBAL void  osSatDefaultTranslation(
18779                    tiRoot_t             *tiRoot,
18780                    tiIORequest_t        *tiIORequest,
18781                    satIOContext_t       *satIOContext,
18782                    scsiRspSense_t       *pSense,
18783                    bit8                 ataStatus,
18784                    bit8                 ataError,
18785                    bit32                interruptContext )
18786 {
18787 
18788   /*
18789    * Check for device fault case
18790    */
18791   if ( ataStatus & DF_ATA_STATUS_MASK )
18792   {
18793     satSetSensePayload( pSense,
18794                         SCSI_SNSKEY_HARDWARE_ERROR,
18795                         0,
18796                         SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18797                         satIOContext);
18798 
18799     ostiInitiatorIOCompleted( tiRoot,
18800                               tiIORequest,
18801                               tiIOSuccess,
18802                               SCSI_STAT_CHECK_CONDITION,
18803                               satIOContext->pTiSenseData,
18804                               interruptContext );
18805     return;
18806   }
18807 
18808   /*
18809    * If status error bit it set, need to check the error register
18810    */
18811   if ( ataStatus & ERR_ATA_STATUS_MASK )
18812   {
18813     if ( ataError & NM_ATA_ERROR_MASK )
18814     {
18815       TI_DBG1(("osSatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18816                  ataError, tiIORequest));
18817       satSetSensePayload( pSense,
18818                           SCSI_SNSKEY_NOT_READY,
18819                           0,
18820                           SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
18821                           satIOContext);
18822     }
18823 
18824     else if (ataError & UNC_ATA_ERROR_MASK)
18825     {
18826       TI_DBG1(("osSatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18827                  ataError, tiIORequest));
18828       satSetSensePayload( pSense,
18829                           SCSI_SNSKEY_MEDIUM_ERROR,
18830                           0,
18831                           SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
18832                           satIOContext);
18833     }
18834 
18835     else if (ataError & IDNF_ATA_ERROR_MASK)
18836     {
18837       TI_DBG1(("osSatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18838                  ataError, tiIORequest));
18839       satSetSensePayload( pSense,
18840                           SCSI_SNSKEY_MEDIUM_ERROR,
18841                           0,
18842                           SCSI_SNSCODE_RECORD_NOT_FOUND,
18843                           satIOContext);
18844     }
18845 
18846     else if (ataError & MC_ATA_ERROR_MASK)
18847     {
18848       TI_DBG1(("osSatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18849                  ataError, tiIORequest));
18850       satSetSensePayload( pSense,
18851                           SCSI_SNSKEY_UNIT_ATTENTION,
18852                           0,
18853                           SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
18854                           satIOContext);
18855     }
18856 
18857     else if (ataError & MCR_ATA_ERROR_MASK)
18858     {
18859       TI_DBG1(("osSatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18860                  ataError, tiIORequest));
18861       satSetSensePayload( pSense,
18862                           SCSI_SNSKEY_UNIT_ATTENTION,
18863                           0,
18864                           SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
18865                           satIOContext);
18866     }
18867 
18868     else if (ataError & ICRC_ATA_ERROR_MASK)
18869     {
18870       TI_DBG1(("osSatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18871                  ataError, tiIORequest));
18872       satSetSensePayload( pSense,
18873                           SCSI_SNSKEY_ABORTED_COMMAND,
18874                           0,
18875                           SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
18876                           satIOContext);
18877     }
18878 
18879     else if (ataError & ABRT_ATA_ERROR_MASK)
18880     {
18881       TI_DBG1(("osSatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18882                  ataError, tiIORequest));
18883       satSetSensePayload( pSense,
18884                           SCSI_SNSKEY_ABORTED_COMMAND,
18885                           0,
18886                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
18887                           satIOContext);
18888     }
18889 
18890     else
18891     {
18892       TI_DBG1(("osSatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, tiIORequest=%p\n",
18893                  ataError, tiIORequest));
18894       satSetSensePayload( pSense,
18895                           SCSI_SNSKEY_HARDWARE_ERROR,
18896                           0,
18897                           SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18898                           satIOContext);
18899     }
18900 
18901     /* Send the completion response now */
18902     ostiInitiatorIOCompleted( tiRoot,
18903                               tiIORequest,
18904                               tiIOSuccess,
18905                               SCSI_STAT_CHECK_CONDITION,
18906                               satIOContext->pTiSenseData,
18907                               interruptContext );
18908     return;
18909 
18910 
18911   }
18912 
18913   else /*  (ataStatus & ERR_ATA_STATUS_MASK ) is false */
18914   {
18915     /* This case should never happen */
18916     TI_DBG1(("osSatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** tiIORequest=%p\n",
18917                  ataStatus, tiIORequest));
18918     satSetSensePayload( pSense,
18919                         SCSI_SNSKEY_HARDWARE_ERROR,
18920                         0,
18921                         SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18922                         satIOContext);
18923 
18924     ostiInitiatorIOCompleted( tiRoot,
18925                               tiIORequest,
18926                               tiIOSuccess,
18927                               SCSI_STAT_CHECK_CONDITION,
18928                               satIOContext->pTiSenseData,
18929                               interruptContext );
18930     return;
18931 
18932   }
18933 
18934 
18935 }
18936 
18937 /*****************************************************************************/
18938 /*! \brief  Allocate resource for SAT intervally generated I/O.
18939  *
18940  *  Allocate resource for SAT intervally generated I/O.
18941  *
18942  *  \param   tiRoot:      Pointer to TISA driver/port instance.
18943  *  \param   satDevData:  Pointer to SAT specific device data.
18944  *  \param   allocLength: Length in byte of the DMA mem to allocate, upto
18945  *                        one page size.
18946  *  \param   satIntIo:    Pointer (output) to context for SAT internally
18947  *                        generated I/O that is allocated by this routine.
18948  *
18949  *  \return If command is started successfully
18950  *    - \e tiSuccess:     Success.
18951  *    - \e tiError:       Failed allocating resource.
18952  */
18953 /*****************************************************************************/
18954 GLOBAL satInternalIo_t * satAllocIntIoResource(
18955                     tiRoot_t              *tiRoot,
18956                     tiIORequest_t         *tiIORequest,
18957                     satDeviceData_t       *satDevData,
18958                     bit32                 dmaAllocLength,
18959                     satInternalIo_t       *satIntIo)
18960 {
18961   tdList_t          *tdList = agNULL;
18962   bit32             memAllocStatus;
18963 
18964   TI_DBG1(("satAllocIntIoResource: start\n"));
18965   TI_DBG6(("satAllocIntIoResource: satIntIo %p\n", satIntIo));
18966   if (satDevData == agNULL)
18967   {
18968     TI_DBG1(("satAllocIntIoResource: ***** ASSERT satDevData is null\n"));
18969     return agNULL;
18970   }
18971 
18972   tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
18973   if (!TDLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
18974   {
18975     TDLIST_DEQUEUE_FROM_HEAD(&tdList, &(satDevData->satFreeIntIoLinkList));
18976   }
18977   else
18978   {
18979     tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18980     TI_DBG1(("satAllocIntIoResource() no more internal free link.\n"));
18981     return agNULL;
18982   }
18983 
18984   if (tdList == agNULL)
18985   {
18986     tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18987     TI_DBG1(("satAllocIntIoResource() FAIL to alloc satIntIo.\n"));
18988     return agNULL;
18989   }
18990 
18991   satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
18992   TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
18993 
18994   /* Put in active list */
18995   TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
18996   TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
18997   tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18998 
18999 #ifdef REMOVED
19000   /* Put in active list */
19001   tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19002   TDLIST_DEQUEUE_THIS (tdList);
19003   TDLIST_ENQUEUE_AT_TAIL (tdList, &(satDevData->satActiveIntIoLinkList));
19004   tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19005 
19006   satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
19007   TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19008 #endif
19009 
19010   /*
19011     typedef struct
19012     {
19013       tdList_t                    satIntIoLink;
19014       tiIORequest_t               satIntTiIORequest;
19015       void                        *satIntRequestBody;
19016       tiScsiInitiatorRequest_t   satIntTiScsiXchg;
19017       tiMem_t                     satIntDmaMem;
19018       tiMem_t                     satIntReqBodyMem;
19019       bit32                       satIntFlag;
19020     } satInternalIo_t;
19021   */
19022 
19023   /*
19024    * Allocate mem for Request Body
19025    */
19026   satIntIo->satIntReqBodyMem.totalLength = sizeof(tdIORequestBody_t);
19027 
19028   memAllocStatus = ostiAllocMemory( tiRoot,
19029                                     &satIntIo->satIntReqBodyMem.osHandle,
19030                                     (void **)&satIntIo->satIntRequestBody,
19031                                     &satIntIo->satIntReqBodyMem.physAddrUpper,
19032                                     &satIntIo->satIntReqBodyMem.physAddrLower,
19033                                     8,
19034                                     satIntIo->satIntReqBodyMem.totalLength,
19035                                     agTRUE );
19036 
19037   if (memAllocStatus != tiSuccess)
19038   {
19039     TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for Req Body.\n"));
19040     /*
19041      * Return satIntIo to the free list
19042      */
19043     tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19044     TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19045     TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19046     tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19047 
19048     return agNULL;
19049   }
19050 
19051   /*
19052    *   Allocate DMA memory if required
19053    */
19054   if (dmaAllocLength != 0)
19055   {
19056     satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
19057 
19058     memAllocStatus = ostiAllocMemory( tiRoot,
19059                                       &satIntIo->satIntDmaMem.osHandle,
19060                                       (void **)&satIntIo->satIntDmaMem.virtPtr,
19061                                       &satIntIo->satIntDmaMem.physAddrUpper,
19062                                       &satIntIo->satIntDmaMem.physAddrLower,
19063                                       8,
19064                                       satIntIo->satIntDmaMem.totalLength,
19065                                       agFALSE);
19066     TI_DBG6(("satAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
19067     TI_DBG6(("satAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
19068 
19069     if (memAllocStatus != tiSuccess)
19070     {
19071       TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for DMA mem.\n"));
19072       /*
19073        * Return satIntIo to the free list
19074        */
19075       tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19076       TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19077       TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19078       tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19079 
19080       /*
19081        * Free mem allocated for Req body
19082        */
19083       ostiFreeMemory( tiRoot,
19084                       satIntIo->satIntReqBodyMem.osHandle,
19085                       satIntIo->satIntReqBodyMem.totalLength);
19086 
19087       return agNULL;
19088     }
19089   }
19090 
19091   /*
19092     typedef struct
19093     {
19094       tdList_t                    satIntIoLink;
19095       tiIORequest_t               satIntTiIORequest;
19096       void                        *satIntRequestBody;
19097       tiScsiInitiatorRequest_t   satIntTiScsiXchg;
19098       tiMem_t                     satIntDmaMem;
19099       tiMem_t                     satIntReqBodyMem;
19100       bit32                       satIntFlag;
19101     } satInternalIo_t;
19102   */
19103 
19104   /*
19105    * Initialize satIntTiIORequest field
19106    */
19107   satIntIo->satIntTiIORequest.osData = agNULL;  /* Not used for internal SAT I/O */
19108   satIntIo->satIntTiIORequest.tdData = satIntIo->satIntRequestBody;
19109 
19110   /*
19111    * saves the original tiIOrequest
19112    */
19113   satIntIo->satOrgTiIORequest = tiIORequest;
19114   /*
19115     typedef struct tiIniScsiCmnd
19116     {
19117       tiLUN_t     lun;
19118       bit32       expDataLength;
19119       bit32       taskAttribute;
19120       bit32       crn;
19121       bit8        cdb[16];
19122     } tiIniScsiCmnd_t;
19123 
19124     typedef struct tiScsiInitiatorExchange
19125     {
19126       void                *sglVirtualAddr;
19127       tiIniScsiCmnd_t     scsiCmnd;
19128       tiSgl_t             agSgl1;
19129       tiSgl_t             agSgl2;
19130       tiDataDirection_t   dataDirection;
19131     } tiScsiInitiatorRequest_t;
19132 
19133   */
19134 
19135   /*
19136    * Initialize satIntTiScsiXchg. Since the internal SAT request is NOT
19137    * originated from SCSI request, only the following fields are initialized:
19138    *  - sglVirtualAddr if DMA transfer is involved
19139    *  - agSgl1 if DMA transfer is involved
19140    *  - expDataLength in scsiCmnd since this field is read by sataLLIOStart()
19141    */
19142   if (dmaAllocLength != 0)
19143   {
19144     satIntIo->satIntTiScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
19145 
19146     OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntTiScsiXchg.agSgl1.len, 0,
19147                      satIntIo->satIntDmaMem.totalLength);
19148     satIntIo->satIntTiScsiXchg.agSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
19149     satIntIo->satIntTiScsiXchg.agSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
19150     satIntIo->satIntTiScsiXchg.agSgl1.type  = tiSgl;
19151 
19152     satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
19153   }
19154   else
19155   {
19156     satIntIo->satIntTiScsiXchg.sglVirtualAddr = agNULL;
19157 
19158     satIntIo->satIntTiScsiXchg.agSgl1.len   = 0;
19159     satIntIo->satIntTiScsiXchg.agSgl1.lower = 0;
19160     satIntIo->satIntTiScsiXchg.agSgl1.upper = 0;
19161     satIntIo->satIntTiScsiXchg.agSgl1.type  = tiSgl;
19162 
19163     satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19164   }
19165 
19166   TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
19167 
19168   TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
19169 
19170   TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
19171 
19172   TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
19173     TI_DBG5(("satAllocIntIoResource: return satIntIo %p\n", satIntIo));
19174   return  satIntIo;
19175 
19176 }
19177 
19178 /*****************************************************************************/
19179 /*! \brief  Free resource for SAT intervally generated I/O.
19180  *
19181  *  Free resource for SAT intervally generated I/O that was previously
19182  *  allocated in satAllocIntIoResource().
19183  *
19184  *  \param   tiRoot:      Pointer to TISA driver/port instance.
19185  *  \param   satDevData:  Pointer to SAT specific device data.
19186  *  \param   satIntIo:    Pointer to context for SAT internal I/O that was
19187  *                        previously allocated in satAllocIntIoResource().
19188  *
19189  *  \return  None
19190  */
19191 /*****************************************************************************/
19192 GLOBAL void  satFreeIntIoResource(
19193                     tiRoot_t              *tiRoot,
19194                     satDeviceData_t       *satDevData,
19195                     satInternalIo_t       *satIntIo)
19196 {
19197   TI_DBG6(("satFreeIntIoResource: start\n"));
19198 
19199   if (satIntIo == agNULL)
19200   {
19201     TI_DBG6(("satFreeIntIoResource: allowed call\n"));
19202     return;
19203   }
19204 
19205   /* sets the original tiIOrequest to agNULL for internally generated ATA cmnd */
19206   satIntIo->satOrgTiIORequest = agNULL;
19207 
19208   /*
19209    * Free DMA memory if previosly alocated
19210    */
19211   if (satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength != 0)
19212   {
19213     TI_DBG1(("satFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
19214     TI_DBG6(("satFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
19215 
19216     ostiFreeMemory( tiRoot,
19217                     satIntIo->satIntDmaMem.osHandle,
19218                     satIntIo->satIntDmaMem.totalLength);
19219     satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19220   }
19221 
19222   if (satIntIo->satIntReqBodyMem.totalLength != 0)
19223   {
19224     TI_DBG1(("satFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
19225     /*
19226      * Free mem allocated for Req body
19227      */
19228     ostiFreeMemory( tiRoot,
19229                     satIntIo->satIntReqBodyMem.osHandle,
19230                     satIntIo->satIntReqBodyMem.totalLength);
19231 
19232     satIntIo->satIntReqBodyMem.totalLength = 0;
19233   }
19234 
19235   TI_DBG6(("satFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19236   /*
19237    * Return satIntIo to the free list
19238    */
19239   tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19240   TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
19241   TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
19242   tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19243 
19244 }
19245 
19246 
19247 /*****************************************************************************/
19248 /*! \brief SAT implementation for SCSI INQUIRY.
19249  *
19250  *  SAT implementation for SCSI INQUIRY.
19251  *  This function sends ATA Identify Device data command for SCSI INQUIRY
19252  *
19253  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
19254  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
19255  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
19256  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
19257  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19258  *
19259  *  \return If command is started successfully
19260  *    - \e tiSuccess:     I/O request successfully initiated.
19261  *    - \e tiBusy:        No resources available, try again later.
19262  *    - \e tiIONoDevice:  Invalid device handle.
19263  *    - \e tiError:       Other errors.
19264  */
19265 /*****************************************************************************/
19266 GLOBAL bit32  satSendIDDev(
19267                            tiRoot_t                  *tiRoot,
19268                            tiIORequest_t             *tiIORequest,
19269                            tiDeviceHandle_t          *tiDeviceHandle,
19270                            tiScsiInitiatorRequest_t *tiScsiRequest,
19271                            satIOContext_t            *satIOContext)
19272 
19273 {
19274   bit32                     status;
19275   bit32                     agRequestType;
19276   satDeviceData_t           *pSatDevData;
19277   agsaFisRegHostToDevice_t  *fis;
19278 #ifdef  TD_DEBUG_ENABLE
19279   satInternalIo_t           *satIntIoContext;
19280   tdsaDeviceData_t          *oneDeviceData;
19281   tdIORequestBody_t         *tdIORequestBody;
19282 #endif
19283 
19284   pSatDevData   = satIOContext->pSatDevData;
19285   fis           = satIOContext->pFis;
19286 
19287   TI_DBG5(("satSendIDDev: start\n"));
19288 #ifdef  TD_DEBUG_ENABLE
19289   oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
19290 #endif
19291   TI_DBG5(("satSendIDDev: did %d\n", oneDeviceData->id));
19292 
19293 
19294 #ifdef  TD_DEBUG_ENABLE
19295   satIntIoContext = satIOContext->satIntIoContext;
19296   tdIORequestBody = satIntIoContext->satIntRequestBody;
19297 #endif
19298 
19299   TI_DBG5(("satSendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
19300 
19301   fis->h.fisType        = 0x27;                   /* Reg host to device */
19302   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19303   if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
19304       fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
19305   else
19306       fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
19307   fis->h.features       = 0;                      /* FIS reserve */
19308   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
19309   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19310   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19311   fis->d.device         = 0;                      /* FIS LBA mode  */
19312   fis->d.lbaLowExp      = 0;
19313   fis->d.lbaMidExp      = 0;
19314   fis->d.lbaHighExp     = 0;
19315   fis->d.featuresExp    = 0;
19316   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
19317   fis->d.sectorCountExp = 0;
19318   fis->d.reserved4      = 0;
19319   fis->d.control        = 0;                      /* FIS HOB bit clear */
19320   fis->d.reserved5      = 0;
19321 
19322   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19323 
19324   /* Initialize CB for SATA completion.
19325    */
19326   satIOContext->satCompleteCB = &satInquiryCB;
19327 
19328   /*
19329    * Prepare SGL and send FIS to LL layer.
19330    */
19331   satIOContext->reqType = agRequestType;       /* Save it */
19332 
19333 #ifdef TD_INTERNAL_DEBUG
19334   tdhexdump("satSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19335 #ifdef  TD_DEBUG_ENABLE
19336   tdhexdump("satSendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19337 #endif
19338 #endif
19339 
19340   status = sataLLIOStart( tiRoot,
19341                           tiIORequest,
19342                           tiDeviceHandle,
19343                           tiScsiRequest,
19344                           satIOContext);
19345 
19346   TI_DBG6(("satSendIDDev: end status %d\n", status));
19347   return status;
19348 }
19349 
19350 
19351 /*****************************************************************************/
19352 /*! \brief SAT implementation for SCSI INQUIRY.
19353  *
19354  *  SAT implementation for SCSI INQUIRY.
19355  *  This function prepares TD layer internal resource to send ATA
19356  *  Identify Device data command for SCSI INQUIRY
19357  *
19358  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
19359  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
19360  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
19361  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
19362  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19363  *
19364  *  \return If command is started successfully
19365  *    - \e tiSuccess:     I/O request successfully initiated.
19366  *    - \e tiBusy:        No resources available, try again later.
19367  *    - \e tiIONoDevice:  Invalid device handle.
19368  *    - \e tiError:       Other errors.
19369  */
19370 /*****************************************************************************/
19371 /* prerequsite: tdsaDeviceData and agdevhandle must exist; in other words, LL discovered the device
19372    already */
19373 /*
19374   convert OS generated IO to TD generated IO due to difference in sgl
19375 */
19376 GLOBAL bit32  satStartIDDev(
19377                                tiRoot_t                  *tiRoot,
19378                                tiIORequest_t             *tiIORequest,
19379                                tiDeviceHandle_t          *tiDeviceHandle,
19380                                tiScsiInitiatorRequest_t *tiScsiRequest,
19381                                satIOContext_t            *satIOContext
19382                             )
19383 {
19384   satInternalIo_t           *satIntIo = agNULL;
19385   satDeviceData_t           *satDevData = agNULL;
19386   tdIORequestBody_t         *tdIORequestBody;
19387   satIOContext_t            *satNewIOContext;
19388   bit32                     status;
19389 
19390   TI_DBG6(("satStartIDDev: start\n"));
19391 
19392   satDevData = satIOContext->pSatDevData;
19393 
19394   TI_DBG6(("satStartIDDev: before alloc\n"));
19395 
19396   /* allocate identify device command */
19397   satIntIo = satAllocIntIoResource( tiRoot,
19398                                     tiIORequest,
19399                                     satDevData,
19400                                     sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
19401                                     satIntIo);
19402 
19403   TI_DBG6(("satStartIDDev: before after\n"));
19404 
19405   if (satIntIo == agNULL)
19406   {
19407     TI_DBG1(("satStartIDDev: can't alloacate\n"));
19408 
19409 #if 0
19410     ostiInitiatorIOCompleted (
19411                               tiRoot,
19412                               tiIORequest,
19413                               tiIOFailed,
19414                               tiDetailOtherError,
19415                               agNULL,
19416                               satIOContext->interruptContext
19417                               );
19418 #endif
19419 
19420     return tiError;
19421   }
19422 
19423   /* fill in fields */
19424   /* real ttttttthe one worked and the same; 5/21/07/ */
19425   satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
19426   tdIORequestBody = satIntIo->satIntRequestBody;
19427   satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
19428 
19429   satNewIOContext->pSatDevData   = satDevData;
19430   satNewIOContext->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
19431   satNewIOContext->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
19432   satNewIOContext->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
19433   satNewIOContext->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
19434   satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
19435   satNewIOContext->interruptContext = tiInterruptContext;
19436   satNewIOContext->satIntIoContext  = satIntIo;
19437 
19438   satNewIOContext->ptiDeviceHandle = agNULL;
19439   satNewIOContext->satOrgIOContext = satIOContext; /* changed */
19440 
19441   /* this is valid only for TD layer generated (not triggered by OS at all) IO */
19442   satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
19443 
19444 
19445   TI_DBG6(("satStartIDDev: OS satIOContext %p \n", satIOContext));
19446   TI_DBG6(("satStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
19447   TI_DBG6(("satStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
19448   TI_DBG6(("satStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
19449 
19450 
19451 
19452   TI_DBG1(("satStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
19453 
19454   status = satSendIDDev( tiRoot,
19455                          &satIntIo->satIntTiIORequest, /* New tiIORequest */
19456                          tiDeviceHandle,
19457                          satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
19458                          satNewIOContext);
19459 
19460   if (status != tiSuccess)
19461   {
19462     TI_DBG1(("satStartIDDev: failed in sending\n"));
19463 
19464     satFreeIntIoResource( tiRoot,
19465                           satDevData,
19466                           satIntIo);
19467 
19468 #if 0
19469     ostiInitiatorIOCompleted (
19470                               tiRoot,
19471                               tiIORequest,
19472                               tiIOFailed,
19473                               tiDetailOtherError,
19474                               agNULL,
19475                               satIOContext->interruptContext
19476                               );
19477 #endif
19478 
19479     return tiError;
19480   }
19481 
19482 
19483   TI_DBG6(("satStartIDDev: end\n"));
19484 
19485   return status;
19486 
19487 
19488 }
19489 
19490 /*****************************************************************************/
19491 /*! \brief satComputeCDB10LBA.
19492  *
19493  *  This fuctions computes LBA of CDB10.
19494  *
19495  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19496  *
19497  *  \return
19498  *    - \e LBA
19499  */
19500 /*****************************************************************************/
19501 bit32 satComputeCDB10LBA(satIOContext_t            *satIOContext)
19502 {
19503   tiIniScsiCmnd_t           *scsiCmnd;
19504   tiScsiInitiatorRequest_t *tiScsiRequest;
19505   bit32                     lba = 0;
19506 
19507   TI_DBG5(("satComputeCDB10LBA: start\n"));
19508   tiScsiRequest = satIOContext->tiScsiXchg;
19509   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19510 
19511   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19512     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19513 
19514   return lba;
19515 }
19516 
19517 /*****************************************************************************/
19518 /*! \brief satComputeCDB10TL.
19519  *
19520  *  This fuctions computes transfer length of CDB10.
19521  *
19522  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19523  *
19524  *  \return
19525  *    - \e TL
19526  */
19527 /*****************************************************************************/
19528 bit32 satComputeCDB10TL(satIOContext_t            *satIOContext)
19529 {
19530 
19531   tiIniScsiCmnd_t           *scsiCmnd;
19532   tiScsiInitiatorRequest_t *tiScsiRequest;
19533   bit32                     tl = 0;
19534 
19535   TI_DBG5(("satComputeCDB10TL: start\n"));
19536   tiScsiRequest = satIOContext->tiScsiXchg;
19537   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19538 
19539   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
19540   return tl;
19541 }
19542 
19543 /*****************************************************************************/
19544 /*! \brief satComputeCDB12LBA.
19545  *
19546  *  This fuctions computes LBA of CDB12.
19547  *
19548  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19549  *
19550  *  \return
19551  *    - \e LBA
19552  */
19553 /*****************************************************************************/
19554 bit32 satComputeCDB12LBA(satIOContext_t            *satIOContext)
19555 {
19556   tiIniScsiCmnd_t           *scsiCmnd;
19557   tiScsiInitiatorRequest_t *tiScsiRequest;
19558   bit32                     lba = 0;
19559 
19560   TI_DBG5(("satComputeCDB10LBA: start\n"));
19561   tiScsiRequest = satIOContext->tiScsiXchg;
19562   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19563 
19564   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19565     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19566 
19567   return lba;
19568 }
19569 
19570 /*****************************************************************************/
19571 /*! \brief satComputeCDB12TL.
19572  *
19573  *  This fuctions computes transfer length of CDB12.
19574  *
19575  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19576  *
19577  *  \return
19578  *    - \e TL
19579  */
19580 /*****************************************************************************/
19581 bit32 satComputeCDB12TL(satIOContext_t            *satIOContext)
19582 {
19583 
19584   tiIniScsiCmnd_t           *scsiCmnd;
19585   tiScsiInitiatorRequest_t *tiScsiRequest;
19586   bit32                     tl = 0;
19587 
19588   TI_DBG5(("satComputeCDB10TL: start\n"));
19589   tiScsiRequest = satIOContext->tiScsiXchg;
19590   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19591 
19592   tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19593     + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19594   return tl;
19595 }
19596 
19597 
19598 /*****************************************************************************/
19599 /*! \brief satComputeCDB16LBA.
19600  *
19601  *  This fuctions computes LBA of CDB16.
19602  *
19603  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19604  *
19605  *  \return
19606  *    - \e LBA
19607  */
19608 /*****************************************************************************/
19609 /*
19610   CBD16 has bit64 LBA
19611   But it has to be less than (2^28 - 1)
19612   Therefore, use last four bytes to compute LBA is OK
19613 */
19614 bit32 satComputeCDB16LBA(satIOContext_t            *satIOContext)
19615 {
19616   tiIniScsiCmnd_t           *scsiCmnd;
19617   tiScsiInitiatorRequest_t *tiScsiRequest;
19618   bit32                     lba = 0;
19619 
19620   TI_DBG5(("satComputeCDB10LBA: start\n"));
19621   tiScsiRequest = satIOContext->tiScsiXchg;
19622   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19623 
19624   lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19625     + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19626 
19627   return lba;
19628 }
19629 
19630 /*****************************************************************************/
19631 /*! \brief satComputeCDB16TL.
19632  *
19633  *  This fuctions computes transfer length of CDB16.
19634  *
19635  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19636  *
19637  *  \return
19638  *    - \e TL
19639  */
19640 /*****************************************************************************/
19641 bit32 satComputeCDB16TL(satIOContext_t            *satIOContext)
19642 {
19643 
19644   tiIniScsiCmnd_t           *scsiCmnd;
19645   tiScsiInitiatorRequest_t *tiScsiRequest;
19646   bit32                     tl = 0;
19647 
19648   TI_DBG5(("satComputeCDB10TL: start\n"));
19649   tiScsiRequest = satIOContext->tiScsiXchg;
19650   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19651 
19652   tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
19653     + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
19654   return tl;
19655 }
19656 
19657 /*****************************************************************************/
19658 /*! \brief satComputeLoopNum.
19659  *
19660  *  This fuctions computes the number of interation needed for a transfer
19661  *  length with a specific number.
19662  *
19663  *  \param   a:   a numerator
19664  *  \param   b:   a denominator
19665  *
19666  *  \return
19667  *    - \e number of interation
19668  */
19669 /*****************************************************************************/
19670 /*
19671   (tl, denom)
19672   tl can be upto bit32 because CDB16 has bit32 tl
19673   Therefore, fine
19674   either (tl, 0xFF) or (tl, 0xFFFF)
19675 */
19676 bit32 satComputeLoopNum(bit32 a, bit32 b)
19677 {
19678 
19679   bit32 quo = 0, rem = 0;
19680   bit32 LoopNum = 0;
19681 
19682   TI_DBG5(("satComputeLoopNum: start\n"));
19683 
19684   quo = a/b;
19685 
19686   if (quo == 0)
19687   {
19688     LoopNum = 1;
19689   }
19690   else
19691   {
19692     rem = a % b;
19693     if (rem == 0)
19694     {
19695       LoopNum = quo;
19696     }
19697     else
19698     {
19699       LoopNum = quo + 1;
19700     }
19701   }
19702 
19703   return LoopNum;
19704 }
19705 
19706 /*****************************************************************************/
19707 /*! \brief satAddNComparebit64.
19708  *
19709  *
19710  *
19711  *
19712  *  \param   a:   lba
19713  *  \param   b:   tl
19714  *
19715  *  \return
19716  *    - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19717  *    - \e FALSE otherwise
19718  *  \note: a and b must be in the same length
19719  */
19720 /*****************************************************************************/
19721 /*
19722   input: bit8 a[8], bit8 b[8] (lba, tl) must be in same length
19723   if (lba + tl > SAT_TR_LBA_LIMIT)
19724   then returns true
19725   else returns false
19726   (LBA,TL)
19727 */
19728 bit32 satAddNComparebit64(bit8 *a, bit8 *b)
19729 {
19730   bit16 ans[8];       // 0 MSB, 8 LSB
19731   bit8  final_ans[9]; // 0 MSB, 9 LSB
19732   bit8  max[9];
19733   int i;
19734 
19735   TI_DBG5(("satAddNComparebit64: start\n"));
19736 
19737   osti_memset(ans, 0, sizeof(ans));
19738   osti_memset(final_ans, 0, sizeof(final_ans));
19739   osti_memset(max, 0, sizeof(max));
19740 
19741   max[0] = 0x1; //max = 0x1 0000 0000 0000 0000
19742 
19743   // adding from LSB to MSB
19744   for(i=7;i>=0;i--)
19745   {
19746     ans[i] = (bit16)(a[i] + b[i]);
19747     if (i != 7)
19748     {
19749       ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19750     }
19751   }
19752 
19753   /*
19754     filling in the final answer
19755    */
19756   final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19757   final_ans[1] = (bit8)(ans[0] & 0xFF);
19758 
19759   for(i=2;i<=8;i++)
19760   {
19761     final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19762   }
19763 
19764   //compare final_ans to max
19765   for(i=0;i<=8;i++)
19766   {
19767     if (final_ans[i] > max[i])
19768     {
19769       TI_DBG5(("satAddNComparebit64: yes at %d\n", i));
19770       return agTRUE;
19771     }
19772     else if (final_ans[i] < max[i])
19773     {
19774       TI_DBG5(("satAddNComparebit64: no at %d\n", i));
19775       return agFALSE;
19776     }
19777     else
19778     {
19779       continue;
19780     }
19781   }
19782 
19783 
19784   return agFALSE;
19785 }
19786 
19787 /*****************************************************************************/
19788 /*! \brief satAddNComparebit32.
19789  *
19790  *
19791  *
19792  *
19793  *  \param   a:   lba
19794  *  \param   b:   tl
19795  *
19796  *  \return
19797  *    - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19798  *    - \e FALSE otherwise
19799  *  \note: a and b must be in the same length
19800  */
19801 /*****************************************************************************/
19802 /*
19803   input: bit8 a[4], bit8 b[4] (lba, tl) must be in same length
19804   if (lba + tl > SAT_TR_LBA_LIMIT)
19805   then returns true
19806   else returns false
19807   (LBA,TL)
19808 */
19809 bit32 satAddNComparebit32(bit8 *a, bit8 *b)
19810 {
19811   bit16 ans[4];       // 0 MSB, 4 LSB
19812   bit8  final_ans[5]; // 0 MSB, 5 LSB
19813   bit8   max[4];
19814   int i;
19815 
19816   TI_DBG5(("satAddNComparebit32: start\n"));
19817 
19818   osti_memset(ans, 0, sizeof(ans));
19819   osti_memset(final_ans, 0, sizeof(final_ans));
19820   osti_memset(max, 0, sizeof(max));
19821 
19822   max[0] = 0x10; // max =0x1000 0000
19823 
19824   // adding from LSB to MSB
19825   for(i=3;i>=0;i--)
19826   {
19827     ans[i] = (bit16)(a[i] + b[i]);
19828     if (i != 3)
19829     {
19830       ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19831     }
19832   }
19833 
19834 
19835   /*
19836     filling in the final answer
19837    */
19838   final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19839   final_ans[1] = (bit8)(ans[0] & 0xFF);
19840 
19841   for(i=2;i<=4;i++)
19842   {
19843     final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19844   }
19845 
19846   //compare final_ans to max
19847   if (final_ans[0] != 0)
19848   {
19849     TI_DBG5(("satAddNComparebit32: yes bigger and out of range\n"));
19850     return agTRUE;
19851   }
19852   for(i=1;i<=4;i++)
19853   {
19854     if (final_ans[i] > max[i-1])
19855     {
19856       TI_DBG5(("satAddNComparebit32: yes at %d\n", i));
19857       return agTRUE;
19858     }
19859     else if (final_ans[i] < max[i-1])
19860     {
19861       TI_DBG5(("satAddNComparebit32: no at %d\n", i));
19862       return agFALSE;
19863     }
19864     else
19865     {
19866       continue;
19867     }
19868   }
19869 
19870 
19871   return agFALSE;
19872 }
19873 
19874 /*****************************************************************************/
19875 /*! \brief satCompareLBALimitbit.
19876  *
19877  *
19878  *
19879  *
19880  *  \param   lba:   lba
19881  *
19882  *  \return
19883  *    - \e TRUE if (lba > SAT_TR_LBA_LIMIT - 1)
19884  *    - \e FALSE otherwise
19885  *  \note: a and b must be in the same length
19886  */
19887 /*****************************************************************************/
19888 
19889 /*
19890   lba
19891 */
19892 /*
19893   input: bit8 lba[8]
19894   if (lba > SAT_TR_LBA_LIMIT - 1)
19895   then returns true
19896   else returns false
19897   (LBA,TL)
19898 */
19899 bit32 satCompareLBALimitbit(bit8 *lba)
19900 {
19901   bit32 i;
19902   bit8 limit[8];
19903 
19904   /* limit is 0xF FF FF = 2^28 - 1 */
19905   limit[0] = 0x0;   /* MSB */
19906   limit[1] = 0x0;
19907   limit[2] = 0x0;
19908   limit[3] = 0x0;
19909   limit[4] = 0xF;
19910   limit[5] = 0xFF;
19911   limit[6] = 0xFF;
19912   limit[7] = 0xFF; /* LSB */
19913 
19914   //compare lba to limit
19915   for(i=0;i<8;i++)
19916   {
19917     if (lba[i] > limit[i])
19918     {
19919       TI_DBG5(("satCompareLBALimitbit64: yes at %d\n", i));
19920       return agTRUE;
19921     }
19922     else if (lba[i] < limit[i])
19923     {
19924       TI_DBG5(("satCompareLBALimitbit64: no at %d\n", i));
19925       return agFALSE;
19926     }
19927     else
19928     {
19929       continue;
19930     }
19931   }
19932 
19933 
19934   return agFALSE;
19935 
19936 }
19937 /*****************************************************************************
19938 *! \brief
19939 *  Purpose: bitwise set
19940 *
19941 *  Parameters:
19942 *   data        - input output buffer
19943 *   index       - bit to set
19944 *
19945 *  Return:
19946 *   none
19947 *
19948 *****************************************************************************/
19949 GLOBAL void
19950 satBitSet(bit8 *data, bit32 index)
19951 {
19952   data[index/8] |= (1 << (index%8));
19953 }
19954 
19955 /*****************************************************************************
19956 *! \brief
19957 *  Purpose: bitwise clear
19958 *
19959 *  Parameters:
19960 *   data        - input output buffer
19961 *   index       - bit to clear
19962 *
19963 *  Return:
19964 *   none
19965 *
19966 *****************************************************************************/
19967 GLOBAL void
19968 satBitClear(bit8 *data, bit32 index)
19969 {
19970   data[index/8] &= ~(1 << (index%8));
19971 }
19972 
19973 /*****************************************************************************
19974 *! \brief
19975 *  Purpose: bitwise test
19976 *
19977 *  Parameters:
19978 *   data        - input output buffer
19979 *   index       - bit to test
19980 *
19981 *  Return:
19982 *   0 - not set
19983 *   1 - set
19984 *
19985 *****************************************************************************/
19986 GLOBAL agBOOLEAN
19987 satBitTest(bit8 *data, bit32 index)
19988 {
19989   return ( (BOOLEAN)((data[index/8] & (1 << (index%8)) ) ? 1: 0));
19990 }
19991 
19992 
19993 /******************************************************************************/
19994 /*! \brief allocate an available SATA tag
19995  *
19996  *  allocate an available SATA tag
19997  *
19998  *  \param tiRoot           Pointer to TISA initiator driver/port instance.
19999  *  \param pSatDevData
20000  *  \param pTag
20001  *
20002  *  \return -Success or fail-
20003  */
20004 /*******************************************************************************/
20005 GLOBAL bit32 satTagAlloc(
20006                            tiRoot_t          *tiRoot,
20007                            satDeviceData_t   *pSatDevData,
20008                            bit8              *pTag
20009                            )
20010 {
20011   bit32             retCode = agFALSE;
20012   bit32             i;
20013 
20014   tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20015   for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
20016   {
20017     if ( 0 == satBitTest((bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
20018     {
20019       satBitSet((bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20020       *pTag = (bit8) i;
20021       retCode = agTRUE;
20022       break;
20023     }
20024   }
20025   tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20026   return retCode;
20027 }
20028 
20029 /******************************************************************************/
20030 /*! \brief release an SATA tag
20031  *
20032  *  release an available SATA tag
20033  *
20034  *  \param tiRoot           Pointer to TISA initiator driver/port instance.
20035  *  \param pSatDevData
20036  *  \param Tag
20037  *
20038  *  \return -the tag-
20039  */
20040 /*******************************************************************************/
20041 GLOBAL bit32 satTagRelease(
20042                               tiRoot_t          *tiRoot,
20043                               satDeviceData_t   *pSatDevData,
20044                               bit8              tag
20045                               )
20046 {
20047   bit32             retCode = agFALSE;
20048 
20049   tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20050   if ( tag < pSatDevData->satNCQMaxIO )
20051   {
20052     satBitClear( (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
20053     retCode = agTRUE;
20054   }
20055   tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20056   return retCode;
20057 }
20058 
20059 /*****************************************************************************
20060  *! \brief  satSubTM
20061  *
20062  *   This routine is called to initiate a TM request to SATL.
20063  *   This routine is independent of HW/LL API.
20064  *
20065  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
20066  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20067  *  \param  task:             SAM-3 task management request.
20068  *  \param  lun:              Pointer to LUN.
20069  *  \param  taskTag:          Pointer to the associated task where the TM
20070  *                            command is to be applied.
20071  *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
20072  *  \param  NotifyOS          flag determines whether notify OS layer or not
20073  *
20074  *  \return:
20075  *
20076  *  \e tiSuccess:     I/O request successfully initiated.
20077  *  \e tiBusy:        No resources available, try again later.
20078  *  \e tiIONoDevice:  Invalid device handle.
20079  *  \e tiError:       Other errors that prevent the I/O request to be started.
20080  *
20081  *  \note:
20082  *        This funcion is triggered bottom up. Not yet in use.
20083  *****************************************************************************/
20084 /* called for bottom up */
20085 osGLOBAL bit32 satSubTM(
20086                         tiRoot_t          *tiRoot,
20087                         tiDeviceHandle_t  *tiDeviceHandle,
20088                         bit32             task,
20089                         tiLUN_t           *lun,
20090                         tiIORequest_t     *taskTag,
20091                         tiIORequest_t     *currentTaskTag,
20092                         bit32              NotifyOS
20093                         )
20094 {
20095   void                        *osMemHandle;
20096   tdIORequestBody_t           *TMtdIORequestBody;
20097   bit32                       PhysUpper32;
20098   bit32                       PhysLower32;
20099   bit32                       memAllocStatus;
20100   agsaIORequest_t             *agIORequest = agNULL;
20101 
20102   TI_DBG6(("satSubTM: start\n"));
20103 
20104   /* allocation tdIORequestBody and pass it to satTM() */
20105   memAllocStatus = ostiAllocMemory(
20106                                    tiRoot,
20107                                    &osMemHandle,
20108                                    (void **)&TMtdIORequestBody,
20109                                    &PhysUpper32,
20110                                    &PhysLower32,
20111                                    8,
20112                                    sizeof(tdIORequestBody_t),
20113                                    agTRUE
20114                                    );
20115 
20116   if (memAllocStatus != tiSuccess)
20117   {
20118     TI_DBG1(("satSubTM: ostiAllocMemory failed... \n"));
20119     return tiError;
20120   }
20121 
20122   if (TMtdIORequestBody == agNULL)
20123   {
20124     TI_DBG1(("satSubTM: ostiAllocMemory returned NULL TMIORequestBody\n"));
20125     return tiError;
20126    }
20127 
20128   /* setup task management structure */
20129   TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
20130   TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
20131   TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
20132 
20133   /* initialize tiDevhandle */
20134   TMtdIORequestBody->tiDevHandle = tiDeviceHandle;
20135 
20136   /* initialize tiIORequest */
20137   TMtdIORequestBody->tiIORequest = agNULL;
20138 
20139   /* initialize agIORequest */
20140   agIORequest = &(TMtdIORequestBody->agIORequest);
20141   agIORequest->osData = (void *) TMtdIORequestBody;
20142   agIORequest->sdkData = agNULL; /* SA takes care of this */
20143   satTM(tiRoot,
20144         tiDeviceHandle,
20145         task, /* TD_INTERNAL_TM_RESET */
20146         agNULL,
20147         agNULL,
20148         agNULL,
20149         TMtdIORequestBody,
20150         agFALSE);
20151 
20152   return tiSuccess;
20153 }
20154 
20155 
20156 /*****************************************************************************/
20157 /*! \brief SAT implementation for satStartResetDevice.
20158  *
20159  *  SAT implementation for sending SRT and send FIS request to LL layer.
20160  *
20161  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20162  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20163  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20164  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20165  *  \param   satIOContext_t:   Pointer to the SAT IO Context
20166  *
20167  *  \return If command is started successfully
20168  *    - \e tiSuccess:     I/O request successfully initiated.
20169  *    - \e tiBusy:        No resources available, try again later.
20170  *    - \e tiIONoDevice:  Invalid device handle.
20171  *    - \e tiError:       Other errors.
20172  *  \note : triggerred by OS layer or bottom up
20173  */
20174 /*****************************************************************************/
20175 /* OS triggerred or bottom up */
20176 GLOBAL bit32
20177 satStartResetDevice(
20178                             tiRoot_t                  *tiRoot,
20179                             tiIORequest_t             *tiIORequest, /* currentTaskTag */
20180                             tiDeviceHandle_t          *tiDeviceHandle,
20181                             tiScsiInitiatorRequest_t *tiScsiRequest, /* should be NULL */
20182                             satIOContext_t            *satIOContext
20183                             )
20184 {
20185   satInternalIo_t           *satIntIo = agNULL;
20186   satDeviceData_t           *satDevData = agNULL;
20187   satIOContext_t            *satNewIOContext;
20188   bit32                     status;
20189   tiIORequest_t             *currentTaskTag = agNULL;
20190 
20191   TI_DBG1(("satStartResetDevice: start\n"));
20192 
20193   currentTaskTag = tiIORequest;
20194 
20195   satDevData = satIOContext->pSatDevData;
20196 
20197   TI_DBG6(("satStartResetDevice: before alloc\n"));
20198 
20199   /* allocate any fis for seting SRT bit in device control */
20200   satIntIo = satAllocIntIoResource( tiRoot,
20201                                     tiIORequest,
20202                                     satDevData,
20203                                     0,
20204                                     satIntIo);
20205 
20206   TI_DBG6(("satStartResetDevice: before after\n"));
20207 
20208   if (satIntIo == agNULL)
20209   {
20210     TI_DBG1(("satStartResetDevice: can't alloacate\n"));
20211     if (satIOContext->NotifyOS)
20212     {
20213       ostiInitiatorEvent( tiRoot,
20214                           NULL,
20215                           NULL,
20216                           tiIntrEventTypeTaskManagement,
20217                           tiTMFailed,
20218                           currentTaskTag );
20219     }
20220     return tiError;
20221   }
20222 
20223   satNewIOContext = satPrepareNewIO(satIntIo,
20224                                     tiIORequest,
20225                                     satDevData,
20226                                     agNULL,
20227                                     satIOContext);
20228 
20229   TI_DBG6(("satStartResetDevice: OS satIOContext %p \n", satIOContext));
20230   TI_DBG6(("satStartResetDevice: TD satNewIOContext %p \n", satNewIOContext));
20231   TI_DBG6(("satStartResetDevice: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
20232   TI_DBG6(("satStartResetDevice: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
20233 
20234 
20235 
20236   TI_DBG6(("satStartResetDevice: satNewIOContext %p \n", satNewIOContext));
20237 
20238   if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
20239   {
20240     status = satDeviceReset(tiRoot,
20241                           &satIntIo->satIntTiIORequest, /* New tiIORequest */
20242                           tiDeviceHandle,
20243                           satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20244                           satNewIOContext);
20245   }
20246   else
20247   {
20248     status = satResetDevice(tiRoot,
20249                           &satIntIo->satIntTiIORequest, /* New tiIORequest */
20250                           tiDeviceHandle,
20251                           satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20252                           satNewIOContext);
20253   }
20254 
20255   if (status != tiSuccess)
20256   {
20257     TI_DBG1(("satStartResetDevice: failed in sending\n"));
20258 
20259     satFreeIntIoResource( tiRoot,
20260                           satDevData,
20261                           satIntIo);
20262     if (satIOContext->NotifyOS)
20263     {
20264       ostiInitiatorEvent( tiRoot,
20265                           NULL,
20266                           NULL,
20267                           tiIntrEventTypeTaskManagement,
20268                           tiTMFailed,
20269                           currentTaskTag );
20270     }
20271 
20272     return tiError;
20273   }
20274 
20275 
20276   TI_DBG6(("satStartResetDevice: end\n"));
20277 
20278   return status;
20279 }
20280 
20281 /*****************************************************************************/
20282 /*! \brief SAT implementation for satResetDevice.
20283  *
20284  *  SAT implementation for building SRT FIS and sends the request to LL layer.
20285  *
20286  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20287  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20288  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20289  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20290  *  \param   satIOContext_t:   Pointer to the SAT IO Context
20291  *
20292  *  \return If command is started successfully
20293  *    - \e tiSuccess:     I/O request successfully initiated.
20294  *    - \e tiBusy:        No resources available, try again later.
20295  *    - \e tiIONoDevice:  Invalid device handle.
20296  *    - \e tiError:       Other errors.
20297  */
20298 /*****************************************************************************/
20299 
20300 /*
20301   create any fis and set SRST bit in device control
20302 */
20303 GLOBAL bit32
20304 satResetDevice(
20305                             tiRoot_t                  *tiRoot,
20306                             tiIORequest_t             *tiIORequest,
20307                             tiDeviceHandle_t          *tiDeviceHandle,
20308                             tiScsiInitiatorRequest_t *tiScsiRequest,
20309                             satIOContext_t            *satIOContext
20310                             )
20311 {
20312   bit32                     status;
20313   bit32                     agRequestType;
20314   agsaFisRegHostToDevice_t  *fis;
20315 #ifdef  TD_DEBUG_ENABLE
20316   tdIORequestBody_t         *tdIORequestBody;
20317   satInternalIo_t           *satIntIoContext;
20318 #endif
20319 
20320   fis           = satIOContext->pFis;
20321 
20322   TI_DBG2(("satResetDevice: start\n"));
20323 
20324 #ifdef  TD_DEBUG_ENABLE
20325   satIntIoContext = satIOContext->satIntIoContext;
20326   tdIORequestBody = satIntIoContext->satIntRequestBody;
20327 #endif
20328   TI_DBG5(("satResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20329   /* any fis should work */
20330   fis->h.fisType        = 0x27;                   /* Reg host to device */
20331   fis->h.c_pmPort       = 0;                      /* C Bit is not set */
20332   fis->h.command        = 0;                      /* any command */
20333   fis->h.features       = 0;                      /* FIS reserve */
20334   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
20335   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
20336   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
20337   fis->d.device         = 0;                      /* FIS LBA mode  */
20338   fis->d.lbaLowExp      = 0;
20339   fis->d.lbaMidExp      = 0;
20340   fis->d.lbaHighExp     = 0;
20341   fis->d.featuresExp    = 0;
20342   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
20343   fis->d.sectorCountExp = 0;
20344   fis->d.reserved4      = 0;
20345   fis->d.control        = 0x4;                    /* SRST bit is set  */
20346   fis->d.reserved5      = 0;
20347 
20348   agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
20349 
20350   satIOContext->satCompleteCB = &satResetDeviceCB;
20351 
20352   /*
20353    * Prepare SGL and send FIS to LL layer.
20354    */
20355   satIOContext->reqType = agRequestType;       /* Save it */
20356 
20357 #ifdef TD_INTERNAL_DEBUG
20358   tdhexdump("satResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20359 #ifdef  TD_DEBUG_ENABLE
20360   tdhexdump("satResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20361 #endif
20362 #endif
20363 
20364   status = sataLLIOStart( tiRoot,
20365                           tiIORequest,
20366                           tiDeviceHandle,
20367                           tiScsiRequest,
20368                           satIOContext);
20369 
20370   TI_DBG6(("satResetDevice: end status %d\n", status));
20371   return status;
20372 }
20373 
20374 /*****************************************************************************
20375 *! \brief  satResetDeviceCB
20376 *
20377 *   This routine is a callback function called from ossaSATACompleted().
20378 *   This CB routine deals with SRT completion. This function send DSRT
20379 *
20380 *  \param   agRoot:      Handles for this instance of SAS/SATA hardware
20381 *  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
20382 *  \param   agIOStatus:  Status of completed I/O.
20383 *  \param   agFirstDword:Pointer to the four bytes of FIS.
20384 *  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20385 *                        length.
20386 *  \param   agParam:     Additional info based on status.
20387 *  \param   ioContext:   Pointer to satIOContext_t.
20388 *
20389 *  \return: none
20390 *
20391 *****************************************************************************/
20392 GLOBAL void satResetDeviceCB(
20393                    agsaRoot_t        *agRoot,
20394                    agsaIORequest_t   *agIORequest,
20395                    bit32             agIOStatus,
20396                    agsaFisHeader_t   *agFirstDword,
20397                    bit32             agIOInfoLen,
20398                    agsaFrameHandle_t agFrameHandle,
20399                    void              *ioContext
20400                    )
20401 {
20402   /* callback for satResetDevice */
20403   tdsaRootOsData_t   *osData = (tdsaRootOsData_t *)agRoot->osData;
20404   tiRoot_t           *tiRoot = (tiRoot_t *)osData->tiRoot;
20405   tdsaRoot_t         *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
20406   tdsaContext_t      *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20407   tdIORequestBody_t  *tdIORequestBody;
20408   tdIORequestBody_t  *tdOrgIORequestBody;
20409   satIOContext_t     *satIOContext;
20410   satIOContext_t     *satOrgIOContext;
20411   satIOContext_t     *satNewIOContext;
20412   satInternalIo_t    *satIntIo;
20413   satInternalIo_t    *satNewIntIo = agNULL;
20414   satDeviceData_t    *satDevData;
20415   tiIORequest_t      *tiOrgIORequest;
20416 #ifdef  TD_DEBUG_ENABLE
20417   bit32                     ataStatus = 0;
20418   bit32                     ataError;
20419   agsaFisPioSetupHeader_t  *satPIOSetupHeader = agNULL;
20420 #endif
20421   bit32                     status;
20422 
20423   TI_DBG1(("satResetDeviceCB: start\n"));
20424   TI_DBG6(("satResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20425 
20426   tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
20427   satIOContext           = (satIOContext_t *) ioContext;
20428   satIntIo               = satIOContext->satIntIoContext;
20429   satDevData             = satIOContext->pSatDevData;
20430   if (satIntIo == agNULL)
20431   {
20432     TI_DBG6(("satResetDeviceCB: External, OS generated\n"));
20433     satOrgIOContext      = satIOContext;
20434     tiOrgIORequest       = tdIORequestBody->tiIORequest;
20435   }
20436   else
20437   {
20438     TI_DBG6(("satResetDeviceCB: Internal, TD generated\n"));
20439     satOrgIOContext        = satIOContext->satOrgIOContext;
20440     if (satOrgIOContext == agNULL)
20441     {
20442       TI_DBG6(("satResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20443       return;
20444     }
20445     else
20446     {
20447       TI_DBG6(("satResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20448     }
20449     tdOrgIORequestBody    = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20450     tiOrgIORequest        = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20451   }
20452 
20453   tdIORequestBody->ioCompleted = agTRUE;
20454   tdIORequestBody->ioStarted = agFALSE;
20455 
20456   if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20457   {
20458     TI_DBG1(("satResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20459     if (satOrgIOContext->NotifyOS == agTRUE)
20460     {
20461       ostiInitiatorEvent( tiRoot,
20462                           NULL,
20463                           NULL,
20464                           tiIntrEventTypeTaskManagement,
20465                           tiTMFailed,
20466                           tiOrgIORequest );
20467     }
20468 
20469     satDevData->satTmTaskTag = agNULL;
20470 
20471     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20472 
20473     satFreeIntIoResource( tiRoot,
20474                           satDevData,
20475                           satIntIo);
20476     return;
20477   }
20478 
20479   if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20480       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20481       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20482       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20483       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20484       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20485       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20486       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20487       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20488       )
20489   {
20490     TI_DBG1(("satResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20491 
20492     if (satOrgIOContext->NotifyOS == agTRUE)
20493     {
20494       ostiInitiatorEvent( tiRoot,
20495                           NULL,
20496                           NULL,
20497                           tiIntrEventTypeTaskManagement,
20498                           tiTMFailed,
20499                           tiOrgIORequest );
20500     }
20501 
20502     satDevData->satTmTaskTag = agNULL;
20503 
20504     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20505 
20506     satFreeIntIoResource( tiRoot,
20507                          satDevData,
20508                          satIntIo);
20509     return;
20510   }
20511 
20512  if (agIOStatus != OSSA_IO_SUCCESS)
20513   {
20514 #ifdef  TD_DEBUG_ENABLE
20515     /* only agsaFisPioSetup_t is expected */
20516     satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20517     ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
20518     ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
20519 #endif
20520     TI_DBG1(("satResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20521 
20522      if (satOrgIOContext->NotifyOS == agTRUE)
20523      {
20524       ostiInitiatorEvent( tiRoot,
20525                           NULL,
20526                           NULL,
20527                           tiIntrEventTypeTaskManagement,
20528                           tiTMFailed,
20529                           tiOrgIORequest );
20530      }
20531 
20532     satDevData->satTmTaskTag = agNULL;
20533 
20534     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20535 
20536     satFreeIntIoResource( tiRoot,
20537                           satDevData,
20538                           satIntIo);
20539     return;
20540   }
20541 
20542   /* success */
20543 
20544   satNewIntIo = satAllocIntIoResource( tiRoot,
20545                                        tiOrgIORequest,
20546                                        satDevData,
20547                                        0,
20548                                        satNewIntIo);
20549   if (satNewIntIo == agNULL)
20550   {
20551     satDevData->satTmTaskTag = agNULL;
20552 
20553     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20554 
20555     /* memory allocation failure */
20556     satFreeIntIoResource( tiRoot,
20557                           satDevData,
20558                           satNewIntIo);
20559 
20560     if (satOrgIOContext->NotifyOS == agTRUE)
20561     {
20562       ostiInitiatorEvent( tiRoot,
20563                           NULL,
20564                           NULL,
20565                           tiIntrEventTypeTaskManagement,
20566                           tiTMFailed,
20567                           tiOrgIORequest );
20568     }
20569 
20570 
20571       TI_DBG1(("satResetDeviceCB: momory allocation fails\n"));
20572       return;
20573     } /* end of memory allocation failure */
20574 
20575     /*
20576      * Need to initialize all the fields within satIOContext
20577      */
20578 
20579     satNewIOContext = satPrepareNewIO(
20580                                       satNewIntIo,
20581                                       tiOrgIORequest,
20582                                       satDevData,
20583                                       agNULL,
20584                                       satOrgIOContext
20585                                       );
20586 
20587 
20588 
20589 
20590     /* send AGSA_SATA_PROTOCOL_SRST_DEASSERT */
20591     status = satDeResetDevice(tiRoot,
20592                               tiOrgIORequest,
20593                               satOrgIOContext->ptiDeviceHandle,
20594                               agNULL,
20595                               satNewIOContext
20596                               );
20597 
20598     if (status != tiSuccess)
20599     {
20600       if (satOrgIOContext->NotifyOS == agTRUE)
20601       {
20602         ostiInitiatorEvent( tiRoot,
20603                             NULL,
20604                             NULL,
20605                             tiIntrEventTypeTaskManagement,
20606                             tiTMFailed,
20607                             tiOrgIORequest );
20608       }
20609 
20610       /* sending AGSA_SATA_PROTOCOL_SRST_DEASSERT fails */
20611 
20612       satDevData->satTmTaskTag = agNULL;
20613 
20614       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20615 
20616       satFreeIntIoResource( tiRoot,
20617                           satDevData,
20618                           satNewIntIo);
20619       return;
20620 
20621     }
20622 
20623   satDevData->satTmTaskTag = agNULL;
20624 
20625   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20626 
20627   satFreeIntIoResource( tiRoot,
20628                         satDevData,
20629                         satIntIo);
20630   TI_DBG5(("satResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20631   TI_DBG6(("satResetDeviceCB: end\n"));
20632   return;
20633 
20634 }
20635 
20636 
20637 /*****************************************************************************/
20638 /*! \brief SAT implementation for satDeResetDevice.
20639  *
20640  *  SAT implementation for building DSRT FIS and sends the request to LL layer.
20641  *
20642  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20643  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20644  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20645  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20646  *  \param   satIOContext_t:   Pointer to the SAT IO Context
20647  *
20648  *  \return If command is started successfully
20649  *    - \e tiSuccess:     I/O request successfully initiated.
20650  *    - \e tiBusy:        No resources available, try again later.
20651  *    - \e tiIONoDevice:  Invalid device handle.
20652  *    - \e tiError:       Other errors.
20653  */
20654 /*****************************************************************************/
20655 GLOBAL bit32  satDeResetDevice(
20656                             tiRoot_t                  *tiRoot,
20657                             tiIORequest_t             *tiIORequest,
20658                             tiDeviceHandle_t          *tiDeviceHandle,
20659                             tiScsiInitiatorRequest_t *tiScsiRequest,
20660                             satIOContext_t            *satIOContext
20661                             )
20662 {
20663   bit32                     status;
20664   bit32                     agRequestType;
20665   agsaFisRegHostToDevice_t  *fis;
20666 #ifdef  TD_DEBUG_ENABLE
20667   tdIORequestBody_t         *tdIORequestBody;
20668   satInternalIo_t           *satIntIoContext;
20669 #endif
20670   fis           = satIOContext->pFis;
20671 
20672   TI_DBG6(("satDeResetDevice: start\n"));
20673 
20674 #ifdef  TD_DEBUG_ENABLE
20675   satIntIoContext = satIOContext->satIntIoContext;
20676   tdIORequestBody = satIntIoContext->satIntRequestBody;
20677   TI_DBG5(("satDeResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20678 #endif
20679   /* any fis should work */
20680   fis->h.fisType        = 0x27;                   /* Reg host to device */
20681   fis->h.c_pmPort       = 0;                      /* C Bit is not set */
20682   fis->h.command        = 0;                      /* any command */
20683   fis->h.features       = 0;                      /* FIS reserve */
20684   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
20685   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
20686   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
20687   fis->d.device         = 0;                      /* FIS LBA mode  */
20688   fis->d.lbaLowExp      = 0;
20689   fis->d.lbaMidExp      = 0;
20690   fis->d.lbaHighExp     = 0;
20691   fis->d.featuresExp    = 0;
20692   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
20693   fis->d.sectorCountExp = 0;
20694   fis->d.reserved4      = 0;
20695   fis->d.control        = 0;                    /* SRST bit is not set  */
20696   fis->d.reserved5      = 0;
20697 
20698   agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT;
20699 
20700   satIOContext->satCompleteCB = &satDeResetDeviceCB;
20701 
20702   /*
20703    * Prepare SGL and send FIS to LL layer.
20704    */
20705   satIOContext->reqType = agRequestType;       /* Save it */
20706 
20707 #ifdef TD_INTERNAL_DEBUG
20708   tdhexdump("satDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20709 #ifdef  TD_DEBUG_ENABLE
20710   tdhexdump("satDeResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20711 #endif
20712 #endif
20713 
20714   status = sataLLIOStart( tiRoot,
20715                           tiIORequest,
20716                           tiDeviceHandle,
20717                           tiScsiRequest,
20718                           satIOContext);
20719 
20720   TI_DBG6(("satDeResetDevice: end status %d\n", status));
20721   return status;
20722 
20723 }
20724 
20725 /*****************************************************************************
20726 *! \brief  satDeResetDeviceCB
20727 *
20728 *   This routine is a callback function called from ossaSATACompleted().
20729 *   This CB routine deals with DSRT completion.
20730 *
20731 *  \param   agRoot:      Handles for this instance of SAS/SATA hardware
20732 *  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
20733 *  \param   agIOStatus:  Status of completed I/O.
20734 *  \param   agFirstDword:Pointer to the four bytes of FIS.
20735 *  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20736 *                        length.
20737 *  \param   agParam:     Additional info based on status.
20738 *  \param   ioContext:   Pointer to satIOContext_t.
20739 *
20740 *  \return: none
20741 *
20742 *****************************************************************************/
20743 GLOBAL void satDeResetDeviceCB(
20744                    agsaRoot_t        *agRoot,
20745                    agsaIORequest_t   *agIORequest,
20746                    bit32             agIOStatus,
20747                    agsaFisHeader_t   *agFirstDword,
20748                    bit32             agIOInfoLen,
20749                    agsaFrameHandle_t agFrameHandle,
20750                    void              *ioContext
20751                    )
20752 {
20753   /* callback for satDeResetDevice */
20754   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
20755   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
20756   tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
20757   tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20758   tdIORequestBody_t       *tdIORequestBody;
20759   tdIORequestBody_t       *tdOrgIORequestBody = agNULL;
20760   satIOContext_t          *satIOContext;
20761   satIOContext_t          *satOrgIOContext;
20762   satInternalIo_t         *satIntIo;
20763   satDeviceData_t         *satDevData;
20764   tiIORequest_t           *tiOrgIORequest;
20765 #ifdef  TD_DEBUG_ENABLE
20766   bit32                    ataStatus = 0;
20767   bit32                    ataError;
20768   agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
20769 #endif
20770   bit32                     report = agFALSE;
20771   bit32                     AbortTM = agFALSE;
20772 
20773   TI_DBG1(("satDeResetDeviceCB: start\n"));
20774   TI_DBG6(("satDeResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20775   tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
20776   satIOContext           = (satIOContext_t *) ioContext;
20777   satIntIo               = satIOContext->satIntIoContext;
20778   satDevData             = satIOContext->pSatDevData;
20779   if (satIntIo == agNULL)
20780   {
20781     TI_DBG6(("satDeResetDeviceCB: External, OS generated\n"));
20782     satOrgIOContext      = satIOContext;
20783     tiOrgIORequest       = tdIORequestBody->tiIORequest;
20784   }
20785   else
20786   {
20787     TI_DBG6(("satDeResetDeviceCB: Internal, TD generated\n"));
20788     satOrgIOContext        = satIOContext->satOrgIOContext;
20789     if (satOrgIOContext == agNULL)
20790     {
20791       TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20792       return;
20793     }
20794     else
20795     {
20796       TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20797     }
20798     tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20799     tiOrgIORequest         = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20800   }
20801 
20802   tdIORequestBody->ioCompleted = agTRUE;
20803   tdIORequestBody->ioStarted = agFALSE;
20804 
20805   if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20806   {
20807     TI_DBG1(("satDeResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20808     if (satOrgIOContext->NotifyOS == agTRUE)
20809     {
20810       ostiInitiatorEvent( tiRoot,
20811                           NULL,
20812                           NULL,
20813                           tiIntrEventTypeTaskManagement,
20814                           tiTMFailed,
20815                           tiOrgIORequest );
20816     }
20817 
20818     satDevData->satTmTaskTag = agNULL;
20819     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20820 
20821     satFreeIntIoResource( tiRoot,
20822                           satDevData,
20823                           satIntIo);
20824     return;
20825   }
20826 
20827   if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20828       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20829       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20830       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20831       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20832       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20833       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20834       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20835       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20836       )
20837   {
20838     TI_DBG1(("satDeResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20839 
20840     if (satOrgIOContext->NotifyOS == agTRUE)
20841     {
20842       ostiInitiatorEvent( tiRoot,
20843                           NULL,
20844                           NULL,
20845                           tiIntrEventTypeTaskManagement,
20846                           tiTMFailed,
20847                           tiOrgIORequest );
20848     }
20849 
20850     satDevData->satTmTaskTag = agNULL;
20851 
20852     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20853 
20854     satFreeIntIoResource( tiRoot,
20855                          satDevData,
20856                          satIntIo);
20857     return;
20858   }
20859 
20860  if (agIOStatus != OSSA_IO_SUCCESS)
20861   {
20862 #ifdef  TD_DEBUG_ENABLE
20863     /* only agsaFisPioSetup_t is expected */
20864     satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20865     ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
20866     ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
20867 #endif
20868     TI_DBG1(("satDeResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20869 
20870      if (satOrgIOContext->NotifyOS == agTRUE)
20871      {
20872       ostiInitiatorEvent( tiRoot,
20873                           NULL,
20874                           NULL,
20875                           tiIntrEventTypeTaskManagement,
20876                           tiTMFailed,
20877                           tiOrgIORequest );
20878      }
20879 
20880     satDevData->satTmTaskTag = agNULL;
20881 
20882     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20883 
20884     satFreeIntIoResource( tiRoot,
20885                           satDevData,
20886                           satIntIo);
20887     return;
20888   }
20889 
20890   /* success */
20891   TI_DBG1(("satDeResetDeviceCB: success \n"));
20892   TI_DBG1(("satDeResetDeviceCB: TMF %d\n", satOrgIOContext->TMF));
20893 
20894   if (satOrgIOContext->TMF == AG_ABORT_TASK)
20895   {
20896     AbortTM = agTRUE;
20897   }
20898 
20899   if (satOrgIOContext->NotifyOS == agTRUE)
20900   {
20901     report = agTRUE;
20902   }
20903 
20904   if (AbortTM == agTRUE)
20905   {
20906     TI_DBG1(("satDeResetDeviceCB: calling satAbort\n"));
20907     satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
20908   }
20909   satDevData->satTmTaskTag = agNULL;
20910 
20911   satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
20912 
20913   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20914 
20915   TI_DBG1(("satDeResetDeviceCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
20916   TI_DBG1(("satDeResetDeviceCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
20917 
20918   satFreeIntIoResource( tiRoot,
20919                         satDevData,
20920                         satIntIo);
20921 
20922   /* clean up TD layer's IORequestBody */
20923   if (tdOrgIORequestBody != agNULL)
20924   {
20925     ostiFreeMemory(
20926                    tiRoot,
20927                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
20928                    sizeof(tdIORequestBody_t)
20929                    );
20930   }
20931   else
20932   {
20933     TI_DBG1(("satDeResetDeviceCB: tdOrgIORequestBody is NULL, wrong\n"));
20934   }
20935 
20936 
20937   if (report)
20938   {
20939     ostiInitiatorEvent( tiRoot,
20940                         NULL,
20941                         NULL,
20942                         tiIntrEventTypeTaskManagement,
20943                         tiTMOK,
20944                         tiOrgIORequest );
20945   }
20946 
20947 
20948   TI_DBG5(("satDeResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20949   TI_DBG6(("satDeResetDeviceCB: end\n"));
20950   return;
20951 
20952 }
20953 
20954 /*****************************************************************************/
20955 /*! \brief SAT implementation for satStartCheckPowerMode.
20956  *
20957  *  SAT implementation for abort task management for non-ncq sata disk.
20958  *  This function sends CHECK POWER MODE
20959  *
20960  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20961  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20962  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20963  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20964  *  \param   satIOContext_t:   Pointer to the SAT IO Context
20965  *
20966  *  \return If command is started successfully
20967  *    - \e tiSuccess:     I/O request successfully initiated.
20968  *    - \e tiBusy:        No resources available, try again later.
20969  *    - \e tiIONoDevice:  Invalid device handle.
20970  *    - \e tiError:       Other errors.
20971  */
20972 /*****************************************************************************/
20973 GLOBAL bit32  satStartCheckPowerMode(
20974                             tiRoot_t                  *tiRoot,
20975                             tiIORequest_t             *tiIORequest,
20976                             tiDeviceHandle_t          *tiDeviceHandle,
20977                             tiScsiInitiatorRequest_t  *tiScsiRequest, /* NULL */
20978                             satIOContext_t            *satIOContext
20979                             )
20980 {
20981   satInternalIo_t           *satIntIo = agNULL;
20982   satDeviceData_t           *satDevData = agNULL;
20983   satIOContext_t            *satNewIOContext;
20984   bit32                     status;
20985   tiIORequest_t             *currentTaskTag = agNULL;
20986 
20987   TI_DBG6(("satStartCheckPowerMode: start\n"));
20988 
20989   currentTaskTag = tiIORequest;
20990 
20991   satDevData = satIOContext->pSatDevData;
20992 
20993   TI_DBG6(("satStartCheckPowerMode: before alloc\n"));
20994 
20995   /* allocate any fis for seting SRT bit in device control */
20996   satIntIo = satAllocIntIoResource( tiRoot,
20997                                     tiIORequest,
20998                                     satDevData,
20999                                     0,
21000                                     satIntIo);
21001 
21002   TI_DBG6(("satStartCheckPowerMode: before after\n"));
21003 
21004   if (satIntIo == agNULL)
21005   {
21006     TI_DBG1(("satStartCheckPowerMode: can't alloacate\n"));
21007     if (satIOContext->NotifyOS)
21008     {
21009       ostiInitiatorEvent( tiRoot,
21010                           NULL,
21011                           NULL,
21012                           tiIntrEventTypeTaskManagement,
21013                           tiTMFailed,
21014                           currentTaskTag );
21015     }
21016     return tiError;
21017   }
21018 
21019   satNewIOContext = satPrepareNewIO(satIntIo,
21020                                     tiIORequest,
21021                                     satDevData,
21022                                     agNULL,
21023                                     satIOContext);
21024 
21025   TI_DBG6(("satStartCheckPowerMode: OS satIOContext %p \n", satIOContext));
21026   TI_DBG6(("satStartCheckPowerMode: TD satNewIOContext %p \n", satNewIOContext));
21027   TI_DBG6(("satStartCheckPowerMode: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21028   TI_DBG6(("satStartCheckPowerMode: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21029 
21030 
21031 
21032   TI_DBG1(("satStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
21033 
21034   status = satCheckPowerMode(tiRoot,
21035                              &satIntIo->satIntTiIORequest, /* New tiIORequest */
21036                              tiDeviceHandle,
21037                              satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21038                              satNewIOContext);
21039 
21040   if (status != tiSuccess)
21041   {
21042     TI_DBG1(("satStartCheckPowerMode: failed in sending\n"));
21043 
21044     satFreeIntIoResource( tiRoot,
21045                           satDevData,
21046                           satIntIo);
21047     if (satIOContext->NotifyOS)
21048     {
21049       ostiInitiatorEvent( tiRoot,
21050                           NULL,
21051                           NULL,
21052                           tiIntrEventTypeTaskManagement,
21053                           tiTMFailed,
21054                           currentTaskTag );
21055     }
21056 
21057     return tiError;
21058   }
21059 
21060 
21061   TI_DBG6(("satStartCheckPowerMode: end\n"));
21062 
21063   return status;
21064 }
21065 
21066 /*****************************************************************************/
21067 /*! \brief SAT implementation for satCheckPowerMode.
21068  *
21069  *  This function creates CHECK POWER MODE fis and sends the request to LL layer
21070  *
21071  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
21072  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
21073  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
21074  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
21075  *  \param   satIOContext_t:   Pointer to the SAT IO Context
21076  *
21077  *  \return If command is started successfully
21078  *    - \e tiSuccess:     I/O request successfully initiated.
21079  *    - \e tiBusy:        No resources available, try again later.
21080  *    - \e tiIONoDevice:  Invalid device handle.
21081  *    - \e tiError:       Other errors.
21082  */
21083 /*****************************************************************************/
21084 GLOBAL bit32  satCheckPowerMode(
21085                             tiRoot_t                  *tiRoot,
21086                             tiIORequest_t             *tiIORequest,
21087                             tiDeviceHandle_t          *tiDeviceHandle,
21088                             tiScsiInitiatorRequest_t *tiScsiRequest,
21089                             satIOContext_t            *satIOContext
21090                             )
21091 {
21092   /*
21093     sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands
21094     internally generated - no directly corresponding scsi
21095   */
21096   bit32                     status;
21097   bit32                     agRequestType;
21098   agsaFisRegHostToDevice_t  *fis;
21099 
21100   fis           = satIOContext->pFis;
21101   TI_DBG5(("satCheckPowerMode: start\n"));
21102   /*
21103    * Send the ATA CHECK POWER MODE command.
21104    */
21105   fis->h.fisType        = 0x27;                   /* Reg host to device */
21106   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
21107   fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
21108   fis->h.features       = 0;
21109   fis->d.lbaLow         = 0;
21110   fis->d.lbaMid         = 0;
21111   fis->d.lbaHigh        = 0;
21112   fis->d.device         = 0;
21113   fis->d.lbaLowExp      = 0;
21114   fis->d.lbaMidExp      = 0;
21115   fis->d.lbaHighExp     = 0;
21116   fis->d.featuresExp    = 0;
21117   fis->d.sectorCount    = 0;
21118   fis->d.sectorCountExp = 0;
21119   fis->d.reserved4      = 0;
21120   fis->d.control        = 0;                      /* FIS HOB bit clear */
21121   fis->d.reserved5      = 0;
21122 
21123   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
21124 
21125   /* Initialize CB for SATA completion.
21126    */
21127   satIOContext->satCompleteCB = &satCheckPowerModeCB;
21128 
21129   /*
21130    * Prepare SGL and send FIS to LL layer.
21131    */
21132   satIOContext->reqType = agRequestType;       /* Save it */
21133 
21134   status = sataLLIOStart( tiRoot,
21135                           tiIORequest,
21136                           tiDeviceHandle,
21137                           tiScsiRequest,
21138                           satIOContext);
21139 
21140   TI_DBG5(("satCheckPowerMode: return\n"));
21141 
21142   return status;
21143 }
21144 
21145 /*****************************************************************************
21146 *! \brief  satCheckPowerModeCB
21147 *
21148 *   This routine is a callback function called from ossaSATACompleted().
21149 *   This CB routine deals with CHECK POWER MODE completion as abort task
21150 *   management.
21151 *
21152 *  \param   agRoot:      Handles for this instance of SAS/SATA hardware
21153 *  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
21154 *  \param   agIOStatus:  Status of completed I/O.
21155 *  \param   agFirstDword:Pointer to the four bytes of FIS.
21156 *  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21157 *                        length.
21158 *  \param   agParam:     Additional info based on status.
21159 *  \param   ioContext:   Pointer to satIOContext_t.
21160 *
21161 *  \return: none
21162 *
21163 *****************************************************************************/
21164 GLOBAL void satCheckPowerModeCB(
21165                    agsaRoot_t        *agRoot,
21166                    agsaIORequest_t   *agIORequest,
21167                    bit32             agIOStatus,
21168                    agsaFisHeader_t   *agFirstDword,
21169                    bit32             agIOInfoLen,
21170                    agsaFrameHandle_t agFrameHandle,
21171                    void              *ioContext
21172                    )
21173 {
21174   /* callback for satDeResetDevice */
21175   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
21176   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
21177   tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
21178   tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21179   tdIORequestBody_t       *tdIORequestBody;
21180   tdIORequestBody_t       *tdOrgIORequestBody = agNULL;
21181   satIOContext_t          *satIOContext;
21182   satIOContext_t          *satOrgIOContext;
21183   satInternalIo_t         *satIntIo;
21184   satDeviceData_t         *satDevData;
21185 
21186   tiIORequest_t             *tiOrgIORequest;
21187 #ifdef  TD_DEBUG_ENABLE
21188   bit32                     ataStatus = 0;
21189   bit32                     ataError;
21190   agsaFisPioSetupHeader_t   *satPIOSetupHeader = agNULL;
21191 #endif
21192   bit32                     report = agFALSE;
21193   bit32                     AbortTM = agFALSE;
21194 
21195 
21196   TI_DBG1(("satCheckPowerModeCB: start\n"));
21197 
21198   TI_DBG1(("satCheckPowerModeCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21199 
21200   tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
21201   satIOContext           = (satIOContext_t *) ioContext;
21202   satIntIo               = satIOContext->satIntIoContext;
21203   satDevData             = satIOContext->pSatDevData;
21204   if (satIntIo == agNULL)
21205   {
21206     TI_DBG6(("satCheckPowerModeCB: External, OS generated\n"));
21207     satOrgIOContext      = satIOContext;
21208     tiOrgIORequest       = tdIORequestBody->tiIORequest;
21209   }
21210   else
21211   {
21212     TI_DBG6(("satCheckPowerModeCB: Internal, TD generated\n"));
21213     satOrgIOContext        = satIOContext->satOrgIOContext;
21214     if (satOrgIOContext == agNULL)
21215     {
21216       TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NULL, wrong\n"));
21217       return;
21218     }
21219     else
21220     {
21221       TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NOT NULL\n"));
21222     }
21223     tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21224     tiOrgIORequest         = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
21225   }
21226 
21227 
21228   tdIORequestBody->ioCompleted = agTRUE;
21229   tdIORequestBody->ioStarted = agFALSE;
21230 
21231   if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21232   {
21233     TI_DBG1(("satCheckPowerModeCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21234 
21235     if (satOrgIOContext->NotifyOS == agTRUE)
21236     {
21237       ostiInitiatorEvent( tiRoot,
21238                           NULL,
21239                           NULL,
21240                           tiIntrEventTypeTaskManagement,
21241                           tiTMFailed,
21242                           tiOrgIORequest );
21243     }
21244 
21245     satDevData->satTmTaskTag = agNULL;
21246 
21247     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21248 
21249     satFreeIntIoResource( tiRoot,
21250                           satDevData,
21251                           satIntIo);
21252     return;
21253   }
21254 
21255   if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21256       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21257       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21258       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21259       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21260       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21261       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21262       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21263       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21264       )
21265   {
21266     TI_DBG1(("satCheckPowerModeCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21267 
21268     if (satOrgIOContext->NotifyOS == agTRUE)
21269     {
21270       ostiInitiatorEvent( tiRoot,
21271                           NULL,
21272                           NULL,
21273                           tiIntrEventTypeTaskManagement,
21274                           tiTMFailed,
21275                           tiOrgIORequest );
21276     }
21277 
21278     satDevData->satTmTaskTag = agNULL;
21279 
21280     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21281 
21282     satFreeIntIoResource( tiRoot,
21283                          satDevData,
21284                          satIntIo);
21285     return;
21286   }
21287 
21288  if (agIOStatus != OSSA_IO_SUCCESS)
21289   {
21290 #ifdef  TD_DEBUG_ENABLE
21291     /* only agsaFisPioSetup_t is expected */
21292     satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
21293     ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
21294     ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
21295 #endif
21296     TI_DBG1(("satCheckPowerModeCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
21297 
21298      if (satOrgIOContext->NotifyOS == agTRUE)
21299      {
21300       ostiInitiatorEvent( tiRoot,
21301                           NULL,
21302                           NULL,
21303                           tiIntrEventTypeTaskManagement,
21304                           tiTMFailed,
21305                           tiOrgIORequest );
21306      }
21307 
21308     satDevData->satTmTaskTag = agNULL;
21309 
21310     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21311 
21312     satFreeIntIoResource( tiRoot,
21313                           satDevData,
21314                           satIntIo);
21315     return;
21316   }
21317 
21318   /* success */
21319   TI_DBG1(("satCheckPowerModeCB: success\n"));
21320   TI_DBG1(("satCheckPowerModeCB: TMF %d\n", satOrgIOContext->TMF));
21321 
21322   if (satOrgIOContext->TMF == AG_ABORT_TASK)
21323   {
21324     AbortTM = agTRUE;
21325   }
21326 
21327   if (satOrgIOContext->NotifyOS == agTRUE)
21328   {
21329     report = agTRUE;
21330   }
21331   if (AbortTM == agTRUE)
21332   {
21333     TI_DBG1(("satCheckPowerModeCB: calling satAbort\n"));
21334     satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
21335   }
21336   satDevData->satTmTaskTag = agNULL;
21337 
21338   satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
21339 
21340   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21341 
21342   TI_DBG1(("satCheckPowerModeCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
21343   TI_DBG1(("satCheckPowerModeCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
21344 
21345   satFreeIntIoResource( tiRoot,
21346                         satDevData,
21347                         satIntIo);
21348 
21349   /* clean up TD layer's IORequestBody */
21350   if (tdOrgIORequestBody != agNULL)
21351   {
21352     ostiFreeMemory(
21353                    tiRoot,
21354                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21355                    sizeof(tdIORequestBody_t)
21356                    );
21357   }
21358   else
21359   {
21360     TI_DBG1(("satCheckPowerModeCB: tdOrgIORequestBody is NULL, wrong\n"));
21361   }
21362   if (report)
21363   {
21364     ostiInitiatorEvent( tiRoot,
21365                         NULL,
21366                         NULL,
21367                         tiIntrEventTypeTaskManagement,
21368                         tiTMOK,
21369                         tiOrgIORequest );
21370   }
21371 
21372   TI_DBG5(("satCheckPowerModeCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
21373   TI_DBG2(("satCheckPowerModeCB: end\n"));
21374   return;
21375 
21376 }
21377 
21378 /*****************************************************************************/
21379 /*! \brief SAT implementation for satAddSATAStartIDDev.
21380  *
21381  *  This function sends identify device data to find out the uniqueness
21382  *  of device.
21383  *
21384  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
21385  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
21386  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
21387  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
21388  *  \param   satIOContext_t:   Pointer to the SAT IO Context
21389  *
21390  *  \return If command is started successfully
21391  *    - \e tiSuccess:     I/O request successfully initiated.
21392  *    - \e tiBusy:        No resources available, try again later.
21393  *    - \e tiIONoDevice:  Invalid device handle.
21394  *    - \e tiError:       Other errors.
21395  */
21396 /*****************************************************************************/
21397 GLOBAL bit32  satAddSATAStartIDDev(
21398                                tiRoot_t                  *tiRoot,
21399                                tiIORequest_t             *tiIORequest,
21400                                tiDeviceHandle_t          *tiDeviceHandle,
21401                                tiScsiInitiatorRequest_t  *tiScsiRequest, // NULL
21402                                satIOContext_t            *satIOContext
21403                             )
21404 {
21405   satInternalIo_t           *satIntIo = agNULL;
21406   satDeviceData_t           *satDevData = agNULL;
21407   tdIORequestBody_t         *tdIORequestBody;
21408   satIOContext_t            *satNewIOContext;
21409   bit32                     status;
21410 
21411   TI_DBG2(("satAddSATAStartIDDev: start\n"));
21412 
21413   satDevData = satIOContext->pSatDevData;
21414 
21415   TI_DBG2(("satAddSATAStartIDDev: before alloc\n"));
21416 
21417   /* allocate identify device command */
21418   satIntIo = satAllocIntIoResource( tiRoot,
21419                                     tiIORequest,
21420                                     satDevData,
21421                                     sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
21422                                     satIntIo);
21423 
21424   TI_DBG2(("satAddSATAStartIDDev: after alloc\n"));
21425 
21426   if (satIntIo == agNULL)
21427   {
21428     TI_DBG1(("satAddSATAStartIDDev: can't alloacate\n"));
21429 
21430     return tiError;
21431   }
21432 
21433   /* fill in fields */
21434   /* real ttttttthe one worked and the same; 5/21/07/ */
21435   satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
21436   tdIORequestBody = satIntIo->satIntRequestBody;
21437   satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
21438 
21439   satNewIOContext->pSatDevData   = satDevData;
21440   satNewIOContext->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
21441   satNewIOContext->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
21442   satNewIOContext->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
21443   satNewIOContext->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
21444   satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
21445   satNewIOContext->interruptContext = tiInterruptContext;
21446   satNewIOContext->satIntIoContext  = satIntIo;
21447 
21448   satNewIOContext->ptiDeviceHandle = agNULL;
21449   satNewIOContext->satOrgIOContext = satIOContext; /* changed */
21450 
21451   /* this is valid only for TD layer generated (not triggered by OS at all) IO */
21452   satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
21453 
21454 
21455   TI_DBG6(("satAddSATAStartIDDev: OS satIOContext %p \n", satIOContext));
21456   TI_DBG6(("satAddSATAStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
21457   TI_DBG6(("satAddSATAStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21458   TI_DBG6(("satAddSATAStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21459 
21460 
21461 
21462   TI_DBG2(("satAddSATAStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
21463 
21464   status = satAddSATASendIDDev( tiRoot,
21465                                 &satIntIo->satIntTiIORequest, /* New tiIORequest */
21466                                 tiDeviceHandle,
21467                                 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21468                                 satNewIOContext);
21469 
21470   if (status != tiSuccess)
21471   {
21472     TI_DBG1(("satAddSATAStartIDDev: failed in sending\n"));
21473 
21474     satFreeIntIoResource( tiRoot,
21475                           satDevData,
21476                           satIntIo);
21477 
21478     return tiError;
21479   }
21480 
21481 
21482   TI_DBG6(("satAddSATAStartIDDev: end\n"));
21483 
21484   return status;
21485 
21486 
21487 }
21488 
21489 /*****************************************************************************/
21490 /*! \brief SAT implementation for satAddSATASendIDDev.
21491  *
21492  *  This function creates identify device data fis and send it to LL
21493  *
21494  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
21495  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
21496  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
21497  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
21498  *  \param   satIOContext_t:   Pointer to the SAT IO Context
21499  *
21500  *  \return If command is started successfully
21501  *    - \e tiSuccess:     I/O request successfully initiated.
21502  *    - \e tiBusy:        No resources available, try again later.
21503  *    - \e tiIONoDevice:  Invalid device handle.
21504  *    - \e tiError:       Other errors.
21505  */
21506 /*****************************************************************************/
21507 GLOBAL bit32  satAddSATASendIDDev(
21508                            tiRoot_t                  *tiRoot,
21509                            tiIORequest_t             *tiIORequest,
21510                            tiDeviceHandle_t          *tiDeviceHandle,
21511                            tiScsiInitiatorRequest_t  *tiScsiRequest,
21512                            satIOContext_t            *satIOContext)
21513 {
21514   bit32                     status;
21515   bit32                     agRequestType;
21516   satDeviceData_t           *pSatDevData;
21517   agsaFisRegHostToDevice_t  *fis;
21518 #ifdef  TD_DEBUG_ENABLE
21519   tdIORequestBody_t         *tdIORequestBody;
21520   satInternalIo_t           *satIntIoContext;
21521 #endif
21522 
21523   pSatDevData   = satIOContext->pSatDevData;
21524   fis           = satIOContext->pFis;
21525   TI_DBG2(("satAddSATASendIDDev: start\n"));
21526 #ifdef  TD_DEBUG_ENABLE
21527   satIntIoContext = satIOContext->satIntIoContext;
21528   tdIORequestBody = satIntIoContext->satIntRequestBody;
21529 #endif
21530   TI_DBG5(("satAddSATASendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
21531 
21532   fis->h.fisType        = 0x27;                   /* Reg host to device */
21533   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
21534   if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
21535       fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
21536   else
21537       fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
21538   fis->h.features       = 0;                      /* FIS reserve */
21539   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
21540   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
21541   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
21542   fis->d.device         = 0;                      /* FIS LBA mode  */
21543   fis->d.lbaLowExp      = 0;
21544   fis->d.lbaMidExp      = 0;
21545   fis->d.lbaHighExp     = 0;
21546   fis->d.featuresExp    = 0;
21547   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
21548   fis->d.sectorCountExp = 0;
21549   fis->d.reserved4      = 0;
21550   fis->d.control        = 0;                      /* FIS HOB bit clear */
21551   fis->d.reserved5      = 0;
21552 
21553   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
21554 
21555   /* Initialize CB for SATA completion.
21556    */
21557   satIOContext->satCompleteCB = &satAddSATAIDDevCB;
21558 
21559   /*
21560    * Prepare SGL and send FIS to LL layer.
21561    */
21562   satIOContext->reqType = agRequestType;       /* Save it */
21563 
21564 #ifdef TD_INTERNAL_DEBUG
21565   tdhexdump("satAddSATASendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
21566 #ifdef  TD_DEBUG_ENABLE
21567   tdhexdump("satAddSATASendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
21568 #endif
21569 #endif
21570 
21571   status = sataLLIOStart( tiRoot,
21572                           tiIORequest,
21573                           tiDeviceHandle,
21574                           tiScsiRequest,
21575                           satIOContext);
21576 
21577   TI_DBG2(("satAddSATASendIDDev: end status %d\n", status));
21578   return status;
21579 }
21580 
21581 /*****************************************************************************
21582 *! \brief  satAddSATAIDDevCB
21583 *
21584 *   This routine is a callback function for satAddSATASendIDDev()
21585 *   Using Identify Device Data, this function finds whether devicedata is
21586 *   new or old. If new, add it to the devicelist.
21587 *
21588 *  \param   agRoot:      Handles for this instance of SAS/SATA hardware
21589 *  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
21590 *  \param   agIOStatus:  Status of completed I/O.
21591 *  \param   agFirstDword:Pointer to the four bytes of FIS.
21592 *  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21593 *                        length.
21594 *  \param   agParam:     Additional info based on status.
21595 *  \param   ioContext:   Pointer to satIOContext_t.
21596 *
21597 *  \return: none
21598 *
21599 *****************************************************************************/
21600 void satAddSATAIDDevCB(
21601                    agsaRoot_t        *agRoot,
21602                    agsaIORequest_t   *agIORequest,
21603                    bit32             agIOStatus,
21604                    agsaFisHeader_t   *agFirstDword,
21605                    bit32             agIOInfoLen,
21606                    void              *agParam,
21607                    void              *ioContext
21608                    )
21609 {
21610 
21611   /*
21612     In the process of Inquiry
21613     Process SAT_IDENTIFY_DEVICE
21614   */
21615   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
21616   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
21617   tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
21618   tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21619   tdIORequestBody_t       *tdIORequestBody;
21620   tdIORequestBody_t       *tdOrgIORequestBody;
21621   satIOContext_t          *satIOContext;
21622   satIOContext_t          *satOrgIOContext;
21623   satIOContext_t          *satNewIOContext;
21624   satInternalIo_t         *satIntIo;
21625   satInternalIo_t         *satNewIntIo = agNULL;
21626   satDeviceData_t         *satDevData;
21627   tiIORequest_t           *tiOrgIORequest = agNULL;
21628   agsaSATAIdentifyData_t    *pSATAIdData;
21629   bit16                     *tmpptr, tmpptr_tmp;
21630   bit32                     x;
21631   tdsaDeviceData_t          *NewOneDeviceData = agNULL;
21632   tdsaDeviceData_t          *oneDeviceData = agNULL;
21633   tdList_t                  *DeviceListList;
21634   int                       new_device = agTRUE;
21635   bit8                      PhyID;
21636   void                      *sglVirtualAddr;
21637   bit32                     retry_status;
21638   agsaContext_t             *agContext;
21639   tdsaPortContext_t         *onePortContext;
21640   bit32                     status = 0;
21641 
21642   TI_DBG2(("satAddSATAIDDevCB: start\n"));
21643   TI_DBG6(("satAddSATAIDDevCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21644   tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
21645   satIOContext           = (satIOContext_t *) ioContext;
21646   satIntIo               = satIOContext->satIntIoContext;
21647   satDevData             = satIOContext->pSatDevData;
21648 
21649   NewOneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
21650   TI_DBG2(("satAddSATAIDDevCB: NewOneDeviceData %p did %d\n", NewOneDeviceData, NewOneDeviceData->id));
21651   PhyID = NewOneDeviceData->phyID;
21652   TI_DBG2(("satAddSATAIDDevCB: phyID %d\n", PhyID));
21653   agContext = &(NewOneDeviceData->agDeviceResetContext);
21654   agContext->osData = agNULL;
21655   if (satIntIo == agNULL)
21656   {
21657     TI_DBG1(("satAddSATAIDDevCB: External, OS generated\n"));
21658     TI_DBG1(("satAddSATAIDDevCB: Not possible case\n"));
21659     satOrgIOContext      = satIOContext;
21660     tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21661     tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21662 
21663     /* put onedevicedata back to free list */
21664     osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21665     TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21666     TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21667 
21668     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21669 
21670     satFreeIntIoResource( tiRoot,
21671                           satDevData,
21672                           satIntIo);
21673     /* clean up TD layer's IORequestBody */
21674     ostiFreeMemory(
21675                    tiRoot,
21676                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21677                    sizeof(tdIORequestBody_t)
21678                    );
21679 
21680     /* notifying link up */
21681     ostiPortEvent (
21682                    tiRoot,
21683                    tiPortLinkUp,
21684                    tiSuccess,
21685                    (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
21686                    );
21687 #ifdef INITIATOR_DRIVER
21688     /* triggers discovery */
21689     ostiPortEvent(
21690                   tiRoot,
21691                   tiPortDiscoveryReady,
21692                   tiSuccess,
21693                   (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
21694                   );
21695 #endif
21696     return;
21697   }
21698   else
21699   {
21700     TI_DBG1(("satAddSATAIDDevCB: Internal, TD generated\n"));
21701     satOrgIOContext        = satIOContext->satOrgIOContext;
21702     if (satOrgIOContext == agNULL)
21703     {
21704       TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NULL\n"));
21705       return;
21706     }
21707     else
21708     {
21709       TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NOT NULL\n"));
21710       tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21711       sglVirtualAddr         = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
21712     }
21713   }
21714   tiOrgIORequest           = tdIORequestBody->tiIORequest;
21715 
21716   tdIORequestBody->ioCompleted = agTRUE;
21717   tdIORequestBody->ioStarted = agFALSE;
21718   TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21719   /* protect against double completion for old port */
21720   if (satOrgIOContext->pid != tdsaAllShared->Ports[PhyID].portContext->id)
21721   {
21722     TI_DBG2(("satAddSATAIDDevCB: incorrect pid\n"));
21723     TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21724     TI_DBG2(("satAddSATAIDDevCB: tiPortalContext pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
21725     tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21726     /* put onedevicedata back to free list */
21727     osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21728     TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21729     TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21730     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21731 
21732     satFreeIntIoResource( tiRoot,
21733                           satDevData,
21734                           satIntIo);
21735     /* clean up TD layer's IORequestBody */
21736     ostiFreeMemory(
21737                    tiRoot,
21738                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21739                    sizeof(tdIORequestBody_t)
21740                    );
21741     /* no notification to OS layer */
21742     return;
21743   }
21744   /* completion after portcontext is invalidated */
21745   onePortContext = NewOneDeviceData->tdPortContext;
21746   if (onePortContext != agNULL)
21747   {
21748     if (onePortContext->valid == agFALSE)
21749     {
21750       TI_DBG1(("satAddSATAIDDevCB: portcontext is invalid\n"));
21751       TI_DBG1(("satAddSATAIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
21752       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21753 
21754       satFreeIntIoResource( tiRoot,
21755                             satDevData,
21756                             satIntIo);
21757       /* clean up TD layer's IORequestBody */
21758       ostiFreeMemory(
21759                      tiRoot,
21760                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21761                      sizeof(tdIORequestBody_t)
21762                      );
21763       /* no notification to OS layer */
21764       return;
21765     }
21766   }
21767   else
21768   {
21769     TI_DBG1(("satAddSATAIDDevCB: onePortContext is NULL!!!\n"));
21770     return;
21771   }
21772   if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21773   {
21774     TI_DBG1(("satAddSATAIDDevCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21775     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21776     {
21777       satDevData->satPendingNONNCQIO--;
21778       satDevData->satPendingIO--;
21779       retry_status = sataLLIOStart(tiRoot,
21780                                    &satIntIo->satIntTiIORequest,
21781                                    &(NewOneDeviceData->tiDeviceHandle),
21782                                    satIOContext->tiScsiXchg,
21783                                    satIOContext);
21784       if (retry_status != tiSuccess)
21785       {
21786         /* simply give up */
21787         satDevData->ID_Retries = 0;
21788         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21789         return;
21790       }
21791       satDevData->ID_Retries++;
21792       tdIORequestBody->ioCompleted = agFALSE;
21793       tdIORequestBody->ioStarted = agTRUE;
21794       return;
21795     }
21796     else
21797     {
21798       if (tdsaAllShared->ResetInDiscovery == 0)
21799       {
21800         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21801       }
21802       else /* ResetInDiscovery in on */
21803       {
21804         /* RESET only one after ID retries */
21805         if (satDevData->NumOfIDRetries <= 0)
21806         {
21807           satDevData->NumOfIDRetries++;
21808           satDevData->ID_Retries = 0;
21809           satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21810           /* send link reset */
21811           saLocalPhyControl(agRoot,
21812                             agContext,
21813                             tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21814                             PhyID,
21815                             AGSA_PHY_HARD_RESET,
21816                             agNULL);
21817         }
21818         else
21819         {
21820           satDevData->ID_Retries = 0;
21821           satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21822         }
21823       }
21824       return;
21825     }
21826   }
21827   if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21828       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21829       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21830       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21831       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21832       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21833       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21834       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21835       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21836       )
21837   {
21838     TI_DBG1(("satAddSATAIDDevCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21839     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21840     {
21841       satDevData->satPendingNONNCQIO--;
21842       satDevData->satPendingIO--;
21843       retry_status = sataLLIOStart(tiRoot,
21844                                    &satIntIo->satIntTiIORequest,
21845                                    &(NewOneDeviceData->tiDeviceHandle),
21846                                    satIOContext->tiScsiXchg,
21847                                    satIOContext);
21848       if (retry_status != tiSuccess)
21849       {
21850         /* simply give up */
21851         satDevData->ID_Retries = 0;
21852         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21853         return;
21854       }
21855       satDevData->ID_Retries++;
21856       tdIORequestBody->ioCompleted = agFALSE;
21857       tdIORequestBody->ioStarted = agTRUE;
21858       return;
21859     }
21860     else
21861     {
21862       if (tdsaAllShared->ResetInDiscovery == 0)
21863       {
21864         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21865       }
21866       else /* ResetInDiscovery in on */
21867       {
21868         /* RESET only one after ID retries */
21869         if (satDevData->NumOfIDRetries <= 0)
21870         {
21871           satDevData->NumOfIDRetries++;
21872           satDevData->ID_Retries = 0;
21873           satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21874           /* send link reset */
21875           saLocalPhyControl(agRoot,
21876                             agContext,
21877                             tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21878                             PhyID,
21879                             AGSA_PHY_HARD_RESET,
21880                             agNULL);
21881         }
21882         else
21883         {
21884           satDevData->ID_Retries = 0;
21885           satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21886         }
21887       }
21888       return;
21889     }
21890   }
21891 
21892   if ( agIOStatus != OSSA_IO_SUCCESS ||
21893       (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
21894     )
21895   {
21896     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21897     {
21898       satIOContext->pSatDevData->satPendingNONNCQIO--;
21899       satIOContext->pSatDevData->satPendingIO--;
21900       retry_status = sataLLIOStart(tiRoot,
21901                                    &satIntIo->satIntTiIORequest,
21902                                    &(NewOneDeviceData->tiDeviceHandle),
21903                                    satIOContext->tiScsiXchg,
21904                                    satIOContext);
21905       if (retry_status != tiSuccess)
21906       {
21907         /* simply give up */
21908         satDevData->ID_Retries = 0;
21909         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21910         return;
21911       }
21912       satDevData->ID_Retries++;
21913       tdIORequestBody->ioCompleted = agFALSE;
21914       tdIORequestBody->ioStarted = agTRUE;
21915       return;
21916     }
21917     else
21918     {
21919       if (tdsaAllShared->ResetInDiscovery == 0)
21920       {
21921         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21922       }
21923       else /* ResetInDiscovery in on */
21924       {
21925         /* RESET only one after ID retries */
21926         if (satDevData->NumOfIDRetries <= 0)
21927         {
21928           satDevData->NumOfIDRetries++;
21929           satDevData->ID_Retries = 0;
21930           satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21931           /* send link reset */
21932           saLocalPhyControl(agRoot,
21933                             agContext,
21934                             tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21935                             PhyID,
21936                             AGSA_PHY_HARD_RESET,
21937                             agNULL);
21938         }
21939         else
21940         {
21941           satDevData->ID_Retries = 0;
21942           satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21943         }
21944       }
21945       return;
21946     }
21947   }
21948 
21949   /* success */
21950   TI_DBG2(("satAddSATAIDDevCB: Success\n"));
21951   /* Convert to host endian */
21952   tmpptr = (bit16*)sglVirtualAddr;
21953   //tdhexdump("satAddSATAIDDevCB before", (bit8 *)sglVirtualAddr, sizeof(agsaSATAIdentifyData_t));
21954   for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
21955   {
21956    OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
21957    *tmpptr = tmpptr_tmp;
21958    tmpptr++;
21959     /*Print tmpptr_tmp here for debugging purpose*/
21960   }
21961 
21962   pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
21963   //tdhexdump("satAddSATAIDDevCB after", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
21964 
21965   TI_DBG5(("satAddSATAIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
21966   TI_DBG5(("satAddSATAIDDevCB: TD satIOContext %p \n", satIOContext));
21967   TI_DBG5(("satAddSATAIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
21968   TI_DBG5(("satAddSATAIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21969 
21970 
21971   /* compare idenitfy device data to the exiting list */
21972   DeviceListList = tdsaAllShared->MainDeviceList.flink;
21973   while (DeviceListList != &(tdsaAllShared->MainDeviceList))
21974   {
21975     oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
21976     TI_DBG1(("satAddSATAIDDevCB: LOOP oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
21977     //tdhexdump("satAddSATAIDDevCB LOOP", (bit8 *)&oneDeviceData->satDevData.satIdentifyData, sizeof(agsaSATAIdentifyData_t));
21978 
21979     /* what is unique ID for sata device -> response of identify devicedata; not really
21980        Let's compare serial number, firmware version, model number
21981     */
21982     if ( oneDeviceData->DeviceType == TD_SATA_DEVICE &&
21983          (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.serialNumber,
21984                        pSATAIdData->serialNumber,
21985                        20) == 0) &&
21986          (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.firmwareVersion,
21987                        pSATAIdData->firmwareVersion,
21988                        8) == 0) &&
21989          (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.modelNumber,
21990                        pSATAIdData->modelNumber,
21991                        40) == 0)
21992        )
21993     {
21994       TI_DBG2(("satAddSATAIDDevCB: did %d\n", oneDeviceData->id));
21995       new_device = agFALSE;
21996       break;
21997     }
21998     DeviceListList = DeviceListList->flink;
21999   }
22000 
22001   if (new_device == agFALSE)
22002   {
22003     TI_DBG2(("satAddSATAIDDevCB: old device data\n"));
22004     oneDeviceData->valid = agTRUE;
22005     oneDeviceData->valid2 = agTRUE;
22006     /* save data field from new device data */
22007     oneDeviceData->agRoot = agRoot;
22008     oneDeviceData->agDevHandle = NewOneDeviceData->agDevHandle;
22009     oneDeviceData->agDevHandle->osData = oneDeviceData; /* TD layer */
22010     oneDeviceData->tdPortContext = NewOneDeviceData->tdPortContext;
22011     oneDeviceData->phyID = NewOneDeviceData->phyID;
22012 
22013     /*
22014       one SATA directly attached device per phy;
22015       Therefore, deregister then register
22016     */
22017     saDeregisterDeviceHandle(agRoot, agNULL, NewOneDeviceData->agDevHandle, 0);
22018 
22019     if (oneDeviceData->registered == agFALSE)
22020     {
22021       TI_DBG2(("satAddSATAIDDevCB: re-registering old device data\n"));
22022       /* already has old information; just register it again */
22023       saRegisterNewDevice( /* satAddSATAIDDevCB */
22024                           agRoot,
22025                           &oneDeviceData->agContext,
22026                           tdsaRotateQnumber(tiRoot, oneDeviceData),
22027                           &oneDeviceData->agDeviceInfo,
22028                           oneDeviceData->tdPortContext->agPortContext,
22029                           0
22030                           );
22031     }
22032 
22033 //    tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
22034     /* put onedevicedata back to free list */
22035     osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22036     TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
22037     TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22038     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22039 
22040     satFreeIntIoResource( tiRoot,
22041                           satDevData,
22042                           satIntIo);
22043 
22044     if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22045     {
22046       /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22047       satNewIntIo = satAllocIntIoResource( tiRoot,
22048                                        tiOrgIORequest,
22049                                        satDevData,
22050                                        0,
22051                                        satNewIntIo);
22052 
22053       if (satNewIntIo == agNULL)
22054       {
22055         TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22056           /* clean up TD layer's IORequestBody */
22057         ostiFreeMemory(
22058                      tiRoot,
22059                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22060                      sizeof(tdIORequestBody_t)
22061                      );
22062         return;
22063       } /* end memory allocation */
22064 
22065       satNewIOContext = satPrepareNewIO(satNewIntIo,
22066                                         tiOrgIORequest,
22067                                         satDevData,
22068                                         agNULL,
22069                                         satOrgIOContext
22070                                         );
22071       /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22072       status = satSetFeatures(tiRoot,
22073                      &satNewIntIo->satIntTiIORequest,
22074                      satNewIOContext->ptiDeviceHandle,
22075                      &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22076                      satNewIOContext,
22077                      agFALSE);
22078       if (status != tiSuccess)
22079       {
22080            satFreeIntIoResource( tiRoot,
22081                         satDevData,
22082                         satIntIo);
22083            /* clean up TD layer's IORequestBody */
22084            ostiFreeMemory(
22085                      tiRoot,
22086                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22087                      sizeof(tdIORequestBody_t)
22088                      );
22089       }
22090     }
22091     else
22092     {
22093       /* clean up TD layer's IORequestBody */
22094       ostiFreeMemory(
22095                    tiRoot,
22096                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22097                    sizeof(tdIORequestBody_t)
22098                    );
22099       TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22100       /* notifying link up */
22101       ostiPortEvent(
22102                    tiRoot,
22103                    tiPortLinkUp,
22104                    tiSuccess,
22105                    (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22106                    );
22107 
22108 
22109     #ifdef INITIATOR_DRIVER
22110         /* triggers discovery */
22111         ostiPortEvent(
22112                   tiRoot,
22113                   tiPortDiscoveryReady,
22114                   tiSuccess,
22115                   (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22116                   );
22117     #endif
22118     }
22119     return;
22120   }
22121 
22122   TI_DBG2(("satAddSATAIDDevCB: new device data\n"));
22123   /* copy ID Dev data to satDevData */
22124   satDevData->satIdentifyData = *pSATAIdData;
22125 
22126 
22127   satDevData->IDDeviceValid = agTRUE;
22128 #ifdef TD_INTERNAL_DEBUG
22129   tdhexdump("satAddSATAIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
22130   tdhexdump("satAddSATAIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
22131 #endif
22132 
22133   /* set satDevData fields from IndentifyData */
22134   satSetDevInfo(satDevData,pSATAIdData);
22135   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22136 
22137   satFreeIntIoResource( tiRoot,
22138                         satDevData,
22139                         satIntIo);
22140 
22141   if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22142   {
22143       /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22144       satNewIntIo = satAllocIntIoResource( tiRoot,
22145                                        tiOrgIORequest,
22146                                        satDevData,
22147                                        0,
22148                                        satNewIntIo);
22149 
22150       if (satNewIntIo == agNULL)
22151       {
22152         TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22153           /* clean up TD layer's IORequestBody */
22154         ostiFreeMemory(
22155                      tiRoot,
22156                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22157                      sizeof(tdIORequestBody_t)
22158                      );
22159         return;
22160       } /* end memory allocation */
22161 
22162       satNewIOContext = satPrepareNewIO(satNewIntIo,
22163                                         tiOrgIORequest,
22164                                         satDevData,
22165                                         agNULL,
22166                                         satOrgIOContext
22167                                         );
22168       /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22169       status = satSetFeatures(tiRoot,
22170                      &satNewIntIo->satIntTiIORequest,
22171                      satNewIOContext->ptiDeviceHandle,
22172                      &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22173                      satNewIOContext,
22174                      agFALSE);
22175       if (status != tiSuccess)
22176       {
22177            satFreeIntIoResource( tiRoot,
22178                         satDevData,
22179                         satIntIo);
22180            /* clean up TD layer's IORequestBody */
22181            ostiFreeMemory(
22182                      tiRoot,
22183                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22184                      sizeof(tdIORequestBody_t)
22185                      );
22186       }
22187 
22188   }
22189   else
22190   {
22191        /* clean up TD layer's IORequestBody */
22192       ostiFreeMemory(
22193                      tiRoot,
22194                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22195                      sizeof(tdIORequestBody_t)
22196                      );
22197 
22198       TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22199       /* notifying link up */
22200       ostiPortEvent (
22201                      tiRoot,
22202                      tiPortLinkUp,
22203                      tiSuccess,
22204                      (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22205                      );
22206     #ifdef INITIATOR_DRIVER
22207       /* triggers discovery */
22208       ostiPortEvent(
22209                     tiRoot,
22210                     tiPortDiscoveryReady,
22211                     tiSuccess,
22212                     (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22213                     );
22214     #endif
22215   }
22216 
22217  TI_DBG2(("satAddSATAIDDevCB: end\n"));
22218  return;
22219 
22220 }
22221 
22222 /*****************************************************************************
22223 *! \brief  satAddSATAIDDevCBReset
22224 *
22225 *   This routine cleans up IOs for failed Identify device data
22226 *
22227 *  \param   agRoot:           Handles for this instance of SAS/SATA hardware
22228 *  \param   oneDeviceData:    Pointer to the device data.
22229 *  \param   ioContext:        Pointer to satIOContext_t.
22230 *  \param   tdIORequestBody:  Pointer to the request body
22231 *  \param   flag:             Decrement pending io or not
22232 *
22233 *  \return: none
22234 *
22235 *****************************************************************************/
22236 void satAddSATAIDDevCBReset(
22237                    agsaRoot_t        *agRoot,
22238                    tdsaDeviceData_t  *oneDeviceData,
22239                    satIOContext_t    *satIOContext,
22240                    tdIORequestBody_t *tdIORequestBody
22241                    )
22242 {
22243   tdsaRootOsData_t   *osData = (tdsaRootOsData_t *)agRoot->osData;
22244   tiRoot_t           *tiRoot = (tiRoot_t *)osData->tiRoot;
22245   tdsaRoot_t         *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
22246   tdsaContext_t      *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22247   satInternalIo_t    *satIntIo;
22248   satDeviceData_t    *satDevData;
22249 
22250   TI_DBG2(("satAddSATAIDDevCBReset: start\n"));
22251   satIntIo           = satIOContext->satIntIoContext;
22252   satDevData         = satIOContext->pSatDevData;
22253   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22254 
22255   satFreeIntIoResource( tiRoot,
22256                         satDevData,
22257                         satIntIo);
22258   /* clean up TD layer's IORequestBody */
22259   ostiFreeMemory(
22260                  tiRoot,
22261                  tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22262                  sizeof(tdIORequestBody_t)
22263                 );
22264   return;
22265 }
22266 
22267 
22268 /*****************************************************************************
22269 *! \brief  satAddSATAIDDevCBCleanup
22270 *
22271 *   This routine cleans up IOs for failed Identify device data
22272 *
22273 *  \param   agRoot:           Handles for this instance of SAS/SATA hardware
22274 *  \param   oneDeviceData:    Pointer to the device data.
22275 *  \param   ioContext:        Pointer to satIOContext_t.
22276 *  \param   tdIORequestBody:  Pointer to the request body
22277 *
22278 *  \return: none
22279 *
22280 *****************************************************************************/
22281 void satAddSATAIDDevCBCleanup(
22282                    agsaRoot_t        *agRoot,
22283                    tdsaDeviceData_t  *oneDeviceData,
22284                    satIOContext_t    *satIOContext,
22285                    tdIORequestBody_t *tdIORequestBody
22286                    )
22287 {
22288   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
22289   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
22290   tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
22291   tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22292   satInternalIo_t         *satIntIo;
22293   satDeviceData_t         *satDevData;
22294   bit8                    PhyID;
22295 
22296   TI_DBG2(("satAddSATAIDDevCBCleanup: start\n"));
22297   satIntIo               = satIOContext->satIntIoContext;
22298   satDevData             = satIOContext->pSatDevData;
22299   PhyID                  = oneDeviceData->phyID;
22300   tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
22301   /* put onedevicedata back to free list */
22302   osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22303   TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
22304   TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22305 
22306   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22307 
22308 
22309   satFreeIntIoResource( tiRoot,
22310                         satDevData,
22311                         satIntIo);
22312 
22313   /* clean up TD layer's IORequestBody */
22314   ostiFreeMemory(
22315                  tiRoot,
22316                  tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22317                  sizeof(tdIORequestBody_t)
22318                 );
22319 
22320   /* notifying link up */
22321   ostiPortEvent (
22322                  tiRoot,
22323                  tiPortLinkUp,
22324                  tiSuccess,
22325                  (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22326                 );
22327 #ifdef INITIATOR_DRIVER
22328   /* triggers discovery */
22329   ostiPortEvent(
22330                 tiRoot,
22331                 tiPortDiscoveryReady,
22332                 tiSuccess,
22333                 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22334                 );
22335 #endif
22336 
22337   return;
22338 }
22339 
22340 /*****************************************************************************/
22341 /*! \brief SAT implementation for tdsaDiscoveryStartIDDev.
22342  *
22343  *  This function sends identify device data to SATA device in discovery
22344  *
22345  *
22346  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
22347  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
22348  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
22349  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
22350  *  \param   oneDeviceData :   Pointer to the device data.
22351  *
22352  *  \return If command is started successfully
22353  *    - \e tiSuccess:     I/O request successfully initiated.
22354  *    - \e tiBusy:        No resources available, try again later.
22355  *    - \e tiIONoDevice:  Invalid device handle.
22356  *    - \e tiError:       Other errors.
22357  */
22358 /*****************************************************************************/
22359 GLOBAL bit32
22360 tdsaDiscoveryStartIDDev(tiRoot_t                  *tiRoot,
22361                         tiIORequest_t             *tiIORequest, /* agNULL */
22362                         tiDeviceHandle_t          *tiDeviceHandle,
22363                         tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */
22364                         tdsaDeviceData_t          *oneDeviceData
22365                         )
22366 {
22367   void                        *osMemHandle;
22368   tdIORequestBody_t           *tdIORequestBody;
22369   bit32                       PhysUpper32;
22370   bit32                       PhysLower32;
22371   bit32                       memAllocStatus;
22372   agsaIORequest_t             *agIORequest = agNULL; /* identify device data itself */
22373   satIOContext_t              *satIOContext = agNULL;
22374   bit32                       status;
22375 
22376   /* allocate tdiorequestbody and call tdsaDiscoveryIntStartIDDev
22377   tdsaDiscoveryIntStartIDDev(tiRoot, agNULL, tiDeviceHandle, satIOContext);
22378 
22379   */
22380 
22381   TI_DBG3(("tdsaDiscoveryStartIDDev: start\n"));
22382   TI_DBG3(("tdsaDiscoveryStartIDDev: did %d\n", oneDeviceData->id));
22383 
22384   /* allocation tdIORequestBody and pass it to satTM() */
22385   memAllocStatus = ostiAllocMemory(
22386                                    tiRoot,
22387                                    &osMemHandle,
22388                                    (void **)&tdIORequestBody,
22389                                    &PhysUpper32,
22390                                    &PhysLower32,
22391                                    8,
22392                                    sizeof(tdIORequestBody_t),
22393                                    agTRUE
22394                                    );
22395 
22396   if (memAllocStatus != tiSuccess)
22397   {
22398     TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory failed... loc 1\n"));
22399     return tiError;
22400   }
22401   if (tdIORequestBody == agNULL)
22402   {
22403     TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory returned NULL tdIORequestBody loc 2\n"));
22404     return tiError;
22405   }
22406 
22407   /* setup identify device data IO structure */
22408   tdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
22409   tdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
22410   tdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
22411 
22412   /* initialize tiDevhandle */
22413   tdIORequestBody->tiDevHandle = &(oneDeviceData->tiDeviceHandle);
22414   tdIORequestBody->tiDevHandle->tdData = oneDeviceData;
22415 
22416   /* initialize tiIORequest */
22417   tdIORequestBody->tiIORequest = agNULL;
22418 
22419   /* initialize agIORequest */
22420   agIORequest = &(tdIORequestBody->agIORequest);
22421   agIORequest->osData = (void *) tdIORequestBody;
22422   agIORequest->sdkData = agNULL; /* SA takes care of this */
22423 
22424   /* set up satIOContext */
22425   satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22426   satIOContext->pSatDevData   = &(oneDeviceData->satDevData);
22427   satIOContext->pFis          =
22428     &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22429 
22430   satIOContext->tiRequestBody = tdIORequestBody;
22431   satIOContext->ptiDeviceHandle = &(oneDeviceData->tiDeviceHandle);
22432   satIOContext->tiScsiXchg = agNULL;
22433   satIOContext->satIntIoContext  = agNULL;
22434   satIOContext->satOrgIOContext  = agNULL;
22435   /* followings are used only for internal IO */
22436   satIOContext->currentLBA = 0;
22437   satIOContext->OrgTL = 0;
22438   satIOContext->satToBeAbortedIOContext = agNULL;
22439   satIOContext->NotifyOS = agFALSE;
22440 
22441   /* saving port ID just in case of full discovery to full discovery transition */
22442   satIOContext->pid = oneDeviceData->tdPortContext->id;
22443   osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0x0, sizeof(agsaSATAIdentifyData_t));
22444   status = tdsaDiscoveryIntStartIDDev(tiRoot,
22445                                       tiIORequest, /* agNULL */
22446                                       tiDeviceHandle, /* &(oneDeviceData->tiDeviceHandle)*/
22447                                       agNULL,
22448                                       satIOContext
22449                                       );
22450   if (status != tiSuccess)
22451   {
22452     TI_DBG1(("tdsaDiscoveryStartIDDev: failed in sending %d\n", status));
22453     ostiFreeMemory(tiRoot, osMemHandle, sizeof(tdIORequestBody_t));
22454   }
22455   return status;
22456 }
22457 
22458 /*****************************************************************************/
22459 /*! \brief SAT implementation for tdsaDiscoveryIntStartIDDev.
22460  *
22461  *  This function sends identify device data to SATA device.
22462  *
22463  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
22464  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
22465  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
22466  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
22467  *  \param   satIOContext_t:   Pointer to the SAT IO Context
22468  *
22469  *  \return If command is started successfully
22470  *    - \e tiSuccess:     I/O request successfully initiated.
22471  *    - \e tiBusy:        No resources available, try again later.
22472  *    - \e tiIONoDevice:  Invalid device handle.
22473  *    - \e tiError:       Other errors.
22474  */
22475 /*****************************************************************************/
22476 GLOBAL bit32
22477 tdsaDiscoveryIntStartIDDev(tiRoot_t                  *tiRoot,
22478                            tiIORequest_t             *tiIORequest, /* agNULL */
22479                            tiDeviceHandle_t          *tiDeviceHandle,
22480                            tiScsiInitiatorRequest_t  *tiScsiRequest, /* agNULL */
22481                            satIOContext_t            *satIOContext
22482                            )
22483 {
22484   satInternalIo_t           *satIntIo = agNULL;
22485   satDeviceData_t           *satDevData = agNULL;
22486   tdIORequestBody_t         *tdIORequestBody;
22487   satIOContext_t            *satNewIOContext;
22488   bit32                     status;
22489 
22490   TI_DBG3(("tdsaDiscoveryIntStartIDDev: start\n"));
22491 
22492   satDevData = satIOContext->pSatDevData;
22493 
22494   /* allocate identify device command */
22495   satIntIo = satAllocIntIoResource( tiRoot,
22496                                     tiIORequest,
22497                                     satDevData,
22498                                     sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
22499                                     satIntIo);
22500 
22501   if (satIntIo == agNULL)
22502   {
22503     TI_DBG2(("tdsaDiscoveryIntStartIDDev: can't alloacate\n"));
22504 
22505     return tiError;
22506   }
22507 
22508   /* fill in fields */
22509   /* real ttttttthe one worked and the same; 5/21/07/ */
22510   satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
22511   tdIORequestBody = satIntIo->satIntRequestBody;
22512   satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22513 
22514   satNewIOContext->pSatDevData   = satDevData;
22515   satNewIOContext->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22516   satNewIOContext->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
22517   satNewIOContext->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
22518   satNewIOContext->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
22519   satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
22520   satNewIOContext->interruptContext = tiInterruptContext;
22521   satNewIOContext->satIntIoContext  = satIntIo;
22522 
22523   satNewIOContext->ptiDeviceHandle = agNULL;
22524   satNewIOContext->satOrgIOContext = satIOContext; /* changed */
22525 
22526   /* this is valid only for TD layer generated (not triggered by OS at all) IO */
22527   satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
22528 
22529 
22530   TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS satIOContext %p \n", satIOContext));
22531   TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
22532   TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
22533   TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
22534 
22535 
22536 
22537   TI_DBG3(("tdsaDiscoveryIntStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
22538 
22539   status = tdsaDiscoverySendIDDev(tiRoot,
22540                                   &satIntIo->satIntTiIORequest, /* New tiIORequest */
22541                                   tiDeviceHandle,
22542                                   satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
22543                                   satNewIOContext);
22544 
22545   if (status != tiSuccess)
22546   {
22547     TI_DBG1(("tdsaDiscoveryIntStartIDDev: failed in sending %d\n", status));
22548 
22549     satFreeIntIoResource( tiRoot,
22550                           satDevData,
22551                           satIntIo);
22552 
22553     return tiError;
22554   }
22555 
22556 
22557   TI_DBG6(("tdsaDiscoveryIntStartIDDev: end\n"));
22558 
22559   return status;
22560 }
22561 
22562 
22563 /*****************************************************************************/
22564 /*! \brief SAT implementation for tdsaDiscoverySendIDDev.
22565  *
22566  *  This function prepares identify device data FIS and sends it to SATA device.
22567  *
22568  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
22569  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
22570  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
22571  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
22572  *  \param   satIOContext_t:   Pointer to the SAT IO Context
22573  *
22574  *  \return If command is started successfully
22575  *    - \e tiSuccess:     I/O request successfully initiated.
22576  *    - \e tiBusy:        No resources available, try again later.
22577  *    - \e tiIONoDevice:  Invalid device handle.
22578  *    - \e tiError:       Other errors.
22579  */
22580 /*****************************************************************************/
22581 GLOBAL bit32
22582 tdsaDiscoverySendIDDev(tiRoot_t                  *tiRoot,
22583                        tiIORequest_t             *tiIORequest,
22584                        tiDeviceHandle_t          *tiDeviceHandle,
22585                        tiScsiInitiatorRequest_t  *tiScsiRequest,
22586                        satIOContext_t            *satIOContext
22587                        )
22588 {
22589   bit32                     status;
22590   bit32                     agRequestType;
22591   satDeviceData_t           *pSatDevData;
22592   agsaFisRegHostToDevice_t  *fis;
22593 #ifdef  TD_DEBUG_ENABLE
22594   tdIORequestBody_t         *tdIORequestBody;
22595   satInternalIo_t           *satIntIoContext;
22596 #endif
22597 
22598   pSatDevData   = satIOContext->pSatDevData;
22599   fis           = satIOContext->pFis;
22600   TI_DBG3(("tdsaDiscoverySendIDDev: start\n"));
22601 #ifdef  TD_DEBUG_ENABLE
22602   satIntIoContext = satIOContext->satIntIoContext;
22603   tdIORequestBody = satIntIoContext->satIntRequestBody;
22604 #endif
22605   TI_DBG5(("tdsaDiscoverySendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
22606 
22607   fis->h.fisType        = 0x27;                   /* Reg host to device */
22608   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
22609   if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
22610       fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0xA1 */
22611   else
22612       fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
22613   fis->h.features       = 0;                      /* FIS reserve */
22614   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
22615   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
22616   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
22617   fis->d.device         = 0;                      /* FIS LBA mode  */
22618   fis->d.lbaLowExp      = 0;
22619   fis->d.lbaMidExp      = 0;
22620   fis->d.lbaHighExp     = 0;
22621   fis->d.featuresExp    = 0;
22622   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
22623   fis->d.sectorCountExp = 0;
22624   fis->d.reserved4      = 0;
22625   fis->d.control        = 0;                      /* FIS HOB bit clear */
22626   fis->d.reserved5      = 0;
22627 
22628   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
22629 
22630   /* Initialize CB for SATA completion.
22631    */
22632   satIOContext->satCompleteCB = &tdsaDiscoveryStartIDDevCB;
22633 
22634   /*
22635    * Prepare SGL and send FIS to LL layer.
22636    */
22637   satIOContext->reqType = agRequestType;       /* Save it */
22638 
22639 #ifdef TD_INTERNAL_DEBUG
22640   tdhexdump("tdsaDiscoverySendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
22641 #ifdef  TD_DEBUG_ENABLE
22642   tdhexdump("tdsaDiscoverySendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
22643 #endif
22644 #endif
22645   status = sataLLIOStart( tiRoot,
22646                           tiIORequest,
22647                           tiDeviceHandle,
22648                           tiScsiRequest,
22649                           satIOContext);
22650   TI_DBG3(("tdsaDiscoverySendIDDev: end status %d\n", status));
22651   return status;
22652 }
22653 
22654 
22655 /*****************************************************************************
22656 *! \brief  tdsaDiscoveryStartIDDevCB
22657 *
22658 *   This routine is a callback function for tdsaDiscoverySendIDDev()
22659 *   Using Identify Device Data, this function finds whether devicedata is
22660 *   new or old. If new, add it to the devicelist. This is done as a part
22661 *   of discovery.
22662 *
22663 *  \param   agRoot:      Handles for this instance of SAS/SATA hardware
22664 *  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
22665 *  \param   agIOStatus:  Status of completed I/O.
22666 *  \param   agFirstDword:Pointer to the four bytes of FIS.
22667 *  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
22668 *                        length.
22669 *  \param   agParam:     Additional info based on status.
22670 *  \param   ioContext:   Pointer to satIOContext_t.
22671 *
22672 *  \return: none
22673 *
22674 *****************************************************************************/
22675 void tdsaDiscoveryStartIDDevCB(
22676                                agsaRoot_t        *agRoot,
22677                                agsaIORequest_t   *agIORequest,
22678                                 bit32             agIOStatus,
22679                                 agsaFisHeader_t   *agFirstDword,
22680                                 bit32             agIOInfoLen,
22681                                 void              *agParam,
22682                                 void              *ioContext
22683                                 )
22684 {
22685  /*
22686     In the process of SAT_IDENTIFY_DEVICE during discovery
22687   */
22688   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
22689   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
22690   tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
22691   tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22692   tdIORequestBody_t       *tdIORequestBody;
22693   tdIORequestBody_t       *tdOrgIORequestBody;
22694   satIOContext_t          *satIOContext;
22695   satIOContext_t          *satOrgIOContext;
22696   satIOContext_t          *satNewIOContext;
22697   satInternalIo_t         *satIntIo;
22698   satInternalIo_t         *satNewIntIo = agNULL;
22699   satDeviceData_t         *satDevData;
22700   tiIORequest_t           *tiOrgIORequest = agNULL;
22701 
22702 #ifdef  TD_DEBUG_ENABLE
22703   bit32                     ataStatus = 0;
22704   bit32                     ataError;
22705   agsaFisPioSetupHeader_t   *satPIOSetupHeader = agNULL;
22706 #endif
22707   agsaSATAIdentifyData_t    *pSATAIdData;
22708   bit16                     *tmpptr, tmpptr_tmp;
22709   bit32                     x;
22710   tdsaDeviceData_t          *oneDeviceData = agNULL;
22711   void                      *sglVirtualAddr;
22712   tdsaPortContext_t         *onePortContext = agNULL;
22713   tiPortalContext_t         *tiPortalContext = agNULL;
22714   bit32                     retry_status;
22715 
22716   TI_DBG3(("tdsaDiscoveryStartIDDevCB: start\n"));
22717 
22718   tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
22719   satIOContext           = (satIOContext_t *) ioContext;
22720   satIntIo               = satIOContext->satIntIoContext;
22721   satDevData             = satIOContext->pSatDevData;
22722   oneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
22723   TI_DBG3(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22724   onePortContext = oneDeviceData->tdPortContext;
22725   if (onePortContext == agNULL)
22726   {
22727       TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL\n"));
22728       return;
22729   }
22730   tiPortalContext= onePortContext->tiPortalContext;
22731 
22732   satDevData->IDDeviceValid = agFALSE;
22733 
22734   if (satIntIo == agNULL)
22735   {
22736     TI_DBG1(("tdsaDiscoveryStartIDDevCB: External, OS generated\n"));
22737     TI_DBG1(("tdsaDiscoveryStartIDDevCB: Not possible case\n"));
22738     satOrgIOContext      = satIOContext;
22739     tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22740 
22741     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22742 
22743     satFreeIntIoResource( tiRoot,
22744                           satDevData,
22745                           satIntIo);
22746 
22747     /* clean up TD layer's IORequestBody */
22748     ostiFreeMemory(
22749                    tiRoot,
22750                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22751                    sizeof(tdIORequestBody_t)
22752                    );
22753     return;
22754   }
22755   else
22756   {
22757     TI_DBG3(("tdsaDiscoveryStartIDDevCB: Internal, TD generated\n"));
22758     satOrgIOContext        = satIOContext->satOrgIOContext;
22759     if (satOrgIOContext == agNULL)
22760     {
22761       TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NULL\n"));
22762       return;
22763     }
22764     else
22765     {
22766       TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NOT NULL\n"));
22767       tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22768       sglVirtualAddr         = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
22769     }
22770   }
22771 
22772   tiOrgIORequest           = tdIORequestBody->tiIORequest;
22773   tdIORequestBody->ioCompleted = agTRUE;
22774   tdIORequestBody->ioStarted = agFALSE;
22775 
22776   TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22777 
22778   /* protect against double completion for old port */
22779   if (satOrgIOContext->pid != oneDeviceData->tdPortContext->id)
22780   {
22781     TI_DBG3(("tdsaDiscoveryStartIDDevCB: incorrect pid\n"));
22782     TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22783     TI_DBG3(("tdsaDiscoveryStartIDDevCB: tiPortalContext pid %d\n", oneDeviceData->tdPortContext->id));
22784 
22785     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22786 
22787     satFreeIntIoResource( tiRoot,
22788                           satDevData,
22789                           satIntIo);
22790 
22791     /* clean up TD layer's IORequestBody */
22792     ostiFreeMemory(
22793                    tiRoot,
22794                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22795                    sizeof(tdIORequestBody_t)
22796                    );
22797 
22798     return;
22799   }
22800 
22801   /* completion after portcontext is invalidated */
22802   if (onePortContext != agNULL)
22803   {
22804     if (onePortContext->valid == agFALSE)
22805     {
22806       TI_DBG1(("tdsaDiscoveryStartIDDevCB: portcontext is invalid\n"));
22807       TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
22808       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22809 
22810       satFreeIntIoResource( tiRoot,
22811                             satDevData,
22812                             satIntIo);
22813 
22814       /* clean up TD layer's IORequestBody */
22815       ostiFreeMemory(
22816                      tiRoot,
22817                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22818                      sizeof(tdIORequestBody_t)
22819                      );
22820 
22821       /* no notification to OS layer */
22822       return;
22823     }
22824   }
22825 
22826   if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
22827   {
22828     TI_DBG1(("tdsaDiscoveryStartIDDevCB: agFirstDword is NULL when error, status %d\n", agIOStatus));
22829     TI_DBG1(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22830 
22831     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22832     {
22833       satIOContext->pSatDevData->satPendingNONNCQIO--;
22834       satIOContext->pSatDevData->satPendingIO--;
22835       retry_status = sataLLIOStart(tiRoot,
22836                                    &satIntIo->satIntTiIORequest,
22837            &(oneDeviceData->tiDeviceHandle),
22838            satIOContext->tiScsiXchg,
22839            satIOContext);
22840       if (retry_status != tiSuccess)
22841       {
22842         /* simply give up */
22843         satDevData->ID_Retries = 0;
22844         satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22845 
22846         satFreeIntIoResource( tiRoot,
22847                               satDevData,
22848                               satIntIo);
22849 
22850         /* clean up TD layer's IORequestBody */
22851         ostiFreeMemory(
22852                        tiRoot,
22853                        tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22854                        sizeof(tdIORequestBody_t)
22855                        );
22856         return;
22857       }
22858       satDevData->ID_Retries++;
22859       tdIORequestBody->ioCompleted = agFALSE;
22860       tdIORequestBody->ioStarted = agTRUE;
22861       return;
22862     }
22863     else
22864     {
22865       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22866       satFreeIntIoResource( tiRoot,
22867                             satDevData,
22868                             satIntIo);
22869 
22870       /* clean up TD layer's IORequestBody */
22871       ostiFreeMemory(
22872                      tiRoot,
22873                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22874                      sizeof(tdIORequestBody_t)
22875                      );
22876       if (tdsaAllShared->ResetInDiscovery != 0)
22877       {
22878         /* ResetInDiscovery in on */
22879         if (satDevData->NumOfIDRetries <= 0)
22880         {
22881           satDevData->NumOfIDRetries++;
22882           satDevData->ID_Retries = 0;
22883           /* send link reset */
22884           tdsaPhyControlSend(tiRoot,
22885                              oneDeviceData,
22886                              SMP_PHY_CONTROL_HARD_RESET,
22887                              agNULL,
22888                              tdsaRotateQnumber(tiRoot, oneDeviceData)
22889                             );
22890         }
22891       }
22892       return;
22893     }
22894   }
22895 
22896   if (agIOStatus == OSSA_IO_ABORTED ||
22897       agIOStatus == OSSA_IO_UNDERFLOW ||
22898       agIOStatus == OSSA_IO_XFER_ERROR_BREAK ||
22899       agIOStatus == OSSA_IO_XFER_ERROR_PHY_NOT_READY ||
22900       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
22901       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
22902       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
22903       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
22904       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
22905       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY ||
22906       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
22907       agIOStatus == OSSA_IO_XFER_ERROR_NAK_RECEIVED ||
22908       agIOStatus == OSSA_IO_XFER_ERROR_DMA ||
22909       agIOStatus == OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT ||
22910       agIOStatus == OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE ||
22911       agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT ||
22912       agIOStatus == OSSA_IO_NO_DEVICE ||
22913       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
22914       agIOStatus == OSSA_IO_PORT_IN_RESET ||
22915       agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
22916       agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
22917       agIOStatus == OSSA_IO_DS_IN_ERROR
22918       )
22919   {
22920     TI_DBG1(("tdsaDiscoveryStartIDDevCB: OSSA_IO_OPEN_CNX_ERROR 0x%x\n", agIOStatus));
22921     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22922     {
22923       satIOContext->pSatDevData->satPendingNONNCQIO--;
22924       satIOContext->pSatDevData->satPendingIO--;
22925       retry_status = sataLLIOStart(tiRoot,
22926                                    &satIntIo->satIntTiIORequest,
22927            &(oneDeviceData->tiDeviceHandle),
22928            satIOContext->tiScsiXchg,
22929            satIOContext);
22930       if (retry_status != tiSuccess)
22931       {
22932         /* simply give up */
22933         satDevData->ID_Retries = 0;
22934         satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22935 
22936         satFreeIntIoResource( tiRoot,
22937                               satDevData,
22938                               satIntIo);
22939 
22940         /* clean up TD layer's IORequestBody */
22941         ostiFreeMemory(
22942                        tiRoot,
22943                        tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22944                        sizeof(tdIORequestBody_t)
22945                        );
22946         return;
22947       }
22948       satDevData->ID_Retries++;
22949       tdIORequestBody->ioCompleted = agFALSE;
22950       tdIORequestBody->ioStarted = agTRUE;
22951       return;
22952     }
22953     else
22954     {
22955       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22956       satFreeIntIoResource( tiRoot,
22957                             satDevData,
22958                             satIntIo);
22959 
22960       /* clean up TD layer's IORequestBody */
22961       ostiFreeMemory(
22962                      tiRoot,
22963                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22964                      sizeof(tdIORequestBody_t)
22965                      );
22966       if (tdsaAllShared->ResetInDiscovery != 0)
22967       {
22968         /* ResetInDiscovery in on */
22969         if (satDevData->NumOfIDRetries <= 0)
22970         {
22971           satDevData->NumOfIDRetries++;
22972           satDevData->ID_Retries = 0;
22973           /* send link reset */
22974           tdsaPhyControlSend(tiRoot,
22975                              oneDeviceData,
22976                              SMP_PHY_CONTROL_HARD_RESET,
22977                              agNULL,
22978                              tdsaRotateQnumber(tiRoot, oneDeviceData)
22979                             );
22980         }
22981       }
22982       return;
22983     }
22984   }
22985 
22986   if ( agIOStatus != OSSA_IO_SUCCESS ||
22987        (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
22988      )
22989   {
22990 #ifdef  TD_DEBUG_ENABLE
22991     /* only agsaFisPioSetup_t is expected */
22992     satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
22993     ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
22994     ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
22995 #endif
22996     TI_DBG1(("tdsaDiscoveryStartIDDevCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
22997 
22998     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22999     {
23000       satIOContext->pSatDevData->satPendingNONNCQIO--;
23001       satIOContext->pSatDevData->satPendingIO--;
23002       retry_status = sataLLIOStart(tiRoot,
23003                                    &satIntIo->satIntTiIORequest,
23004            &(oneDeviceData->tiDeviceHandle),
23005            satIOContext->tiScsiXchg,
23006            satIOContext);
23007       if (retry_status != tiSuccess)
23008       {
23009         /* simply give up */
23010         satDevData->ID_Retries = 0;
23011         satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23012 
23013         satFreeIntIoResource( tiRoot,
23014                               satDevData,
23015                               satIntIo);
23016 
23017         /* clean up TD layer's IORequestBody */
23018         ostiFreeMemory(
23019                        tiRoot,
23020                        tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23021                        sizeof(tdIORequestBody_t)
23022                        );
23023         return;
23024       }
23025       satDevData->ID_Retries++;
23026       tdIORequestBody->ioCompleted = agFALSE;
23027       tdIORequestBody->ioStarted = agTRUE;
23028       return;
23029     }
23030     else
23031     {
23032       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23033       satFreeIntIoResource( tiRoot,
23034                             satDevData,
23035                             satIntIo);
23036 
23037       /* clean up TD layer's IORequestBody */
23038       ostiFreeMemory(
23039                      tiRoot,
23040                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23041                      sizeof(tdIORequestBody_t)
23042                      );
23043       if (tdsaAllShared->ResetInDiscovery != 0)
23044       {
23045         /* ResetInDiscovery in on */
23046         if (satDevData->NumOfIDRetries <= 0)
23047         {
23048           satDevData->NumOfIDRetries++;
23049           satDevData->ID_Retries = 0;
23050           /* send link reset */
23051           tdsaPhyControlSend(tiRoot,
23052                              oneDeviceData,
23053                              SMP_PHY_CONTROL_HARD_RESET,
23054                              agNULL,
23055                              tdsaRotateQnumber(tiRoot, oneDeviceData)
23056                             );
23057         }
23058       }
23059       return;
23060     }
23061   }
23062 
23063 
23064   /* success */
23065   TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success\n"));
23066   TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success did %d\n", oneDeviceData->id));
23067 
23068   /* Convert to host endian */
23069   tmpptr = (bit16*)sglVirtualAddr;
23070   for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
23071   {
23072     OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
23073     *tmpptr = tmpptr_tmp;
23074     tmpptr++;
23075   }
23076 
23077   pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
23078   //tdhexdump("satAddSATAIDDevCB before", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23079 
23080   TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
23081   TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD satIOContext %p \n", satIOContext));
23082   TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
23083   TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
23084 
23085 
23086    /* copy ID Dev data to satDevData */
23087   satDevData->satIdentifyData = *pSATAIdData;
23088   satDevData->IDDeviceValid = agTRUE;
23089 
23090 #ifdef TD_INTERNAL_DEBUG
23091   tdhexdump("tdsaDiscoveryStartIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23092   tdhexdump("tdsaDiscoveryStartIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
23093 #endif
23094 
23095   /* set satDevData fields from IndentifyData */
23096   satSetDevInfo(satDevData,pSATAIdData);
23097   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23098 
23099   satFreeIntIoResource( tiRoot,
23100                         satDevData,
23101                         satIntIo);
23102 
23103   if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
23104   {
23105       /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
23106       satNewIntIo = satAllocIntIoResource( tiRoot,
23107                                        tiOrgIORequest,
23108                                        satDevData,
23109                                        0,
23110                                        satNewIntIo);
23111 
23112       if (satNewIntIo == agNULL)
23113       {
23114         TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
23115           /* clean up TD layer's IORequestBody */
23116         ostiFreeMemory(
23117                      tiRoot,
23118                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23119                      sizeof(tdIORequestBody_t)
23120                      );
23121         return;
23122       } /* end memory allocation */
23123 
23124       satNewIOContext = satPrepareNewIO(satNewIntIo,
23125                                         tiOrgIORequest,
23126                                         satDevData,
23127                                         agNULL,
23128                                         satOrgIOContext
23129                                         );
23130       /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
23131       retry_status = satSetFeatures(tiRoot,
23132                                  &satNewIntIo->satIntTiIORequest,
23133                                  satNewIOContext->ptiDeviceHandle,
23134                                  &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
23135                                  satNewIOContext,
23136                                  agFALSE);
23137       if (retry_status != tiSuccess)
23138       {
23139           satFreeIntIoResource(tiRoot, satDevData, satIntIo);
23140           /* clean up TD layer's IORequestBody */
23141           ostiFreeMemory(
23142                  tiRoot,
23143                  tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23144                  sizeof(tdIORequestBody_t)
23145                  );
23146       }
23147   }
23148   else
23149   {
23150       /* clean up TD layer's IORequestBody */
23151       ostiFreeMemory(
23152                      tiRoot,
23153                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23154                      sizeof(tdIORequestBody_t)
23155                      );
23156       if (onePortContext != agNULL)
23157       {
23158         if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED)
23159         {
23160           TI_DBG1(("tdsaDiscoveryStartIDDevCB: ID completed after discovery is done; tiDeviceArrival\n"));
23161           /* in case registration is finished after discovery is finished */
23162           ostiInitiatorEvent(
23163                              tiRoot,
23164                              tiPortalContext,
23165                              agNULL,
23166                              tiIntrEventTypeDeviceChange,
23167                              tiDeviceArrival,
23168                              agNULL
23169                              );
23170         }
23171       }
23172       else
23173       {
23174         TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL, wrong\n"));
23175       }
23176   }
23177   TI_DBG3(("tdsaDiscoveryStartIDDevCB: end\n"));
23178   return;
23179 }
23180 /*****************************************************************************
23181 *! \brief  satAbort
23182 *
23183 *   This routine does local abort for outstanding FIS.
23184 *
23185 *  \param   agRoot:         Handles for this instance of SAS/SATA hardware
23186 *  \param   satIOContext:   Pointer to satIOContext_t.
23187 *
23188 *  \return: none
23189 *
23190 *****************************************************************************/
23191 GLOBAL void satAbort(agsaRoot_t        *agRoot,
23192                      satIOContext_t    *satIOContext)
23193 {
23194   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
23195   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
23196   tdIORequestBody_t       *tdIORequestBody; /* io to be aborted */
23197   tdIORequestBody_t       *tdAbortIORequestBody; /* abort io itself */
23198   agsaIORequest_t         *agToBeAbortedIORequest; /* io to be aborted */
23199   agsaIORequest_t         *agAbortIORequest;  /* abort io itself */
23200   bit32                   PhysUpper32;
23201   bit32                   PhysLower32;
23202   bit32                   memAllocStatus;
23203   void                    *osMemHandle;
23204 
23205   TI_DBG1(("satAbort: start\n"));
23206 
23207   if (satIOContext == agNULL)
23208   {
23209     TI_DBG1(("satAbort: satIOContext is NULL, wrong\n"));
23210     return;
23211   }
23212   tdIORequestBody = (tdIORequestBody_t *)satIOContext->tiRequestBody;
23213   agToBeAbortedIORequest = (agsaIORequest_t *)&(tdIORequestBody->agIORequest);
23214   /* allocating agIORequest for abort itself */
23215   memAllocStatus = ostiAllocMemory(
23216                                    tiRoot,
23217                                    &osMemHandle,
23218                                    (void **)&tdAbortIORequestBody,
23219                                    &PhysUpper32,
23220                                    &PhysLower32,
23221                                    8,
23222                                    sizeof(tdIORequestBody_t),
23223                                    agTRUE
23224                                    );
23225 
23226   if (memAllocStatus != tiSuccess)
23227   {
23228     /* let os process IO */
23229     TI_DBG1(("satAbort: ostiAllocMemory failed...\n"));
23230     return;
23231   }
23232 
23233   if (tdAbortIORequestBody == agNULL)
23234   {
23235     /* let os process IO */
23236     TI_DBG1(("satAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
23237     return;
23238   }
23239   /* setup task management structure */
23240   tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
23241   tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
23242 
23243   /* initialize agIORequest */
23244   agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
23245   agAbortIORequest->osData = (void *) tdAbortIORequestBody;
23246   agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
23247 
23248 
23249   /*
23250    * Issue abort
23251    */
23252   saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, agNULL );
23253 
23254 
23255   TI_DBG1(("satAbort: end\n"));
23256   return;
23257 }
23258 
23259 /*****************************************************************************
23260  *! \brief  satSATADeviceReset
23261  *
23262  *   This routine is called to reset all phys of port which a device belongs to
23263  *
23264  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
23265  *  \param   oneDeviceData:    Pointer to the device data.
23266  *  \param   flag:             reset flag
23267  *
23268  *  \return:
23269  *
23270  *  none
23271  *
23272  *****************************************************************************/
23273 osGLOBAL void
23274 satSATADeviceReset(                                                                                                  tiRoot_t            *tiRoot,
23275                 tdsaDeviceData_t    *oneDeviceData,
23276                 bit32               flag)
23277 {
23278   agsaRoot_t              *agRoot;
23279   tdsaPortContext_t       *onePortContext;
23280   bit32                   i;
23281 
23282   TI_DBG1(("satSATADeviceReset: start\n"));
23283   agRoot         = oneDeviceData->agRoot;
23284   onePortContext = oneDeviceData->tdPortContext;
23285 
23286   if (agRoot == agNULL)
23287   {
23288     TI_DBG1(("satSATADeviceReset: Error!!! agRoot is NULL\n"));
23289     return;
23290   }
23291   if (onePortContext == agNULL)
23292   {
23293     TI_DBG1(("satSATADeviceReset: Error!!! onePortContext is NULL\n"));
23294     return;
23295   }
23296 
23297    for(i=0;i<TD_MAX_NUM_PHYS;i++)
23298   {
23299     if (onePortContext->PhyIDList[i] == agTRUE)
23300     {
23301       saLocalPhyControl(agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, flag, agNULL);
23302     }
23303   }
23304 
23305   return;
23306 }
23307 
23308 #endif  /* #ifdef SATA_ENABLE */
23309