xref: /freebsd/sys/dev/pms/RefTisa/tisa/sassata/sata/host/sat.c (revision d6b92ffa)
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 __FBSDID("$FreeBSD$");
32 #include <dev/pms/config.h>
33 
34 #include <dev/pms/freebsd/driver/common/osenv.h>
35 #include <dev/pms/freebsd/driver/common/ostypes.h>
36 #include <dev/pms/freebsd/driver/common/osdebug.h>
37 
38 #ifdef SATA_ENABLE
39 
40 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
41 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
42 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
43 
44 #include <dev/pms/RefTisa/tisa/api/titypes.h>
45 #include <dev/pms/RefTisa/tisa/api/ostiapi.h>
46 #include <dev/pms/RefTisa/tisa/api/tiapi.h>
47 #include <dev/pms/RefTisa/tisa/api/tiglobal.h>
48 
49 #ifdef FDS_SM
50 #include <dev/pms/RefTisa/sat/api/sm.h>
51 #include <dev/pms/RefTisa/sat/api/smapi.h>
52 #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
53 #endif
54 
55 #ifdef FDS_DM
56 #include <dev/pms/RefTisa/discovery/api/dm.h>
57 #include <dev/pms/RefTisa/discovery/api/dmapi.h>
58 #include <dev/pms/RefTisa/discovery/api/tddmapi.h>
59 #endif
60 
61 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
62 #include <dev/pms/freebsd/driver/common/osstring.h>
63 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
64 
65 #ifdef INITIATOR_DRIVER
66 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
67 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
68 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
69 #endif
70 
71 #ifdef TARGET_DRIVER
72 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
73 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
74 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
75 #endif
76 
77 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
78 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
79 
80 #include <dev/pms/RefTisa/tisa/sassata/sata/host/sat.h>
81 #include <dev/pms/RefTisa/tisa/sassata/sata/host/satproto.h>
82 
83 /*****************************************************************************
84  *! \brief  satIOStart
85  *
86  *   This routine is called to initiate a new SCSI request to SATL.
87  *
88  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
89  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
90  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
91  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
92  *  \param   satIOContext_t:   Pointer to the SAT IO Context
93  *
94  *  \return:
95  *
96  *  \e tiSuccess:     I/O request successfully initiated.
97  *  \e tiBusy:        No resources available, try again later.
98  *  \e tiIONoDevice:  Invalid device handle.
99  *  \e tiError:       Other errors that prevent the I/O request to be started.
100  *
101  *
102  *****************************************************************************/
103 GLOBAL bit32  satIOStart(
104                    tiRoot_t                  *tiRoot,
105                    tiIORequest_t             *tiIORequest,
106                    tiDeviceHandle_t          *tiDeviceHandle,
107                    tiScsiInitiatorRequest_t  *tiScsiRequest,
108                    satIOContext_t            *satIOContext
109                   )
110 {
111 
112   bit32             retVal = tiSuccess;
113   satDeviceData_t   *pSatDevData;
114   scsiRspSense_t    *pSense;
115   tiIniScsiCmnd_t   *scsiCmnd;
116   tiLUN_t           *pLun;
117   satInternalIo_t   *pSatIntIo;
118 #ifdef  TD_DEBUG_ENABLE
119   tdsaDeviceData_t  *oneDeviceData;
120 #endif
121 
122   pSense        = satIOContext->pSense;
123   pSatDevData   = satIOContext->pSatDevData;
124   scsiCmnd      = &tiScsiRequest->scsiCmnd;
125   pLun          = &scsiCmnd->lun;
126 
127   /*
128    * Reject all other LUN other than LUN 0.
129    */
130   if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
131          pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) &&
132         (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)
133      )
134   {
135     TI_DBG1(("satIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
136                  scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
137     satSetSensePayload( pSense,
138                         SCSI_SNSKEY_ILLEGAL_REQUEST,
139                         0,
140                         SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
141                         satIOContext);
142 
143     ostiInitiatorIOCompleted( tiRoot,
144                               tiIORequest,
145                               tiIOSuccess,
146                               SCSI_STAT_CHECK_CONDITION,
147                               satIOContext->pTiSenseData,
148                               satIOContext->interruptContext );
149     retVal = tiSuccess;
150     goto ext;
151   }
152 
153   TI_DBG6(("satIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
154 
155   /* this may happen after tiCOMReset until OS sends inquiry */
156   if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
157   {
158 #ifdef  TD_DEBUG_ENABLE
159     oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
160 #endif
161     TI_DBG1(("satIOStart: invalid identify device data did %d\n", oneDeviceData->id));
162     retVal = tiIONoDevice;
163     goto ext;
164   }
165   /*
166    * Check if we need to return BUSY, i.e. recovery in progress
167    */
168   if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
169   {
170 #ifdef  TD_DEBUG_ENABLE
171     oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
172 #endif
173     TI_DBG1(("satIOStart: IN RECOVERY STATE cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
174                  scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
175     TI_DBG1(("satIOStart: IN RECOVERY STATE did %d\n", oneDeviceData->id));
176 
177     TI_DBG1(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
178     TI_DBG1(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
179     retVal = tiError;
180     goto ext;
181 //    return tiBusy;
182   }
183 
184   if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
185   {
186      if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
187      {
188         return satReportLun(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
189      }
190      else
191      {
192         return satPacket(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
193      }
194   }
195   else /* pSatDevData->satDeviceType != SATA_ATAPI_DEVICE */
196   {
197      /* Parse CDB */
198      switch(scsiCmnd->cdb[0])
199      {
200        case SCSIOPC_READ_6:
201          retVal = satRead6( tiRoot,
202                             tiIORequest,
203                             tiDeviceHandle,
204                             tiScsiRequest,
205                             satIOContext);
206          break;
207 
208        case SCSIOPC_READ_10:
209          retVal = satRead10( tiRoot,
210                              tiIORequest,
211                              tiDeviceHandle,
212                              tiScsiRequest,
213                              satIOContext);
214          break;
215 
216        case SCSIOPC_READ_12:
217          TI_DBG5(("satIOStart: SCSIOPC_READ_12\n"));
218          retVal = satRead12( tiRoot,
219                              tiIORequest,
220                              tiDeviceHandle,
221                              tiScsiRequest,
222                              satIOContext);
223          break;
224 
225        case SCSIOPC_READ_16:
226          retVal = satRead16( tiRoot,
227                              tiIORequest,
228                              tiDeviceHandle,
229                              tiScsiRequest,
230                              satIOContext);
231          break;
232 
233        case SCSIOPC_WRITE_6:
234          retVal = satWrite6( tiRoot,
235                              tiIORequest,
236                              tiDeviceHandle,
237                              tiScsiRequest,
238                              satIOContext);
239          break;
240 
241        case SCSIOPC_WRITE_10:
242          retVal = satWrite10( tiRoot,
243                               tiIORequest,
244                               tiDeviceHandle,
245                               tiScsiRequest,
246                               satIOContext);
247          break;
248 
249        case SCSIOPC_WRITE_12:
250          TI_DBG5(("satIOStart: SCSIOPC_WRITE_12 \n"));
251          retVal = satWrite12( tiRoot,
252                               tiIORequest,
253                               tiDeviceHandle,
254                               tiScsiRequest,
255                               satIOContext);
256 
257          break;
258 
259        case SCSIOPC_WRITE_16:
260          TI_DBG5(("satIOStart: SCSIOPC_WRITE_16\n"));
261          retVal = satWrite16( tiRoot,
262                               tiIORequest,
263                               tiDeviceHandle,
264                               tiScsiRequest,
265                               satIOContext);
266 
267          break;
268 
269        case SCSIOPC_VERIFY_10:
270          retVal = satVerify10( tiRoot,
271                                tiIORequest,
272                                tiDeviceHandle,
273                                tiScsiRequest,
274                                satIOContext);
275          break;
276 
277        case SCSIOPC_VERIFY_12:
278          TI_DBG5(("satIOStart: SCSIOPC_VERIFY_12\n"));
279          retVal = satVerify12( tiRoot,
280                                tiIORequest,
281                                tiDeviceHandle,
282                                tiScsiRequest,
283                                satIOContext);
284          break;
285 
286        case SCSIOPC_VERIFY_16:
287          TI_DBG5(("satIOStart: SCSIOPC_VERIFY_16\n"));
288          retVal = satVerify16( tiRoot,
289                                tiIORequest,
290                                tiDeviceHandle,
291                                tiScsiRequest,
292                                satIOContext);
293          break;
294 
295        case SCSIOPC_TEST_UNIT_READY:
296          retVal = satTestUnitReady( tiRoot,
297                                     tiIORequest,
298                                     tiDeviceHandle,
299                                     tiScsiRequest,
300                                     satIOContext);
301          break;
302 
303        case SCSIOPC_INQUIRY:
304          retVal = satInquiry( tiRoot,
305                               tiIORequest,
306                               tiDeviceHandle,
307                               tiScsiRequest,
308                               satIOContext);
309          break;
310 
311        case SCSIOPC_REQUEST_SENSE:
312          retVal = satRequestSense( tiRoot,
313                                    tiIORequest,
314                                    tiDeviceHandle,
315                                    tiScsiRequest,
316                                    satIOContext);
317          break;
318 
319        case SCSIOPC_MODE_SENSE_6:
320          retVal = satModeSense6( tiRoot,
321                                  tiIORequest,
322                                  tiDeviceHandle,
323                                  tiScsiRequest,
324                                  satIOContext);
325          break;
326 
327        case SCSIOPC_MODE_SENSE_10:
328          retVal = satModeSense10( tiRoot,
329                                  tiIORequest,
330                                  tiDeviceHandle,
331                                  tiScsiRequest,
332                                  satIOContext);
333          break;
334 
335 
336        case SCSIOPC_READ_CAPACITY_10:
337          retVal = satReadCapacity10( tiRoot,
338                                      tiIORequest,
339                                      tiDeviceHandle,
340                                      tiScsiRequest,
341                                      satIOContext);
342          break;
343 
344        case SCSIOPC_READ_CAPACITY_16:
345          retVal = satReadCapacity16( tiRoot,
346                                      tiIORequest,
347                                      tiDeviceHandle,
348                                      tiScsiRequest,
349                                      satIOContext);
350          break;
351 
352        case SCSIOPC_REPORT_LUN:
353          retVal = satReportLun( tiRoot,
354                                 tiIORequest,
355                                 tiDeviceHandle,
356                                 tiScsiRequest,
357                                 satIOContext);
358          break;
359 
360        case SCSIOPC_FORMAT_UNIT:
361          TI_DBG5(("satIOStart: SCSIOPC_FORMAT_UNIT\n"));
362          retVal = satFormatUnit( tiRoot,
363                                  tiIORequest,
364                                  tiDeviceHandle,
365                                  tiScsiRequest,
366                                  satIOContext);
367          break;
368        case SCSIOPC_SEND_DIAGNOSTIC: /* Table 28, p40 */
369          TI_DBG5(("satIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
370          retVal = satSendDiagnostic( tiRoot,
371                                      tiIORequest,
372                                      tiDeviceHandle,
373                                      tiScsiRequest,
374                                      satIOContext);
375          break;
376 
377        case SCSIOPC_START_STOP_UNIT:
378          TI_DBG5(("satIOStart: SCSIOPC_START_STOP_UNIT\n"));
379          retVal = satStartStopUnit( tiRoot,
380                                     tiIORequest,
381                                     tiDeviceHandle,
382                                     tiScsiRequest,
383                                     satIOContext);
384          break;
385 
386        case SCSIOPC_WRITE_SAME_10: /*  sector and LBA; SAT p64 case 3 accessing payload and very
387                                       inefficient now */
388          TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_10\n"));
389          retVal = satWriteSame10( tiRoot,
390                                   tiIORequest,
391                                   tiDeviceHandle,
392                                   tiScsiRequest,
393                                   satIOContext);
394          break;
395 
396        case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */
397          TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_16\n"));
398          retVal = satWriteSame16( tiRoot,
399                                   tiIORequest,
400                                   tiDeviceHandle,
401                                   tiScsiRequest,
402                                   satIOContext);
403          break;
404 
405        case SCSIOPC_LOG_SENSE: /* SCT and log parameter(informational exceptions) */
406          TI_DBG5(("satIOStart: SCSIOPC_LOG_SENSE\n"));
407          retVal = satLogSense( tiRoot,
408                                tiIORequest,
409                                tiDeviceHandle,
410                                tiScsiRequest,
411                                satIOContext);
412          break;
413 
414        case SCSIOPC_MODE_SELECT_6: /*mode layout and AlloLen check */
415          TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_6\n"));
416          retVal = satModeSelect6( tiRoot,
417                                   tiIORequest,
418                                   tiDeviceHandle,
419                                   tiScsiRequest,
420                                   satIOContext);
421          break;
422 
423        case SCSIOPC_MODE_SELECT_10: /* mode layout and AlloLen check and sharing CB with  satModeSelect6*/
424          TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_10\n"));
425          retVal = satModeSelect10( tiRoot,
426                                    tiIORequest,
427                                    tiDeviceHandle,
428                                    tiScsiRequest,
429                                    satIOContext);
430          break;
431 
432        case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with
433                                            satSynchronizeCache16 */
434          TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
435          retVal = satSynchronizeCache10( tiRoot,
436                                          tiIORequest,
437                                          tiDeviceHandle,
438                                          tiScsiRequest,
439                                          satIOContext);
440          break;
441 
442        case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with
443                                             satSynchronizeCache16 */
444 
445          TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
446          retVal = satSynchronizeCache16( tiRoot,
447                                          tiIORequest,
448                                          tiDeviceHandle,
449                                          tiScsiRequest,
450                                          satIOContext);
451          break;
452 
453        case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */
454          TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
455          retVal = satWriteAndVerify10( tiRoot,
456                                        tiIORequest,
457                                        tiDeviceHandle,
458                                        tiScsiRequest,
459                                        satIOContext);
460          break;
461 
462        case SCSIOPC_WRITE_AND_VERIFY_12:
463          TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
464          retVal = satWriteAndVerify12( tiRoot,
465                                        tiIORequest,
466                                        tiDeviceHandle,
467                                        tiScsiRequest,
468                                        satIOContext);
469          break;
470 
471        case SCSIOPC_WRITE_AND_VERIFY_16:
472          TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
473          retVal = satWriteAndVerify16( tiRoot,
474                                        tiIORequest,
475                                        tiDeviceHandle,
476                                        tiScsiRequest,
477                                        satIOContext);
478 
479          break;
480 
481        case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
482          TI_DBG5(("satIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
483          retVal = satReadMediaSerialNumber( tiRoot,
484                                             tiIORequest,
485                                             tiDeviceHandle,
486                                             tiScsiRequest,
487                                             satIOContext);
488 
489          break;
490 
491        case SCSIOPC_READ_BUFFER:
492          TI_DBG5(("satIOStart: SCSIOPC_READ_BUFFER\n"));
493          retVal = satReadBuffer( tiRoot,
494                                  tiIORequest,
495                                  tiDeviceHandle,
496                                  tiScsiRequest,
497                                  satIOContext);
498 
499          break;
500 
501        case SCSIOPC_WRITE_BUFFER:
502          TI_DBG5(("satIOStart: SCSIOPC_WRITE_BUFFER\n"));
503          retVal = satWriteBuffer( tiRoot,
504                                  tiIORequest,
505                                  tiDeviceHandle,
506                                  tiScsiRequest,
507                                  satIOContext);
508 
509          break;
510 
511        case SCSIOPC_REASSIGN_BLOCKS:
512          TI_DBG5(("satIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
513          retVal = satReassignBlocks( tiRoot,
514                                  tiIORequest,
515                                  tiDeviceHandle,
516                                  tiScsiRequest,
517                                  satIOContext);
518 
519          break;
520 
521        default:
522          /* Not implemented SCSI cmd, set up error response */
523          TI_DBG1(("satIOStart: unsupported SCSI cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
524                     scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
525 
526          satSetSensePayload( pSense,
527                              SCSI_SNSKEY_ILLEGAL_REQUEST,
528                              0,
529                              SCSI_SNSCODE_INVALID_COMMAND,
530                              satIOContext);
531 
532          ostiInitiatorIOCompleted( tiRoot,
533                                    tiIORequest,
534                                    tiIOSuccess,
535                                    SCSI_STAT_CHECK_CONDITION,
536                                    satIOContext->pTiSenseData,
537                                    satIOContext->interruptContext );
538          retVal = tiSuccess;
539 
540          break;
541 
542      }  /* end switch  */
543   }
544   if (retVal == tiBusy)
545   {
546 #ifdef  TD_DEBUG_ENABLE
547     oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
548 #endif
549     TI_DBG1(("satIOStart: BUSY did %d\n", oneDeviceData->id));
550     TI_DBG3(("satIOStart: LL is busy or target queue is full\n"));
551     TI_DBG3(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
552     TI_DBG3(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
553     pSatIntIo               = satIOContext->satIntIoContext;
554 
555     /* interal structure free */
556     satFreeIntIoResource( tiRoot,
557                           pSatDevData,
558                           pSatIntIo);
559   }
560 
561 ext:
562   return retVal;
563 }
564 
565 
566 /*****************************************************************************/
567 /*! \brief Setup up the SCSI Sense response.
568  *
569  *  This function is used to setup up the Sense Data payload for
570  *     CHECK CONDITION status.
571  *
572  *  \param pSense:      Pointer to the scsiRspSense_t sense data structure.
573  *  \param SnsKey:      SCSI Sense Key.
574  *  \param SnsInfo:     SCSI Sense Info.
575  *  \param SnsCode:     SCSI Sense Code.
576  *
577  *  \return: None
578  */
579 /*****************************************************************************/
580 void satSetSensePayload( scsiRspSense_t   *pSense,
581                          bit8             SnsKey,
582                          bit32            SnsInfo,
583                          bit16            SnsCode,
584                          satIOContext_t   *satIOContext
585                          )
586 {
587   /* for fixed format sense data, SPC-4, p37 */
588   bit32      i;
589   bit32      senseLength;
590 
591   TI_DBG5(("satSetSensePayload: start\n"));
592 
593   senseLength  = sizeof(scsiRspSense_t);
594 
595   /* zero out the data area */
596   for (i=0;i< senseLength;i++)
597   {
598     ((bit8*)pSense)[i] = 0;
599   }
600 
601   /*
602    * SCSI Sense Data part of response data
603    */
604   pSense->snsRespCode  = 0x70;    /*  0xC0 == vendor specific */
605                                       /*  0x70 == standard current error */
606   pSense->senseKey     = SnsKey;
607   /*
608    * Put sense info in scsi order format
609    */
610   pSense->info[0]      = (bit8)((SnsInfo >> 24) & 0xff);
611   pSense->info[1]      = (bit8)((SnsInfo >> 16) & 0xff);
612   pSense->info[2]      = (bit8)((SnsInfo >> 8) & 0xff);
613   pSense->info[3]      = (bit8)((SnsInfo) & 0xff);
614   pSense->addSenseLen  = 11;          /* fixed size of sense data = 18 */
615   pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
616   pSense->senseQual    = (bit8)(SnsCode & 0xFF);
617   /*
618    * Set pointer in scsi status
619    */
620   switch(SnsKey)
621   {
622     /*
623      * set illegal request sense key specific error in cdb, no bit pointer
624      */
625     case SCSI_SNSKEY_ILLEGAL_REQUEST:
626       pSense->skeySpecific[0] = 0xC8;
627       break;
628 
629     default:
630       break;
631   }
632   /* setting sense data length */
633   if (satIOContext != agNULL)
634   {
635     satIOContext->pTiSenseData->senseLen = 18;
636   }
637   else
638   {
639     TI_DBG1(("satSetSensePayload: satIOContext is NULL\n"));
640   }
641 }
642 
643 /*****************************************************************************/
644 /*! \brief Setup up the SCSI Sense response.
645  *
646  *  This function is used to setup up the Sense Data payload for
647  *     CHECK CONDITION status.
648  *
649  *  \param pSense:      Pointer to the scsiRspSense_t sense data structure.
650  *  \param SnsKey:      SCSI Sense Key.
651  *  \param SnsInfo:     SCSI Sense Info.
652  *  \param SnsCode:     SCSI Sense Code.
653  *
654  *  \return: None
655  */
656 /*****************************************************************************/
657 
658 void satSetDeferredSensePayload( scsiRspSense_t  *pSense,
659                                  bit8             SnsKey,
660                                  bit32            SnsInfo,
661                                  bit16            SnsCode,
662                                  satIOContext_t   *satIOContext
663                                  )
664 {
665   /* for fixed format sense data, SPC-4, p37 */
666   bit32      i;
667   bit32      senseLength;
668 
669   senseLength  = sizeof(scsiRspSense_t);
670 
671   /* zero out the data area */
672   for (i=0;i< senseLength;i++)
673   {
674     ((bit8*)pSense)[i] = 0;
675   }
676 
677   /*
678    * SCSI Sense Data part of response data
679    */
680   pSense->snsRespCode  = 0x71;        /*  0xC0 == vendor specific */
681                                       /*  0x70 == standard current error */
682   pSense->senseKey     = SnsKey;
683   /*
684    * Put sense info in scsi order format
685    */
686   pSense->info[0]      = (bit8)((SnsInfo >> 24) & 0xff);
687   pSense->info[1]      = (bit8)((SnsInfo >> 16) & 0xff);
688   pSense->info[2]      = (bit8)((SnsInfo >> 8) & 0xff);
689   pSense->info[3]      = (bit8)((SnsInfo) & 0xff);
690   pSense->addSenseLen  = 11;          /* fixed size of sense data = 18 */
691   pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
692   pSense->senseQual    = (bit8)(SnsCode & 0xFF);
693   /*
694    * Set pointer in scsi status
695    */
696   switch(SnsKey)
697   {
698     /*
699      * set illegal request sense key specific error in cdb, no bit pointer
700      */
701     case SCSI_SNSKEY_ILLEGAL_REQUEST:
702       pSense->skeySpecific[0] = 0xC8;
703       break;
704 
705     default:
706       break;
707   }
708 
709   /* setting sense data length */
710   if (satIOContext != agNULL)
711   {
712     satIOContext->pTiSenseData->senseLen = 18;
713   }
714   else
715   {
716     TI_DBG1(("satSetDeferredSensePayload: satIOContext is NULL\n"));
717   }
718 
719 }
720 /*****************************************************************************/
721 /*! \brief SAT implementation for ATAPI Packet Command.
722  *
723  *  SAT implementation for ATAPI Packet and send FIS request to LL layer.
724  *
725  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
726  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
727  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
728  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
729  *  \param   satIOContext_t:   Pointer to the SAT IO Context
730  *
731  *  \return If command is started successfully
732  *    - \e tiSuccess:     I/O request successfully initiated.
733  *    - \e tiBusy:        No resources available, try again later.
734  *    - \e tiIONoDevice:  Invalid device handle.
735  *    - \e tiError:       Other errors.
736  */
737 /*****************************************************************************/
738 GLOBAL bit32  satPacket(
739                    tiRoot_t                  *tiRoot,
740                    tiIORequest_t             *tiIORequest,
741                    tiDeviceHandle_t          *tiDeviceHandle,
742                    tiScsiInitiatorRequest_t  *tiScsiRequest,
743                    satIOContext_t            *satIOContext)
744 {
745   bit32                     status;
746   bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
747   satDeviceData_t           *pSatDevData;
748   tiIniScsiCmnd_t           *scsiCmnd;
749   agsaFisRegHostToDevice_t  *fis;
750 
751   pSatDevData   = satIOContext->pSatDevData;
752   scsiCmnd      = &tiScsiRequest->scsiCmnd;
753   fis           = satIOContext->pFis;
754 
755   TI_DBG3(("satPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
756            scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
757            scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
758            scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
759 
760   fis->h.fisType        = 0x27;                   /* Reg host to device */
761   fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
762   fis->h.command        = SAT_PACKET;             /* 0xA0 */
763   if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
764   {
765      fis->h.features    = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
766   }
767   else
768   {
769      fis->h.features    = 0;                      /* FIS reserve */
770   }
771   /* Byte count low and byte count high */
772   if ( scsiCmnd->expDataLength > 0xFFFF )
773   {
774      fis->d.lbaMid = 0xFF;                               /* FIS LBA (7 :0 ) */
775      fis->d.lbaHigh = 0xFF;                              /* FIS LBA (15:8 ) */
776   }
777   else
778   {
779      fis->d.lbaMid = (bit8)scsiCmnd->expDataLength;       /* FIS LBA (7 :0 ) */
780      fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (15:8 ) */
781   }
782 
783   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
784   fis->d.device         = 0;                      /* FIS LBA (27:24) and FIS LBA mode  */
785   fis->d.lbaLowExp      = 0;
786   fis->d.lbaMidExp      = 0;
787   fis->d.lbaHighExp     = 0;
788   fis->d.featuresExp    = 0;
789   fis->d.sectorCount    = 0;                       /* FIS sector count (7:0) */
790   fis->d.sectorCountExp = 0;
791   fis->d.reserved4      = 0;
792   fis->d.control        = 0;                      /* FIS HOB bit clear */
793   fis->d.reserved5      = 0;
794 
795   satIOContext->ATACmd = SAT_PACKET;
796 
797   if (tiScsiRequest->dataDirection == tiDirectionIn)
798   {
799       agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
800   }
801   else
802   {
803       agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
804   }
805 
806   if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
807   {
808      /*DMA transfer mode*/
809      fis->h.features |= 0x01;
810   }
811   else
812   {
813      /*PIO transfer mode*/
814      fis->h.features |= 0x0;
815   }
816 
817   satIOContext->satCompleteCB = &satPacketCB;
818 
819   /*
820    * Prepare SGL and send FIS to LL layer.
821    */
822   satIOContext->reqType = agRequestType;       /* Save it */
823 
824   status = sataLLIOStart( tiRoot,
825                           tiIORequest,
826                           tiDeviceHandle,
827                           tiScsiRequest,
828                           satIOContext);
829 
830   TI_DBG5(("satPacket: return\n"));
831   return (status);
832 }
833 
834 /*****************************************************************************/
835 /*! \brief SAT implementation for satSetFeatures.
836  *
837  *  This function creates SetFeatures fis and sends the request to LL layer
838  *
839  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
840  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
841  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
842  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
843  *  \param   satIOContext_t:   Pointer to the SAT IO Context
844  *
845  *  \return If command is started successfully
846  *    - \e tiSuccess:     I/O request successfully initiated.
847  *    - \e tiBusy:        No resources available, try again later.
848  *    - \e tiIONoDevice:  Invalid device handle.
849  *    - \e tiError:       Other errors.
850  */
851 /*****************************************************************************/
852 GLOBAL bit32  satSetFeatures(
853                             tiRoot_t                  *tiRoot,
854                             tiIORequest_t             *tiIORequest,
855                             tiDeviceHandle_t          *tiDeviceHandle,
856                             tiScsiInitiatorRequest_t  *tiScsiRequest,
857                             satIOContext_t            *satIOContext,
858                             bit8                      bIsDMAMode
859                             )
860 {
861   bit32                     status;
862   bit32                     agRequestType;
863   agsaFisRegHostToDevice_t  *fis;
864 
865   fis           = satIOContext->pFis;
866   TI_DBG3(("satSetFeatures: start\n"));
867 
868   /*
869    * Send the Set Features command.
870    */
871   fis->h.fisType        = 0x27;                   /* Reg host to device */
872   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
873   fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
874   fis->h.features       = 0x03;                   /* set transfer mode */
875   fis->d.lbaLow         = 0;
876   fis->d.lbaMid         = 0;
877   fis->d.lbaHigh        = 0;
878   fis->d.device         = 0;
879   fis->d.lbaLowExp      = 0;
880   fis->d.lbaMidExp      = 0;
881   fis->d.lbaHighExp     = 0;
882   fis->d.featuresExp    = 0;
883   fis->d.sectorCountExp = 0;
884   fis->d.reserved4      = 0;
885   fis->d.control        = 0;                      /* FIS HOB bit clear */
886   fis->d.reserved5      = 0;
887 
888   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
889 
890   /* Initialize CB for SATA completion.
891    */
892   if (bIsDMAMode)
893   {
894       fis->d.sectorCount = 0x45;
895       /*satIOContext->satCompleteCB = &satSetFeaturesDMACB;*/
896   }
897   else
898   {
899       fis->d.sectorCount = 0x0C;
900       /*satIOContext->satCompleteCB = &satSetFeaturesPIOCB;*/
901   }
902   satIOContext->satCompleteCB = &satSetFeaturesCB;
903 
904   /*
905    * Prepare SGL and send FIS to LL layer.
906    */
907   satIOContext->reqType = agRequestType;       /* Save it */
908 
909   status = sataLLIOStart( tiRoot,
910                           tiIORequest,
911                           tiDeviceHandle,
912                           tiScsiRequest,
913                           satIOContext);
914 
915   TI_DBG5(("satSetFeatures: return\n"));
916 
917   return status;
918 }
919 /*****************************************************************************/
920 /*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device.
921  *
922  *  SAT implementation for SCSI REQUEST SENSE.
923  *
924  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
925  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
926  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
927  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
928  *  \param   satIOContext_t:   Pointer to the SAT IO Context
929  *
930  *  \return If command is started successfully
931  *    - \e tiSuccess:     I/O request successfully initiated.
932  *    - \e tiBusy:        No resources available, try again later.
933  *    - \e tiIONoDevice:  Invalid device handle.
934  *    - \e tiError:       Other errors.
935  */
936 /*****************************************************************************/
937 GLOBAL bit32  satRequestSenseForATAPI(
938                    tiRoot_t                  *tiRoot,
939                    tiIORequest_t             *tiIORequest,
940                    tiDeviceHandle_t          *tiDeviceHandle,
941                    tiScsiInitiatorRequest_t  *tiScsiRequest,
942                    satIOContext_t            *satIOContext)
943 {
944   bit32                     status;
945   bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
946   satDeviceData_t           *pSatDevData;
947   tiIniScsiCmnd_t           *scsiCmnd;
948   agsaFisRegHostToDevice_t  *fis;
949 
950   pSatDevData   = satIOContext->pSatDevData;
951   scsiCmnd      = &tiScsiRequest->scsiCmnd;
952   fis           = satIOContext->pFis;
953 
954   scsiCmnd->cdb[0]   = SCSIOPC_REQUEST_SENSE;
955   scsiCmnd->cdb[1]   = 0;
956   scsiCmnd->cdb[2]   = 0;
957   scsiCmnd->cdb[3]   = 0;
958   scsiCmnd->cdb[4]   = SENSE_DATA_LENGTH;
959   scsiCmnd->cdb[5]   = 0;
960   TI_DBG3(("satRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
961            scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
962            scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
963            scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
964 
965   fis->h.fisType        = 0x27;                   /* Reg host to device */
966   fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
967   fis->h.command        = SAT_PACKET;             /* 0xA0 */
968   if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
969   {
970      fis->h.features    = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
971   }
972   else
973   {
974      fis->h.features    = 0;                         /* FIS reserve */
975   }
976 
977   fis->d.lbaLow         = 0;                         /* FIS LBA (7 :0 ) */
978   fis->d.lbaMid         = 0;                         /* FIS LBA (15:8 ) */
979   fis->d.lbaHigh        = 0x20;                      /* FIS LBA (23:16) */
980   fis->d.device         = 0;                         /* FIS LBA (27:24) and FIS LBA mode  */
981   fis->d.lbaLowExp      = 0;
982   fis->d.lbaMidExp      = 0;
983   fis->d.lbaHighExp     = 0;
984   fis->d.featuresExp    = 0;
985   fis->d.sectorCount    = 0;                          /* FIS sector count (7:0) */
986   fis->d.sectorCountExp = 0;
987   fis->d.reserved4      = 0;
988   fis->d.control        = 0;                         /* FIS HOB bit clear */
989   fis->d.reserved5      = (bit32)(scsiCmnd->cdb[0]|(scsiCmnd->cdb[1]<<8)|(scsiCmnd->cdb[2]<<16)|(scsiCmnd->cdb[3]<<24));
990 
991   satIOContext->ATACmd = SAT_PACKET;
992 
993   agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
994 
995   //if (pSatDevData->sat48BitSupport == agTRUE)
996   {
997     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
998     {
999        fis->h.features |= 0x01;
1000     }
1001     else
1002     {
1003        fis->h.features |= 0x0;
1004     }
1005   }
1006 
1007   satIOContext->satCompleteCB = &satRequestSenseForATAPICB;
1008 
1009   /*
1010    * Prepare SGL and send FIS to LL layer.
1011    */
1012   satIOContext->reqType = agRequestType;       /* Save it */
1013 
1014   status = sataLLIOStart( tiRoot,
1015                           tiIORequest,
1016                           tiDeviceHandle,
1017                           tiScsiRequest,
1018                           satIOContext);
1019 
1020   TI_DBG5(("satRequestSenseForATAPI: return\n"));
1021   return (status);
1022 }
1023 /*****************************************************************************/
1024 /*! \brief SAT implementation for satDeviceReset.
1025  *
1026  *  This function creates DEVICE RESET fis and sends the request to LL layer
1027  *
1028  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1029  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1030  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1031  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1032  *  \param   satIOContext_t:   Pointer to the SAT IO Context
1033  *
1034  *  \return If command is started successfully
1035  *    - \e tiSuccess:     I/O request successfully initiated.
1036  *    - \e tiBusy:        No resources available, try again later.
1037  *    - \e tiIONoDevice:  Invalid device handle.
1038  *    - \e tiError:       Other errors.
1039  */
1040 /*****************************************************************************/
1041 GLOBAL bit32 satDeviceReset(
1042                             tiRoot_t                  *tiRoot,
1043                             tiIORequest_t             *tiIORequest,
1044                             tiDeviceHandle_t          *tiDeviceHandle,
1045                             tiScsiInitiatorRequest_t  *tiScsiRequest,
1046                             satIOContext_t            *satIOContext
1047                             )
1048 {
1049   bit32                     status;
1050   bit32                     agRequestType;
1051   agsaFisRegHostToDevice_t  *fis;
1052 
1053   fis           = satIOContext->pFis;
1054 
1055   TI_DBG3(("satDeviceReset: start\n"));
1056 
1057   /*
1058    * Send the  Execute Device Diagnostic command.
1059    */
1060   fis->h.fisType        = 0x27;                   /* Reg host to device */
1061   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1062   fis->h.command        = SAT_DEVICE_RESET;   /* 0x90 */
1063   fis->h.features       = 0;
1064   fis->d.lbaLow         = 0;
1065   fis->d.lbaMid         = 0;
1066   fis->d.lbaHigh        = 0;
1067   fis->d.device         = 0;
1068   fis->d.lbaLowExp      = 0;
1069   fis->d.lbaMidExp      = 0;
1070   fis->d.lbaHighExp     = 0;
1071   fis->d.featuresExp    = 0;
1072   fis->d.sectorCount    = 0;
1073   fis->d.sectorCountExp = 0;
1074   fis->d.reserved4      = 0;
1075   fis->d.control        = 0;                      /* FIS HOB bit clear */
1076   fis->d.reserved5      = 0;
1077 
1078   agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
1079 
1080   /* Initialize CB for SATA completion.
1081    */
1082   satIOContext->satCompleteCB = &satDeviceResetCB;
1083 
1084   /*
1085    * Prepare SGL and send FIS to LL layer.
1086    */
1087   satIOContext->reqType = agRequestType;       /* Save it */
1088 
1089   status = sataLLIOStart( tiRoot,
1090                           tiIORequest,
1091                           tiDeviceHandle,
1092                           tiScsiRequest,
1093                           satIOContext);
1094 
1095   TI_DBG3(("satDeviceReset: return\n"));
1096 
1097   return status;
1098 }
1099 
1100 /*****************************************************************************/
1101 /*! \brief SAT implementation for saExecuteDeviceDiagnostic.
1102  *
1103  *  This function creates Execute Device Diagnostic fis and sends the request to LL layer
1104  *
1105  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1106  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1107  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1108  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1109  *  \param   satIOContext_t:   Pointer to the SAT IO Context
1110  *
1111  *  \return If command is started successfully
1112  *    - \e tiSuccess:     I/O request successfully initiated.
1113  *    - \e tiBusy:        No resources available, try again later.
1114  *    - \e tiIONoDevice:  Invalid device handle.
1115  *    - \e tiError:       Other errors.
1116  */
1117 /*****************************************************************************/
1118 GLOBAL bit32  satExecuteDeviceDiagnostic(
1119                             tiRoot_t                  *tiRoot,
1120                             tiIORequest_t             *tiIORequest,
1121                             tiDeviceHandle_t          *tiDeviceHandle,
1122                             tiScsiInitiatorRequest_t  *tiScsiRequest,
1123                             satIOContext_t            *satIOContext
1124                             )
1125 {
1126   bit32                     status;
1127   bit32                     agRequestType;
1128   agsaFisRegHostToDevice_t  *fis;
1129 
1130   fis           = satIOContext->pFis;
1131 
1132   TI_DBG3(("satExecuteDeviceDiagnostic: start\n"));
1133 
1134   /*
1135    * Send the  Execute Device Diagnostic command.
1136    */
1137   fis->h.fisType        = 0x27;                   /* Reg host to device */
1138   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1139   fis->h.command        = SAT_EXECUTE_DEVICE_DIAGNOSTIC;   /* 0x90 */
1140   fis->h.features       = 0;
1141   fis->d.lbaLow         = 0;
1142   fis->d.lbaMid         = 0;
1143   fis->d.lbaHigh        = 0;
1144   fis->d.device         = 0;
1145   fis->d.lbaLowExp      = 0;
1146   fis->d.lbaMidExp      = 0;
1147   fis->d.lbaHighExp     = 0;
1148   fis->d.featuresExp    = 0;
1149   fis->d.sectorCount    = 0;
1150   fis->d.sectorCountExp = 0;
1151   fis->d.reserved4      = 0;
1152   fis->d.control        = 0;                      /* FIS HOB bit clear */
1153   fis->d.reserved5      = 0;
1154 
1155   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
1156 
1157   /* Initialize CB for SATA completion.
1158    */
1159   satIOContext->satCompleteCB = &satExecuteDeviceDiagnosticCB;
1160 
1161   /*
1162    * Prepare SGL and send FIS to LL layer.
1163    */
1164   satIOContext->reqType = agRequestType;       /* Save it */
1165 
1166   status = sataLLIOStart( tiRoot,
1167                           tiIORequest,
1168                           tiDeviceHandle,
1169                           tiScsiRequest,
1170                           satIOContext);
1171 
1172   TI_DBG5(("satExecuteDeviceDiagnostic: return\n"));
1173 
1174   return status;
1175 }
1176 
1177 
1178 /*****************************************************************************/
1179 /*! \brief SAT implementation for SCSI READ10.
1180  *
1181  *  SAT implementation for SCSI READ10 and send FIS request to LL layer.
1182  *
1183  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1184  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1185  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1186  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1187  *  \param   satIOContext_t:   Pointer to the SAT IO Context
1188  *
1189  *  \return If command is started successfully
1190  *    - \e tiSuccess:     I/O request successfully initiated.
1191  *    - \e tiBusy:        No resources available, try again later.
1192  *    - \e tiIONoDevice:  Invalid device handle.
1193  *    - \e tiError:       Other errors.
1194  */
1195 /*****************************************************************************/
1196 GLOBAL bit32  satRead10(
1197                    tiRoot_t                  *tiRoot,
1198                    tiIORequest_t             *tiIORequest,
1199                    tiDeviceHandle_t          *tiDeviceHandle,
1200                    tiScsiInitiatorRequest_t *tiScsiRequest,
1201                    satIOContext_t            *satIOContext)
1202 {
1203 
1204   bit32                     status;
1205   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1206   satDeviceData_t           *pSatDevData;
1207   scsiRspSense_t            *pSense;
1208   tiIniScsiCmnd_t           *scsiCmnd;
1209   agsaFisRegHostToDevice_t  *fis;
1210   bit32                     lba = 0;
1211   bit32                     tl = 0;
1212   bit32                     LoopNum = 1;
1213   bit8                      LBA[4];
1214   bit8                      TL[4];
1215   bit32                     rangeChk = agFALSE; /* lba and tl range check */
1216 
1217   pSense        = satIOContext->pSense;
1218   pSatDevData   = satIOContext->pSatDevData;
1219   scsiCmnd      = &tiScsiRequest->scsiCmnd;
1220   fis           = satIOContext->pFis;
1221 
1222   TI_DBG5(("satRead10: start\n"));
1223   TI_DBG5(("satRead10: pSatDevData=%p\n", pSatDevData));
1224   //  tdhexdump("satRead10", (bit8 *)scsiCmnd->cdb, 10);
1225 
1226   /* checking FUA_NV */
1227   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1228   {
1229     satSetSensePayload( pSense,
1230                         SCSI_SNSKEY_ILLEGAL_REQUEST,
1231                         0,
1232                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1233                         satIOContext);
1234 
1235     ostiInitiatorIOCompleted( tiRoot,
1236                               tiIORequest,
1237                               tiIOSuccess,
1238                               SCSI_STAT_CHECK_CONDITION,
1239                               satIOContext->pTiSenseData,
1240                               satIOContext->interruptContext );
1241 
1242     TI_DBG1(("satRead10: return FUA_NV\n"));
1243     return tiSuccess;
1244 
1245   }
1246 
1247   /* checking CONTROL */
1248   /* NACA == 1 or LINK == 1*/
1249   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
1250   {
1251     satSetSensePayload( pSense,
1252                         SCSI_SNSKEY_ILLEGAL_REQUEST,
1253                         0,
1254                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1255                         satIOContext);
1256 
1257     ostiInitiatorIOCompleted( tiRoot,
1258                               tiIORequest,
1259                               tiIOSuccess,
1260                               SCSI_STAT_CHECK_CONDITION,
1261                               satIOContext->pTiSenseData,
1262                               satIOContext->interruptContext );
1263 
1264     TI_DBG1(("satRead10: return control\n"));
1265     return tiSuccess;
1266   }
1267 
1268   osti_memset(LBA, 0, sizeof(LBA));
1269   osti_memset(TL, 0, sizeof(TL));
1270 
1271   /* do not use memcpy due to indexing in LBA and TL */
1272   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
1273   LBA[1] = scsiCmnd->cdb[3];
1274   LBA[2] = scsiCmnd->cdb[4];
1275   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
1276 
1277   TL[0] = 0;
1278   TL[1] = 0;
1279   TL[2] = scsiCmnd->cdb[7];   /* MSB */
1280   TL[3] = scsiCmnd->cdb[8];   /* LSB */
1281 
1282   rangeChk = satAddNComparebit32(LBA, TL);
1283 
1284   /* cbd10; computing LBA and transfer length */
1285   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
1286     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
1287   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
1288 
1289 
1290   TI_DBG5(("satRead10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
1291   TI_DBG5(("satRead10: lba 0x%x functioned lba 0x%x\n", lba, satComputeCDB10LBA(satIOContext)));
1292   TI_DBG5(("satRead10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
1293 
1294   /* Table 34, 9.1, p 46 */
1295   /*
1296     note: As of 2/10/2006, no support for DMA QUEUED
1297    */
1298 
1299   /*
1300     Table 34, 9.1, p 46, b
1301     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
1302     return check condition
1303   */
1304 
1305   if (pSatDevData->satNCQ != agTRUE &&
1306       pSatDevData->sat48BitSupport != agTRUE
1307       )
1308   {
1309     if (lba > SAT_TR_LBA_LIMIT - 1)
1310     {
1311       TI_DBG1(("satRead10: return LBA out of range, not EXT\n"));
1312       satSetSensePayload( pSense,
1313                           SCSI_SNSKEY_ILLEGAL_REQUEST,
1314                           0,
1315                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1316                           satIOContext);
1317 
1318       ostiInitiatorIOCompleted( tiRoot,
1319                                 tiIORequest,
1320                                 tiIOSuccess,
1321                                 SCSI_STAT_CHECK_CONDITION,
1322                                 satIOContext->pTiSenseData,
1323                                 satIOContext->interruptContext );
1324 
1325     return tiSuccess;
1326     }
1327 
1328 
1329     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
1330     {
1331       TI_DBG1(("satRead10: return LBA+TL out of range, not EXT\n"));
1332       satSetSensePayload( pSense,
1333                           SCSI_SNSKEY_ILLEGAL_REQUEST,
1334                           0,
1335                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1336                           satIOContext);
1337 
1338       ostiInitiatorIOCompleted( tiRoot,
1339                                 tiIORequest,
1340                                 tiIOSuccess,
1341                                 SCSI_STAT_CHECK_CONDITION,
1342                                 satIOContext->pTiSenseData,
1343                                 satIOContext->interruptContext );
1344 
1345     return tiSuccess;
1346     }
1347   }
1348 
1349   /* case 1 and 2 */
1350   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
1351   {
1352     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1353     {
1354       /* case 2 */
1355       /* READ DMA*/
1356       /* in case that we can't fit the transfer length,
1357          we need to make it fit by sending multiple ATA cmnds */
1358       TI_DBG5(("satRead10: case 2\n"));
1359 
1360 
1361       fis->h.fisType        = 0x27;                   /* Reg host to device */
1362       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1363       fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
1364       fis->h.features       = 0;                      /* FIS reserve */
1365       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1366       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1367       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1368       fis->d.device         =
1369         (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
1370       fis->d.lbaLowExp      = 0;
1371       fis->d.lbaMidExp      = 0;
1372       fis->d.lbaHighExp     = 0;
1373       fis->d.featuresExp    = 0;
1374       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1375       fis->d.sectorCountExp = 0;
1376       fis->d.reserved4      = 0;
1377       fis->d.control        = 0;                      /* FIS HOB bit clear */
1378       fis->d.reserved5      = 0;
1379 
1380 
1381       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1382       satIOContext->ATACmd = SAT_READ_DMA;
1383     }
1384     else
1385     {
1386       /* case 1 */
1387       /* READ MULTIPLE or READ SECTOR(S) */
1388       /* READ SECTORS for easier implemetation */
1389       /* in case that we can't fit the transfer length,
1390          we need to make it fit by sending multiple ATA cmnds */
1391       TI_DBG5(("satRead10: case 1\n"));
1392 
1393       fis->h.fisType        = 0x27;                   /* Reg host to device */
1394       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1395       fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
1396       fis->h.features       = 0;                      /* FIS reserve */
1397       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1398       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1399       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1400       fis->d.device         =
1401         (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
1402       fis->d.lbaLowExp      = 0;
1403       fis->d.lbaMidExp      = 0;
1404       fis->d.lbaHighExp     = 0;
1405       fis->d.featuresExp    = 0;
1406       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1407       fis->d.sectorCountExp = 0;
1408       fis->d.reserved4      = 0;
1409       fis->d.control        = 0;                      /* FIS HOB bit clear */
1410       fis->d.reserved5      = 0;
1411 
1412 
1413       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1414       satIOContext->ATACmd = SAT_READ_SECTORS;
1415     }
1416   }
1417 
1418    /* case 3 and 4 */
1419   if (pSatDevData->sat48BitSupport == agTRUE)
1420   {
1421     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1422     {
1423       /* case 3 */
1424       /* READ DMA EXT */
1425       TI_DBG5(("satRead10: case 3\n"));
1426       fis->h.fisType        = 0x27;                   /* Reg host to device */
1427 
1428       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1429       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
1430       fis->h.features       = 0;                      /* FIS reserve */
1431       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1432       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1433       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1434       fis->d.device         = 0x40;                   /* FIS LBA mode set */
1435       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
1436       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1437       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1438       fis->d.featuresExp    = 0;                      /* FIS reserve */
1439       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1440       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
1441       fis->d.reserved4      = 0;
1442       fis->d.control        = 0;                      /* FIS HOB bit clear */
1443       fis->d.reserved5      = 0;
1444 
1445       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1446       satIOContext->ATACmd = SAT_READ_DMA_EXT;
1447 
1448     }
1449     else
1450     {
1451       /* case 4 */
1452       /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
1453       /* READ SECTORS EXT for easier implemetation */
1454       TI_DBG5(("satRead10: case 4\n"));
1455       fis->h.fisType        = 0x27;                   /* Reg host to device */
1456       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1457 
1458       /* Check FUA bit */
1459       if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1460       {
1461 
1462         /* for now, no support for FUA */
1463         satSetSensePayload( pSense,
1464                             SCSI_SNSKEY_ILLEGAL_REQUEST,
1465                             0,
1466                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1467                             satIOContext);
1468 
1469         ostiInitiatorIOCompleted( tiRoot,
1470                                   tiIORequest,
1471                                   tiIOSuccess,
1472                                   SCSI_STAT_CHECK_CONDITION,
1473                                   satIOContext->pTiSenseData,
1474                                   satIOContext->interruptContext );
1475         return tiSuccess;
1476       }
1477 
1478       fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
1479 
1480       fis->h.features       = 0;                      /* FIS reserve */
1481       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1482       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1483       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1484       fis->d.device         = 0x40;                   /* FIS LBA mode set */
1485       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
1486       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1487       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1488       fis->d.featuresExp    = 0;                      /* FIS reserve */
1489       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1490       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
1491       fis->d.reserved4      = 0;
1492       fis->d.control        = 0;                      /* FIS HOB bit clear */
1493       fis->d.reserved5      = 0;
1494 
1495       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1496       satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
1497     }
1498   }
1499 
1500   /* case 5 */
1501   if (pSatDevData->satNCQ == agTRUE)
1502   {
1503     /* READ FPDMA QUEUED */
1504     if (pSatDevData->sat48BitSupport != agTRUE)
1505     {
1506       TI_DBG5(("satRead10: case 5 !!! error NCQ but 28 bit address support \n"));
1507       satSetSensePayload( pSense,
1508                           SCSI_SNSKEY_ILLEGAL_REQUEST,
1509                           0,
1510                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1511                           satIOContext);
1512 
1513       ostiInitiatorIOCompleted( tiRoot,
1514                                 tiIORequest,
1515                                 tiIOSuccess,
1516                                 SCSI_STAT_CHECK_CONDITION,
1517                                 satIOContext->pTiSenseData,
1518                                 satIOContext->interruptContext );
1519       return tiSuccess;
1520     }
1521 
1522     TI_DBG6(("satRead10: case 5\n"));
1523 
1524     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
1525 
1526     fis->h.fisType        = 0x27;                   /* Reg host to device */
1527     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1528     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
1529     fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1530     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1531     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1532     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1533 
1534     /* Check FUA bit */
1535     if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1536       fis->d.device       = 0xC0;                   /* FIS FUA set */
1537     else
1538       fis->d.device       = 0x40;                   /* FIS FUA clear */
1539 
1540     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
1541     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1542     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1543     fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
1544     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
1545     fis->d.sectorCountExp = 0;
1546     fis->d.reserved4      = 0;
1547     fis->d.control        = 0;                      /* FIS HOB bit clear */
1548     fis->d.reserved5      = 0;
1549 
1550     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1551     satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
1552   }
1553 
1554 
1555   //  tdhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
1556 
1557   /* saves the current LBA and orginal TL */
1558   satIOContext->currentLBA = lba;
1559   satIOContext->OrgTL = tl;
1560 
1561  /*
1562     computing number of loop and remainder for tl
1563     0xFF in case not ext
1564     0xFFFF in case EXT
1565   */
1566   if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1567   {
1568     LoopNum = satComputeLoopNum(tl, 0xFF);
1569   }
1570   else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1571   {
1572     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1573     LoopNum = satComputeLoopNum(tl, 0xFFFF);
1574   }
1575   else
1576   {
1577     /* SAT_READ_FPDMA_QUEUED */
1578     LoopNum = satComputeLoopNum(tl, 0xFFFF);
1579   }
1580 
1581   satIOContext->LoopNum = LoopNum;
1582 
1583   /* Initialize CB for SATA completion.
1584    */
1585   if (LoopNum == 1)
1586   {
1587     TI_DBG5(("satRead10: NON CHAINED data\n"));
1588     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
1589   }
1590   else
1591   {
1592     TI_DBG1(("satRead10: CHAINED data\n"));
1593     /* re-setting tl */
1594     if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1595     {
1596        fis->d.sectorCount    = 0xFF;
1597     }
1598     else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1599     {
1600       /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1601       fis->d.sectorCount    = 0xFF;
1602       fis->d.sectorCountExp = 0xFF;
1603     }
1604     else
1605     {
1606       /* SAT_READ_FPDMA_QUEUED */
1607       fis->h.features       = 0xFF;
1608       fis->d.featuresExp    = 0xFF;
1609     }
1610 
1611     /* chained data */
1612     satIOContext->satCompleteCB = &satChainedDataIOCB;
1613 
1614   }
1615 
1616   /*
1617    * Prepare SGL and send FIS to LL layer.
1618    */
1619   satIOContext->reqType = agRequestType;       /* Save it */
1620 
1621   status = sataLLIOStart( tiRoot,
1622                           tiIORequest,
1623                           tiDeviceHandle,
1624                           tiScsiRequest,
1625                           satIOContext);
1626 
1627   TI_DBG5(("satRead10: return\n"));
1628   return (status);
1629 
1630 }
1631 
1632 
1633 /*****************************************************************************/
1634 /*! \brief SAT implementation for SCSI satRead_1.
1635  *
1636  *  SAT implementation for SCSI satRead_1
1637  *  Sub function of satRead10
1638  *
1639  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1640  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1641  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1642  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1643  *  \param   satIOContext_t:   Pointer to the SAT IO Context
1644  *
1645  *  \return If command is started successfully
1646  *    - \e tiSuccess:     I/O request successfully initiated.
1647  *    - \e tiBusy:        No resources available, try again later.
1648  *    - \e tiIONoDevice:  Invalid device handle.
1649  *    - \e tiError:       Other errors.
1650  */
1651 /*****************************************************************************/
1652 /*
1653  * as a part of loop for read10
1654  */
1655 GLOBAL bit32  satRead_1(
1656                           tiRoot_t                  *tiRoot,
1657                           tiIORequest_t             *tiIORequest,
1658                           tiDeviceHandle_t          *tiDeviceHandle,
1659                           tiScsiInitiatorRequest_t *tiScsiRequest,
1660                           satIOContext_t            *satIOContext)
1661 {
1662   /*
1663     Assumption: error check on lba and tl has been done in satRead*()
1664     lba = lba + tl;
1665   */
1666   bit32                     status;
1667   satIOContext_t            *satOrgIOContext = agNULL;
1668   tiIniScsiCmnd_t           *scsiCmnd;
1669   agsaFisRegHostToDevice_t  *fis;
1670   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1671   bit32                     lba = 0;
1672   bit32                     DenomTL = 0xFF;
1673   bit32                     Remainder = 0;
1674   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
1675 
1676   TI_DBG2(("satRead_1: start\n"));
1677 
1678   fis             = satIOContext->pFis;
1679   satOrgIOContext = satIOContext->satOrgIOContext;
1680   scsiCmnd        = satOrgIOContext->pScsiCmnd;
1681 
1682   osti_memset(LBA,0, sizeof(LBA));
1683 
1684   switch (satOrgIOContext->ATACmd)
1685   {
1686   case SAT_READ_DMA:
1687     DenomTL = 0xFF;
1688     break;
1689   case SAT_READ_SECTORS:
1690     DenomTL = 0xFF;
1691     break;
1692   case SAT_READ_DMA_EXT:
1693     DenomTL = 0xFFFF;
1694     break;
1695   case SAT_READ_SECTORS_EXT:
1696     DenomTL = 0xFFFF;
1697     break;
1698   case SAT_READ_FPDMA_QUEUED:
1699     DenomTL = 0xFFFF;
1700     break;
1701   default:
1702     TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1703     return tiError;
1704     break;
1705   }
1706 
1707   Remainder = satOrgIOContext->OrgTL % DenomTL;
1708   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
1709   lba = satOrgIOContext->currentLBA;
1710 
1711   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3));
1712   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
1713   LBA[2] = (bit8)((lba & 0xF0) >> 8);
1714   LBA[3] = (bit8)(lba & 0xF);
1715 
1716 
1717   switch (satOrgIOContext->ATACmd)
1718   {
1719   case SAT_READ_DMA:
1720     fis->h.fisType        = 0x27;                   /* Reg host to device */
1721     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1722     fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
1723     fis->h.features       = 0;                      /* FIS reserve */
1724     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1725     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1726     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1727     fis->d.device         =
1728       (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
1729     fis->d.lbaLowExp      = 0;
1730     fis->d.lbaMidExp      = 0;
1731     fis->d.lbaHighExp     = 0;
1732     fis->d.featuresExp    = 0;
1733 
1734     if (satOrgIOContext->LoopNum == 1)
1735     {
1736       /* last loop */
1737       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
1738     }
1739     else
1740     {
1741       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
1742     }
1743 
1744     fis->d.sectorCountExp = 0;
1745     fis->d.reserved4      = 0;
1746     fis->d.control        = 0;                      /* FIS HOB bit clear */
1747     fis->d.reserved5      = 0;
1748 
1749     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1750 
1751     break;
1752   case SAT_READ_SECTORS:
1753     fis->h.fisType        = 0x27;                   /* Reg host to device */
1754     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1755     fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
1756     fis->h.features       = 0;                      /* FIS reserve */
1757     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1758     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1759     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1760     fis->d.device         =
1761       (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
1762     fis->d.lbaLowExp      = 0;
1763     fis->d.lbaMidExp      = 0;
1764     fis->d.lbaHighExp     = 0;
1765     fis->d.featuresExp    = 0;
1766     if (satOrgIOContext->LoopNum == 1)
1767     {
1768       /* last loop */
1769       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
1770     }
1771     else
1772     {
1773       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
1774     }
1775     fis->d.sectorCountExp = 0;
1776     fis->d.reserved4      = 0;
1777     fis->d.control        = 0;                      /* FIS HOB bit clear */
1778     fis->d.reserved5      = 0;
1779 
1780     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1781 
1782     break;
1783   case SAT_READ_DMA_EXT:
1784     fis->h.fisType        = 0x27;                   /* Reg host to device */
1785     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1786     fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
1787     fis->h.features       = 0;                      /* FIS reserve */
1788     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1789     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1790     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1791     fis->d.device         = 0x40;                   /* FIS LBA mode set */
1792     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
1793     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1794     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1795     fis->d.featuresExp    = 0;                      /* FIS reserve */
1796     if (satOrgIOContext->LoopNum == 1)
1797     {
1798       /* last loop */
1799       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
1800       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
1801 
1802     }
1803     else
1804     {
1805       fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
1806       fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
1807     }
1808     fis->d.reserved4      = 0;
1809     fis->d.control        = 0;                      /* FIS HOB bit clear */
1810     fis->d.reserved5      = 0;
1811 
1812     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1813 
1814     break;
1815   case SAT_READ_SECTORS_EXT:
1816     fis->h.fisType        = 0x27;                   /* Reg host to device */
1817     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1818     fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
1819     fis->h.features       = 0;                      /* FIS reserve */
1820     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1821     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1822     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1823     fis->d.device         = 0x40;                   /* FIS LBA mode set */
1824     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
1825     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1826     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1827     fis->d.featuresExp    = 0;                      /* FIS reserve */
1828     if (satOrgIOContext->LoopNum == 1)
1829     {
1830       /* last loop */
1831       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
1832       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);  /* FIS sector count (15:8) */
1833     }
1834     else
1835     {
1836       fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
1837       fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
1838     }
1839     fis->d.reserved4      = 0;
1840     fis->d.control        = 0;                      /* FIS HOB bit clear */
1841     fis->d.reserved5      = 0;
1842 
1843     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1844     break;
1845   case SAT_READ_FPDMA_QUEUED:
1846     fis->h.fisType        = 0x27;                   /* Reg host to device */
1847     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1848     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
1849     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1850     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1851     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1852 
1853     /* Check FUA bit */
1854     if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1855       fis->d.device       = 0xC0;                   /* FIS FUA set */
1856     else
1857       fis->d.device       = 0x40;                   /* FIS FUA clear */
1858 
1859     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
1860     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1861     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1862     if (satOrgIOContext->LoopNum == 1)
1863     {
1864       /* last loop */
1865       fis->h.features       = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
1866       fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
1867     }
1868     else
1869     {
1870       fis->h.features       = 0xFF;       /* FIS sector count (7:0) */
1871       fis->d.featuresExp    = 0xFF;       /* FIS sector count (15:8) */
1872     }
1873     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
1874     fis->d.sectorCountExp = 0;
1875     fis->d.reserved4      = 0;
1876     fis->d.control        = 0;                      /* FIS HOB bit clear */
1877     fis->d.reserved5      = 0;
1878 
1879     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1880     break;
1881   default:
1882     TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1883     return tiError;
1884     break;
1885   }
1886 
1887   /* Initialize CB for SATA completion.
1888    */
1889   /* chained data */
1890   satIOContext->satCompleteCB = &satChainedDataIOCB;
1891 
1892 
1893   /*
1894    * Prepare SGL and send FIS to LL layer.
1895    */
1896   satIOContext->reqType = agRequestType;       /* Save it */
1897 
1898   status = sataLLIOStart( tiRoot,
1899                           tiIORequest,
1900                           tiDeviceHandle,
1901                           tiScsiRequest,
1902                           satIOContext);
1903 
1904   TI_DBG5(("satRead_1: return\n"));
1905   return (status);
1906 }
1907 /*****************************************************************************/
1908 /*! \brief SAT implementation for SCSI READ12.
1909  *
1910  *  SAT implementation for SCSI READ12 and send FIS request to LL layer.
1911  *
1912  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1913  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1914  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1915  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1916  *  \param   satIOContext_t:   Pointer to the SAT IO Context
1917  *
1918  *  \return If command is started successfully
1919  *    - \e tiSuccess:     I/O request successfully initiated.
1920  *    - \e tiBusy:        No resources available, try again later.
1921  *    - \e tiIONoDevice:  Invalid device handle.
1922  *    - \e tiError:       Other errors.
1923  */
1924 /*****************************************************************************/
1925 GLOBAL bit32  satRead12(
1926                    tiRoot_t                  *tiRoot,
1927                    tiIORequest_t             *tiIORequest,
1928                    tiDeviceHandle_t          *tiDeviceHandle,
1929                    tiScsiInitiatorRequest_t *tiScsiRequest,
1930                    satIOContext_t            *satIOContext)
1931 {
1932   bit32                     status;
1933   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1934   satDeviceData_t           *pSatDevData;
1935   scsiRspSense_t            *pSense;
1936   tiIniScsiCmnd_t           *scsiCmnd;
1937   agsaFisRegHostToDevice_t  *fis;
1938   bit32                     lba = 0;
1939   bit32                     tl = 0;
1940   bit32                     LoopNum = 1;
1941   bit8                      LBA[4];
1942   bit8                      TL[4];
1943   bit32                     rangeChk = agFALSE; /* lba and tl range check */
1944 
1945   pSense        = satIOContext->pSense;
1946   pSatDevData   = satIOContext->pSatDevData;
1947   scsiCmnd      = &tiScsiRequest->scsiCmnd;
1948   fis           = satIOContext->pFis;
1949 
1950   TI_DBG5(("satRead12: start\n"));
1951 
1952   /* checking FUA_NV */
1953   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1954   {
1955     satSetSensePayload( pSense,
1956                         SCSI_SNSKEY_ILLEGAL_REQUEST,
1957                         0,
1958                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1959                         satIOContext);
1960 
1961     ostiInitiatorIOCompleted( tiRoot,
1962                               tiIORequest,
1963                               tiIOSuccess,
1964                               SCSI_STAT_CHECK_CONDITION,
1965                               satIOContext->pTiSenseData,
1966                               satIOContext->interruptContext );
1967 
1968     TI_DBG1(("satRead12: return FUA_NV\n"));
1969     return tiSuccess;
1970 
1971   }
1972 
1973   /* checking CONTROL */
1974   /* NACA == 1 or LINK == 1*/
1975   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
1976   {
1977     satSetSensePayload( pSense,
1978                         SCSI_SNSKEY_ILLEGAL_REQUEST,
1979                         0,
1980                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1981                         satIOContext);
1982 
1983     ostiInitiatorIOCompleted( tiRoot,
1984                               tiIORequest,
1985                               tiIOSuccess,
1986                               SCSI_STAT_CHECK_CONDITION,
1987                               satIOContext->pTiSenseData,
1988                               satIOContext->interruptContext );
1989 
1990     TI_DBG2(("satRead12: return control\n"));
1991     return tiSuccess;
1992   }
1993 
1994   osti_memset(LBA, 0, sizeof(LBA));
1995   osti_memset(TL, 0, sizeof(TL));
1996 
1997   /* do not use memcpy due to indexing in LBA and TL */
1998   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
1999   LBA[1] = scsiCmnd->cdb[3];
2000   LBA[2] = scsiCmnd->cdb[4];
2001   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
2002 
2003   TL[0] = scsiCmnd->cdb[6];   /* MSB */
2004   TL[1] = scsiCmnd->cdb[7];
2005   TL[2] = scsiCmnd->cdb[8];
2006   TL[3] = scsiCmnd->cdb[9];   /* LSB */
2007 
2008   rangeChk = satAddNComparebit32(LBA, TL);
2009 
2010   lba = satComputeCDB12LBA(satIOContext);
2011   tl = satComputeCDB12TL(satIOContext);
2012 
2013   /* Table 34, 9.1, p 46 */
2014   /*
2015     note: As of 2/10/2006, no support for DMA QUEUED
2016    */
2017 
2018   /*
2019     Table 34, 9.1, p 46, b
2020     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2021     return check condition
2022   */
2023   if (pSatDevData->satNCQ != agTRUE &&
2024       pSatDevData->sat48BitSupport != agTRUE
2025       )
2026   {
2027     if (lba > SAT_TR_LBA_LIMIT - 1)
2028     {
2029       TI_DBG1(("satRead12: return LBA out of range, not EXT\n"));
2030       satSetSensePayload( pSense,
2031                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2032                           0,
2033                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2034                           satIOContext);
2035 
2036       ostiInitiatorIOCompleted( tiRoot,
2037                                 tiIORequest,
2038                                 tiIOSuccess,
2039                                 SCSI_STAT_CHECK_CONDITION,
2040                                 satIOContext->pTiSenseData,
2041                                 satIOContext->interruptContext );
2042 
2043     return tiSuccess;
2044     }
2045     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
2046     {
2047       TI_DBG1(("satRead12: return LBA+TL out of range, not EXT\n"));
2048       satSetSensePayload( pSense,
2049                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2050                           0,
2051                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2052                           satIOContext);
2053 
2054       ostiInitiatorIOCompleted( tiRoot,
2055                                 tiIORequest,
2056                                 tiIOSuccess,
2057                                 SCSI_STAT_CHECK_CONDITION,
2058                                 satIOContext->pTiSenseData,
2059                                 satIOContext->interruptContext );
2060 
2061     return tiSuccess;
2062     }
2063   }
2064 
2065   /* case 1 and 2 */
2066   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
2067   {
2068     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2069     {
2070       /* case 2 */
2071       /* READ DMA*/
2072       /* in case that we can't fit the transfer length,
2073          we need to make it fit by sending multiple ATA cmnds */
2074       TI_DBG5(("satRead12: case 2\n"));
2075 
2076 
2077       fis->h.fisType        = 0x27;                   /* Reg host to device */
2078       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2079       fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
2080       fis->h.features       = 0;                      /* FIS reserve */
2081       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2082       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2083       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2084       fis->d.device         =
2085         (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2086       fis->d.lbaLowExp      = 0;
2087       fis->d.lbaMidExp      = 0;
2088       fis->d.lbaHighExp     = 0;
2089       fis->d.featuresExp    = 0;
2090       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2091       fis->d.sectorCountExp = 0;
2092       fis->d.reserved4      = 0;
2093       fis->d.control        = 0;                      /* FIS HOB bit clear */
2094       fis->d.reserved5      = 0;
2095 
2096 
2097       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2098       satIOContext->ATACmd = SAT_READ_DMA;
2099     }
2100     else
2101     {
2102       /* case 1 */
2103       /* READ MULTIPLE or READ SECTOR(S) */
2104       /* READ SECTORS for easier implemetation */
2105       /* can't fit the transfer length but need to make it fit by sending multiple*/
2106       TI_DBG5(("satRead12: case 1\n"));
2107 
2108       fis->h.fisType        = 0x27;                   /* Reg host to device */
2109       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2110       fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
2111       fis->h.features       = 0;                      /* FIS reserve */
2112       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2113       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2114       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2115       fis->d.device         =
2116         (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2117       fis->d.lbaLowExp      = 0;
2118       fis->d.lbaMidExp      = 0;
2119       fis->d.lbaHighExp     = 0;
2120       fis->d.featuresExp    = 0;
2121       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2122       fis->d.sectorCountExp = 0;
2123       fis->d.reserved4      = 0;
2124       fis->d.control        = 0;                      /* FIS HOB bit clear */
2125       fis->d.reserved5      = 0;
2126 
2127 
2128       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2129       satIOContext->ATACmd = SAT_READ_SECTORS;
2130     }
2131   }
2132 
2133   /* case 3 and 4 */
2134   if (pSatDevData->sat48BitSupport == agTRUE)
2135   {
2136     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2137     {
2138       /* case 3 */
2139       /* READ DMA EXT */
2140       TI_DBG5(("satRead12: case 3\n"));
2141       fis->h.fisType        = 0x27;                   /* Reg host to device */
2142 
2143       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2144       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
2145       fis->h.features       = 0;                      /* FIS reserve */
2146       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2147       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2148       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2149       fis->d.device         = 0x40;                   /* FIS LBA mode set */
2150       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
2151       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2152       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2153       fis->d.featuresExp    = 0;                      /* FIS reserve */
2154       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2155       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
2156       fis->d.reserved4      = 0;
2157       fis->d.control        = 0;                      /* FIS HOB bit clear */
2158       fis->d.reserved5      = 0;
2159 
2160       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2161       satIOContext->ATACmd = SAT_READ_DMA_EXT;
2162 
2163     }
2164     else
2165     {
2166       /* case 4 */
2167       /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2168       /* READ SECTORS EXT for easier implemetation */
2169       TI_DBG5(("satRead12: case 4\n"));
2170       fis->h.fisType        = 0x27;                   /* Reg host to device */
2171       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2172 
2173       /* Check FUA bit */
2174       if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2175       {
2176         /* for now, no support for FUA */
2177         satSetSensePayload( pSense,
2178                             SCSI_SNSKEY_ILLEGAL_REQUEST,
2179                             0,
2180                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2181                             satIOContext);
2182 
2183         ostiInitiatorIOCompleted( tiRoot,
2184                                   tiIORequest,
2185                                   tiIOSuccess,
2186                                   SCSI_STAT_CHECK_CONDITION,
2187                                   satIOContext->pTiSenseData,
2188                                   satIOContext->interruptContext );
2189         return tiSuccess;
2190       }
2191 
2192       fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
2193 
2194       fis->h.features       = 0;                      /* FIS reserve */
2195       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2196       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2197       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2198       fis->d.device         = 0x40;                   /* FIS LBA mode set */
2199       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
2200       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2201       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2202       fis->d.featuresExp    = 0;                      /* FIS reserve */
2203       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2204       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
2205       fis->d.reserved4      = 0;
2206       fis->d.control        = 0;                      /* FIS HOB bit clear */
2207       fis->d.reserved5      = 0;
2208 
2209       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2210       satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2211     }
2212   }
2213 
2214   /* case 5 */
2215   if (pSatDevData->satNCQ == agTRUE)
2216   {
2217     /* READ FPDMA QUEUED */
2218     if (pSatDevData->sat48BitSupport != agTRUE)
2219     {
2220       TI_DBG5(("satRead12: case 5 !!! error NCQ but 28 bit address support \n"));
2221       satSetSensePayload( pSense,
2222                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2223                           0,
2224                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2225                           satIOContext);
2226 
2227       ostiInitiatorIOCompleted( tiRoot,
2228                                 tiIORequest,
2229                                 tiIOSuccess,
2230                                 SCSI_STAT_CHECK_CONDITION,
2231                                 satIOContext->pTiSenseData,
2232                                 satIOContext->interruptContext );
2233       return tiSuccess;
2234     }
2235 
2236     TI_DBG6(("satRead12: case 5\n"));
2237 
2238     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2239 
2240     fis->h.fisType        = 0x27;                   /* Reg host to device */
2241     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2242     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
2243     fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2244     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2245     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2246     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2247 
2248     /* Check FUA bit */
2249     if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2250       fis->d.device       = 0xC0;                   /* FIS FUA set */
2251     else
2252       fis->d.device       = 0x40;                   /* FIS FUA clear */
2253 
2254     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
2255     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2256     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2257     fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
2258     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
2259     fis->d.sectorCountExp = 0;
2260     fis->d.reserved4      = 0;
2261     fis->d.control        = 0;                      /* FIS HOB bit clear */
2262     fis->d.reserved5      = 0;
2263 
2264     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2265     satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2266   }
2267 
2268   /* saves the current LBA and orginal TL */
2269   satIOContext->currentLBA = lba;
2270   satIOContext->OrgTL = tl;
2271 
2272   /*
2273     computing number of loop and remainder for tl
2274     0xFF in case not ext
2275     0xFFFF in case EXT
2276   */
2277   if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2278   {
2279     LoopNum = satComputeLoopNum(tl, 0xFF);
2280   }
2281   else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2282   {
2283     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2284     LoopNum = satComputeLoopNum(tl, 0xFFFF);
2285   }
2286   else
2287   {
2288     /* SAT_READ_FPDMA_QUEUEDK */
2289     LoopNum = satComputeLoopNum(tl, 0xFFFF);
2290   }
2291 
2292   satIOContext->LoopNum = LoopNum;
2293 
2294   if (LoopNum == 1)
2295   {
2296     TI_DBG5(("satRead12: NON CHAINED data\n"));
2297     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2298   }
2299   else
2300   {
2301     TI_DBG1(("satRead12: CHAINED data\n"));
2302     /* re-setting tl */
2303     if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2304     {
2305        fis->d.sectorCount    = 0xFF;
2306     }
2307     else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2308     {
2309       /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2310       fis->d.sectorCount    = 0xFF;
2311       fis->d.sectorCountExp = 0xFF;
2312     }
2313     else
2314     {
2315       /* SAT_READ_FPDMA_QUEUED */
2316       fis->h.features       = 0xFF;
2317       fis->d.featuresExp    = 0xFF;
2318     }
2319 
2320     /* chained data */
2321     satIOContext->satCompleteCB = &satChainedDataIOCB;
2322   }
2323 
2324   /*
2325    * Prepare SGL and send FIS to LL layer.
2326    */
2327   satIOContext->reqType = agRequestType;       /* Save it */
2328 
2329   status = sataLLIOStart( tiRoot,
2330                           tiIORequest,
2331                           tiDeviceHandle,
2332                           tiScsiRequest,
2333                           satIOContext);
2334 
2335   TI_DBG5(("satRead12: return\n"));
2336   return (status);
2337 }
2338 /*****************************************************************************/
2339 /*! \brief SAT implementation for SCSI READ16.
2340  *
2341  *  SAT implementation for SCSI READ16 and send FIS request to LL layer.
2342  *
2343  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
2344  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
2345  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
2346  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
2347  *  \param   satIOContext_t:   Pointer to the SAT IO Context
2348  *
2349  *  \return If command is started successfully
2350  *    - \e tiSuccess:     I/O request successfully initiated.
2351  *    - \e tiBusy:        No resources available, try again later.
2352  *    - \e tiIONoDevice:  Invalid device handle.
2353  *    - \e tiError:       Other errors.
2354  */
2355 /*****************************************************************************/
2356 GLOBAL bit32  satRead16(
2357                    tiRoot_t                  *tiRoot,
2358                    tiIORequest_t             *tiIORequest,
2359                    tiDeviceHandle_t          *tiDeviceHandle,
2360                    tiScsiInitiatorRequest_t *tiScsiRequest,
2361                    satIOContext_t            *satIOContext)
2362 {
2363   bit32                     status;
2364   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2365   satDeviceData_t           *pSatDevData;
2366   scsiRspSense_t            *pSense;
2367   tiIniScsiCmnd_t           *scsiCmnd;
2368   agsaFisRegHostToDevice_t  *fis;
2369   bit32                     lba = 0;
2370   bit32                     tl = 0;
2371   bit32                     LoopNum = 1;
2372   bit8                      LBA[8];
2373   bit8                      TL[8];
2374   bit32                     rangeChk = agFALSE; /* lba and tl range check */
2375   bit32                     limitChk = agFALSE; /* lba and tl range check */
2376 
2377   pSense        = satIOContext->pSense;
2378   pSatDevData   = satIOContext->pSatDevData;
2379   scsiCmnd      = &tiScsiRequest->scsiCmnd;
2380   fis           = satIOContext->pFis;
2381 
2382   TI_DBG5(("satRead16: start\n"));
2383 
2384   /* checking FUA_NV */
2385   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
2386   {
2387     satSetSensePayload( pSense,
2388                         SCSI_SNSKEY_ILLEGAL_REQUEST,
2389                         0,
2390                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2391                         satIOContext);
2392 
2393     ostiInitiatorIOCompleted( tiRoot,
2394                               tiIORequest,
2395                               tiIOSuccess,
2396                               SCSI_STAT_CHECK_CONDITION,
2397                               satIOContext->pTiSenseData,
2398                               satIOContext->interruptContext );
2399 
2400     TI_DBG1(("satRead16: return FUA_NV\n"));
2401     return tiSuccess;
2402 
2403   }
2404 
2405   /* checking CONTROL */
2406   /* NACA == 1 or LINK == 1*/
2407   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
2408   {
2409     satSetSensePayload( pSense,
2410                         SCSI_SNSKEY_ILLEGAL_REQUEST,
2411                         0,
2412                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2413                         satIOContext);
2414 
2415     ostiInitiatorIOCompleted( tiRoot,
2416                               tiIORequest,
2417                               tiIOSuccess,
2418                               SCSI_STAT_CHECK_CONDITION,
2419                               satIOContext->pTiSenseData,
2420                               satIOContext->interruptContext );
2421 
2422     TI_DBG1(("satRead16: return control\n"));
2423     return tiSuccess;
2424   }
2425 
2426 
2427   osti_memset(LBA, 0, sizeof(LBA));
2428   osti_memset(TL, 0, sizeof(TL));
2429 
2430 
2431   /* do not use memcpy due to indexing in LBA and TL */
2432   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
2433   LBA[1] = scsiCmnd->cdb[3];
2434   LBA[2] = scsiCmnd->cdb[4];
2435   LBA[3] = scsiCmnd->cdb[5];
2436   LBA[4] = scsiCmnd->cdb[6];
2437   LBA[5] = scsiCmnd->cdb[7];
2438   LBA[6] = scsiCmnd->cdb[8];
2439   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
2440 
2441   TL[0] = 0;
2442   TL[1] = 0;
2443   TL[2] = 0;
2444   TL[3] = 0;
2445   TL[4] = scsiCmnd->cdb[10];   /* MSB */
2446   TL[5] = scsiCmnd->cdb[11];
2447   TL[6] = scsiCmnd->cdb[12];
2448   TL[7] = scsiCmnd->cdb[13];   /* LSB */
2449 
2450  rangeChk = satAddNComparebit64(LBA, TL);
2451 
2452  limitChk = satCompareLBALimitbit(LBA);
2453 
2454  lba = satComputeCDB16LBA(satIOContext);
2455  tl = satComputeCDB16TL(satIOContext);
2456 
2457 
2458   /* Table 34, 9.1, p 46 */
2459   /*
2460     note: As of 2/10/2006, no support for DMA QUEUED
2461    */
2462 
2463   /*
2464     Table 34, 9.1, p 46, b
2465     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2466     return check condition
2467   */
2468   if (pSatDevData->satNCQ != agTRUE &&
2469       pSatDevData->sat48BitSupport != agTRUE
2470       )
2471   {
2472     if (limitChk)
2473     {
2474       TI_DBG1(("satRead16: return LBA out of range, not EXT\n"));
2475       satSetSensePayload( pSense,
2476                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2477                           0,
2478                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2479                           satIOContext);
2480 
2481       ostiInitiatorIOCompleted( tiRoot,
2482                                 tiIORequest,
2483                                 tiIOSuccess,
2484                                 SCSI_STAT_CHECK_CONDITION,
2485                                 satIOContext->pTiSenseData,
2486                                 satIOContext->interruptContext );
2487 
2488     return tiSuccess;
2489     }
2490     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
2491     {
2492       TI_DBG1(("satRead16: return LBA+TL out of range, not EXT\n"));
2493       satSetSensePayload( pSense,
2494                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2495                           0,
2496                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2497                           satIOContext);
2498 
2499       ostiInitiatorIOCompleted( tiRoot,
2500                                 tiIORequest,
2501                                 tiIOSuccess,
2502                                 SCSI_STAT_CHECK_CONDITION,
2503                                 satIOContext->pTiSenseData,
2504                                 satIOContext->interruptContext );
2505 
2506     return tiSuccess;
2507     }
2508   }
2509 
2510   /* case 1 and 2 */
2511   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
2512   {
2513     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2514     {
2515       /* case 2 */
2516       /* READ DMA*/
2517       /* in case that we can't fit the transfer length,
2518          we need to make it fit by sending multiple ATA cmnds */
2519       TI_DBG5(("satRead16: case 2\n"));
2520 
2521 
2522       fis->h.fisType        = 0x27;                   /* Reg host to device */
2523       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2524       fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
2525       fis->h.features       = 0;                      /* FIS reserve */
2526       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2527       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2528       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2529       fis->d.device         =
2530         (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2531       fis->d.lbaLowExp      = 0;
2532       fis->d.lbaMidExp      = 0;
2533       fis->d.lbaHighExp     = 0;
2534       fis->d.featuresExp    = 0;
2535       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2536       fis->d.sectorCountExp = 0;
2537       fis->d.reserved4      = 0;
2538       fis->d.control        = 0;                      /* FIS HOB bit clear */
2539       fis->d.reserved5      = 0;
2540 
2541 
2542       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2543       satIOContext->ATACmd = SAT_READ_DMA;
2544     }
2545     else
2546     {
2547       /* case 1 */
2548       /* READ MULTIPLE or READ SECTOR(S) */
2549       /* READ SECTORS for easier implemetation */
2550       /* can't fit the transfer length but need to make it fit by sending multiple*/
2551       TI_DBG5(("satRead16: case 1\n"));
2552 
2553       fis->h.fisType        = 0x27;                   /* Reg host to device */
2554       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2555       fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
2556       fis->h.features       = 0;                      /* FIS reserve */
2557       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2558       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2559       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2560       fis->d.device         =
2561         (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2562       fis->d.lbaLowExp      = 0;
2563       fis->d.lbaMidExp      = 0;
2564       fis->d.lbaHighExp     = 0;
2565       fis->d.featuresExp    = 0;
2566       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2567       fis->d.sectorCountExp = 0;
2568       fis->d.reserved4      = 0;
2569       fis->d.control        = 0;                      /* FIS HOB bit clear */
2570       fis->d.reserved5      = 0;
2571 
2572 
2573       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2574       satIOContext->ATACmd = SAT_READ_SECTORS;
2575     }
2576   }
2577 
2578   /* case 3 and 4 */
2579   if (pSatDevData->sat48BitSupport == agTRUE)
2580   {
2581     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2582     {
2583       /* case 3 */
2584       /* READ DMA EXT */
2585       TI_DBG5(("satRead16: case 3\n"));
2586       fis->h.fisType        = 0x27;                   /* Reg host to device */
2587 
2588       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2589       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
2590       fis->h.features       = 0;                      /* FIS reserve */
2591       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2592       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2593       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2594       fis->d.device         = 0x40;                   /* FIS LBA mode set */
2595       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
2596       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
2597       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
2598       fis->d.featuresExp    = 0;                      /* FIS reserve */
2599       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2600       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
2601       fis->d.reserved4      = 0;
2602       fis->d.control        = 0;                      /* FIS HOB bit clear */
2603       fis->d.reserved5      = 0;
2604 
2605       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2606       satIOContext->ATACmd = SAT_READ_DMA_EXT;
2607 
2608     }
2609     else
2610     {
2611       /* case 4 */
2612       /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2613       /* READ SECTORS EXT for easier implemetation */
2614       TI_DBG5(("satRead16: case 4\n"));
2615       fis->h.fisType        = 0x27;                   /* Reg host to device */
2616       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2617 
2618       /* Check FUA bit */
2619       if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2620       {
2621 
2622         /* for now, no support for FUA */
2623         satSetSensePayload( pSense,
2624                             SCSI_SNSKEY_ILLEGAL_REQUEST,
2625                             0,
2626                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2627                             satIOContext);
2628 
2629         ostiInitiatorIOCompleted( tiRoot,
2630                                   tiIORequest,
2631                                   tiIOSuccess,
2632                                   SCSI_STAT_CHECK_CONDITION,
2633                                   satIOContext->pTiSenseData,
2634                                   satIOContext->interruptContext );
2635         return tiSuccess;
2636       }
2637 
2638       fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
2639 
2640       fis->h.features       = 0;                      /* FIS reserve */
2641       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2642       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2643       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2644       fis->d.device         = 0x40;                   /* FIS LBA mode set */
2645       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
2646       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
2647       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
2648       fis->d.featuresExp    = 0;                      /* FIS reserve */
2649       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2650       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
2651       fis->d.reserved4      = 0;
2652       fis->d.control        = 0;                      /* FIS HOB bit clear */
2653       fis->d.reserved5      = 0;
2654 
2655       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2656       satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2657     }
2658   }
2659 
2660 
2661   /* case 5 */
2662   if (pSatDevData->satNCQ == agTRUE)
2663   {
2664     /* READ FPDMA QUEUED */
2665     if (pSatDevData->sat48BitSupport != agTRUE)
2666     {
2667       TI_DBG5(("satRead16: case 5 !!! error NCQ but 28 bit address support \n"));
2668       satSetSensePayload( pSense,
2669                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2670                           0,
2671                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2672                           satIOContext);
2673 
2674       ostiInitiatorIOCompleted( tiRoot,
2675                                 tiIORequest,
2676                                 tiIOSuccess,
2677                                 SCSI_STAT_CHECK_CONDITION,
2678                                 satIOContext->pTiSenseData,
2679                                 satIOContext->interruptContext );
2680       return tiSuccess;
2681     }
2682 
2683     TI_DBG6(("satRead16: case 5\n"));
2684 
2685     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2686 
2687     fis->h.fisType        = 0x27;                   /* Reg host to device */
2688     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2689     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
2690     fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2691     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2692     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2693     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2694 
2695     /* Check FUA bit */
2696     if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2697       fis->d.device       = 0xC0;                   /* FIS FUA set */
2698     else
2699       fis->d.device       = 0x40;                   /* FIS FUA clear */
2700 
2701     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
2702     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
2703     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
2704     fis->d.featuresExp    = scsiCmnd->cdb[12];      /* FIS sector count (15:8) */
2705     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
2706     fis->d.sectorCountExp = 0;
2707     fis->d.reserved4      = 0;
2708     fis->d.control        = 0;                      /* FIS HOB bit clear */
2709     fis->d.reserved5      = 0;
2710 
2711     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2712     satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2713   }
2714 
2715   /* saves the current LBA and orginal TL */
2716   satIOContext->currentLBA = lba;
2717   satIOContext->OrgTL = tl;
2718 
2719   /*
2720     computing number of loop and remainder for tl
2721     0xFF in case not ext
2722     0xFFFF in case EXT
2723   */
2724   if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2725   {
2726     LoopNum = satComputeLoopNum(tl, 0xFF);
2727   }
2728   else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2729   {
2730     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2731     LoopNum = satComputeLoopNum(tl, 0xFFFF);
2732   }
2733   else
2734   {
2735     /* SAT_READ_FPDMA_QUEUEDK */
2736     LoopNum = satComputeLoopNum(tl, 0xFFFF);
2737   }
2738   satIOContext->LoopNum = LoopNum;
2739 
2740   if (LoopNum == 1)
2741   {
2742     TI_DBG5(("satRead16: NON CHAINED data\n"));
2743     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2744   }
2745   else
2746   {
2747     TI_DBG1(("satRead16: CHAINED data\n"));
2748     /* re-setting tl */
2749     if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2750     {
2751        fis->d.sectorCount    = 0xFF;
2752     }
2753     else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2754     {
2755       /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2756       fis->d.sectorCount    = 0xFF;
2757       fis->d.sectorCountExp = 0xFF;
2758     }
2759     else
2760     {
2761       /* SAT_READ_FPDMA_QUEUED */
2762       fis->h.features       = 0xFF;
2763       fis->d.featuresExp    = 0xFF;
2764     }
2765 
2766     /* chained data */
2767     satIOContext->satCompleteCB = &satChainedDataIOCB;
2768   }
2769 
2770   /*
2771    * Prepare SGL and send FIS to LL layer.
2772    */
2773   satIOContext->reqType = agRequestType;       /* Save it */
2774 
2775   status = sataLLIOStart( tiRoot,
2776                           tiIORequest,
2777                           tiDeviceHandle,
2778                           tiScsiRequest,
2779                           satIOContext);
2780 
2781   TI_DBG5(("satRead16: return\n"));
2782   return (status);
2783 
2784 }
2785 
2786 /*****************************************************************************/
2787 /*! \brief SAT implementation for SCSI READ6.
2788  *
2789  *  SAT implementation for SCSI READ6 and send FIS request to LL layer.
2790  *
2791  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
2792  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
2793  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
2794  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
2795  *  \param   satIOContext_t:   Pointer to the SAT IO Context
2796  *
2797  *  \return If command is started successfully
2798  *    - \e tiSuccess:     I/O request successfully initiated.
2799  *    - \e tiBusy:        No resources available, try again later.
2800  *    - \e tiIONoDevice:  Invalid device handle.
2801  *    - \e tiError:       Other errors.
2802  */
2803 /*****************************************************************************/
2804 GLOBAL bit32  satRead6(
2805                    tiRoot_t                  *tiRoot,
2806                    tiIORequest_t             *tiIORequest,
2807                    tiDeviceHandle_t          *tiDeviceHandle,
2808                    tiScsiInitiatorRequest_t *tiScsiRequest,
2809                    satIOContext_t            *satIOContext)
2810 {
2811 
2812   bit32                     status;
2813   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2814   satDeviceData_t           *pSatDevData;
2815   scsiRspSense_t            *pSense;
2816   tiIniScsiCmnd_t           *scsiCmnd;
2817   agsaFisRegHostToDevice_t  *fis;
2818   bit32                     lba = 0;
2819   bit16                     tl = 0;
2820 
2821   pSense        = satIOContext->pSense;
2822   pSatDevData   = satIOContext->pSatDevData;
2823   scsiCmnd      = &tiScsiRequest->scsiCmnd;
2824   fis           = satIOContext->pFis;
2825 
2826 
2827    TI_DBG5(("satRead6: start\n"));
2828 
2829   /* no FUA checking since read6 */
2830 
2831 
2832   /* checking CONTROL */
2833   /* NACA == 1 or LINK == 1*/
2834   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
2835   {
2836     satSetSensePayload( pSense,
2837                         SCSI_SNSKEY_ILLEGAL_REQUEST,
2838                         0,
2839                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2840                         satIOContext);
2841 
2842     ostiInitiatorIOCompleted( tiRoot,
2843                               tiIORequest,
2844                               tiIOSuccess,
2845                               SCSI_STAT_CHECK_CONDITION,
2846                               satIOContext->pTiSenseData,
2847                               satIOContext->interruptContext );
2848 
2849     TI_DBG2(("satRead6: return control\n"));
2850     return tiSuccess;
2851   }
2852 
2853   /* cbd6; computing LBA and transfer length */
2854   lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
2855     + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
2856   tl = scsiCmnd->cdb[4];
2857 
2858 
2859   /* Table 34, 9.1, p 46 */
2860   /*
2861     note: As of 2/10/2006, no support for DMA QUEUED
2862    */
2863 
2864   /*
2865     Table 34, 9.1, p 46, b
2866     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2867     return check condition
2868   */
2869   if (pSatDevData->satNCQ != agTRUE &&
2870       pSatDevData->sat48BitSupport != agTRUE
2871       )
2872   {
2873     if (lba > SAT_TR_LBA_LIMIT - 1)
2874     {
2875       satSetSensePayload( pSense,
2876                           SCSI_SNSKEY_ILLEGAL_REQUEST,
2877                           0,
2878                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2879                           satIOContext);
2880 
2881       ostiInitiatorIOCompleted( tiRoot,
2882                                 tiIORequest,
2883                                 tiIOSuccess,
2884                                 SCSI_STAT_CHECK_CONDITION,
2885                                 satIOContext->pTiSenseData,
2886                                 satIOContext->interruptContext );
2887 
2888     TI_DBG1(("satRead6: return LBA out of range\n"));
2889     return tiSuccess;
2890     }
2891   }
2892 
2893   /* case 1 and 2 */
2894   if (lba + tl <= SAT_TR_LBA_LIMIT)
2895   {
2896     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2897     {
2898       /* case 2 */
2899       /* READ DMA*/
2900       TI_DBG5(("satRead6: case 2\n"));
2901 
2902 
2903       fis->h.fisType        = 0x27;                   /* Reg host to device */
2904       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2905       fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
2906       fis->h.features       = 0;                      /* FIS reserve */
2907       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
2908       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
2909       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
2910       fis->d.device         = 0x40;                   /* FIS LBA mode  */
2911       fis->d.lbaLowExp      = 0;
2912       fis->d.lbaMidExp      = 0;
2913       fis->d.lbaHighExp     = 0;
2914       fis->d.featuresExp    = 0;
2915       if (tl == 0)
2916       {
2917         /* temporary fix */
2918         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
2919       }
2920       else
2921       {
2922         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
2923       }
2924       fis->d.sectorCountExp = 0;
2925       fis->d.reserved4      = 0;
2926       fis->d.control        = 0;                      /* FIS HOB bit clear */
2927       fis->d.reserved5      = 0;
2928 
2929       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2930     }
2931     else
2932     {
2933       /* case 1 */
2934       /* READ SECTORS for easier implemetation */
2935       TI_DBG5(("satRead6: case 1\n"));
2936 
2937       fis->h.fisType        = 0x27;                   /* Reg host to device */
2938       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2939       fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
2940       fis->h.features       = 0;                      /* FIS reserve */
2941       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
2942       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
2943       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
2944       fis->d.device         = 0x40;                   /* FIS LBA mode  */
2945       fis->d.lbaLowExp      = 0;
2946       fis->d.lbaMidExp      = 0;
2947       fis->d.lbaHighExp     = 0;
2948       fis->d.featuresExp    = 0;
2949       if (tl == 0)
2950       {
2951         /* temporary fix */
2952         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
2953       }
2954       else
2955       {
2956         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
2957       }
2958       fis->d.sectorCountExp = 0;
2959       fis->d.reserved4      = 0;
2960       fis->d.control        = 0;                      /* FIS HOB bit clear */
2961       fis->d.reserved5      = 0;
2962 
2963       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2964 
2965     }
2966   }
2967 
2968   /* case 3 and 4 */
2969   if (pSatDevData->sat48BitSupport == agTRUE)
2970   {
2971     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2972     {
2973       /* case 3 */
2974       /* READ DMA EXT only */
2975       TI_DBG5(("satRead6: case 3\n"));
2976       fis->h.fisType        = 0x27;                   /* Reg host to device */
2977       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2978       fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
2979       fis->h.features       = 0;                      /* FIS reserve */
2980       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
2981       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
2982       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
2983       fis->d.device         = 0x40;                   /* FIS LBA mode set */
2984       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
2985       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2986       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2987       fis->d.featuresExp    = 0;                      /* FIS reserve */
2988       if (tl == 0)
2989       {
2990         /* sector count is 256, 0x100*/
2991         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
2992         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
2993       }
2994       else
2995       {
2996         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
2997         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
2998       }
2999       fis->d.reserved4      = 0;
3000       fis->d.control        = 0;                      /* FIS HOB bit clear */
3001       fis->d.reserved5      = 0;
3002 
3003       agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
3004     }
3005     else
3006     {
3007       /* case 4 */
3008       /* READ SECTORS EXT for easier implemetation */
3009       TI_DBG5(("satRead6: case 4\n"));
3010 
3011       fis->h.fisType        = 0x27;                   /* Reg host to device */
3012       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3013       fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
3014       fis->h.features       = 0;                      /* FIS reserve */
3015       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
3016       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
3017       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
3018       fis->d.device         = 0x40;                   /* FIS LBA mode set */
3019       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
3020       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3021       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3022       fis->d.featuresExp    = 0;                      /* FIS reserve */
3023       if (tl == 0)
3024       {
3025         /* sector count is 256, 0x100*/
3026         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
3027         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
3028       }
3029       else
3030       {
3031         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
3032         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
3033       }
3034       fis->d.reserved4      = 0;
3035       fis->d.control        = 0;                      /* FIS HOB bit clear */
3036       fis->d.reserved5      = 0;
3037 
3038       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
3039     }
3040   }
3041 
3042   /* case 5 */
3043   if (pSatDevData->satNCQ == agTRUE)
3044   {
3045     /* READ FPDMA QUEUED */
3046     if (pSatDevData->sat48BitSupport != agTRUE)
3047     {
3048       /* sanity check */
3049       TI_DBG5(("satRead6: case 5 !!! error NCQ but 28 bit address support \n"));
3050       satSetSensePayload( pSense,
3051                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3052                           0,
3053                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3054                           satIOContext);
3055 
3056       ostiInitiatorIOCompleted( tiRoot,
3057                                 tiIORequest,
3058                                 tiIOSuccess,
3059                                 SCSI_STAT_CHECK_CONDITION,
3060                                 satIOContext->pTiSenseData,
3061                                 satIOContext->interruptContext );
3062       return tiSuccess;
3063     }
3064     TI_DBG5(("satRead6: case 5\n"));
3065 
3066     /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
3067 
3068     fis->h.fisType        = 0x27;                   /* Reg host to device */
3069     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3070     fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
3071     fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
3072     fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
3073     fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
3074     fis->d.device         = 0x40;                   /* FIS FUA clear */
3075     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
3076     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3077     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3078     if (tl == 0)
3079     {
3080       /* sector count is 256, 0x100*/
3081       fis->h.features       = 0;                         /* FIS sector count (7:0) */
3082       fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
3083     }
3084     else
3085     {
3086       fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
3087       fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
3088     }
3089     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
3090     fis->d.sectorCountExp = 0;
3091     fis->d.reserved4      = 0;
3092     fis->d.control        = 0;                      /* FIS HOB bit clear */
3093     fis->d.reserved5      = 0;
3094 
3095     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
3096   }
3097 
3098    /* Initialize CB for SATA completion.
3099    */
3100   satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3101 
3102   /*
3103    * Prepare SGL and send FIS to LL layer.
3104    */
3105   satIOContext->reqType = agRequestType;       /* Save it */
3106 
3107   status = sataLLIOStart( tiRoot,
3108                           tiIORequest,
3109                           tiDeviceHandle,
3110                           tiScsiRequest,
3111                           satIOContext);
3112   return (status);
3113 
3114 }
3115 
3116 /*****************************************************************************/
3117 /*! \brief SAT implementation for SCSI WRITE16.
3118  *
3119  *  SAT implementation for SCSI WRITE16 and send FIS request to LL layer.
3120  *
3121  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
3122  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
3123  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
3124  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
3125  *  \param   satIOContext_t:   Pointer to the SAT IO Context
3126  *
3127  *  \return If command is started successfully
3128  *    - \e tiSuccess:     I/O request successfully initiated.
3129  *    - \e tiBusy:        No resources available, try again later.
3130  *    - \e tiIONoDevice:  Invalid device handle.
3131  *    - \e tiError:       Other errors.
3132  */
3133 /*****************************************************************************/
3134 GLOBAL bit32  satWrite16(
3135                    tiRoot_t                  *tiRoot,
3136                    tiIORequest_t             *tiIORequest,
3137                    tiDeviceHandle_t          *tiDeviceHandle,
3138                    tiScsiInitiatorRequest_t *tiScsiRequest,
3139                    satIOContext_t            *satIOContext)
3140 {
3141   bit32                     status;
3142   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3143   satDeviceData_t           *pSatDevData;
3144   scsiRspSense_t            *pSense;
3145   tiIniScsiCmnd_t           *scsiCmnd;
3146   agsaFisRegHostToDevice_t  *fis;
3147   bit32                     lba = 0;
3148   bit32                     tl = 0;
3149   bit32                     LoopNum = 1;
3150   bit8                      LBA[8];
3151   bit8                      TL[8];
3152   bit32                     rangeChk = agFALSE; /* lba and tl range check */
3153   bit32                     limitChk = agFALSE; /* lba and tl range check */
3154 
3155   pSense        = satIOContext->pSense;
3156   pSatDevData   = satIOContext->pSatDevData;
3157   scsiCmnd      = &tiScsiRequest->scsiCmnd;
3158   fis           = satIOContext->pFis;
3159 
3160   TI_DBG5(("satWrite16: start\n"));
3161 
3162   /* checking FUA_NV */
3163   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3164   {
3165     satSetSensePayload( pSense,
3166                         SCSI_SNSKEY_ILLEGAL_REQUEST,
3167                         0,
3168                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3169                         satIOContext);
3170 
3171     ostiInitiatorIOCompleted( tiRoot,
3172                               tiIORequest,
3173                               tiIOSuccess,
3174                               SCSI_STAT_CHECK_CONDITION,
3175                               satIOContext->pTiSenseData,
3176                               satIOContext->interruptContext );
3177 
3178     TI_DBG1(("satWrite16: return FUA_NV\n"));
3179     return tiSuccess;
3180 
3181   }
3182 
3183   /* checking CONTROL */
3184   /* NACA == 1 or LINK == 1*/
3185   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
3186   {
3187     satSetSensePayload( pSense,
3188                         SCSI_SNSKEY_ILLEGAL_REQUEST,
3189                         0,
3190                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3191                         satIOContext);
3192 
3193     ostiInitiatorIOCompleted( tiRoot,
3194                               tiIORequest,
3195                               tiIOSuccess,
3196                               SCSI_STAT_CHECK_CONDITION,
3197                               satIOContext->pTiSenseData,
3198                               satIOContext->interruptContext );
3199 
3200     TI_DBG1(("satWrite16: return control\n"));
3201     return tiSuccess;
3202   }
3203 
3204 
3205   osti_memset(LBA, 0, sizeof(LBA));
3206   osti_memset(TL, 0, sizeof(TL));
3207 
3208 
3209   /* do not use memcpy due to indexing in LBA and TL */
3210   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
3211   LBA[1] = scsiCmnd->cdb[3];
3212   LBA[2] = scsiCmnd->cdb[4];
3213   LBA[3] = scsiCmnd->cdb[5];
3214   LBA[4] = scsiCmnd->cdb[6];
3215   LBA[5] = scsiCmnd->cdb[7];
3216   LBA[6] = scsiCmnd->cdb[8];
3217   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
3218 
3219   TL[0] = 0;
3220   TL[1] = 0;
3221   TL[2] = 0;
3222   TL[3] = 0;
3223   TL[4] = scsiCmnd->cdb[10];   /* MSB */
3224   TL[5] = scsiCmnd->cdb[11];
3225   TL[6] = scsiCmnd->cdb[12];
3226   TL[7] = scsiCmnd->cdb[13];   /* LSB */
3227 
3228   rangeChk = satAddNComparebit64(LBA, TL);
3229 
3230   limitChk = satCompareLBALimitbit(LBA);
3231 
3232   lba = satComputeCDB16LBA(satIOContext);
3233   tl = satComputeCDB16TL(satIOContext);
3234 
3235 
3236 
3237   /* Table 34, 9.1, p 46 */
3238   /*
3239     note: As of 2/10/2006, no support for DMA QUEUED
3240   */
3241 
3242   /*
3243     Table 34, 9.1, p 46, b
3244     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3245     return check condition
3246   */
3247   if (pSatDevData->satNCQ != agTRUE &&
3248      pSatDevData->sat48BitSupport != agTRUE
3249      )
3250   {
3251     if (limitChk)
3252     {
3253       TI_DBG1(("satWrite16: return LBA out of range, not EXT\n"));
3254       satSetSensePayload( pSense,
3255                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3256                           0,
3257                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3258                           satIOContext);
3259 
3260       ostiInitiatorIOCompleted( tiRoot,
3261                                 tiIORequest,
3262                                 tiIOSuccess,
3263                                 SCSI_STAT_CHECK_CONDITION,
3264                                 satIOContext->pTiSenseData,
3265                                 satIOContext->interruptContext );
3266 
3267     return tiSuccess;
3268     }
3269     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
3270     {
3271       TI_DBG1(("satWrite16: return LBA+TL out of range, not EXT\n"));
3272       satSetSensePayload( pSense,
3273                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3274                           0,
3275                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3276                           satIOContext);
3277 
3278       ostiInitiatorIOCompleted( tiRoot,
3279                                 tiIORequest,
3280                                 tiIOSuccess,
3281                                 SCSI_STAT_CHECK_CONDITION,
3282                                 satIOContext->pTiSenseData,
3283                                 satIOContext->interruptContext );
3284 
3285     return tiSuccess;
3286     }
3287   }
3288 
3289   /* case 1 and 2 */
3290   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
3291   {
3292     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3293     {
3294       /* case 2 */
3295       /* WRITE DMA*/
3296       /* In case that we can't fit the transfer length, we loop */
3297       TI_DBG5(("satWrite16: case 2\n"));
3298       fis->h.fisType        = 0x27;                   /* Reg host to device */
3299       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3300       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
3301       fis->h.features       = 0;                      /* FIS reserve */
3302       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3303       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3304       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3305 
3306       /* FIS LBA mode set LBA (27:24) */
3307       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3308 
3309       fis->d.lbaLowExp      = 0;
3310       fis->d.lbaMidExp      = 0;
3311       fis->d.lbaHighExp     = 0;
3312       fis->d.featuresExp    = 0;
3313       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3314       fis->d.sectorCountExp = 0;
3315       fis->d.reserved4      = 0;
3316       fis->d.control        = 0;                      /* FIS HOB bit clear */
3317       fis->d.reserved5      = 0;
3318 
3319       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3320       satIOContext->ATACmd = SAT_WRITE_DMA;
3321     }
3322     else
3323     {
3324       /* case 1 */
3325       /* WRITE MULTIPLE or WRITE SECTOR(S) */
3326       /* WRITE SECTORS for easier implemetation */
3327       /* In case that we can't fit the transfer length, we loop */
3328       TI_DBG5(("satWrite16: case 1\n"));
3329       fis->h.fisType        = 0x27;                   /* Reg host to device */
3330       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3331       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
3332       fis->h.features       = 0;                      /* FIS reserve */
3333       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3334       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3335       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3336 
3337       /* FIS LBA mode set LBA (27:24) */
3338       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3339 
3340       fis->d.lbaLowExp      = 0;
3341       fis->d.lbaMidExp      = 0;
3342       fis->d.lbaHighExp     = 0;
3343       fis->d.featuresExp    = 0;
3344       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3345       fis->d.sectorCountExp = 0;
3346       fis->d.reserved4      = 0;
3347       fis->d.control        = 0;                      /* FIS HOB bit clear */
3348       fis->d.reserved5      = 0;
3349 
3350       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3351       satIOContext->ATACmd = SAT_WRITE_SECTORS;
3352     }
3353   }
3354 
3355   /* case 3 and 4 */
3356   if (pSatDevData->sat48BitSupport == agTRUE)
3357   {
3358     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3359     {
3360       /* case 3 */
3361       /* WRITE DMA EXT or WRITE DMA FUA EXT */
3362       TI_DBG5(("satWrite16: case 3\n"));
3363       fis->h.fisType        = 0x27;                   /* Reg host to device */
3364       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3365 
3366       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3367       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
3368 
3369       fis->h.features       = 0;                      /* FIS reserve */
3370       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3371       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3372       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3373       fis->d.device         = 0x40;                   /* FIS LBA mode set */
3374       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
3375       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
3376       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
3377       fis->d.featuresExp    = 0;                      /* FIS reserve */
3378       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3379       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
3380       fis->d.reserved4      = 0;
3381       fis->d.control        = 0;                      /* FIS HOB bit clear */
3382       fis->d.reserved5      = 0;
3383 
3384       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3385       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3386     }
3387     else
3388     {
3389       /* case 4 */
3390       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3391       /* WRITE SECTORS EXT for easier implemetation */
3392       TI_DBG5(("satWrite16: case 4\n"));
3393       fis->h.fisType        = 0x27;                   /* Reg host to device */
3394       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3395       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
3396 
3397       fis->h.features       = 0;                      /* FIS reserve */
3398       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3399       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3400       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3401       fis->d.device         = 0x40;                   /* FIS LBA mode set */
3402       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
3403       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
3404       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
3405       fis->d.featuresExp    = 0;                      /* FIS reserve */
3406       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3407       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
3408       fis->d.reserved4      = 0;
3409       fis->d.control        = 0;                      /* FIS HOB bit clear */
3410       fis->d.reserved5      = 0;
3411 
3412       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3413       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3414     }
3415   }
3416 
3417   /* case 5 */
3418   if (pSatDevData->satNCQ == agTRUE)
3419   {
3420     /* WRITE FPDMA QUEUED */
3421     if (pSatDevData->sat48BitSupport != agTRUE)
3422     {
3423       TI_DBG5(("satWrite16: case 5 !!! error NCQ but 28 bit address support \n"));
3424       satSetSensePayload( pSense,
3425                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3426                           0,
3427                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3428                           satIOContext);
3429 
3430       ostiInitiatorIOCompleted( tiRoot,
3431                                 tiIORequest,
3432                                 tiIOSuccess,
3433                                 SCSI_STAT_CHECK_CONDITION,
3434                                 satIOContext->pTiSenseData,
3435                                 satIOContext->interruptContext );
3436       return tiSuccess;
3437     }
3438     TI_DBG6(("satWrite16: case 5\n"));
3439 
3440     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3441 
3442     fis->h.fisType        = 0x27;                   /* Reg host to device */
3443     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3444     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3445     fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3446     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3447     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3448     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3449 
3450     /* Check FUA bit */
3451     if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
3452       fis->d.device       = 0xC0;                   /* FIS FUA set */
3453     else
3454       fis->d.device       = 0x40;                   /* FIS FUA clear */
3455 
3456     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
3457     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
3458     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
3459     fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
3460     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
3461     fis->d.sectorCountExp = 0;
3462     fis->d.reserved4      = 0;
3463     fis->d.control        = 0;                      /* FIS HOB bit clear */
3464     fis->d.reserved5      = 0;
3465 
3466     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3467     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3468   }
3469 
3470   satIOContext->currentLBA = lba;
3471   satIOContext->OrgTL = tl;
3472 
3473   /*
3474     computing number of loop and remainder for tl
3475     0xFF in case not ext
3476     0xFFFF in case EXT
3477   */
3478   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3479   {
3480     LoopNum = satComputeLoopNum(tl, 0xFF);
3481   }
3482   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3483            fis->h.command == SAT_WRITE_DMA_EXT     ||
3484            fis->h.command == SAT_WRITE_DMA_FUA_EXT
3485            )
3486   {
3487     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3488     LoopNum = satComputeLoopNum(tl, 0xFFFF);
3489   }
3490   else
3491   {
3492     /* SAT_WRITE_FPDMA_QUEUEDK */
3493     LoopNum = satComputeLoopNum(tl, 0xFFFF);
3494   }
3495 
3496   satIOContext->LoopNum = LoopNum;
3497 
3498 
3499   if (LoopNum == 1)
3500   {
3501     TI_DBG5(("satWrite16: NON CHAINED data\n"));
3502     /* Initialize CB for SATA completion.
3503      */
3504     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3505   }
3506   else
3507   {
3508     TI_DBG1(("satWrite16: CHAINED data\n"));
3509     /* re-setting tl */
3510     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3511     {
3512        fis->d.sectorCount    = 0xFF;
3513     }
3514     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3515              fis->h.command == SAT_WRITE_DMA_EXT ||
3516              fis->h.command == SAT_WRITE_DMA_FUA_EXT
3517              )
3518     {
3519       fis->d.sectorCount    = 0xFF;
3520       fis->d.sectorCountExp = 0xFF;
3521     }
3522     else
3523     {
3524       /* SAT_WRITE_FPDMA_QUEUED */
3525       fis->h.features       = 0xFF;
3526       fis->d.featuresExp    = 0xFF;
3527     }
3528 
3529     /* Initialize CB for SATA completion.
3530      */
3531     satIOContext->satCompleteCB = &satChainedDataIOCB;
3532   }
3533 
3534 
3535   /*
3536    * Prepare SGL and send FIS to LL layer.
3537    */
3538   satIOContext->reqType = agRequestType;       /* Save it */
3539 
3540   status = sataLLIOStart( tiRoot,
3541                           tiIORequest,
3542                           tiDeviceHandle,
3543                           tiScsiRequest,
3544                           satIOContext);
3545   return (status);
3546 }
3547 
3548 /*****************************************************************************/
3549 /*! \brief SAT implementation for SCSI WRITE12.
3550  *
3551  *  SAT implementation for SCSI WRITE12 and send FIS request to LL layer.
3552  *
3553  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
3554  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
3555  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
3556  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
3557  *  \param   satIOContext_t:   Pointer to the SAT IO Context
3558  *
3559  *  \return If command is started successfully
3560  *    - \e tiSuccess:     I/O request successfully initiated.
3561  *    - \e tiBusy:        No resources available, try again later.
3562  *    - \e tiIONoDevice:  Invalid device handle.
3563  *    - \e tiError:       Other errors.
3564  */
3565 /*****************************************************************************/
3566 GLOBAL bit32  satWrite12(
3567                    tiRoot_t                  *tiRoot,
3568                    tiIORequest_t             *tiIORequest,
3569                    tiDeviceHandle_t          *tiDeviceHandle,
3570                    tiScsiInitiatorRequest_t *tiScsiRequest,
3571                    satIOContext_t            *satIOContext)
3572 {
3573   bit32                     status;
3574   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3575   satDeviceData_t           *pSatDevData;
3576   scsiRspSense_t            *pSense;
3577   tiIniScsiCmnd_t           *scsiCmnd;
3578   agsaFisRegHostToDevice_t  *fis;
3579   bit32                     lba = 0;
3580   bit32                     tl = 0;
3581   bit32                     LoopNum = 1;
3582   bit8                      LBA[4];
3583   bit8                      TL[4];
3584   bit32                     rangeChk = agFALSE; /* lba and tl range check */
3585 
3586   pSense        = satIOContext->pSense;
3587   pSatDevData   = satIOContext->pSatDevData;
3588   scsiCmnd      = &tiScsiRequest->scsiCmnd;
3589   fis           = satIOContext->pFis;
3590 
3591   TI_DBG5(("satWrite12: start\n"));
3592 
3593   /* checking FUA_NV */
3594   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3595   {
3596     satSetSensePayload( pSense,
3597                         SCSI_SNSKEY_ILLEGAL_REQUEST,
3598                         0,
3599                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3600                         satIOContext);
3601 
3602     ostiInitiatorIOCompleted( tiRoot,
3603                               tiIORequest,
3604                               tiIOSuccess,
3605                               SCSI_STAT_CHECK_CONDITION,
3606                               satIOContext->pTiSenseData,
3607                               satIOContext->interruptContext );
3608 
3609     TI_DBG1(("satWrite12: return FUA_NV\n"));
3610     return tiSuccess;
3611 
3612   }
3613 
3614 
3615   /* checking CONTROL */
3616   /* NACA == 1 or LINK == 1*/
3617   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
3618   {
3619     satSetSensePayload( pSense,
3620                         SCSI_SNSKEY_ILLEGAL_REQUEST,
3621                         0,
3622                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3623                         satIOContext);
3624 
3625     ostiInitiatorIOCompleted( tiRoot,
3626                               tiIORequest,
3627                               tiIOSuccess,
3628                               SCSI_STAT_CHECK_CONDITION,
3629                               satIOContext->pTiSenseData,
3630                               satIOContext->interruptContext );
3631 
3632     TI_DBG1(("satWrite12: return control\n"));
3633     return tiSuccess;
3634   }
3635 
3636 
3637   osti_memset(LBA, 0, sizeof(LBA));
3638   osti_memset(TL, 0, sizeof(TL));
3639 
3640   /* do not use memcpy due to indexing in LBA and TL */
3641   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
3642   LBA[1] = scsiCmnd->cdb[3];
3643   LBA[2] = scsiCmnd->cdb[4];
3644   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
3645 
3646   TL[0] = scsiCmnd->cdb[6];   /* MSB */
3647   TL[1] = scsiCmnd->cdb[7];
3648   TL[2] = scsiCmnd->cdb[8];
3649   TL[3] = scsiCmnd->cdb[9];   /* LSB */
3650 
3651   rangeChk = satAddNComparebit32(LBA, TL);
3652 
3653   lba = satComputeCDB12LBA(satIOContext);
3654   tl = satComputeCDB12TL(satIOContext);
3655 
3656 
3657   /* Table 34, 9.1, p 46 */
3658   /*
3659     note: As of 2/10/2006, no support for DMA QUEUED
3660    */
3661 
3662   /*
3663     Table 34, 9.1, p 46, b
3664     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3665     return check condition
3666   */
3667   if (pSatDevData->satNCQ != agTRUE &&
3668       pSatDevData->sat48BitSupport != agTRUE
3669       )
3670   {
3671     if (lba > SAT_TR_LBA_LIMIT - 1)
3672     {
3673       satSetSensePayload( pSense,
3674                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3675                           0,
3676                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3677                           satIOContext);
3678 
3679       ostiInitiatorIOCompleted( tiRoot,
3680                                 tiIORequest,
3681                                 tiIOSuccess,
3682                                 SCSI_STAT_CHECK_CONDITION,
3683                                 satIOContext->pTiSenseData,
3684                                 satIOContext->interruptContext );
3685 
3686     TI_DBG1(("satWrite12: return LBA out of range, not EXT\n"));
3687     return tiSuccess;
3688     }
3689 
3690     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
3691     {
3692       TI_DBG1(("satWrite12: return LBA+TL out of range, not EXT\n"));
3693       satSetSensePayload( pSense,
3694                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3695                           0,
3696                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3697                           satIOContext);
3698 
3699       ostiInitiatorIOCompleted( tiRoot,
3700                                 tiIORequest,
3701                                 tiIOSuccess,
3702                                 SCSI_STAT_CHECK_CONDITION,
3703                                 satIOContext->pTiSenseData,
3704                                 satIOContext->interruptContext );
3705 
3706     return tiSuccess;
3707     }
3708   }
3709 
3710 
3711   /* case 1 and 2 */
3712   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
3713   {
3714     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3715     {
3716       /* case 2 */
3717       /* WRITE DMA*/
3718       /* In case that we can't fit the transfer length, we loop */
3719       TI_DBG5(("satWrite12: case 2\n"));
3720       fis->h.fisType        = 0x27;                   /* Reg host to device */
3721       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3722       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
3723       fis->h.features       = 0;                      /* FIS reserve */
3724       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3725       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3726       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3727 
3728       /* FIS LBA mode set LBA (27:24) */
3729       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3730 
3731       fis->d.lbaLowExp      = 0;
3732       fis->d.lbaMidExp      = 0;
3733       fis->d.lbaHighExp     = 0;
3734       fis->d.featuresExp    = 0;
3735       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3736       fis->d.sectorCountExp = 0;
3737       fis->d.reserved4      = 0;
3738       fis->d.control        = 0;                      /* FIS HOB bit clear */
3739       fis->d.reserved5      = 0;
3740 
3741       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3742       satIOContext->ATACmd = SAT_WRITE_DMA;
3743     }
3744     else
3745     {
3746       /* case 1 */
3747       /* WRITE MULTIPLE or WRITE SECTOR(S) */
3748       /* WRITE SECTORS for easier implemetation */
3749       /* In case that we can't fit the transfer length, we loop */
3750       TI_DBG5(("satWrite12: case 1\n"));
3751       fis->h.fisType        = 0x27;                   /* Reg host to device */
3752       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3753       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
3754       fis->h.features       = 0;                      /* FIS reserve */
3755       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3756       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3757       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3758 
3759       /* FIS LBA mode set LBA (27:24) */
3760       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3761 
3762       fis->d.lbaLowExp      = 0;
3763       fis->d.lbaMidExp      = 0;
3764       fis->d.lbaHighExp     = 0;
3765       fis->d.featuresExp    = 0;
3766       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3767       fis->d.sectorCountExp = 0;
3768       fis->d.reserved4      = 0;
3769       fis->d.control        = 0;                      /* FIS HOB bit clear */
3770       fis->d.reserved5      = 0;
3771 
3772       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3773       satIOContext->ATACmd = SAT_WRITE_SECTORS;
3774     }
3775   }
3776 
3777   /* case 3 and 4 */
3778   if (pSatDevData->sat48BitSupport == agTRUE)
3779   {
3780     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3781     {
3782       /* case 3 */
3783       /* WRITE DMA EXT or WRITE DMA FUA EXT */
3784       TI_DBG5(("satWrite12: case 3\n"));
3785       fis->h.fisType        = 0x27;                   /* Reg host to device */
3786       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3787 
3788       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3789       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
3790 
3791       fis->h.features       = 0;                      /* FIS reserve */
3792       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3793       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3794       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3795       fis->d.device         = 0x40;                   /* FIS LBA mode set */
3796       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
3797       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3798       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3799       fis->d.featuresExp    = 0;                      /* FIS reserve */
3800       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3801       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
3802       fis->d.reserved4      = 0;
3803       fis->d.control        = 0;                      /* FIS HOB bit clear */
3804       fis->d.reserved5      = 0;
3805 
3806       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3807       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3808     }
3809     else
3810     {
3811       /* case 4 */
3812       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3813       /* WRITE SECTORS EXT for easier implemetation */
3814       TI_DBG5(("satWrite12: case 4\n"));
3815       fis->h.fisType        = 0x27;                   /* Reg host to device */
3816       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3817       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
3818 
3819       fis->h.features       = 0;                      /* FIS reserve */
3820       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3821       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3822       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3823       fis->d.device         = 0x40;                   /* FIS LBA mode set */
3824       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
3825       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3826       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3827       fis->d.featuresExp    = 0;                      /* FIS reserve */
3828       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3829       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
3830       fis->d.reserved4      = 0;
3831       fis->d.control        = 0;                      /* FIS HOB bit clear */
3832       fis->d.reserved5      = 0;
3833 
3834       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3835       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3836     }
3837   }
3838 
3839   /* case 5 */
3840   if (pSatDevData->satNCQ == agTRUE)
3841   {
3842     /* WRITE FPDMA QUEUED */
3843     if (pSatDevData->sat48BitSupport != agTRUE)
3844     {
3845       TI_DBG5(("satWrite12: case 5 !!! error NCQ but 28 bit address support \n"));
3846        satSetSensePayload( pSense,
3847                           SCSI_SNSKEY_ILLEGAL_REQUEST,
3848                           0,
3849                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3850                           satIOContext);
3851 
3852       ostiInitiatorIOCompleted( tiRoot,
3853                                 tiIORequest,
3854                                 tiIOSuccess,
3855                                 SCSI_STAT_CHECK_CONDITION,
3856                                 satIOContext->pTiSenseData,
3857                                 satIOContext->interruptContext );
3858       return tiSuccess;
3859     }
3860     TI_DBG6(("satWrite12: case 5\n"));
3861 
3862     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3863 
3864     fis->h.fisType        = 0x27;                   /* Reg host to device */
3865     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3866     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3867     fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3868     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3869     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3870     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3871 
3872     /* Check FUA bit */
3873     if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
3874       fis->d.device       = 0xC0;                   /* FIS FUA set */
3875     else
3876       fis->d.device       = 0x40;                   /* FIS FUA clear */
3877 
3878     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
3879     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3880     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3881     fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
3882     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
3883     fis->d.sectorCountExp = 0;
3884     fis->d.reserved4      = 0;
3885     fis->d.control        = 0;                      /* FIS HOB bit clear */
3886     fis->d.reserved5      = 0;
3887 
3888     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3889     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3890   }
3891 
3892   satIOContext->currentLBA = lba;
3893   satIOContext->OrgTL = tl;
3894 
3895   /*
3896     computing number of loop and remainder for tl
3897     0xFF in case not ext
3898     0xFFFF in case EXT
3899   */
3900   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3901   {
3902     LoopNum = satComputeLoopNum(tl, 0xFF);
3903   }
3904   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3905            fis->h.command == SAT_WRITE_DMA_EXT     ||
3906            fis->h.command == SAT_WRITE_DMA_FUA_EXT
3907            )
3908   {
3909     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3910     LoopNum = satComputeLoopNum(tl, 0xFFFF);
3911   }
3912   else
3913   {
3914     /* SAT_WRITE_FPDMA_QUEUEDK */
3915     LoopNum = satComputeLoopNum(tl, 0xFFFF);
3916   }
3917 
3918   satIOContext->LoopNum = LoopNum;
3919 
3920 
3921   if (LoopNum == 1)
3922   {
3923     TI_DBG5(("satWrite12: NON CHAINED data\n"));
3924     /* Initialize CB for SATA completion.
3925      */
3926     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3927   }
3928   else
3929   {
3930     TI_DBG1(("satWrite12: CHAINED data\n"));
3931     /* re-setting tl */
3932     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3933     {
3934        fis->d.sectorCount    = 0xFF;
3935     }
3936     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3937              fis->h.command == SAT_WRITE_DMA_EXT ||
3938              fis->h.command == SAT_WRITE_DMA_FUA_EXT
3939              )
3940     {
3941       fis->d.sectorCount    = 0xFF;
3942       fis->d.sectorCountExp = 0xFF;
3943     }
3944     else
3945     {
3946       /* SAT_WRITE_FPDMA_QUEUED */
3947       fis->h.features       = 0xFF;
3948       fis->d.featuresExp    = 0xFF;
3949     }
3950 
3951     /* Initialize CB for SATA completion.
3952      */
3953     satIOContext->satCompleteCB = &satChainedDataIOCB;
3954   }
3955 
3956 
3957   /*
3958    * Prepare SGL and send FIS to LL layer.
3959    */
3960   satIOContext->reqType = agRequestType;       /* Save it */
3961 
3962   status = sataLLIOStart( tiRoot,
3963                           tiIORequest,
3964                           tiDeviceHandle,
3965                           tiScsiRequest,
3966                           satIOContext);
3967   return (status);
3968 }
3969 
3970 /*****************************************************************************/
3971 /*! \brief SAT implementation for SCSI WRITE10.
3972  *
3973  *  SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
3974  *
3975  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
3976  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
3977  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
3978  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
3979  *  \param   satIOContext_t:   Pointer to the SAT IO Context
3980  *
3981  *  \return If command is started successfully
3982  *    - \e tiSuccess:     I/O request successfully initiated.
3983  *    - \e tiBusy:        No resources available, try again later.
3984  *    - \e tiIONoDevice:  Invalid device handle.
3985  *    - \e tiError:       Other errors.
3986  */
3987 /*****************************************************************************/
3988 GLOBAL bit32  satWrite10(
3989                    tiRoot_t                  *tiRoot,
3990                    tiIORequest_t             *tiIORequest,
3991                    tiDeviceHandle_t          *tiDeviceHandle,
3992                    tiScsiInitiatorRequest_t *tiScsiRequest,
3993                    satIOContext_t            *satIOContext)
3994 {
3995 
3996   bit32                     status;
3997   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3998   satDeviceData_t           *pSatDevData;
3999   scsiRspSense_t            *pSense;
4000   tiIniScsiCmnd_t           *scsiCmnd;
4001   agsaFisRegHostToDevice_t  *fis;
4002   bit32                     lba = 0;
4003   bit32                     tl = 0;
4004   bit32                     LoopNum = 1;
4005   bit8                      LBA[4];
4006   bit8                      TL[4];
4007   bit32                     rangeChk = agFALSE; /* lba and tl range check */
4008 
4009   pSense        = satIOContext->pSense;
4010   pSatDevData   = satIOContext->pSatDevData;
4011   scsiCmnd      = &tiScsiRequest->scsiCmnd;
4012   fis           = satIOContext->pFis;
4013 
4014   TI_DBG5(("satWrite10: start\n"));
4015 
4016   /* checking FUA_NV */
4017   if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
4018   {
4019     satSetSensePayload( pSense,
4020                         SCSI_SNSKEY_ILLEGAL_REQUEST,
4021                         0,
4022                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4023                         satIOContext);
4024 
4025     ostiInitiatorIOCompleted( tiRoot,
4026                               tiIORequest,
4027                               tiIOSuccess,
4028                               SCSI_STAT_CHECK_CONDITION,
4029                               satIOContext->pTiSenseData,
4030                               satIOContext->interruptContext );
4031 
4032     TI_DBG1(("satWrite10: return FUA_NV\n"));
4033     return tiSuccess;
4034 
4035   }
4036 
4037   /* checking CONTROL */
4038   /* NACA == 1 or LINK == 1*/
4039   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
4040   {
4041     satSetSensePayload( pSense,
4042                         SCSI_SNSKEY_ILLEGAL_REQUEST,
4043                         0,
4044                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4045                         satIOContext);
4046 
4047     ostiInitiatorIOCompleted( tiRoot,
4048                               tiIORequest,
4049                               tiIOSuccess,
4050                               SCSI_STAT_CHECK_CONDITION,
4051                               satIOContext->pTiSenseData,
4052                               satIOContext->interruptContext );
4053 
4054     TI_DBG1(("satWrite10: return control\n"));
4055     return tiSuccess;
4056   }
4057 
4058   osti_memset(LBA, 0, sizeof(LBA));
4059   osti_memset(TL, 0, sizeof(TL));
4060 
4061   /* do not use memcpy due to indexing in LBA and TL */
4062   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
4063   LBA[1] = scsiCmnd->cdb[3];
4064   LBA[2] = scsiCmnd->cdb[4];
4065   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
4066 
4067   TL[0] = 0;
4068   TL[1] = 0;
4069   TL[2] = scsiCmnd->cdb[7];  /* MSB */
4070   TL[3] = scsiCmnd->cdb[8];  /* LSB */
4071 
4072   rangeChk = satAddNComparebit32(LBA, TL);
4073 
4074 
4075   /* cbd10; computing LBA and transfer length */
4076   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
4077     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
4078   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
4079 
4080   TI_DBG5(("satWrite10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
4081   TI_DBG5(("satWrite10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
4082 
4083   /* Table 34, 9.1, p 46 */
4084   /*
4085     note: As of 2/10/2006, no support for DMA QUEUED
4086    */
4087 
4088   /*
4089     Table 34, 9.1, p 46, b
4090     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4091     return check condition
4092   */
4093   if (pSatDevData->satNCQ != agTRUE &&
4094       pSatDevData->sat48BitSupport != agTRUE
4095       )
4096   {
4097     if (lba > SAT_TR_LBA_LIMIT - 1)
4098     {
4099       satSetSensePayload( pSense,
4100                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4101                           0,
4102                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4103                           satIOContext);
4104 
4105       ostiInitiatorIOCompleted( tiRoot,
4106                                 tiIORequest,
4107                                 tiIOSuccess,
4108                                 SCSI_STAT_CHECK_CONDITION,
4109                                 satIOContext->pTiSenseData,
4110                                 satIOContext->interruptContext );
4111 
4112       TI_DBG1(("satWrite10: return LBA out of range, not EXT\n"));
4113       TI_DBG1(("satWrite10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
4114              scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
4115       TI_DBG1(("satWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
4116       return tiSuccess;
4117     }
4118 
4119     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
4120     {
4121       TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
4122       satSetSensePayload( pSense,
4123                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4124                           0,
4125                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4126                           satIOContext);
4127 
4128       ostiInitiatorIOCompleted( tiRoot,
4129                                 tiIORequest,
4130                                 tiIOSuccess,
4131                                 SCSI_STAT_CHECK_CONDITION,
4132                                 satIOContext->pTiSenseData,
4133                                 satIOContext->interruptContext );
4134 
4135       return tiSuccess;
4136     }
4137 
4138   }
4139 
4140 
4141   /* case 1 and 2 */
4142   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
4143   {
4144     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4145     {
4146       /* case 2 */
4147       /* WRITE DMA*/
4148       /* can't fit the transfer length */
4149       TI_DBG5(("satWrite10: case 2\n"));
4150       fis->h.fisType        = 0x27;                   /* Reg host to device */
4151       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4152       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
4153       fis->h.features       = 0;                      /* FIS reserve */
4154       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4155       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4156       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4157 
4158       /* FIS LBA mode set LBA (27:24) */
4159       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4160 
4161       fis->d.lbaLowExp      = 0;
4162       fis->d.lbaMidExp      = 0;
4163       fis->d.lbaHighExp     = 0;
4164       fis->d.featuresExp    = 0;
4165       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4166       fis->d.sectorCountExp = 0;
4167       fis->d.reserved4      = 0;
4168       fis->d.control        = 0;                      /* FIS HOB bit clear */
4169       fis->d.reserved5      = 0;
4170 
4171       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4172       satIOContext->ATACmd = SAT_WRITE_DMA;
4173     }
4174     else
4175     {
4176       /* case 1 */
4177       /* WRITE MULTIPLE or WRITE SECTOR(S) */
4178       /* WRITE SECTORS for easier implemetation */
4179       /* can't fit the transfer length */
4180       TI_DBG5(("satWrite10: case 1\n"));
4181       fis->h.fisType        = 0x27;                   /* Reg host to device */
4182       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4183       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
4184       fis->h.features       = 0;                      /* FIS reserve */
4185       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4186       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4187       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4188 
4189       /* FIS LBA mode set LBA (27:24) */
4190       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4191 
4192       fis->d.lbaLowExp      = 0;
4193       fis->d.lbaMidExp      = 0;
4194       fis->d.lbaHighExp     = 0;
4195       fis->d.featuresExp    = 0;
4196       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4197       fis->d.sectorCountExp = 0;
4198       fis->d.reserved4      = 0;
4199       fis->d.control        = 0;                      /* FIS HOB bit clear */
4200       fis->d.reserved5      = 0;
4201 
4202       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4203       satIOContext->ATACmd = SAT_WRITE_SECTORS;
4204     }
4205   }
4206   /* case 3 and 4 */
4207   if (pSatDevData->sat48BitSupport == agTRUE)
4208   {
4209     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4210     {
4211       /* case 3 */
4212       /* WRITE DMA EXT or WRITE DMA FUA EXT */
4213       TI_DBG5(("satWrite10: case 3\n"));
4214       fis->h.fisType        = 0x27;                   /* Reg host to device */
4215       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4216 
4217       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
4218       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
4219       satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
4220 
4221       fis->h.features       = 0;                      /* FIS reserve */
4222       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4223       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4224       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4225       fis->d.device         = 0x40;                   /* FIS LBA mode set */
4226       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4227       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4228       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4229       fis->d.featuresExp    = 0;                      /* FIS reserve */
4230       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4231       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4232       fis->d.reserved4      = 0;
4233       fis->d.control        = 0;                      /* FIS HOB bit clear */
4234       fis->d.reserved5      = 0;
4235 
4236       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4237     }
4238     else
4239     {
4240       /* case 4 */
4241       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
4242       /* WRITE SECTORS EXT for easier implemetation */
4243       TI_DBG5(("satWrite10: case 4\n"));
4244       fis->h.fisType        = 0x27;                   /* Reg host to device */
4245       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4246       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
4247 
4248       fis->h.features       = 0;                      /* FIS reserve */
4249       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4250       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4251       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4252       fis->d.device         = 0x40;                   /* FIS LBA mode set */
4253       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4254       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4255       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4256       fis->d.featuresExp    = 0;                      /* FIS reserve */
4257       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4258       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4259       fis->d.reserved4      = 0;
4260       fis->d.control        = 0;                      /* FIS HOB bit clear */
4261       fis->d.reserved5      = 0;
4262 
4263       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4264       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
4265     }
4266   }
4267   /* case 5 */
4268   if (pSatDevData->satNCQ == agTRUE)
4269   {
4270     /* WRITE FPDMA QUEUED */
4271     if (pSatDevData->sat48BitSupport != agTRUE)
4272     {
4273       TI_DBG5(("satWrite10: case 5 !!! error NCQ but 28 bit address support \n"));
4274       satSetSensePayload( pSense,
4275                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4276                           0,
4277                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4278                           satIOContext);
4279 
4280       ostiInitiatorIOCompleted( tiRoot,
4281                                 tiIORequest,
4282                                 tiIOSuccess,
4283                                 SCSI_STAT_CHECK_CONDITION,
4284                                 satIOContext->pTiSenseData,
4285                                 satIOContext->interruptContext );
4286       return tiSuccess;
4287     }
4288     TI_DBG6(("satWrite10: case 5\n"));
4289 
4290     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4291 
4292     fis->h.fisType        = 0x27;                   /* Reg host to device */
4293     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4294     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4295     fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4296     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4297     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4298     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4299 
4300     /* Check FUA bit */
4301     if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4302       fis->d.device       = 0xC0;                   /* FIS FUA set */
4303     else
4304       fis->d.device       = 0x40;                   /* FIS FUA clear */
4305 
4306     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4307     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4308     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4309     fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4310     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4311     fis->d.sectorCountExp = 0;
4312     fis->d.reserved4      = 0;
4313     fis->d.control        = 0;                      /* FIS HOB bit clear */
4314     fis->d.reserved5      = 0;
4315 
4316     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4317     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
4318   }
4319 
4320   //  tdhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
4321 
4322   satIOContext->currentLBA = lba;
4323   satIOContext->OrgTL = tl;
4324 
4325   /*
4326     computing number of loop and remainder for tl
4327     0xFF in case not ext
4328     0xFFFF in case EXT
4329   */
4330   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4331   {
4332     LoopNum = satComputeLoopNum(tl, 0xFF);
4333   }
4334   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4335            fis->h.command == SAT_WRITE_DMA_EXT     ||
4336            fis->h.command == SAT_WRITE_DMA_FUA_EXT
4337            )
4338   {
4339     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
4340     LoopNum = satComputeLoopNum(tl, 0xFFFF);
4341   }
4342   else
4343   {
4344     /* SAT_WRITE_FPDMA_QUEUEDK */
4345     LoopNum = satComputeLoopNum(tl, 0xFFFF);
4346   }
4347 
4348   satIOContext->LoopNum = LoopNum;
4349 
4350 
4351   if (LoopNum == 1)
4352   {
4353     TI_DBG5(("satWrite10: NON CHAINED data\n"));
4354     /* Initialize CB for SATA completion.
4355      */
4356     satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4357   }
4358   else
4359   {
4360     TI_DBG1(("satWrite10: CHAINED data\n"));
4361     /* re-setting tl */
4362     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4363     {
4364        fis->d.sectorCount    = 0xFF;
4365     }
4366     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4367              fis->h.command == SAT_WRITE_DMA_EXT ||
4368              fis->h.command == SAT_WRITE_DMA_FUA_EXT
4369              )
4370     {
4371       fis->d.sectorCount    = 0xFF;
4372       fis->d.sectorCountExp = 0xFF;
4373     }
4374     else
4375     {
4376       /* SAT_WRITE_FPDMA_QUEUED */
4377       fis->h.features       = 0xFF;
4378       fis->d.featuresExp    = 0xFF;
4379     }
4380 
4381     /* Initialize CB for SATA completion.
4382      */
4383     satIOContext->satCompleteCB = &satChainedDataIOCB;
4384   }
4385 
4386 
4387   /*
4388    * Prepare SGL and send FIS to LL layer.
4389    */
4390   satIOContext->reqType = agRequestType;       /* Save it */
4391 
4392   status = sataLLIOStart( tiRoot,
4393                           tiIORequest,
4394                           tiDeviceHandle,
4395                           tiScsiRequest,
4396                           satIOContext);
4397   return (status);
4398 }
4399 
4400 /*****************************************************************************/
4401 /*! \brief SAT implementation for SCSI satWrite_1.
4402  *
4403  *  SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
4404  *  This is used when WRITE10 is divided into multiple ATA commands
4405  *
4406  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4407  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4408  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4409  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4410  *  \param   satIOContext_t:   Pointer to the SAT IO Context
4411  *
4412  *  \return If command is started successfully
4413  *    - \e tiSuccess:     I/O request successfully initiated.
4414  *    - \e tiBusy:        No resources available, try again later.
4415  *    - \e tiIONoDevice:  Invalid device handle.
4416  *    - \e tiError:       Other errors.
4417  */
4418 /*****************************************************************************/
4419 GLOBAL bit32  satWrite_1(
4420                    tiRoot_t                  *tiRoot,
4421                    tiIORequest_t             *tiIORequest,
4422                    tiDeviceHandle_t          *tiDeviceHandle,
4423                    tiScsiInitiatorRequest_t *tiScsiRequest,
4424                    satIOContext_t            *satIOContext)
4425 {
4426   /*
4427     Assumption: error check on lba and tl has been done in satWrite*()
4428     lba = lba + tl;
4429   */
4430   bit32                     status;
4431   satIOContext_t            *satOrgIOContext = agNULL;
4432   tiIniScsiCmnd_t           *scsiCmnd;
4433   agsaFisRegHostToDevice_t  *fis;
4434   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4435   bit32                     lba = 0;
4436   bit32                     DenomTL = 0xFF;
4437   bit32                     Remainder = 0;
4438   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
4439 
4440   TI_DBG2(("satWrite_1: start\n"));
4441 
4442   fis             = satIOContext->pFis;
4443   satOrgIOContext = satIOContext->satOrgIOContext;
4444   scsiCmnd        = satOrgIOContext->pScsiCmnd;
4445 
4446   osti_memset(LBA,0, sizeof(LBA));
4447 
4448   switch (satOrgIOContext->ATACmd)
4449   {
4450   case SAT_WRITE_DMA:
4451     DenomTL = 0xFF;
4452     break;
4453   case SAT_WRITE_SECTORS:
4454     DenomTL = 0xFF;
4455     break;
4456   case SAT_WRITE_DMA_EXT:
4457     DenomTL = 0xFFFF;
4458     break;
4459   case SAT_WRITE_DMA_FUA_EXT:
4460     DenomTL = 0xFFFF;
4461     break;
4462   case SAT_WRITE_SECTORS_EXT:
4463     DenomTL = 0xFFFF;
4464     break;
4465   case SAT_WRITE_FPDMA_QUEUED:
4466     DenomTL = 0xFFFF;
4467     break;
4468   default:
4469     TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4470     return tiError;
4471     break;
4472   }
4473 
4474   Remainder = satOrgIOContext->OrgTL % DenomTL;
4475   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
4476   lba = satOrgIOContext->currentLBA;
4477 
4478   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
4479   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
4480   LBA[2] = (bit8)((lba & 0xF0) >> 8);
4481   LBA[3] = (bit8)(lba & 0xF);               /* LSB */
4482 
4483   switch (satOrgIOContext->ATACmd)
4484   {
4485   case SAT_WRITE_DMA:
4486     fis->h.fisType        = 0x27;                   /* Reg host to device */
4487     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4488     fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
4489     fis->h.features       = 0;                      /* FIS reserve */
4490     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4491     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4492     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4493 
4494     /* FIS LBA mode set LBA (27:24) */
4495     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4496 
4497     fis->d.lbaLowExp      = 0;
4498     fis->d.lbaMidExp      = 0;
4499     fis->d.lbaHighExp     = 0;
4500     fis->d.featuresExp    = 0;
4501     if (satOrgIOContext->LoopNum == 1)
4502     {
4503       /* last loop */
4504       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
4505     }
4506     else
4507     {
4508       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
4509     }
4510     fis->d.sectorCountExp = 0;
4511     fis->d.reserved4      = 0;
4512     fis->d.control        = 0;                      /* FIS HOB bit clear */
4513     fis->d.reserved5      = 0;
4514 
4515     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4516 
4517     break;
4518   case SAT_WRITE_SECTORS:
4519     fis->h.fisType        = 0x27;                   /* Reg host to device */
4520     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4521     fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
4522     fis->h.features       = 0;                      /* FIS reserve */
4523     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4524     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4525     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4526 
4527     /* FIS LBA mode set LBA (27:24) */
4528     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4529 
4530     fis->d.lbaLowExp      = 0;
4531     fis->d.lbaMidExp      = 0;
4532     fis->d.lbaHighExp     = 0;
4533     fis->d.featuresExp    = 0;
4534     if (satOrgIOContext->LoopNum == 1)
4535     {
4536       /* last loop */
4537       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
4538     }
4539     else
4540     {
4541       fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
4542     }
4543     fis->d.sectorCountExp = 0;
4544     fis->d.reserved4      = 0;
4545     fis->d.control        = 0;                      /* FIS HOB bit clear */
4546     fis->d.reserved5      = 0;
4547 
4548     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4549 
4550     break;
4551   case SAT_WRITE_DMA_EXT:
4552     fis->h.fisType        = 0x27;                   /* Reg host to device */
4553     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4554     fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
4555     fis->h.features       = 0;                      /* FIS reserve */
4556     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4557     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4558     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4559     fis->d.device         = 0x40;                   /* FIS LBA mode set */
4560     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
4561     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4562     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4563     fis->d.featuresExp    = 0;                      /* FIS reserve */
4564     if (satOrgIOContext->LoopNum == 1)
4565     {
4566       /* last loop */
4567       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
4568       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
4569     }
4570     else
4571     {
4572       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
4573       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
4574     }
4575     fis->d.reserved4      = 0;
4576     fis->d.control        = 0;                       /* FIS HOB bit clear */
4577     fis->d.reserved5      = 0;
4578 
4579     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4580 
4581     break;
4582   case SAT_WRITE_SECTORS_EXT:
4583     fis->h.fisType        = 0x27;                   /* Reg host to device */
4584     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4585     fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
4586 
4587     fis->h.features       = 0;                      /* FIS reserve */
4588     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4589     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4590     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4591     fis->d.device         = 0x40;                   /* FIS LBA mode set */
4592     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
4593     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4594     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4595     fis->d.featuresExp    = 0;                      /* FIS reserve */
4596     if (satOrgIOContext->LoopNum == 1)
4597     {
4598       /* last loop */
4599       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
4600       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
4601     }
4602     else
4603     {
4604       fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
4605       fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
4606     }
4607     fis->d.reserved4      = 0;
4608     fis->d.control        = 0;                      /* FIS HOB bit clear */
4609     fis->d.reserved5      = 0;
4610 
4611     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4612 
4613     break;
4614   case SAT_WRITE_FPDMA_QUEUED:
4615     fis->h.fisType        = 0x27;                   /* Reg host to device */
4616     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4617     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4618     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4619     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4620     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4621 
4622     /* Check FUA bit */
4623     if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4624       fis->d.device       = 0xC0;                   /* FIS FUA set */
4625     else
4626       fis->d.device       = 0x40;                   /* FIS FUA clear */
4627 
4628     fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
4629     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4630     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4631     if (satOrgIOContext->LoopNum == 1)
4632     {
4633       /* last loop */
4634       fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
4635       fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
4636     }
4637     else
4638     {
4639       fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
4640       fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
4641     }
4642     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4643     fis->d.sectorCountExp = 0;
4644     fis->d.reserved4      = 0;
4645     fis->d.control        = 0;                      /* FIS HOB bit clear */
4646     fis->d.reserved5      = 0;
4647 
4648     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4649     break;
4650 
4651   default:
4652     TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4653     return tiError;
4654     break;
4655   }
4656 
4657   /* Initialize CB for SATA completion.
4658    */
4659   /* chained data */
4660   satIOContext->satCompleteCB = &satChainedDataIOCB;
4661 
4662 
4663   /*
4664    * Prepare SGL and send FIS to LL layer.
4665    */
4666   satIOContext->reqType = agRequestType;       /* Save it */
4667 
4668   status = sataLLIOStart( tiRoot,
4669                           tiIORequest,
4670                           tiDeviceHandle,
4671                           tiScsiRequest,
4672                           satIOContext);
4673 
4674   TI_DBG5(("satWrite_1: return\n"));
4675   return (status);
4676 }
4677 
4678 /*****************************************************************************/
4679 /*! \brief SAT implementation for SCSI WRITE6.
4680  *
4681  *  SAT implementation for SCSI WRITE6 and send FIS request to LL layer.
4682  *
4683  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4684  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4685  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4686  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4687  *  \param   satIOContext_t:   Pointer to the SAT IO Context
4688  *
4689  *  \return If command is started successfully
4690  *    - \e tiSuccess:     I/O request successfully initiated.
4691  *    - \e tiBusy:        No resources available, try again later.
4692  *    - \e tiIONoDevice:  Invalid device handle.
4693  *    - \e tiError:       Other errors.
4694  */
4695 /*****************************************************************************/
4696 GLOBAL bit32  satWrite6(
4697                    tiRoot_t                  *tiRoot,
4698                    tiIORequest_t             *tiIORequest,
4699                    tiDeviceHandle_t          *tiDeviceHandle,
4700                    tiScsiInitiatorRequest_t *tiScsiRequest,
4701                    satIOContext_t            *satIOContext)
4702 {
4703 
4704   bit32                     status;
4705   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4706   satDeviceData_t           *pSatDevData;
4707   scsiRspSense_t            *pSense;
4708   tiIniScsiCmnd_t           *scsiCmnd;
4709   agsaFisRegHostToDevice_t  *fis;
4710   bit32                     lba = 0;
4711   bit16                     tl = 0;
4712 
4713   pSense        = satIOContext->pSense;
4714   pSatDevData   = satIOContext->pSatDevData;
4715   scsiCmnd      = &tiScsiRequest->scsiCmnd;
4716   fis           = satIOContext->pFis;
4717 
4718   TI_DBG5(("satWrite6: start\n"));
4719 
4720   /* checking CONTROL */
4721   /* NACA == 1 or LINK == 1*/
4722   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
4723   {
4724     satSetSensePayload( pSense,
4725                         SCSI_SNSKEY_ILLEGAL_REQUEST,
4726                         0,
4727                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4728                         satIOContext);
4729 
4730     ostiInitiatorIOCompleted( tiRoot,
4731                               tiIORequest,
4732                               tiIOSuccess,
4733                               SCSI_STAT_CHECK_CONDITION,
4734                               satIOContext->pTiSenseData,
4735                               satIOContext->interruptContext );
4736 
4737     TI_DBG1(("satWrite6: return control\n"));
4738     return tiSuccess;
4739   }
4740 
4741 
4742   /* cbd6; computing LBA and transfer length */
4743   lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
4744     + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
4745   tl = scsiCmnd->cdb[4];
4746 
4747 
4748   /* Table 34, 9.1, p 46 */
4749   /*
4750     note: As of 2/10/2006, no support for DMA QUEUED
4751    */
4752 
4753   /*
4754     Table 34, 9.1, p 46, b
4755     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4756     return check condition
4757   */
4758   if (pSatDevData->satNCQ != agTRUE &&
4759       pSatDevData->sat48BitSupport != agTRUE
4760       )
4761   {
4762     if (lba > SAT_TR_LBA_LIMIT - 1)
4763     {
4764       satSetSensePayload( pSense,
4765                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4766                           0,
4767                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4768                           satIOContext);
4769 
4770       ostiInitiatorIOCompleted( tiRoot,
4771                                 tiIORequest,
4772                                 tiIOSuccess,
4773                                 SCSI_STAT_CHECK_CONDITION,
4774                                 satIOContext->pTiSenseData,
4775                                 satIOContext->interruptContext );
4776 
4777     TI_DBG1(("satWrite6: return LBA out of range\n"));
4778     return tiSuccess;
4779     }
4780   }
4781 
4782   /* case 1 and 2 */
4783   if (lba + tl <= SAT_TR_LBA_LIMIT)
4784   {
4785     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4786     {
4787       /* case 2 */
4788       /* WRITE DMA*/
4789       TI_DBG5(("satWrite6: case 2\n"));
4790 
4791 
4792       fis->h.fisType        = 0x27;                   /* Reg host to device */
4793       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4794       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
4795       fis->h.features       = 0;                      /* FIS reserve */
4796       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4797       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4798       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4799       fis->d.device         = 0x40;                   /* FIS LBA mode  */
4800       fis->d.lbaLowExp      = 0;
4801       fis->d.lbaMidExp      = 0;
4802       fis->d.lbaHighExp     = 0;
4803       fis->d.featuresExp    = 0;
4804       if (tl == 0)
4805       {
4806         /* temporary fix */
4807         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4808       }
4809       else
4810       {
4811         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4812       }
4813       fis->d.sectorCountExp = 0;
4814       fis->d.reserved4      = 0;
4815       fis->d.control        = 0;                      /* FIS HOB bit clear */
4816       fis->d.reserved5      = 0;
4817 
4818       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4819     }
4820     else
4821     {
4822       /* case 1 */
4823       /* WRITE SECTORS for easier implemetation */
4824       TI_DBG5(("satWrite6: case 1\n"));
4825 
4826       fis->h.fisType        = 0x27;                   /* Reg host to device */
4827       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4828       fis->h.command        = SAT_WRITE_SECTORS;          /* 0xCA */
4829       fis->h.features       = 0;                      /* FIS reserve */
4830       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4831       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4832       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4833       fis->d.device         = 0x40;                   /* FIS LBA mode  */
4834       fis->d.lbaLowExp      = 0;
4835       fis->d.lbaMidExp      = 0;
4836       fis->d.lbaHighExp     = 0;
4837       fis->d.featuresExp    = 0;
4838       if (tl == 0)
4839       {
4840         /* temporary fix */
4841         fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4842       }
4843       else
4844       {
4845         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4846       }
4847       fis->d.sectorCountExp = 0;
4848       fis->d.reserved4      = 0;
4849       fis->d.control        = 0;                      /* FIS HOB bit clear */
4850       fis->d.reserved5      = 0;
4851 
4852       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4853 
4854     }
4855   }
4856 
4857   /* case 3 and 4 */
4858   if (pSatDevData->sat48BitSupport == agTRUE)
4859   {
4860     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4861     {
4862       /* case 3 */
4863       /* WRITE DMA EXT only */
4864       TI_DBG5(("satWrite6: case 3\n"));
4865       fis->h.fisType        = 0x27;                   /* Reg host to device */
4866       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4867       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
4868       fis->h.features       = 0;                      /* FIS reserve */
4869       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4870       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4871       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4872       fis->d.device         = 0x40;                   /* FIS LBA mode set */
4873       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4874       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4875       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4876       fis->d.featuresExp    = 0;                      /* FIS reserve */
4877       if (tl == 0)
4878       {
4879         /* sector count is 256, 0x100*/
4880         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4881         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4882       }
4883       else
4884       {
4885         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4886         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4887       }
4888       fis->d.reserved4      = 0;
4889       fis->d.control        = 0;                      /* FIS HOB bit clear */
4890       fis->d.reserved5      = 0;
4891 
4892       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4893     }
4894     else
4895     {
4896       /* case 4 */
4897       /* WRITE SECTORS EXT for easier implemetation */
4898       TI_DBG5(("satWrite6: case 4\n"));
4899 
4900       fis->h.fisType        = 0x27;                   /* Reg host to device */
4901       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4902       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
4903       fis->h.features       = 0;                      /* FIS reserve */
4904       fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4905       fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4906       fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4907       fis->d.device         = 0x40;                   /* FIS LBA mode set */
4908       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4909       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4910       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4911       fis->d.featuresExp    = 0;                      /* FIS reserve */
4912       if (tl == 0)
4913       {
4914         /* sector count is 256, 0x100*/
4915         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4916         fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4917       }
4918       else
4919       {
4920         fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4921         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4922       }
4923       fis->d.reserved4      = 0;
4924       fis->d.control        = 0;                      /* FIS HOB bit clear */
4925       fis->d.reserved5      = 0;
4926 
4927       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4928     }
4929   }
4930 
4931    /* case 5 */
4932   if (pSatDevData->satNCQ == agTRUE)
4933   {
4934     /* WRITE FPDMA QUEUED */
4935     if (pSatDevData->sat48BitSupport != agTRUE)
4936     {
4937       /* sanity check */
4938       TI_DBG5(("satWrite6: case 5 !!! error NCQ but 28 bit address support \n"));
4939        satSetSensePayload( pSense,
4940                           SCSI_SNSKEY_ILLEGAL_REQUEST,
4941                           0,
4942                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4943                           satIOContext);
4944 
4945       ostiInitiatorIOCompleted( tiRoot,
4946                                 tiIORequest,
4947                                 tiIOSuccess,
4948                                 SCSI_STAT_CHECK_CONDITION,
4949                                 satIOContext->pTiSenseData,
4950                                 satIOContext->interruptContext );
4951       return tiSuccess;
4952     }
4953     TI_DBG5(("satWrite6: case 5\n"));
4954 
4955     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4956 
4957     fis->h.fisType        = 0x27;                   /* Reg host to device */
4958     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4959     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4960     fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4961     fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4962     fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4963     fis->d.device         = 0x40;                   /* FIS FUA clear */
4964     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4965     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4966     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4967     if (tl == 0)
4968     {
4969       /* sector count is 256, 0x100*/
4970       fis->h.features       = 0;                         /* FIS sector count (7:0) */
4971       fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
4972     }
4973     else
4974     {
4975       fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4976       fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
4977     }
4978     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4979     fis->d.sectorCountExp = 0;
4980     fis->d.reserved4      = 0;
4981     fis->d.control        = 0;                      /* FIS HOB bit clear */
4982     fis->d.reserved5      = 0;
4983 
4984     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4985   }
4986 
4987   /* Initialize CB for SATA completion.
4988    */
4989   satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4990 
4991   /*
4992    * Prepare SGL and send FIS to LL layer.
4993    */
4994   satIOContext->reqType = agRequestType;       /* Save it */
4995 
4996   status = sataLLIOStart( tiRoot,
4997                           tiIORequest,
4998                           tiDeviceHandle,
4999                           tiScsiRequest,
5000                           satIOContext);
5001   return (status);
5002 }
5003 
5004 
5005 /*****************************************************************************/
5006 /*! \brief SAT implementation for SCSI TEST UNIT READY.
5007  *
5008  *  SAT implementation for SCSI TUR and send FIS request to LL layer.
5009  *
5010  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5011  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5012  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5013  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5014  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5015  *
5016  *  \return If command is started successfully
5017  *    - \e tiSuccess:     I/O request successfully initiated.
5018  *    - \e tiBusy:        No resources available, try again later.
5019  *    - \e tiIONoDevice:  Invalid device handle.
5020  *    - \e tiError:       Other errors.
5021  */
5022 /*****************************************************************************/
5023 GLOBAL bit32  satTestUnitReady(
5024                    tiRoot_t                  *tiRoot,
5025                    tiIORequest_t             *tiIORequest,
5026                    tiDeviceHandle_t          *tiDeviceHandle,
5027                    tiScsiInitiatorRequest_t *tiScsiRequest,
5028                    satIOContext_t            *satIOContext)
5029 {
5030 
5031   bit32                     status;
5032   bit32                     agRequestType;
5033   satDeviceData_t           *pSatDevData;
5034   scsiRspSense_t            *pSense;
5035   tiIniScsiCmnd_t           *scsiCmnd;
5036   agsaFisRegHostToDevice_t  *fis;
5037 
5038   pSense        = satIOContext->pSense;
5039   pSatDevData   = satIOContext->pSatDevData;
5040   scsiCmnd      = &tiScsiRequest->scsiCmnd;
5041   fis           = satIOContext->pFis;
5042 
5043   TI_DBG6(("satTestUnitReady: entry tiDeviceHandle=%p tiIORequest=%p\n",
5044       tiDeviceHandle, tiIORequest));
5045 
5046   /* checking CONTROL */
5047   /* NACA == 1 or LINK == 1*/
5048   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5049   {
5050     satSetSensePayload( pSense,
5051                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5052                         0,
5053                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5054                         satIOContext);
5055 
5056     ostiInitiatorIOCompleted( tiRoot,
5057                               tiIORequest,
5058                               tiIOSuccess,
5059                               SCSI_STAT_CHECK_CONDITION,
5060                               satIOContext->pTiSenseData,
5061                               satIOContext->interruptContext );
5062 
5063     TI_DBG1(("satTestUnitReady: return control\n"));
5064     return tiSuccess;
5065   }
5066 
5067   /* SAT revision 8, 8.11.2, p42*/
5068   if (pSatDevData->satStopState == agTRUE)
5069   {
5070     satSetSensePayload( pSense,
5071                         SCSI_SNSKEY_NOT_READY,
5072                         0,
5073                         SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
5074                         satIOContext);
5075 
5076     ostiInitiatorIOCompleted( tiRoot,
5077                               tiIORequest,
5078                               tiIOSuccess,
5079                               SCSI_STAT_CHECK_CONDITION,
5080                               satIOContext->pTiSenseData,
5081                               satIOContext->interruptContext );
5082     TI_DBG1(("satTestUnitReady: stop state\n"));
5083     return tiSuccess;
5084   }
5085 
5086   /*
5087    * Check if format is in progress
5088    */
5089 
5090   if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
5091   {
5092     TI_DBG1(("satTestUnitReady() FORMAT_IN_PROGRESS  tiDeviceHandle=%p tiIORequest=%p\n",
5093          tiDeviceHandle, tiIORequest));
5094 
5095     satSetSensePayload( pSense,
5096                         SCSI_SNSKEY_NOT_READY,
5097                         0,
5098                         SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
5099                         satIOContext);
5100 
5101     ostiInitiatorIOCompleted( tiRoot,
5102                               tiIORequest,
5103                               tiIOSuccess,
5104                               SCSI_STAT_CHECK_CONDITION,
5105                               satIOContext->pTiSenseData,
5106                               satIOContext->interruptContext );
5107     TI_DBG1(("satTestUnitReady: format in progress\n"));
5108     return tiSuccess;
5109   }
5110 
5111   /*
5112     check previously issued ATA command
5113   */
5114   if (pSatDevData->satPendingIO != 0)
5115   {
5116     if (pSatDevData->satDeviceFaultState == agTRUE)
5117     {
5118       satSetSensePayload( pSense,
5119                           SCSI_SNSKEY_HARDWARE_ERROR,
5120                           0,
5121                           SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
5122                           satIOContext);
5123 
5124       ostiInitiatorIOCompleted( tiRoot,
5125                                 tiIORequest,
5126                                 tiIOSuccess,
5127                                 SCSI_STAT_CHECK_CONDITION,
5128                                 satIOContext->pTiSenseData,
5129                                 satIOContext->interruptContext );
5130       TI_DBG1(("satTestUnitReady: previous command ended in error\n"));
5131       return tiSuccess;
5132     }
5133   }
5134   /*
5135     check removalbe media feature set
5136    */
5137   if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
5138   {
5139     TI_DBG5(("satTestUnitReady: sending get media status cmnd\n"));
5140     /* send GET MEDIA STATUS command */
5141     fis->h.fisType        = 0x27;                   /* Reg host to device */
5142     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5143     fis->h.command        = SAT_GET_MEDIA_STATUS;   /* 0xDA */
5144     fis->h.features       = 0;                      /* FIS features NA       */
5145     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
5146     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
5147     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
5148     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
5149     fis->d.lbaLowExp      = 0;
5150     fis->d.lbaMidExp      = 0;
5151     fis->d.lbaHighExp     = 0;
5152     fis->d.featuresExp    = 0;
5153     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
5154     fis->d.sectorCountExp = 0;
5155     fis->d.reserved4      = 0;
5156     fis->d.control        = 0;                      /* FIS HOB bit clear */
5157     fis->d.reserved5      = 0;
5158     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5159 
5160     /* Initialize CB for SATA completion.
5161      */
5162     satIOContext->satCompleteCB = &satTestUnitReadyCB;
5163 
5164     /*
5165      * Prepare SGL and send FIS to LL layer.
5166      */
5167     satIOContext->reqType = agRequestType;       /* Save it */
5168 
5169     status = sataLLIOStart( tiRoot,
5170                             tiIORequest,
5171                             tiDeviceHandle,
5172                             tiScsiRequest,
5173                             satIOContext);
5174 
5175     return (status);
5176   }
5177   /*
5178     number 6) in SAT p42
5179     send ATA CHECK POWER MODE
5180   */
5181    TI_DBG5(("satTestUnitReady: sending check power mode cmnd\n"));
5182    status = satTestUnitReady_1( tiRoot,
5183                                tiIORequest,
5184                                tiDeviceHandle,
5185                                tiScsiRequest,
5186                                satIOContext);
5187    return (status);
5188 }
5189 
5190 
5191 /*****************************************************************************/
5192 /*! \brief SAT implementation for SCSI satTestUnitReady_1.
5193  *
5194  *  SAT implementation for SCSI satTestUnitReady_1.
5195  *
5196  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5197  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5198  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5199  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5200  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5201  *
5202  *  \return If command is started successfully
5203  *    - \e tiSuccess:     I/O request successfully initiated.
5204  *    - \e tiBusy:        No resources available, try again later.
5205  *    - \e tiIONoDevice:  Invalid device handle.
5206  *    - \e tiError:       Other errors.
5207  */
5208 /*****************************************************************************/
5209 GLOBAL bit32  satTestUnitReady_1(
5210                          tiRoot_t                  *tiRoot,
5211                          tiIORequest_t             *tiIORequest,
5212                          tiDeviceHandle_t          *tiDeviceHandle,
5213                          tiScsiInitiatorRequest_t *tiScsiRequest,
5214                          satIOContext_t            *satIOContext)
5215 {
5216   /*
5217     sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY
5218     internally generated - no directly corresponding scsi
5219     called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42
5220   */
5221   bit32                     status;
5222   bit32                     agRequestType;
5223   agsaFisRegHostToDevice_t  *fis;
5224 
5225   fis           = satIOContext->pFis;
5226 
5227   TI_DBG5(("satTestUnitReady_1: start\n"));
5228 
5229   /*
5230    * Send the ATA CHECK POWER MODE command.
5231    */
5232   fis->h.fisType        = 0x27;                   /* Reg host to device */
5233   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5234   fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
5235   fis->h.features       = 0;
5236   fis->d.lbaLow         = 0;
5237   fis->d.lbaMid         = 0;
5238   fis->d.lbaHigh        = 0;
5239   fis->d.device         = 0;
5240   fis->d.lbaLowExp      = 0;
5241   fis->d.lbaMidExp      = 0;
5242   fis->d.lbaHighExp     = 0;
5243   fis->d.featuresExp    = 0;
5244   fis->d.sectorCount    = 0;
5245   fis->d.sectorCountExp = 0;
5246   fis->d.reserved4      = 0;
5247   fis->d.control        = 0;                      /* FIS HOB bit clear */
5248   fis->d.reserved5      = 0;
5249 
5250   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5251 
5252   /* Initialize CB for SATA completion.
5253    */
5254   satIOContext->satCompleteCB = &satTestUnitReadyCB;
5255 
5256   /*
5257    * Prepare SGL and send FIS to LL layer.
5258    */
5259   satIOContext->reqType = agRequestType;       /* Save it */
5260 
5261   status = sataLLIOStart( tiRoot,
5262                           tiIORequest,
5263                           tiDeviceHandle,
5264                           tiScsiRequest,
5265                           satIOContext);
5266 
5267   TI_DBG5(("satTestUnitReady_1: return\n"));
5268 
5269   return status;
5270 }
5271 
5272 
5273 /*****************************************************************************/
5274 /*! \brief SAT implementation for SCSI satReportLun.
5275  *
5276  *  SAT implementation for SCSI satReportLun. Only LUN0 is reported.
5277  *
5278  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5279  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5280  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5281  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5282  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5283  *
5284  *  \return If command is started successfully
5285  *    - \e tiSuccess:     I/O request successfully initiated.
5286  *    - \e tiBusy:        No resources available, try again later.
5287  *    - \e tiIONoDevice:  Invalid device handle.
5288  *    - \e tiError:       Other errors.
5289  */
5290 /*****************************************************************************/
5291 GLOBAL bit32  satReportLun(
5292                    tiRoot_t                  *tiRoot,
5293                    tiIORequest_t             *tiIORequest,
5294                    tiDeviceHandle_t          *tiDeviceHandle,
5295                    tiScsiInitiatorRequest_t *tiScsiRequest,
5296                    satIOContext_t            *satIOContext)
5297 {
5298   scsiRspSense_t        *pSense;
5299   bit32                 allocationLen;
5300   bit32                 reportLunLen;
5301   scsiReportLun_t       *pReportLun;
5302   tiIniScsiCmnd_t       *scsiCmnd;
5303 
5304   TI_DBG5(("satReportLun entry: tiDeviceHandle=%p tiIORequest=%p\n",
5305       tiDeviceHandle, tiIORequest));
5306 
5307   pSense     = satIOContext->pSense;
5308   pReportLun = (scsiReportLun_t *) tiScsiRequest->sglVirtualAddr;
5309   scsiCmnd   = &tiScsiRequest->scsiCmnd;
5310 
5311 //  tdhexdump("satReportLun cdb", (bit8 *)scsiCmnd, 16);
5312 
5313   /* Find the buffer size allocated by Initiator */
5314   allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
5315                   (((bit32)scsiCmnd->cdb[7]) << 16) |
5316                   (((bit32)scsiCmnd->cdb[8]) << 8 ) |
5317                   (((bit32)scsiCmnd->cdb[9])      );
5318 
5319   reportLunLen  = 16;     /* 8 byte header and 8 bytes of LUN0 */
5320 
5321   if (allocationLen < reportLunLen)
5322   {
5323     TI_DBG1(("satReportLun *** ERROR *** insufficient len=0x%x tiDeviceHandle=%p tiIORequest=%p\n",
5324         reportLunLen, tiDeviceHandle, tiIORequest));
5325 
5326     satSetSensePayload( pSense,
5327                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5328                         0,
5329                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5330                         satIOContext);
5331 
5332     ostiInitiatorIOCompleted( tiRoot,
5333                               tiIORequest,
5334                               tiIOSuccess,
5335                               SCSI_STAT_CHECK_CONDITION,
5336                               satIOContext->pTiSenseData,
5337                               satIOContext->interruptContext );
5338     return tiSuccess;
5339 
5340   }
5341 
5342   /* Set length to one entry */
5343   pReportLun->len[0] = 0;
5344   pReportLun->len[1] = 0;
5345   pReportLun->len[2] = 0;
5346   pReportLun->len[3] = sizeof (tiLUN_t);
5347 
5348   pReportLun->reserved = 0;
5349 
5350   /* Set to LUN 0:
5351    * - address method to 0x00: Peripheral device addressing method,
5352    * - bus identifier to 0
5353    */
5354   pReportLun->lunList[0].lun[0] = 0;
5355   pReportLun->lunList[0].lun[1] = 0;
5356   pReportLun->lunList[0].lun[2] = 0;
5357   pReportLun->lunList[0].lun[3] = 0;
5358   pReportLun->lunList[0].lun[4] = 0;
5359   pReportLun->lunList[0].lun[5] = 0;
5360   pReportLun->lunList[0].lun[6] = 0;
5361   pReportLun->lunList[0].lun[7] = 0;
5362 
5363   if (allocationLen > reportLunLen)
5364   {
5365     /* underrun */
5366     TI_DBG1(("satReportLun reporting underrun reportLunLen=0x%x allocationLen=0x%x \n", reportLunLen, allocationLen));
5367 
5368     ostiInitiatorIOCompleted( tiRoot,
5369                               tiIORequest,
5370                               tiIOUnderRun,
5371                               allocationLen - reportLunLen,
5372                               agNULL,
5373                               satIOContext->interruptContext );
5374 
5375 
5376   }
5377   else
5378   {
5379     ostiInitiatorIOCompleted( tiRoot,
5380                               tiIORequest,
5381                               tiIOSuccess,
5382                               SCSI_STAT_GOOD,
5383                               agNULL,
5384                               satIOContext->interruptContext);
5385   }
5386   return tiSuccess;
5387 }
5388 
5389 
5390 /*****************************************************************************/
5391 /*! \brief SAT implementation for SCSI REQUEST SENSE.
5392  *
5393  *  SAT implementation for SCSI REQUEST SENSE.
5394  *
5395  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5396  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5397  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5398  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5399  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5400  *
5401  *  \return If command is started successfully
5402  *    - \e tiSuccess:     I/O request successfully initiated.
5403  *    - \e tiBusy:        No resources available, try again later.
5404  *    - \e tiIONoDevice:  Invalid device handle.
5405  *    - \e tiError:       Other errors.
5406  */
5407 /*****************************************************************************/
5408 GLOBAL bit32  satRequestSense(
5409                    tiRoot_t                  *tiRoot,
5410                    tiIORequest_t             *tiIORequest,
5411                    tiDeviceHandle_t          *tiDeviceHandle,
5412                    tiScsiInitiatorRequest_t *tiScsiRequest,
5413                    satIOContext_t            *satIOContext)
5414 {
5415   /*
5416     SAT Rev 8 p38, Table25
5417     sending SMART RETURN STATUS
5418     Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB()
5419     Only fixed format sense data is support. In other words, we don't support DESC bit is set
5420     in Request Sense
5421    */
5422   bit32                     status;
5423   bit32                     agRequestType;
5424   scsiRspSense_t            *pSense;
5425   satDeviceData_t           *pSatDevData;
5426   tiIniScsiCmnd_t           *scsiCmnd;
5427   agsaFisRegHostToDevice_t  *fis;
5428   tdIORequestBody_t         *tdIORequestBody;
5429   satInternalIo_t           *satIntIo = agNULL;
5430   satIOContext_t            *satIOContext2;
5431 
5432   TI_DBG4(("satRequestSense entry: tiDeviceHandle=%p tiIORequest=%p\n",
5433       tiDeviceHandle, tiIORequest));
5434 
5435   pSense            = (scsiRspSense_t *) tiScsiRequest->sglVirtualAddr;
5436   pSatDevData       = satIOContext->pSatDevData;
5437   scsiCmnd          = &tiScsiRequest->scsiCmnd;
5438   fis               = satIOContext->pFis;
5439 
5440   TI_DBG4(("satRequestSense: pSatDevData=%p\n", pSatDevData));
5441 
5442   /* checking CONTROL */
5443   /* NACA == 1 or LINK == 1*/
5444   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5445   {
5446     satSetSensePayload( pSense,
5447                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5448                         0,
5449                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5450                         satIOContext);
5451 
5452     ostiInitiatorIOCompleted( tiRoot,
5453                               tiIORequest,
5454                               tiIOSuccess,
5455                               SCSI_STAT_CHECK_CONDITION,
5456                               satIOContext->pTiSenseData,
5457                               satIOContext->interruptContext );
5458 
5459     TI_DBG1(("satRequestSense: return control\n"));
5460     return tiSuccess;
5461   }
5462 
5463   /*
5464     Only fixed format sense data is support. In other words, we don't support DESC bit is set
5465     in Request Sense
5466    */
5467   if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
5468   {
5469     satSetSensePayload( pSense,
5470                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5471                         0,
5472                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5473                         satIOContext);
5474 
5475     ostiInitiatorIOCompleted( tiRoot,
5476                               tiIORequest,
5477                               tiIOSuccess,
5478                               SCSI_STAT_CHECK_CONDITION,
5479                               satIOContext->pTiSenseData,
5480                               satIOContext->interruptContext );
5481 
5482     TI_DBG1(("satRequestSense: DESC bit is set, which we don't support\n"));
5483     return tiSuccess;
5484   }
5485 
5486 
5487   if (pSatDevData->satSMARTEnabled == agTRUE)
5488   {
5489     /* sends SMART RETURN STATUS */
5490     fis->h.fisType        = 0x27;                   /* Reg host to device */
5491     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5492 
5493     fis->h.command        = SAT_SMART_RETURN_STATUS;    /* 0xB0 */
5494     fis->h.features       = 0xDA;                   /* FIS features */
5495     fis->d.featuresExp    = 0;                      /* FIS reserve */
5496     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
5497     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
5498     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
5499     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
5500     fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
5501     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5502     fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
5503     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5504     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
5505     fis->d.control        = 0;                      /* FIS HOB bit clear */
5506     fis->d.reserved4      = 0;
5507     fis->d.reserved5      = 0;
5508 
5509     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5510     /* Initialize CB for SATA completion.
5511      */
5512     satIOContext->satCompleteCB = &satRequestSenseCB;
5513 
5514     /*
5515      * Prepare SGL and send FIS to LL layer.
5516      */
5517     satIOContext->reqType = agRequestType;       /* Save it */
5518 
5519     status = sataLLIOStart( tiRoot,
5520                             tiIORequest,
5521                             tiDeviceHandle,
5522                             tiScsiRequest,
5523                             satIOContext);
5524 
5525     TI_DBG4(("satRequestSense: if return, status %d\n", status));
5526     return (status);
5527   }
5528   else
5529   {
5530     /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE
5531       then call satRequestSense2 */
5532 
5533     TI_DBG4(("satRequestSense: before satIntIo %p\n", satIntIo));
5534     /* allocate iocontext */
5535     satIntIo = satAllocIntIoResource( tiRoot,
5536                                       tiIORequest, /* original request */
5537                                       pSatDevData,
5538                                       tiScsiRequest->scsiCmnd.expDataLength,
5539                                       satIntIo);
5540 
5541     TI_DBG4(("satRequestSense: after satIntIo %p\n", satIntIo));
5542 
5543     if (satIntIo == agNULL)
5544     {
5545       /* memory allocation failure */
5546       satFreeIntIoResource( tiRoot,
5547                             pSatDevData,
5548                             satIntIo);
5549 
5550       /* failed during sending SMART RETURN STATUS */
5551       satSetSensePayload( pSense,
5552                           SCSI_SNSKEY_NO_SENSE,
5553                           0,
5554                           SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5555                           satIOContext);
5556 
5557       ostiInitiatorIOCompleted( tiRoot,
5558                                 tiIORequest,
5559                                 tiIOSuccess,
5560                                 SCSI_STAT_GOOD,
5561                                 agNULL,
5562                                 satIOContext->interruptContext );
5563 
5564       TI_DBG4(("satRequestSense: else fail 1\n"));
5565       return tiSuccess;
5566     } /* end of memory allocation failure */
5567 
5568 
5569     /*
5570      * Need to initialize all the fields within satIOContext except
5571      * reqType and satCompleteCB which will be set depending on cmd.
5572      */
5573 
5574     if (satIntIo == agNULL)
5575     {
5576       TI_DBG4(("satRequestSense: satIntIo is NULL\n"));
5577     }
5578     else
5579     {
5580       TI_DBG4(("satRequestSense: satIntIo is NOT NULL\n"));
5581     }
5582     /* use this --- tttttthe one the same */
5583 
5584 
5585     satIntIo->satOrgTiIORequest = tiIORequest;
5586     tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
5587     satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
5588 
5589     satIOContext2->pSatDevData   = pSatDevData;
5590     satIOContext2->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
5591     satIOContext2->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
5592     satIOContext2->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
5593     satIOContext2->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
5594     satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
5595     satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
5596     satIOContext2->interruptContext = satIOContext->interruptContext;
5597     satIOContext2->satIntIoContext  = satIntIo;
5598     satIOContext2->ptiDeviceHandle = tiDeviceHandle;
5599     satIOContext2->satOrgIOContext = satIOContext;
5600 
5601     TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
5602 
5603     TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
5604 
5605     TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
5606 
5607     TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
5608 
5609     status = satRequestSense_1( tiRoot,
5610                                &(satIntIo->satIntTiIORequest),
5611                                tiDeviceHandle,
5612                                &(satIntIo->satIntTiScsiXchg),
5613                                satIOContext2);
5614 
5615     if (status != tiSuccess)
5616     {
5617       satFreeIntIoResource( tiRoot,
5618                             pSatDevData,
5619                             satIntIo);
5620 
5621       /* failed during sending SMART RETURN STATUS */
5622       satSetSensePayload( pSense,
5623                           SCSI_SNSKEY_NO_SENSE,
5624                           0,
5625                           SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5626                           satIOContext);
5627 
5628       ostiInitiatorIOCompleted( tiRoot,
5629                                 tiIORequest,
5630                                 tiIOSuccess,
5631                                 SCSI_STAT_CHECK_CONDITION,
5632                                 agNULL,
5633                                 satIOContext->interruptContext );
5634 
5635       TI_DBG1(("satRequestSense: else fail 2\n"));
5636       return tiSuccess;
5637     }
5638     TI_DBG4(("satRequestSense: else return success\n"));
5639     return tiSuccess;
5640   }
5641 }
5642 
5643 
5644 /*****************************************************************************/
5645 /*! \brief SAT implementation for SCSI REQUEST SENSE.
5646  *
5647  *  SAT implementation for SCSI REQUEST SENSE.
5648  *  Sub function of satRequestSense
5649  *
5650  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5651  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5652  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5653  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5654  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5655  *
5656  *  \return If command is started successfully
5657  *    - \e tiSuccess:     I/O request successfully initiated.
5658  *    - \e tiBusy:        No resources available, try again later.
5659  *    - \e tiIONoDevice:  Invalid device handle.
5660  *    - \e tiError:       Other errors.
5661  */
5662 /*****************************************************************************/
5663 GLOBAL bit32  satRequestSense_1(
5664                    tiRoot_t                  *tiRoot,
5665                    tiIORequest_t             *tiIORequest,
5666                    tiDeviceHandle_t          *tiDeviceHandle,
5667                    tiScsiInitiatorRequest_t *tiScsiRequest,
5668                    satIOContext_t            *satIOContext)
5669 {
5670   /*
5671     sends SAT_CHECK_POWER_MODE
5672   */
5673   bit32                     status;
5674   bit32                     agRequestType;
5675   agsaFisRegHostToDevice_t  *fis;
5676 
5677   TI_DBG4(("satRequestSense_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
5678       tiDeviceHandle, tiIORequest));
5679 
5680   fis               = satIOContext->pFis;
5681   /*
5682    * Send the ATA CHECK POWER MODE command.
5683    */
5684   fis->h.fisType        = 0x27;                   /* Reg host to device */
5685   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5686 
5687   fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
5688   fis->h.features       = 0;
5689   fis->d.lbaLow         = 0;
5690   fis->d.lbaMid         = 0;
5691   fis->d.lbaHigh        = 0;
5692   fis->d.device         = 0;
5693   fis->d.lbaLowExp      = 0;
5694   fis->d.lbaMidExp      = 0;
5695   fis->d.lbaHighExp     = 0;
5696   fis->d.featuresExp    = 0;
5697   fis->d.sectorCount    = 0;
5698   fis->d.sectorCountExp = 0;
5699   fis->d.reserved4      = 0;
5700   fis->d.control        = 0;                      /* FIS HOB bit clear */
5701   fis->d.reserved5      = 0;
5702 
5703   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5704 
5705   /* Initialize CB for SATA completion.
5706    */
5707   satIOContext->satCompleteCB = &satRequestSenseCB;
5708 
5709   /*
5710    * Prepare SGL and send FIS to LL layer.
5711    */
5712   satIOContext->reqType = agRequestType;       /* Save it */
5713 
5714 
5715   TI_DBG4(("satRequestSense_1: agSgl1.len %d\n", tiScsiRequest->agSgl1.len));
5716 
5717   TI_DBG4(("satRequestSense_1: agSgl1.upper %d\n", tiScsiRequest->agSgl1.upper));
5718 
5719   TI_DBG4(("satRequestSense_1: agSgl1.lower %d\n", tiScsiRequest->agSgl1.lower));
5720 
5721   TI_DBG4(("satRequestSense_1: agSgl1.type %d\n", tiScsiRequest->agSgl1.type));
5722 
5723   //  tdhexdump("satRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
5724 
5725   status = sataLLIOStart( tiRoot,
5726                           tiIORequest,
5727                           tiDeviceHandle,
5728                           tiScsiRequest,
5729                           satIOContext);
5730 
5731 
5732 
5733   return status;
5734 }
5735 
5736 
5737 /*****************************************************************************/
5738 /*! \brief SAT implementation for SCSI INQUIRY.
5739  *
5740  *  SAT implementation for SCSI INQUIRY.
5741  *
5742  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5743  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5744  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5745  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5746  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5747  *
5748  *  \return If command is started successfully
5749  *    - \e tiSuccess:     I/O request successfully initiated.
5750  *    - \e tiBusy:        No resources available, try again later.
5751  *    - \e tiIONoDevice:  Invalid device handle.
5752  *    - \e tiError:       Other errors.
5753  */
5754 /*****************************************************************************/
5755 GLOBAL bit32  satInquiry(
5756                    tiRoot_t                  *tiRoot,
5757                    tiIORequest_t             *tiIORequest,
5758                    tiDeviceHandle_t          *tiDeviceHandle,
5759                    tiScsiInitiatorRequest_t *tiScsiRequest,
5760                    satIOContext_t            *satIOContext)
5761 {
5762   /*
5763     CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8
5764   */
5765   scsiRspSense_t            *pSense;
5766   tiIniScsiCmnd_t           *scsiCmnd;
5767   satDeviceData_t           *pSatDevData;
5768   bit32                     status;
5769 
5770   TI_DBG5(("satInquiry: start\n"));
5771   TI_DBG5(("satInquiry entry: tiDeviceHandle=%p tiIORequest=%p\n",
5772       tiDeviceHandle, tiIORequest));
5773   pSense      = satIOContext->pSense;
5774   scsiCmnd    = &tiScsiRequest->scsiCmnd;
5775   pSatDevData = satIOContext->pSatDevData;
5776   TI_DBG5(("satInquiry: pSatDevData=%p\n", pSatDevData));
5777   //tdhexdump("satInquiry", (bit8 *)scsiCmnd->cdb, 6);
5778   /* checking CONTROL */
5779   /* NACA == 1 or LINK == 1*/
5780   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5781   {
5782     satSetSensePayload( pSense,
5783                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5784                         0,
5785                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5786                         satIOContext);
5787     ostiInitiatorIOCompleted( tiRoot,
5788                               tiIORequest,
5789                               tiIOSuccess,
5790                               SCSI_STAT_CHECK_CONDITION,
5791                               satIOContext->pTiSenseData,
5792                               satIOContext->interruptContext );
5793     TI_DBG2(("satInquiry: return control\n"));
5794     return tiSuccess;
5795   }
5796 
5797   /* checking EVPD and Allocation Length */
5798   /* SPC-4 spec 6.4 p141 */
5799   /* EVPD bit == 0 && PAGE CODE != 0 */
5800   if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
5801        (scsiCmnd->cdb[2] != 0)
5802        )
5803   {
5804     satSetSensePayload( pSense,
5805                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5806                         0,
5807                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5808                         satIOContext);
5809     ostiInitiatorIOCompleted( tiRoot,
5810                               tiIORequest,
5811                               tiIOSuccess,
5812                               SCSI_STAT_CHECK_CONDITION,
5813                               satIOContext->pTiSenseData,
5814                               satIOContext->interruptContext );
5815     TI_DBG1(("satInquiry: return EVPD and PAGE CODE\n"));
5816     return tiSuccess;
5817   }
5818   TI_DBG6(("satInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4]));
5819 
5820   /* convert OS IO to TD internal IO */
5821   if ( pSatDevData->IDDeviceValid == agFALSE)
5822   {
5823     status = satStartIDDev(
5824                          tiRoot,
5825                          tiIORequest,
5826                          tiDeviceHandle,
5827                          tiScsiRequest,
5828                          satIOContext
5829                          );
5830     TI_DBG6(("satInquiry: end status %d\n", status));
5831     return status;
5832   }
5833   else
5834   {
5835     TI_DBG6(("satInquiry: calling satInquiryIntCB\n"));
5836     satInquiryIntCB(
5837                     tiRoot,
5838                     tiIORequest,
5839                     tiDeviceHandle,
5840                     tiScsiRequest,
5841                     satIOContext
5842                     );
5843 
5844     return tiSuccess;
5845   }
5846 
5847 }
5848 
5849 
5850 /*****************************************************************************/
5851 /*! \brief SAT implementation for SCSI satReadCapacity10.
5852  *
5853  *  SAT implementation for SCSI satReadCapacity10.
5854  *
5855  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5856  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5857  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5858  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5859  *  \param   satIOContext_t:   Pointer to the SAT IO Context
5860  *
5861  *  \return If command is started successfully
5862  *    - \e tiSuccess:     I/O request successfully initiated.
5863  *    - \e tiBusy:        No resources available, try again later.
5864  *    - \e tiIONoDevice:  Invalid device handle.
5865  *    - \e tiError:       Other errors.
5866  */
5867 /*****************************************************************************/
5868 GLOBAL bit32  satReadCapacity10(
5869                    tiRoot_t                  *tiRoot,
5870                    tiIORequest_t             *tiIORequest,
5871                    tiDeviceHandle_t          *tiDeviceHandle,
5872                    tiScsiInitiatorRequest_t *tiScsiRequest,
5873                    satIOContext_t            *satIOContext)
5874 {
5875   scsiRspSense_t          *pSense;
5876   tiIniScsiCmnd_t         *scsiCmnd;
5877   bit8              *pVirtAddr;
5878   satDeviceData_t         *pSatDevData;
5879   agsaSATAIdentifyData_t  *pSATAIdData;
5880   bit32                   lastLba;
5881   bit32                   word117_118;
5882   bit32                   word117;
5883   bit32                   word118;
5884   TI_DBG5(("satReadCapacity10: start: tiDeviceHandle=%p tiIORequest=%p\n",
5885       tiDeviceHandle, tiIORequest));
5886 
5887   pSense      = satIOContext->pSense;
5888   pVirtAddr   = (bit8 *) tiScsiRequest->sglVirtualAddr;
5889   scsiCmnd    = &tiScsiRequest->scsiCmnd;
5890   pSatDevData = satIOContext->pSatDevData;
5891   pSATAIdData = &pSatDevData->satIdentifyData;
5892 
5893 
5894   /* checking CONTROL */
5895   /* NACA == 1 or LINK == 1*/
5896   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
5897   {
5898     satSetSensePayload( pSense,
5899                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5900                         0,
5901                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5902                         satIOContext);
5903 
5904     ostiInitiatorIOCompleted( tiRoot,
5905                               tiIORequest,
5906                               tiIOSuccess,
5907                               SCSI_STAT_CHECK_CONDITION,
5908                               satIOContext->pTiSenseData,
5909                               satIOContext->interruptContext );
5910 
5911     TI_DBG1(("satReadCapacity10: return control\n"));
5912     return tiSuccess;
5913   }
5914 
5915 
5916   /*
5917    * If Logical block address is not set to zero, return error
5918    */
5919   if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
5920   {
5921     TI_DBG1(("satReadCapacity10 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
5922         tiDeviceHandle, tiIORequest));
5923 
5924     satSetSensePayload( pSense,
5925                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5926                         0,
5927                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5928                         satIOContext);
5929 
5930     ostiInitiatorIOCompleted( tiRoot,
5931                               tiIORequest,
5932                               tiIOSuccess,
5933                               SCSI_STAT_CHECK_CONDITION,
5934                               satIOContext->pTiSenseData,
5935                               satIOContext->interruptContext );
5936     return tiSuccess;
5937 
5938   }
5939 
5940   /*
5941    * If PMI bit is not zero, return error
5942    */
5943   if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
5944   {
5945     TI_DBG1(("satReadCapacity10 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
5946         tiDeviceHandle, tiIORequest));
5947 
5948     satSetSensePayload( pSense,
5949                         SCSI_SNSKEY_ILLEGAL_REQUEST,
5950                         0,
5951                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5952                         satIOContext);
5953 
5954     ostiInitiatorIOCompleted( tiRoot,
5955                               tiIORequest,
5956                               tiIOSuccess,
5957                               SCSI_STAT_CHECK_CONDITION,
5958                               satIOContext->pTiSenseData,
5959                               satIOContext->interruptContext );
5960     return tiSuccess;
5961 
5962   }
5963 
5964   /*
5965     filling in Read Capacity parameter data
5966     saved identify device has been already flipped
5967     See ATA spec p125 and p136 and SBC spec p54
5968   */
5969   /*
5970    * If 48-bit addressing is supported, set capacity information from Identify
5971    * Device Word 100-103.
5972    */
5973   if (pSatDevData->sat48BitSupport == agTRUE)
5974   {
5975     /*
5976      * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data:
5977      * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL
5978      * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL
5979      * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would
5980      * then issue a READ CAPACITY(16) command.
5981      */
5982     /* ATA Identify Device information word 100 - 103 */
5983     if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
5984     {
5985       pVirtAddr[0] = 0xFF;        /* MSB number of block */
5986       pVirtAddr[1] = 0xFF;
5987       pVirtAddr[2] = 0xFF;
5988       pVirtAddr[3] = 0xFF;        /* LSB number of block */
5989       TI_DBG1(("satReadCapacity10: returns 0xFFFFFFFF\n"));
5990     }
5991     else  /* Fit the Readcapacity10 4-bytes response length */
5992     {
5993       lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
5994                   (pSATAIdData->maxLBA0_15);
5995       lastLba = lastLba - 1;      /* LBA starts from zero */
5996 
5997       /*
5998         for testing
5999       lastLba = lastLba - (512*10) - 1;
6000       */
6001 
6002 
6003       pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
6004       pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6005       pVirtAddr[2] = (bit8)((lastLba >> 8)  & 0xFF);
6006       pVirtAddr[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
6007 
6008       TI_DBG3(("satReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
6009       TI_DBG3(("satReadCapacity10: LBA 0 is 0x%x %d\n", pVirtAddr[0], pVirtAddr[0]));
6010       TI_DBG3(("satReadCapacity10: LBA 1 is 0x%x %d\n", pVirtAddr[1], pVirtAddr[1]));
6011       TI_DBG3(("satReadCapacity10: LBA 2 is 0x%x %d\n", pVirtAddr[2], pVirtAddr[2]));
6012       TI_DBG3(("satReadCapacity10: LBA 3 is 0x%x %d\n", pVirtAddr[3], pVirtAddr[3]));
6013 
6014     }
6015   }
6016 
6017   /*
6018    * For 28-bit addressing, set capacity information from Identify
6019    * Device Word 60-61.
6020    */
6021   else
6022   {
6023     /* ATA Identify Device information word 60 - 61 */
6024     lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6025                 (pSATAIdData->numOfUserAddressableSectorsLo);
6026     lastLba = lastLba - 1;      /* LBA starts from zero */
6027 
6028     pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
6029     pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6030     pVirtAddr[2] = (bit8)((lastLba >> 8)  & 0xFF);
6031     pVirtAddr[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
6032   }
6033   /* SAT Rev 8d */
6034   if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
6035   {
6036     TI_DBG5(("satReadCapacity10: Default Block Length is 512\n"));
6037     /*
6038      * Set the block size, fixed at 512 bytes.
6039      */
6040     pVirtAddr[4] = 0x00;        /* MSB block size in bytes */
6041     pVirtAddr[5] = 0x00;
6042     pVirtAddr[6] = 0x02;
6043     pVirtAddr[7] = 0x00;        /* LSB block size in bytes */
6044   }
6045   else
6046   {
6047     word118 = pSATAIdData->word112_126[6];
6048     word117 = pSATAIdData->word112_126[5];
6049 
6050     word117_118 = (word118 << 16) + word117;
6051     word117_118 = word117_118 * 2;
6052     pVirtAddr[4] = (bit8)((word117_118 >> 24) & 0xFF);        /* MSB block size in bytes */
6053     pVirtAddr[5] = (bit8)((word117_118 >> 16) & 0xFF);
6054     pVirtAddr[6] = (bit8)((word117_118 >> 8) & 0xFF);
6055     pVirtAddr[7] = (bit8)(word117_118 & 0xFF);                /* LSB block size in bytes */
6056 
6057     TI_DBG1(("satReadCapacity10: Nondefault word118 %d 0x%x \n", word118, word118));
6058     TI_DBG1(("satReadCapacity10: Nondefault word117 %d 0x%x \n", word117, word117));
6059     TI_DBG1(("satReadCapacity10: Nondefault Block Length is %d 0x%x \n",word117_118, word117_118));
6060 
6061   }
6062 
6063   /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6064   pSatDevData->satMaxLBA[0] = 0;            /* MSB */
6065   pSatDevData->satMaxLBA[1] = 0;
6066   pSatDevData->satMaxLBA[2] = 0;
6067   pSatDevData->satMaxLBA[3] = 0;
6068   pSatDevData->satMaxLBA[4] = pVirtAddr[0];
6069   pSatDevData->satMaxLBA[5] = pVirtAddr[1];
6070   pSatDevData->satMaxLBA[6] = pVirtAddr[2];
6071   pSatDevData->satMaxLBA[7] = pVirtAddr[3]; /* LSB */
6072 
6073 
6074   TI_DBG4(("satReadCapacity10 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
6075         pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6076         pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6077         tiDeviceHandle, tiIORequest));
6078 
6079 
6080   /*
6081    * Send the completion response now.
6082    */
6083   ostiInitiatorIOCompleted( tiRoot,
6084                             tiIORequest,
6085                             tiIOSuccess,
6086                             SCSI_STAT_GOOD,
6087                             agNULL,
6088                             satIOContext->interruptContext);
6089   return tiSuccess;
6090 }
6091 
6092 
6093 /*****************************************************************************/
6094 /*! \brief SAT implementation for SCSI satReadCapacity16.
6095  *
6096  *  SAT implementation for SCSI satReadCapacity16.
6097  *
6098  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
6099  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
6100  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
6101  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
6102  *  \param   satIOContext_t:   Pointer to the SAT IO Context
6103  *
6104  *  \return If command is started successfully
6105  *    - \e tiSuccess:     I/O request successfully initiated.
6106  *    - \e tiBusy:        No resources available, try again later.
6107  *    - \e tiIONoDevice:  Invalid device handle.
6108  *    - \e tiError:       Other errors.
6109  */
6110 /*****************************************************************************/
6111 GLOBAL bit32  satReadCapacity16(
6112                    tiRoot_t                  *tiRoot,
6113                    tiIORequest_t             *tiIORequest,
6114                    tiDeviceHandle_t          *tiDeviceHandle,
6115                    tiScsiInitiatorRequest_t *tiScsiRequest,
6116                    satIOContext_t            *satIOContext)
6117 {
6118 
6119   scsiRspSense_t          *pSense;
6120   tiIniScsiCmnd_t         *scsiCmnd;
6121   bit8                    *pVirtAddr;
6122   satDeviceData_t         *pSatDevData;
6123   agsaSATAIdentifyData_t  *pSATAIdData;
6124   bit32                   lastLbaLo;
6125   bit32                   allocationLen;
6126   bit32                   readCapacityLen  = 32;
6127   bit32                   i = 0;
6128   TI_DBG5(("satReadCapacity16 start: tiDeviceHandle=%p tiIORequest=%p\n",
6129       tiDeviceHandle, tiIORequest));
6130 
6131   pSense      = satIOContext->pSense;
6132   pVirtAddr   = (bit8 *) tiScsiRequest->sglVirtualAddr;
6133   scsiCmnd    = &tiScsiRequest->scsiCmnd;
6134   pSatDevData = satIOContext->pSatDevData;
6135   pSATAIdData = &pSatDevData->satIdentifyData;
6136 
6137   /* Find the buffer size allocated by Initiator */
6138   allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
6139                   (((bit32)scsiCmnd->cdb[11]) << 16) |
6140                   (((bit32)scsiCmnd->cdb[12]) << 8 ) |
6141                   (((bit32)scsiCmnd->cdb[13])      );
6142 
6143 
6144   if (allocationLen < readCapacityLen)
6145   {
6146     TI_DBG1(("satReadCapacity16 *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x\n", allocationLen, readCapacityLen));
6147 
6148     satSetSensePayload( pSense,
6149                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6150                         0,
6151                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6152                         satIOContext);
6153 
6154     ostiInitiatorIOCompleted( tiRoot,
6155                               tiIORequest,
6156                               tiIOSuccess,
6157                               SCSI_STAT_CHECK_CONDITION,
6158                               satIOContext->pTiSenseData,
6159                               satIOContext->interruptContext );
6160     return tiSuccess;
6161 
6162   }
6163 
6164   /* checking CONTROL */
6165   /* NACA == 1 or LINK == 1*/
6166   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
6167   {
6168     satSetSensePayload( pSense,
6169                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6170                         0,
6171                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6172                         satIOContext);
6173 
6174     ostiInitiatorIOCompleted( tiRoot,
6175                               tiIORequest,
6176                               tiIOSuccess,
6177                               SCSI_STAT_CHECK_CONDITION,
6178                               satIOContext->pTiSenseData,
6179                               satIOContext->interruptContext );
6180 
6181     TI_DBG1(("satReadCapacity16: return control\n"));
6182     return tiSuccess;
6183   }
6184 
6185   /*
6186    * If Logical blcok address is not set to zero, return error
6187    */
6188   if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) ||
6189       (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9])  )
6190   {
6191     TI_DBG1(("satReadCapacity16 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
6192         tiDeviceHandle, tiIORequest));
6193 
6194     satSetSensePayload( pSense,
6195                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6196                         0,
6197                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6198                         satIOContext);
6199 
6200     ostiInitiatorIOCompleted( tiRoot,
6201                               tiIORequest,
6202                               tiIOSuccess,
6203                               SCSI_STAT_CHECK_CONDITION,
6204                               satIOContext->pTiSenseData,
6205                               satIOContext->interruptContext );
6206     return tiSuccess;
6207 
6208   }
6209 
6210   /*
6211    * If PMI bit is not zero, return error
6212    */
6213   if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
6214   {
6215     TI_DBG1(("satReadCapacity16 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
6216         tiDeviceHandle, tiIORequest));
6217 
6218     satSetSensePayload( pSense,
6219                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6220                         0,
6221                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6222                         satIOContext);
6223 
6224     ostiInitiatorIOCompleted( tiRoot,
6225                               tiIORequest,
6226                               tiIOSuccess,
6227                               SCSI_STAT_CHECK_CONDITION,
6228                               satIOContext->pTiSenseData,
6229                               satIOContext->interruptContext );
6230     return tiSuccess;
6231 
6232   }
6233 
6234   /*
6235     filling in Read Capacity parameter data
6236   */
6237 
6238   /*
6239    * If 48-bit addressing is supported, set capacity information from Identify
6240    * Device Word 100-103.
6241    */
6242   if (pSatDevData->sat48BitSupport == agTRUE)
6243   {
6244     pVirtAddr[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff);  /* MSB */
6245     pVirtAddr[1] = (bit8)((pSATAIdData->maxLBA48_63)        & 0xff);
6246     pVirtAddr[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
6247     pVirtAddr[3] = (bit8)((pSATAIdData->maxLBA32_47)        & 0xff);
6248 
6249     lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
6250     lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
6251 
6252     pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6253     pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6254     pVirtAddr[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
6255     pVirtAddr[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
6256 
6257   }
6258 
6259   /*
6260    * For 28-bit addressing, set capacity information from Identify
6261    * Device Word 60-61.
6262    */
6263   else
6264   {
6265     pVirtAddr[0] = 0;       /* MSB */
6266     pVirtAddr[1] = 0;
6267     pVirtAddr[2] = 0;
6268     pVirtAddr[3] = 0;
6269 
6270     lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6271                   (pSATAIdData->numOfUserAddressableSectorsLo);
6272     lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
6273 
6274     pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6275     pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6276     pVirtAddr[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
6277     pVirtAddr[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
6278 
6279   }
6280 
6281   /*
6282    * Set the block size, fixed at 512 bytes.
6283    */
6284   pVirtAddr[8]  = 0x00;        /* MSB block size in bytes */
6285   pVirtAddr[9]  = 0x00;
6286   pVirtAddr[10] = 0x02;
6287   pVirtAddr[11] = 0x00;        /* LSB block size in bytes */
6288 
6289 
6290   /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6291   pSatDevData->satMaxLBA[0] = pVirtAddr[0];            /* MSB */
6292   pSatDevData->satMaxLBA[1] = pVirtAddr[1];
6293   pSatDevData->satMaxLBA[2] = pVirtAddr[2];
6294   pSatDevData->satMaxLBA[3] = pVirtAddr[3];
6295   pSatDevData->satMaxLBA[4] = pVirtAddr[4];
6296   pSatDevData->satMaxLBA[5] = pVirtAddr[5];
6297   pSatDevData->satMaxLBA[6] = pVirtAddr[6];
6298   pSatDevData->satMaxLBA[7] = pVirtAddr[7];             /* LSB */
6299 
6300   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",
6301         pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6302         pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6303         pVirtAddr[8], pVirtAddr[9], pVirtAddr[10], pVirtAddr[11],
6304         tiDeviceHandle, tiIORequest));
6305 
6306   for(i=12;i<=31;i++)
6307   {
6308     pVirtAddr[i] = 0x00;
6309   }
6310 
6311   /*
6312    * Send the completion response now.
6313    */
6314   if (allocationLen > readCapacityLen)
6315   {
6316     /* underrun */
6317     TI_DBG1(("satReadCapacity16 reporting underrun readCapacityLen=0x%x allocationLen=0x%x \n", readCapacityLen, allocationLen));
6318 
6319     ostiInitiatorIOCompleted( tiRoot,
6320                               tiIORequest,
6321                               tiIOUnderRun,
6322                               allocationLen - readCapacityLen,
6323                               agNULL,
6324                               satIOContext->interruptContext );
6325 
6326 
6327   }
6328   else
6329   {
6330     ostiInitiatorIOCompleted( tiRoot,
6331                               tiIORequest,
6332                               tiIOSuccess,
6333                               SCSI_STAT_GOOD,
6334                               agNULL,
6335                               satIOContext->interruptContext);
6336   }
6337   return tiSuccess;
6338 
6339 }
6340 
6341 
6342 /*****************************************************************************/
6343 /*! \brief SAT implementation for SCSI MODE SENSE (6).
6344  *
6345  *  SAT implementation for SCSI MODE SENSE (6).
6346  *
6347  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
6348  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
6349  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
6350  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
6351  *  \param   satIOContext_t:   Pointer to the SAT IO Context
6352  *
6353  *  \return If command is started successfully
6354  *    - \e tiSuccess:     I/O request successfully initiated.
6355  *    - \e tiBusy:        No resources available, try again later.
6356  *    - \e tiIONoDevice:  Invalid device handle.
6357  *    - \e tiError:       Other errors.
6358  */
6359 /*****************************************************************************/
6360 GLOBAL bit32  satModeSense6(
6361                    tiRoot_t                  *tiRoot,
6362                    tiIORequest_t             *tiIORequest,
6363                    tiDeviceHandle_t          *tiDeviceHandle,
6364                    tiScsiInitiatorRequest_t *tiScsiRequest,
6365                    satIOContext_t            *satIOContext)
6366 {
6367 
6368   scsiRspSense_t          *pSense;
6369   bit32                   requestLen;
6370   tiIniScsiCmnd_t         *scsiCmnd;
6371   bit32                   pageSupported;
6372   bit8                    page;
6373   bit8                    *pModeSense;    /* Mode Sense data buffer */
6374   satDeviceData_t         *pSatDevData;
6375   bit8                    PC;
6376   bit8                    AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN];
6377   bit8                    Control[MODE_SENSE6_CONTROL_PAGE_LEN];
6378   bit8                    RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN];
6379   bit8                    Caching[MODE_SENSE6_CACHING_LEN];
6380   bit8                    InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN];
6381   bit8                    lenRead = 0;
6382 
6383 
6384   TI_DBG5(("satModeSense6 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6385       tiDeviceHandle, tiIORequest));
6386 
6387   pSense      = satIOContext->pSense;
6388   scsiCmnd    = &tiScsiRequest->scsiCmnd;
6389   pModeSense  = (bit8 *) tiScsiRequest->sglVirtualAddr;
6390   pSatDevData = satIOContext->pSatDevData;
6391 
6392   //tdhexdump("satModeSense6", (bit8 *)scsiCmnd->cdb, 6);
6393   /* checking CONTROL */
6394   /* NACA == 1 or LINK == 1*/
6395   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
6396   {
6397     satSetSensePayload( pSense,
6398                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6399                         0,
6400                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6401                         satIOContext);
6402 
6403     ostiInitiatorIOCompleted( tiRoot,
6404                               tiIORequest,
6405                               tiIOSuccess,
6406                               SCSI_STAT_CHECK_CONDITION,
6407                               satIOContext->pTiSenseData,
6408                               satIOContext->interruptContext );
6409 
6410     TI_DBG2(("satModeSense6: return control\n"));
6411     return tiSuccess;
6412   }
6413 
6414   /* checking PC(Page Control)
6415      SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6416   */
6417   PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
6418   if (PC != 0)
6419   {
6420     satSetSensePayload( pSense,
6421                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6422                         0,
6423                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6424                         satIOContext);
6425 
6426     ostiInitiatorIOCompleted( tiRoot,
6427                               tiIORequest,
6428                               tiIOSuccess,
6429                               SCSI_STAT_CHECK_CONDITION,
6430                               satIOContext->pTiSenseData,
6431                               satIOContext->interruptContext );
6432 
6433     TI_DBG1(("satModeSense6: return due to PC value pc 0x%x\n", PC >> 6));
6434     return tiSuccess;
6435   }
6436 
6437   /* reading PAGE CODE */
6438   page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
6439 
6440 
6441   TI_DBG5(("satModeSense6: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
6442              page, tiDeviceHandle, tiIORequest));
6443 
6444   requestLen = scsiCmnd->cdb[4];
6445 
6446     /*
6447     Based on page code value, returns a corresponding mode page
6448     note: no support for subpage
6449   */
6450 
6451   switch(page)
6452   {
6453     case MODESENSE_RETURN_ALL_PAGES:
6454     case MODESENSE_CONTROL_PAGE: /* control */
6455     case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6456     case MODESENSE_CACHING: /* caching */
6457     case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6458       pageSupported = agTRUE;
6459       break;
6460     case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
6461     default:
6462       pageSupported = agFALSE;
6463       break;
6464   }
6465 
6466   if (pageSupported == agFALSE)
6467   {
6468 
6469     TI_DBG1(("satModeSense6 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
6470         page, tiDeviceHandle, tiIORequest));
6471 
6472     satSetSensePayload( pSense,
6473                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6474                         0,
6475                         SCSI_SNSCODE_INVALID_COMMAND,
6476                         satIOContext);
6477 
6478     ostiInitiatorIOCompleted( tiRoot,
6479                               tiIORequest,
6480                               tiIOSuccess,
6481                               SCSI_STAT_CHECK_CONDITION,
6482                               satIOContext->pTiSenseData,
6483                               satIOContext->interruptContext );
6484     return tiSuccess;
6485   }
6486 
6487   switch(page)
6488   {
6489   case MODESENSE_RETURN_ALL_PAGES:
6490     lenRead = (bit8)MIN(requestLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
6491     break;
6492   case MODESENSE_CONTROL_PAGE: /* control */
6493     lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CONTROL_PAGE_LEN);
6494     break;
6495   case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6496     lenRead = (bit8)MIN(requestLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
6497     break;
6498   case MODESENSE_CACHING: /* caching */
6499     lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CACHING_LEN);
6500     break;
6501   case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6502     lenRead = (bit8)MIN(requestLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
6503     break;
6504   default:
6505     TI_DBG1(("satModeSense6: default error page %d\n", page));
6506     break;
6507   }
6508 
6509   if (page == MODESENSE_RETURN_ALL_PAGES)
6510   {
6511     TI_DBG5(("satModeSense6: MODESENSE_RETURN_ALL_PAGES\n"));
6512     AllPages[0] = (bit8)(lenRead - 1);
6513     AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */
6514     AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6515     AllPages[3] = 0x08; /* block descriptor length */
6516 
6517     /*
6518      * Fill-up direct-access device block-descriptor, SAT, Table 19
6519      */
6520 
6521     /* density code */
6522     AllPages[4]  = 0x04; /* density-code : reserved for direct-access */
6523     /* number of blocks */
6524     AllPages[5]  = 0x00; /* unspecified */
6525     AllPages[6]  = 0x00; /* unspecified */
6526     AllPages[7]  = 0x00; /* unspecified */
6527     /* reserved */
6528     AllPages[8]  = 0x00; /* reserved */
6529     /* Block size */
6530     AllPages[9]  = 0x00;
6531     AllPages[10] = 0x02;   /* Block size is always 512 bytes */
6532     AllPages[11] = 0x00;
6533 
6534     /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
6535     AllPages[12] = 0x01; /* page code */
6536     AllPages[13] = 0x0A; /* page length */
6537     AllPages[14] = 0x40; /* ARRE is set */
6538     AllPages[15] = 0x00;
6539     AllPages[16] = 0x00;
6540     AllPages[17] = 0x00;
6541     AllPages[18] = 0x00;
6542     AllPages[19] = 0x00;
6543     AllPages[20] = 0x00;
6544     AllPages[21] = 0x00;
6545     AllPages[22] = 0x00;
6546     AllPages[23] = 0x00;
6547     /* MODESENSE_CACHING */
6548     AllPages[24] = 0x08; /* page code */
6549     AllPages[25] = 0x12; /* page length */
6550 #ifdef NOT_YET
6551     if (pSatDevData->satWriteCacheEnabled == agTRUE)
6552     {
6553       AllPages[26] = 0x04;/* WCE bit is set */
6554     }
6555     else
6556     {
6557       AllPages[26] = 0x00;/* WCE bit is NOT set */
6558     }
6559 #endif
6560     AllPages[26] = 0x00;/* WCE bit is NOT set */
6561 
6562     AllPages[27] = 0x00;
6563     AllPages[28] = 0x00;
6564     AllPages[29] = 0x00;
6565     AllPages[30] = 0x00;
6566     AllPages[31] = 0x00;
6567     AllPages[32] = 0x00;
6568     AllPages[33] = 0x00;
6569     AllPages[34] = 0x00;
6570     AllPages[35] = 0x00;
6571     if (pSatDevData->satLookAheadEnabled == agTRUE)
6572     {
6573       AllPages[36] = 0x00;/* DRA bit is NOT set */
6574     }
6575     else
6576     {
6577       AllPages[36] = 0x20;/* DRA bit is set */
6578     }
6579     AllPages[37] = 0x00;
6580     AllPages[38] = 0x00;
6581     AllPages[39] = 0x00;
6582     AllPages[40] = 0x00;
6583     AllPages[41] = 0x00;
6584     AllPages[42] = 0x00;
6585     AllPages[43] = 0x00;
6586     /* MODESENSE_CONTROL_PAGE */
6587     AllPages[44] = 0x0A; /* page code */
6588     AllPages[45] = 0x0A; /* page length */
6589     AllPages[46] = 0x02; /* only GLTSD bit is set */
6590     if (pSatDevData->satNCQ == agTRUE)
6591     {
6592       AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6593     }
6594     else
6595     {
6596       AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6597     }
6598     AllPages[48] = 0x00;
6599     AllPages[49] = 0x00;
6600     AllPages[50] = 0x00; /* obsolete */
6601     AllPages[51] = 0x00; /* obsolete */
6602     AllPages[52] = 0xFF; /* Busy Timeout Period */
6603     AllPages[53] = 0xFF; /* Busy Timeout Period */
6604     AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */
6605     AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */
6606     /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
6607     AllPages[56] = 0x1C; /* page code */
6608     AllPages[57] = 0x0A; /* page length */
6609     if (pSatDevData->satSMARTEnabled == agTRUE)
6610     {
6611       AllPages[58] = 0x00;/* DEXCPT bit is NOT set */
6612     }
6613     else
6614     {
6615       AllPages[58] = 0x08;/* DEXCPT bit is set */
6616     }
6617     AllPages[59] = 0x00; /* We don't support MRIE */
6618     AllPages[60] = 0x00; /* Interval timer vendor-specific */
6619     AllPages[61] = 0x00;
6620     AllPages[62] = 0x00;
6621     AllPages[63] = 0x00;
6622     AllPages[64] = 0x00; /* REPORT-COUNT */
6623     AllPages[65] = 0x00;
6624     AllPages[66] = 0x00;
6625     AllPages[67] = 0x00;
6626 
6627     osti_memcpy(pModeSense, &AllPages, lenRead);
6628   }
6629   else if (page == MODESENSE_CONTROL_PAGE)
6630   {
6631     TI_DBG5(("satModeSense6: MODESENSE_CONTROL_PAGE\n"));
6632     Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1;
6633     Control[1] = 0x00; /* default medium type (currently mounted medium type) */
6634     Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6635     Control[3] = 0x08; /* block descriptor length */
6636     /*
6637      * Fill-up direct-access device block-descriptor, SAT, Table 19
6638      */
6639 
6640     /* density code */
6641     Control[4]  = 0x04; /* density-code : reserved for direct-access */
6642     /* number of blocks */
6643     Control[5]  = 0x00; /* unspecified */
6644     Control[6]  = 0x00; /* unspecified */
6645     Control[7]  = 0x00; /* unspecified */
6646     /* reserved */
6647     Control[8]  = 0x00; /* reserved */
6648     /* Block size */
6649     Control[9]  = 0x00;
6650     Control[10] = 0x02;   /* Block size is always 512 bytes */
6651     Control[11] = 0x00;
6652     /*
6653      * Fill-up control mode page, SAT, Table 65
6654      */
6655     Control[12] = 0x0A; /* page code */
6656     Control[13] = 0x0A; /* page length */
6657     Control[14] = 0x02; /* only GLTSD bit is set */
6658     if (pSatDevData->satNCQ == agTRUE)
6659     {
6660       Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6661     }
6662     else
6663     {
6664       Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6665     }
6666     Control[16] = 0x00;
6667     Control[17] = 0x00;
6668     Control[18] = 0x00; /* obsolete */
6669     Control[19] = 0x00; /* obsolete */
6670     Control[20] = 0xFF; /* Busy Timeout Period */
6671     Control[21] = 0xFF; /* Busy Timeout Period */
6672     Control[22] = 0x00; /* we don't support non-000b value for the self-test code */
6673     Control[23] = 0x00; /* we don't support non-000b value for the self-test code */
6674 
6675     osti_memcpy(pModeSense, &Control, lenRead);
6676 
6677   }
6678   else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
6679   {
6680     TI_DBG5(("satModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
6681     RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1;
6682     RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */
6683     RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6684     RWErrorRecovery[3] = 0x08; /* block descriptor length */
6685     /*
6686      * Fill-up direct-access device block-descriptor, SAT, Table 19
6687      */
6688 
6689     /* density code */
6690     RWErrorRecovery[4]  = 0x04; /* density-code : reserved for direct-access */
6691     /* number of blocks */
6692     RWErrorRecovery[5]  = 0x00; /* unspecified */
6693     RWErrorRecovery[6]  = 0x00; /* unspecified */
6694     RWErrorRecovery[7]  = 0x00; /* unspecified */
6695     /* reserved */
6696     RWErrorRecovery[8]  = 0x00; /* reserved */
6697     /* Block size */
6698     RWErrorRecovery[9]  = 0x00;
6699     RWErrorRecovery[10] = 0x02;   /* Block size is always 512 bytes */
6700     RWErrorRecovery[11] = 0x00;
6701     /*
6702      * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
6703      */
6704     RWErrorRecovery[12] = 0x01; /* page code */
6705     RWErrorRecovery[13] = 0x0A; /* page length */
6706     RWErrorRecovery[14] = 0x40; /* ARRE is set */
6707     RWErrorRecovery[15] = 0x00;
6708     RWErrorRecovery[16] = 0x00;
6709     RWErrorRecovery[17] = 0x00;
6710     RWErrorRecovery[18] = 0x00;
6711     RWErrorRecovery[19] = 0x00;
6712     RWErrorRecovery[20] = 0x00;
6713     RWErrorRecovery[21] = 0x00;
6714     RWErrorRecovery[22] = 0x00;
6715     RWErrorRecovery[23] = 0x00;
6716 
6717     osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
6718 
6719   }
6720   else if (page == MODESENSE_CACHING)
6721   {
6722     TI_DBG5(("satModeSense6: MODESENSE_CACHING\n"));
6723     /* special case */
6724     if (requestLen == 4 && page == MODESENSE_CACHING)
6725     {
6726       TI_DBG5(("satModeSense6: linux 2.6.8.24 support\n"));
6727 
6728       pModeSense[0] = 0x20 - 1; /* 32 - 1 */
6729       pModeSense[1] = 0x00; /* default medium type (currently mounted medium type) */
6730       pModeSense[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6731       pModeSense[3] = 0x08; /* block descriptor length */
6732       ostiInitiatorIOCompleted( tiRoot,
6733                                 tiIORequest,
6734                                 tiIOSuccess,
6735                                 SCSI_STAT_GOOD,
6736                                 agNULL,
6737                                 satIOContext->interruptContext);
6738       return tiSuccess;
6739     }
6740     Caching[0] = MODE_SENSE6_CACHING_LEN - 1;
6741     Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
6742     Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6743     Caching[3] = 0x08; /* block descriptor length */
6744     /*
6745      * Fill-up direct-access device block-descriptor, SAT, Table 19
6746      */
6747 
6748     /* density code */
6749     Caching[4]  = 0x04; /* density-code : reserved for direct-access */
6750     /* number of blocks */
6751     Caching[5]  = 0x00; /* unspecified */
6752     Caching[6]  = 0x00; /* unspecified */
6753     Caching[7]  = 0x00; /* unspecified */
6754     /* reserved */
6755     Caching[8]  = 0x00; /* reserved */
6756     /* Block size */
6757     Caching[9]  = 0x00;
6758     Caching[10] = 0x02;   /* Block size is always 512 bytes */
6759     Caching[11] = 0x00;
6760     /*
6761      * Fill-up Caching mode page, SAT, Table 67
6762      */
6763     /* length 20 */
6764     Caching[12] = 0x08; /* page code */
6765     Caching[13] = 0x12; /* page length */
6766 #ifdef NOT_YET
6767     if (pSatDevData->satWriteCacheEnabled == agTRUE)
6768     {
6769       Caching[14] = 0x04;/* WCE bit is set */
6770     }
6771     else
6772     {
6773       Caching[14] = 0x00;/* WCE bit is NOT set */
6774     }
6775 #endif
6776     Caching[14] = 0x00;/* WCE bit is NOT set */
6777 
6778     Caching[15] = 0x00;
6779     Caching[16] = 0x00;
6780     Caching[17] = 0x00;
6781     Caching[18] = 0x00;
6782     Caching[19] = 0x00;
6783     Caching[20] = 0x00;
6784     Caching[21] = 0x00;
6785     Caching[22] = 0x00;
6786     Caching[23] = 0x00;
6787     if (pSatDevData->satLookAheadEnabled == agTRUE)
6788     {
6789       Caching[24] = 0x00;/* DRA bit is NOT set */
6790     }
6791     else
6792     {
6793       Caching[24] = 0x20;/* DRA bit is set */
6794     }
6795     Caching[25] = 0x00;
6796     Caching[26] = 0x00;
6797     Caching[27] = 0x00;
6798     Caching[28] = 0x00;
6799     Caching[29] = 0x00;
6800     Caching[30] = 0x00;
6801     Caching[31] = 0x00;
6802 
6803     osti_memcpy(pModeSense, &Caching, lenRead);
6804 
6805   }
6806   else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
6807   {
6808     TI_DBG5(("satModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
6809     InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1;
6810     InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */
6811     InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6812     InfoExceptionCtrl[3] = 0x08; /* block descriptor length */
6813     /*
6814      * Fill-up direct-access device block-descriptor, SAT, Table 19
6815      */
6816 
6817     /* density code */
6818     InfoExceptionCtrl[4]  = 0x04; /* density-code : reserved for direct-access */
6819     /* number of blocks */
6820     InfoExceptionCtrl[5]  = 0x00; /* unspecified */
6821     InfoExceptionCtrl[6]  = 0x00; /* unspecified */
6822     InfoExceptionCtrl[7]  = 0x00; /* unspecified */
6823     /* reserved */
6824     InfoExceptionCtrl[8]  = 0x00; /* reserved */
6825     /* Block size */
6826     InfoExceptionCtrl[9]  = 0x00;
6827     InfoExceptionCtrl[10] = 0x02;   /* Block size is always 512 bytes */
6828     InfoExceptionCtrl[11] = 0x00;
6829     /*
6830      * Fill-up informational-exceptions control mode page, SAT, Table 68
6831      */
6832     InfoExceptionCtrl[12] = 0x1C; /* page code */
6833     InfoExceptionCtrl[13] = 0x0A; /* page length */
6834      if (pSatDevData->satSMARTEnabled == agTRUE)
6835     {
6836       InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */
6837     }
6838     else
6839     {
6840       InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */
6841     }
6842     InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */
6843     InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */
6844     InfoExceptionCtrl[17] = 0x00;
6845     InfoExceptionCtrl[18] = 0x00;
6846     InfoExceptionCtrl[19] = 0x00;
6847     InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */
6848     InfoExceptionCtrl[21] = 0x00;
6849     InfoExceptionCtrl[22] = 0x00;
6850     InfoExceptionCtrl[23] = 0x00;
6851     osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
6852 
6853   }
6854   else
6855   {
6856     /* Error */
6857     TI_DBG1(("satModeSense6: Error page %d\n", page));
6858     satSetSensePayload( pSense,
6859                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6860                         0,
6861                         SCSI_SNSCODE_INVALID_COMMAND,
6862                         satIOContext);
6863 
6864     ostiInitiatorIOCompleted( tiRoot,
6865                               tiIORequest,
6866                               tiIOSuccess,
6867                               SCSI_STAT_CHECK_CONDITION,
6868                               satIOContext->pTiSenseData,
6869                               satIOContext->interruptContext );
6870     return tiSuccess;
6871   }
6872 
6873   /* there can be only underrun not overrun in error case */
6874   if (requestLen > lenRead)
6875   {
6876     TI_DBG6(("satModeSense6 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
6877 
6878     ostiInitiatorIOCompleted( tiRoot,
6879                               tiIORequest,
6880                               tiIOUnderRun,
6881                               requestLen - lenRead,
6882                               agNULL,
6883                               satIOContext->interruptContext );
6884 
6885 
6886   }
6887   else
6888   {
6889     ostiInitiatorIOCompleted( tiRoot,
6890                               tiIORequest,
6891                               tiIOSuccess,
6892                               SCSI_STAT_GOOD,
6893                               agNULL,
6894                               satIOContext->interruptContext);
6895   }
6896 
6897   return tiSuccess;
6898 
6899 }
6900 
6901 /*****************************************************************************/
6902 /*! \brief SAT implementation for SCSI MODE SENSE (10).
6903  *
6904  *  SAT implementation for SCSI MODE SENSE (10).
6905  *
6906  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
6907  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
6908  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
6909  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
6910  *  \param   satIOContext_t:   Pointer to the SAT IO Context
6911  *
6912  *  \return If command is started successfully
6913  *    - \e tiSuccess:     I/O request successfully initiated.
6914  *    - \e tiBusy:        No resources available, try again later.
6915  *    - \e tiIONoDevice:  Invalid device handle.
6916  *    - \e tiError:       Other errors.
6917  */
6918 /*****************************************************************************/
6919 GLOBAL bit32  satModeSense10(
6920                    tiRoot_t                  *tiRoot,
6921                    tiIORequest_t             *tiIORequest,
6922                    tiDeviceHandle_t          *tiDeviceHandle,
6923                    tiScsiInitiatorRequest_t *tiScsiRequest,
6924                    satIOContext_t            *satIOContext)
6925 {
6926 
6927   scsiRspSense_t          *pSense;
6928   bit32                   requestLen;
6929   tiIniScsiCmnd_t         *scsiCmnd;
6930   bit32                   pageSupported;
6931   bit8                    page;
6932   bit8                    *pModeSense;    /* Mode Sense data buffer */
6933   satDeviceData_t         *pSatDevData;
6934   bit8                    PC; /* page control */
6935   bit8                    LLBAA; /* Long LBA Accepted */
6936   bit32                   index;
6937   bit8                    AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN];
6938   bit8                    Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN];
6939   bit8                    RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN];
6940   bit8                    Caching[MODE_SENSE10_CACHING_LLBAA_LEN];
6941   bit8                    InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN];
6942   bit8                    lenRead = 0;
6943 
6944   TI_DBG5(("satModeSense10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6945       tiDeviceHandle, tiIORequest));
6946 
6947   pSense      = satIOContext->pSense;
6948   scsiCmnd    = &tiScsiRequest->scsiCmnd;
6949   pModeSense  = (bit8 *) tiScsiRequest->sglVirtualAddr;
6950   pSatDevData = satIOContext->pSatDevData;
6951 
6952   /* checking CONTROL */
6953   /* NACA == 1 or LINK == 1*/
6954   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
6955   {
6956     satSetSensePayload( pSense,
6957                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6958                         0,
6959                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6960                         satIOContext);
6961 
6962     ostiInitiatorIOCompleted( tiRoot,
6963                               tiIORequest,
6964                               tiIOSuccess,
6965                               SCSI_STAT_CHECK_CONDITION,
6966                               satIOContext->pTiSenseData,
6967                               satIOContext->interruptContext );
6968 
6969     TI_DBG2(("satModeSense10: return control\n"));
6970     return tiSuccess;
6971   }
6972 
6973   /* checking PC(Page Control)
6974      SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6975   */
6976   PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
6977   if (PC != 0)
6978   {
6979     satSetSensePayload( pSense,
6980                         SCSI_SNSKEY_ILLEGAL_REQUEST,
6981                         0,
6982                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6983                         satIOContext);
6984 
6985     ostiInitiatorIOCompleted( tiRoot,
6986                               tiIORequest,
6987                               tiIOSuccess,
6988                               SCSI_STAT_CHECK_CONDITION,
6989                               satIOContext->pTiSenseData,
6990                               satIOContext->interruptContext );
6991 
6992     TI_DBG1(("satModeSense10: return due to PC value pc 0x%x\n", PC));
6993     return tiSuccess;
6994   }
6995   /* finding LLBAA bit */
6996   LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
6997   /* reading PAGE CODE */
6998   page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
6999 
7000   TI_DBG5(("satModeSense10: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
7001              page, tiDeviceHandle, tiIORequest));
7002   requestLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7003 
7004   /*
7005     Based on page code value, returns a corresponding mode page
7006     note: no support for subpage
7007   */
7008   switch(page)
7009   {
7010     case MODESENSE_RETURN_ALL_PAGES: /* return all pages */
7011     case MODESENSE_CONTROL_PAGE: /* control */
7012     case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7013     case MODESENSE_CACHING: /* caching */
7014     case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7015       pageSupported = agTRUE;
7016       break;
7017     case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
7018     default:
7019       pageSupported = agFALSE;
7020       break;
7021   }
7022 
7023   if (pageSupported == agFALSE)
7024   {
7025 
7026     TI_DBG1(("satModeSense10 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
7027         page, tiDeviceHandle, tiIORequest));
7028 
7029     satSetSensePayload( pSense,
7030                         SCSI_SNSKEY_ILLEGAL_REQUEST,
7031                         0,
7032                         SCSI_SNSCODE_INVALID_COMMAND,
7033                         satIOContext);
7034 
7035     ostiInitiatorIOCompleted( tiRoot,
7036                               tiIORequest,
7037                               tiIOSuccess,
7038                               SCSI_STAT_CHECK_CONDITION,
7039                               satIOContext->pTiSenseData,
7040                               satIOContext->interruptContext );
7041     return tiSuccess;
7042   }
7043 
7044   switch(page)
7045   {
7046   case MODESENSE_RETURN_ALL_PAGES:
7047     if (LLBAA)
7048     {
7049       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
7050     }
7051     else
7052     {
7053       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
7054     }
7055     break;
7056   case MODESENSE_CONTROL_PAGE: /* control */
7057     if (LLBAA)
7058     {
7059       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
7060     }
7061     else
7062     {
7063       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LEN);
7064     }
7065     break;
7066   case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7067     if (LLBAA)
7068     {
7069       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
7070     }
7071     else
7072     {
7073       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
7074     }
7075     break;
7076   case MODESENSE_CACHING: /* caching */
7077     if (LLBAA)
7078     {
7079       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LLBAA_LEN);
7080     }
7081     else
7082     {
7083       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LEN);
7084     }
7085     break;
7086   case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7087     if (LLBAA)
7088     {
7089       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
7090     }
7091     else
7092     {
7093       lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
7094     }
7095     break;
7096   default:
7097     TI_DBG1(("satModeSense10: default error page %d\n", page));
7098     break;
7099   }
7100 
7101   if (page == MODESENSE_RETURN_ALL_PAGES)
7102   {
7103     TI_DBG5(("satModeSense10: MODESENSE_RETURN_ALL_PAGES\n"));
7104     AllPages[0] = 0;
7105     AllPages[1] = (bit8)(lenRead - 2);
7106     AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7107     AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7108     if (LLBAA)
7109     {
7110       AllPages[4] = 0x00; /* reserved and LONGLBA */
7111       AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */
7112     }
7113     else
7114     {
7115       AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7116     }
7117     AllPages[5] = 0x00; /* reserved */
7118     AllPages[6] = 0x00; /* block descriptot length */
7119     if (LLBAA)
7120     {
7121       AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7122     }
7123     else
7124     {
7125       AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7126     }
7127 
7128     /*
7129      * Fill-up direct-access device block-descriptor, SAT, Table 19
7130      */
7131 
7132     if (LLBAA)
7133     {
7134       /* density code */
7135       AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
7136       /* number of blocks */
7137       AllPages[9]   = 0x00; /* unspecified */
7138       AllPages[10]  = 0x00; /* unspecified */
7139       AllPages[11]  = 0x00; /* unspecified */
7140       AllPages[12]  = 0x00; /* unspecified */
7141       AllPages[13]  = 0x00; /* unspecified */
7142       AllPages[14]  = 0x00; /* unspecified */
7143       AllPages[15]  = 0x00; /* unspecified */
7144       /* reserved */
7145       AllPages[16]  = 0x00; /* reserved */
7146       AllPages[17]  = 0x00; /* reserved */
7147       AllPages[18]  = 0x00; /* reserved */
7148       AllPages[19]  = 0x00; /* reserved */
7149       /* Block size */
7150       AllPages[20]  = 0x00;
7151       AllPages[21]  = 0x00;
7152       AllPages[22]  = 0x02;   /* Block size is always 512 bytes */
7153       AllPages[23]  = 0x00;
7154     }
7155     else
7156     {
7157       /* density code */
7158       AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
7159       /* number of blocks */
7160       AllPages[9]   = 0x00; /* unspecified */
7161       AllPages[10]  = 0x00; /* unspecified */
7162       AllPages[11]  = 0x00; /* unspecified */
7163       /* reserved */
7164       AllPages[12]  = 0x00; /* reserved */
7165       /* Block size */
7166       AllPages[13]  = 0x00;
7167       AllPages[14]  = 0x02;   /* Block size is always 512 bytes */
7168       AllPages[15]  = 0x00;
7169     }
7170 
7171     if (LLBAA)
7172     {
7173       index = 24;
7174     }
7175     else
7176     {
7177       index = 16;
7178     }
7179     /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
7180     AllPages[index+0] = 0x01; /* page code */
7181     AllPages[index+1] = 0x0A; /* page length */
7182     AllPages[index+2] = 0x40; /* ARRE is set */
7183     AllPages[index+3] = 0x00;
7184     AllPages[index+4] = 0x00;
7185     AllPages[index+5] = 0x00;
7186     AllPages[index+6] = 0x00;
7187     AllPages[index+7] = 0x00;
7188     AllPages[index+8] = 0x00;
7189     AllPages[index+9] = 0x00;
7190     AllPages[index+10] = 0x00;
7191     AllPages[index+11] = 0x00;
7192 
7193     /* MODESENSE_CACHING */
7194     /*
7195      * Fill-up Caching mode page, SAT, Table 67
7196      */
7197     /* length 20 */
7198     AllPages[index+12] = 0x08; /* page code */
7199     AllPages[index+13] = 0x12; /* page length */
7200 #ifdef NOT_YET
7201     if (pSatDevData->satWriteCacheEnabled == agTRUE)
7202     {
7203       AllPages[index+14] = 0x04;/* WCE bit is set */
7204     }
7205     else
7206     {
7207       AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7208     }
7209 #endif
7210     AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7211     AllPages[index+15] = 0x00;
7212     AllPages[index+16] = 0x00;
7213     AllPages[index+17] = 0x00;
7214     AllPages[index+18] = 0x00;
7215     AllPages[index+19] = 0x00;
7216     AllPages[index+20] = 0x00;
7217     AllPages[index+21] = 0x00;
7218     AllPages[index+22] = 0x00;
7219     AllPages[index+23] = 0x00;
7220     if (pSatDevData->satLookAheadEnabled == agTRUE)
7221     {
7222       AllPages[index+24] = 0x00;/* DRA bit is NOT set */
7223     }
7224     else
7225     {
7226       AllPages[index+24] = 0x20;/* DRA bit is set */
7227     }
7228     AllPages[index+25] = 0x00;
7229     AllPages[index+26] = 0x00;
7230     AllPages[index+27] = 0x00;
7231     AllPages[index+28] = 0x00;
7232     AllPages[index+29] = 0x00;
7233     AllPages[index+30] = 0x00;
7234     AllPages[index+31] = 0x00;
7235 
7236     /* MODESENSE_CONTROL_PAGE */
7237     /*
7238      * Fill-up control mode page, SAT, Table 65
7239      */
7240     AllPages[index+32] = 0x0A; /* page code */
7241     AllPages[index+33] = 0x0A; /* page length */
7242     AllPages[index+34] = 0x02; /* only GLTSD bit is set */
7243     if (pSatDevData->satNCQ == agTRUE)
7244     {
7245       AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7246     }
7247     else
7248     {
7249       AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7250     }
7251     AllPages[index+36] = 0x00;
7252     AllPages[index+37] = 0x00;
7253     AllPages[index+38] = 0x00; /* obsolete */
7254     AllPages[index+39] = 0x00; /* obsolete */
7255     AllPages[index+40] = 0xFF; /* Busy Timeout Period */
7256     AllPages[index+41] = 0xFF; /* Busy Timeout Period */
7257     AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */
7258     AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */
7259 
7260     /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
7261     /*
7262      * Fill-up informational-exceptions control mode page, SAT, Table 68
7263      */
7264     AllPages[index+44] = 0x1C; /* page code */
7265     AllPages[index+45] = 0x0A; /* page length */
7266      if (pSatDevData->satSMARTEnabled == agTRUE)
7267     {
7268       AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */
7269     }
7270     else
7271     {
7272       AllPages[index+46] = 0x08;/* DEXCPT bit is set */
7273     }
7274     AllPages[index+47] = 0x00; /* We don't support MRIE */
7275     AllPages[index+48] = 0x00; /* Interval timer vendor-specific */
7276     AllPages[index+49] = 0x00;
7277     AllPages[index+50] = 0x00;
7278     AllPages[index+51] = 0x00;
7279     AllPages[index+52] = 0x00; /* REPORT-COUNT */
7280     AllPages[index+53] = 0x00;
7281     AllPages[index+54] = 0x00;
7282     AllPages[index+55] = 0x00;
7283 
7284     osti_memcpy(pModeSense, &AllPages, lenRead);
7285   }
7286   else if (page == MODESENSE_CONTROL_PAGE)
7287   {
7288     TI_DBG5(("satModeSense10: MODESENSE_CONTROL_PAGE\n"));
7289     Control[0] = 0;
7290     Control[1] = (bit8)(lenRead - 2);
7291     Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7292     Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7293     if (LLBAA)
7294     {
7295       Control[4] = 0x00; /* reserved and LONGLBA */
7296       Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */
7297     }
7298     else
7299     {
7300       Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7301     }
7302     Control[5] = 0x00; /* reserved */
7303     Control[6] = 0x00; /* block descriptot length */
7304     if (LLBAA)
7305     {
7306       Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7307     }
7308     else
7309     {
7310       Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7311     }
7312 
7313     /*
7314      * Fill-up direct-access device block-descriptor, SAT, Table 19
7315      */
7316 
7317     if (LLBAA)
7318     {
7319       /* density code */
7320       Control[8]   = 0x04; /* density-code : reserved for direct-access */
7321       /* number of blocks */
7322       Control[9]   = 0x00; /* unspecified */
7323       Control[10]  = 0x00; /* unspecified */
7324       Control[11]  = 0x00; /* unspecified */
7325       Control[12]  = 0x00; /* unspecified */
7326       Control[13]  = 0x00; /* unspecified */
7327       Control[14]  = 0x00; /* unspecified */
7328       Control[15]  = 0x00; /* unspecified */
7329       /* reserved */
7330       Control[16]  = 0x00; /* reserved */
7331       Control[17]  = 0x00; /* reserved */
7332       Control[18]  = 0x00; /* reserved */
7333       Control[19]  = 0x00; /* reserved */
7334       /* Block size */
7335       Control[20]  = 0x00;
7336       Control[21]  = 0x00;
7337       Control[22]  = 0x02;   /* Block size is always 512 bytes */
7338       Control[23]  = 0x00;
7339     }
7340     else
7341     {
7342       /* density code */
7343       Control[8]   = 0x04; /* density-code : reserved for direct-access */
7344       /* number of blocks */
7345       Control[9]   = 0x00; /* unspecified */
7346       Control[10]  = 0x00; /* unspecified */
7347       Control[11]  = 0x00; /* unspecified */
7348       /* reserved */
7349       Control[12]  = 0x00; /* reserved */
7350       /* Block size */
7351       Control[13]  = 0x00;
7352       Control[14]  = 0x02;   /* Block size is always 512 bytes */
7353       Control[15]  = 0x00;
7354     }
7355 
7356     if (LLBAA)
7357     {
7358       index = 24;
7359     }
7360     else
7361     {
7362       index = 16;
7363     }
7364     /*
7365      * Fill-up control mode page, SAT, Table 65
7366      */
7367     Control[index+0] = 0x0A; /* page code */
7368     Control[index+1] = 0x0A; /* page length */
7369     Control[index+2] = 0x02; /* only GLTSD bit is set */
7370     if (pSatDevData->satNCQ == agTRUE)
7371     {
7372       Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7373     }
7374     else
7375     {
7376       Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7377     }
7378     Control[index+4] = 0x00;
7379     Control[index+5] = 0x00;
7380     Control[index+6] = 0x00; /* obsolete */
7381     Control[index+7] = 0x00; /* obsolete */
7382     Control[index+8] = 0xFF; /* Busy Timeout Period */
7383     Control[index+9] = 0xFF; /* Busy Timeout Period */
7384     Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */
7385     Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */
7386 
7387     osti_memcpy(pModeSense, &Control, lenRead);
7388   }
7389   else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
7390   {
7391     TI_DBG5(("satModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
7392     RWErrorRecovery[0] = 0;
7393     RWErrorRecovery[1] = (bit8)(lenRead - 2);
7394     RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7395     RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7396     if (LLBAA)
7397     {
7398       RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */
7399       RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */
7400     }
7401     else
7402     {
7403       RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7404     }
7405     RWErrorRecovery[5] = 0x00; /* reserved */
7406     RWErrorRecovery[6] = 0x00; /* block descriptot length */
7407     if (LLBAA)
7408     {
7409       RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7410     }
7411     else
7412     {
7413       RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7414     }
7415 
7416     /*
7417      * Fill-up direct-access device block-descriptor, SAT, Table 19
7418      */
7419 
7420     if (LLBAA)
7421     {
7422       /* density code */
7423       RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
7424       /* number of blocks */
7425       RWErrorRecovery[9]   = 0x00; /* unspecified */
7426       RWErrorRecovery[10]  = 0x00; /* unspecified */
7427       RWErrorRecovery[11]  = 0x00; /* unspecified */
7428       RWErrorRecovery[12]  = 0x00; /* unspecified */
7429       RWErrorRecovery[13]  = 0x00; /* unspecified */
7430       RWErrorRecovery[14]  = 0x00; /* unspecified */
7431       RWErrorRecovery[15]  = 0x00; /* unspecified */
7432       /* reserved */
7433       RWErrorRecovery[16]  = 0x00; /* reserved */
7434       RWErrorRecovery[17]  = 0x00; /* reserved */
7435       RWErrorRecovery[18]  = 0x00; /* reserved */
7436       RWErrorRecovery[19]  = 0x00; /* reserved */
7437       /* Block size */
7438       RWErrorRecovery[20]  = 0x00;
7439       RWErrorRecovery[21]  = 0x00;
7440       RWErrorRecovery[22]  = 0x02;   /* Block size is always 512 bytes */
7441       RWErrorRecovery[23]  = 0x00;
7442     }
7443     else
7444     {
7445       /* density code */
7446       RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
7447       /* number of blocks */
7448       RWErrorRecovery[9]   = 0x00; /* unspecified */
7449       RWErrorRecovery[10]  = 0x00; /* unspecified */
7450       RWErrorRecovery[11]  = 0x00; /* unspecified */
7451       /* reserved */
7452       RWErrorRecovery[12]  = 0x00; /* reserved */
7453       /* Block size */
7454       RWErrorRecovery[13]  = 0x00;
7455       RWErrorRecovery[14]  = 0x02;   /* Block size is always 512 bytes */
7456       RWErrorRecovery[15]  = 0x00;
7457     }
7458 
7459     if (LLBAA)
7460     {
7461       index = 24;
7462     }
7463     else
7464     {
7465       index = 16;
7466     }
7467     /*
7468      * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
7469      */
7470     RWErrorRecovery[index+0] = 0x01; /* page code */
7471     RWErrorRecovery[index+1] = 0x0A; /* page length */
7472     RWErrorRecovery[index+2] = 0x40; /* ARRE is set */
7473     RWErrorRecovery[index+3] = 0x00;
7474     RWErrorRecovery[index+4] = 0x00;
7475     RWErrorRecovery[index+5] = 0x00;
7476     RWErrorRecovery[index+6] = 0x00;
7477     RWErrorRecovery[index+7] = 0x00;
7478     RWErrorRecovery[index+8] = 0x00;
7479     RWErrorRecovery[index+9] = 0x00;
7480     RWErrorRecovery[index+10] = 0x00;
7481     RWErrorRecovery[index+11] = 0x00;
7482 
7483     osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
7484   }
7485   else if (page == MODESENSE_CACHING)
7486   {
7487     TI_DBG5(("satModeSense10: MODESENSE_CACHING\n"));
7488     Caching[0] = 0;
7489     Caching[1] = (bit8)(lenRead - 2);
7490     Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7491     Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7492     if (LLBAA)
7493     {
7494       Caching[4] = 0x00; /* reserved and LONGLBA */
7495       Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */
7496     }
7497     else
7498     {
7499       Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7500     }
7501     Caching[5] = 0x00; /* reserved */
7502     Caching[6] = 0x00; /* block descriptot length */
7503     if (LLBAA)
7504     {
7505       Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7506     }
7507     else
7508     {
7509       Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7510     }
7511 
7512     /*
7513      * Fill-up direct-access device block-descriptor, SAT, Table 19
7514      */
7515 
7516     if (LLBAA)
7517     {
7518       /* density code */
7519       Caching[8]   = 0x04; /* density-code : reserved for direct-access */
7520       /* number of blocks */
7521       Caching[9]   = 0x00; /* unspecified */
7522       Caching[10]  = 0x00; /* unspecified */
7523       Caching[11]  = 0x00; /* unspecified */
7524       Caching[12]  = 0x00; /* unspecified */
7525       Caching[13]  = 0x00; /* unspecified */
7526       Caching[14]  = 0x00; /* unspecified */
7527       Caching[15]  = 0x00; /* unspecified */
7528       /* reserved */
7529       Caching[16]  = 0x00; /* reserved */
7530       Caching[17]  = 0x00; /* reserved */
7531       Caching[18]  = 0x00; /* reserved */
7532       Caching[19]  = 0x00; /* reserved */
7533       /* Block size */
7534       Caching[20]  = 0x00;
7535       Caching[21]  = 0x00;
7536       Caching[22]  = 0x02;   /* Block size is always 512 bytes */
7537       Caching[23]  = 0x00;
7538     }
7539     else
7540     {
7541       /* density code */
7542       Caching[8]   = 0x04; /* density-code : reserved for direct-access */
7543       /* number of blocks */
7544       Caching[9]   = 0x00; /* unspecified */
7545       Caching[10]  = 0x00; /* unspecified */
7546       Caching[11]  = 0x00; /* unspecified */
7547       /* reserved */
7548       Caching[12]  = 0x00; /* reserved */
7549       /* Block size */
7550       Caching[13]  = 0x00;
7551       Caching[14]  = 0x02;   /* Block size is always 512 bytes */
7552       Caching[15]  = 0x00;
7553     }
7554 
7555     if (LLBAA)
7556     {
7557       index = 24;
7558     }
7559     else
7560     {
7561       index = 16;
7562     }
7563     /*
7564      * Fill-up Caching mode page, SAT, Table 67
7565      */
7566     /* length 20 */
7567     Caching[index+0] = 0x08; /* page code */
7568     Caching[index+1] = 0x12; /* page length */
7569 #ifdef NOT_YET
7570     if (pSatDevData->satWriteCacheEnabled == agTRUE)
7571     {
7572       Caching[index+2] = 0x04;/* WCE bit is set */
7573     }
7574     else
7575     {
7576       Caching[index+2] = 0x00;/* WCE bit is NOT set */
7577     }
7578 #endif
7579     Caching[index+2] = 0x00;/* WCE bit is NOT set */
7580     Caching[index+3] = 0x00;
7581     Caching[index+4] = 0x00;
7582     Caching[index+5] = 0x00;
7583     Caching[index+6] = 0x00;
7584     Caching[index+7] = 0x00;
7585     Caching[index+8] = 0x00;
7586     Caching[index+9] = 0x00;
7587     Caching[index+10] = 0x00;
7588     Caching[index+11] = 0x00;
7589     if (pSatDevData->satLookAheadEnabled == agTRUE)
7590     {
7591       Caching[index+12] = 0x00;/* DRA bit is NOT set */
7592     }
7593     else
7594     {
7595       Caching[index+12] = 0x20;/* DRA bit is set */
7596     }
7597     Caching[index+13] = 0x00;
7598     Caching[index+14] = 0x00;
7599     Caching[index+15] = 0x00;
7600     Caching[index+16] = 0x00;
7601     Caching[index+17] = 0x00;
7602     Caching[index+18] = 0x00;
7603     Caching[index+19] = 0x00;
7604     osti_memcpy(pModeSense, &Caching, lenRead);
7605 
7606   }
7607   else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
7608   {
7609     TI_DBG5(("satModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
7610     InfoExceptionCtrl[0] = 0;
7611     InfoExceptionCtrl[1] = (bit8)(lenRead - 2);
7612     InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7613     InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7614     if (LLBAA)
7615     {
7616       InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */
7617       InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */
7618     }
7619     else
7620     {
7621       InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7622     }
7623     InfoExceptionCtrl[5] = 0x00; /* reserved */
7624     InfoExceptionCtrl[6] = 0x00; /* block descriptot length */
7625     if (LLBAA)
7626     {
7627       InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7628     }
7629     else
7630     {
7631       InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7632     }
7633 
7634     /*
7635      * Fill-up direct-access device block-descriptor, SAT, Table 19
7636      */
7637 
7638     if (LLBAA)
7639     {
7640       /* density code */
7641       InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
7642       /* number of blocks */
7643       InfoExceptionCtrl[9]   = 0x00; /* unspecified */
7644       InfoExceptionCtrl[10]  = 0x00; /* unspecified */
7645       InfoExceptionCtrl[11]  = 0x00; /* unspecified */
7646       InfoExceptionCtrl[12]  = 0x00; /* unspecified */
7647       InfoExceptionCtrl[13]  = 0x00; /* unspecified */
7648       InfoExceptionCtrl[14]  = 0x00; /* unspecified */
7649       InfoExceptionCtrl[15]  = 0x00; /* unspecified */
7650       /* reserved */
7651       InfoExceptionCtrl[16]  = 0x00; /* reserved */
7652       InfoExceptionCtrl[17]  = 0x00; /* reserved */
7653       InfoExceptionCtrl[18]  = 0x00; /* reserved */
7654       InfoExceptionCtrl[19]  = 0x00; /* reserved */
7655       /* Block size */
7656       InfoExceptionCtrl[20]  = 0x00;
7657       InfoExceptionCtrl[21]  = 0x00;
7658       InfoExceptionCtrl[22]  = 0x02;   /* Block size is always 512 bytes */
7659       InfoExceptionCtrl[23]  = 0x00;
7660     }
7661     else
7662     {
7663       /* density code */
7664       InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
7665       /* number of blocks */
7666       InfoExceptionCtrl[9]   = 0x00; /* unspecified */
7667       InfoExceptionCtrl[10]  = 0x00; /* unspecified */
7668       InfoExceptionCtrl[11]  = 0x00; /* unspecified */
7669       /* reserved */
7670       InfoExceptionCtrl[12]  = 0x00; /* reserved */
7671       /* Block size */
7672       InfoExceptionCtrl[13]  = 0x00;
7673       InfoExceptionCtrl[14]  = 0x02;   /* Block size is always 512 bytes */
7674       InfoExceptionCtrl[15]  = 0x00;
7675     }
7676 
7677     if (LLBAA)
7678     {
7679       index = 24;
7680     }
7681     else
7682     {
7683       index = 16;
7684     }
7685     /*
7686      * Fill-up informational-exceptions control mode page, SAT, Table 68
7687      */
7688     InfoExceptionCtrl[index+0] = 0x1C; /* page code */
7689     InfoExceptionCtrl[index+1] = 0x0A; /* page length */
7690      if (pSatDevData->satSMARTEnabled == agTRUE)
7691     {
7692       InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */
7693     }
7694     else
7695     {
7696       InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */
7697     }
7698     InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */
7699     InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */
7700     InfoExceptionCtrl[index+5] = 0x00;
7701     InfoExceptionCtrl[index+6] = 0x00;
7702     InfoExceptionCtrl[index+7] = 0x00;
7703     InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */
7704     InfoExceptionCtrl[index+9] = 0x00;
7705     InfoExceptionCtrl[index+10] = 0x00;
7706     InfoExceptionCtrl[index+11] = 0x00;
7707     osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
7708 
7709   }
7710   else
7711   {
7712     /* Error */
7713     TI_DBG1(("satModeSense10: Error page %d\n", page));
7714     satSetSensePayload( pSense,
7715                         SCSI_SNSKEY_ILLEGAL_REQUEST,
7716                         0,
7717                         SCSI_SNSCODE_INVALID_COMMAND,
7718                         satIOContext);
7719 
7720     ostiInitiatorIOCompleted( tiRoot,
7721                               tiIORequest,
7722                               tiIOSuccess,
7723                               SCSI_STAT_CHECK_CONDITION,
7724                               satIOContext->pTiSenseData,
7725                               satIOContext->interruptContext );
7726     return tiSuccess;
7727   }
7728 
7729   if (requestLen > lenRead)
7730   {
7731     TI_DBG1(("satModeSense10 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
7732 
7733     ostiInitiatorIOCompleted( tiRoot,
7734                               tiIORequest,
7735                               tiIOUnderRun,
7736                               requestLen - lenRead,
7737                               agNULL,
7738                               satIOContext->interruptContext );
7739 
7740 
7741   }
7742   else
7743   {
7744     ostiInitiatorIOCompleted( tiRoot,
7745                               tiIORequest,
7746                               tiIOSuccess,
7747                               SCSI_STAT_GOOD,
7748                               agNULL,
7749                               satIOContext->interruptContext);
7750   }
7751 
7752   return tiSuccess;
7753 }
7754 
7755 
7756 /*****************************************************************************/
7757 /*! \brief SAT implementation for SCSI VERIFY (10).
7758  *
7759  *  SAT implementation for SCSI VERIFY (10).
7760  *
7761  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
7762  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
7763  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
7764  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
7765  *  \param   satIOContext_t:   Pointer to the SAT IO Context
7766  *
7767  *  \return If command is started successfully
7768  *    - \e tiSuccess:     I/O request successfully initiated.
7769  *    - \e tiBusy:        No resources available, try again later.
7770  *    - \e tiIONoDevice:  Invalid device handle.
7771  *    - \e tiError:       Other errors.
7772  */
7773 /*****************************************************************************/
7774 GLOBAL bit32  satVerify10(
7775                    tiRoot_t                  *tiRoot,
7776                    tiIORequest_t             *tiIORequest,
7777                    tiDeviceHandle_t          *tiDeviceHandle,
7778                    tiScsiInitiatorRequest_t *tiScsiRequest,
7779                    satIOContext_t            *satIOContext)
7780 {
7781   /*
7782     For simple implementation,
7783     no byte comparison supported as of 4/5/06
7784   */
7785   scsiRspSense_t            *pSense;
7786   tiIniScsiCmnd_t           *scsiCmnd;
7787   satDeviceData_t           *pSatDevData;
7788   agsaFisRegHostToDevice_t  *fis;
7789   bit32                     status;
7790   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7791   bit32                     lba = 0;
7792   bit32                     tl = 0;
7793   bit32                     LoopNum = 1;
7794   bit8                      LBA[4];
7795   bit8                      TL[4];
7796   bit32                     rangeChk = agFALSE; /* lba and tl range check */
7797 
7798 
7799   TI_DBG5(("satVerify10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
7800       tiDeviceHandle, tiIORequest));
7801 
7802   pSense            = satIOContext->pSense;
7803   scsiCmnd          = &tiScsiRequest->scsiCmnd;
7804   pSatDevData       = satIOContext->pSatDevData;
7805   fis               = satIOContext->pFis;
7806 
7807   /* checking BYTCHK */
7808   if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
7809   {
7810     /*
7811       should do the byte check
7812       but not supported in this version
7813      */
7814     satSetSensePayload( pSense,
7815                         SCSI_SNSKEY_ILLEGAL_REQUEST,
7816                         0,
7817                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7818                         satIOContext);
7819 
7820     ostiInitiatorIOCompleted( tiRoot,
7821                               tiIORequest,
7822                               tiIOSuccess,
7823                               SCSI_STAT_CHECK_CONDITION,
7824                               satIOContext->pTiSenseData,
7825                               satIOContext->interruptContext );
7826 
7827     TI_DBG1(("satVerify10: no byte checking \n"));
7828     return tiSuccess;
7829   }
7830 
7831   /* checking CONTROL */
7832   /* NACA == 1 or LINK == 1*/
7833   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
7834   {
7835     satSetSensePayload( pSense,
7836                         SCSI_SNSKEY_ILLEGAL_REQUEST,
7837                         0,
7838                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7839                         satIOContext);
7840 
7841     ostiInitiatorIOCompleted( tiRoot,
7842                               tiIORequest,
7843                               tiIOSuccess,
7844                               SCSI_STAT_CHECK_CONDITION,
7845                               satIOContext->pTiSenseData,
7846                               satIOContext->interruptContext );
7847 
7848     TI_DBG2(("satVerify10: return control\n"));
7849     return tiSuccess;
7850   }
7851 
7852   osti_memset(LBA, 0, sizeof(LBA));
7853   osti_memset(TL, 0, sizeof(TL));
7854 
7855   /* do not use memcpy due to indexing in LBA and TL */
7856   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
7857   LBA[1] = scsiCmnd->cdb[3];
7858   LBA[2] = scsiCmnd->cdb[4];
7859   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
7860 
7861   TL[0] = 0;
7862   TL[1] = 0;
7863   TL[2] = scsiCmnd->cdb[7];  /* MSB */
7864   TL[3] = scsiCmnd->cdb[8];  /* LSB */
7865 
7866   rangeChk = satAddNComparebit32(LBA, TL);
7867 
7868   /* cbd10; computing LBA and transfer length */
7869   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
7870     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
7871   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7872 
7873   if (pSatDevData->satNCQ != agTRUE &&
7874       pSatDevData->sat48BitSupport != agTRUE
7875       )
7876   {
7877     if (lba > SAT_TR_LBA_LIMIT - 1)
7878     {
7879       satSetSensePayload( pSense,
7880                           SCSI_SNSKEY_ILLEGAL_REQUEST,
7881                           0,
7882                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7883                           satIOContext);
7884 
7885       ostiInitiatorIOCompleted( tiRoot,
7886                                 tiIORequest,
7887                                 tiIOSuccess,
7888                                 SCSI_STAT_CHECK_CONDITION,
7889                                 satIOContext->pTiSenseData,
7890                                 satIOContext->interruptContext );
7891 
7892     TI_DBG1(("satVerify10: return LBA out of range, not EXT\n"));
7893     TI_DBG1(("satVerify10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
7894              scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
7895     TI_DBG1(("satVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
7896     return tiSuccess;
7897     }
7898 
7899     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
7900     {
7901       TI_DBG1(("satVerify10: return LBA+TL out of range, not EXT\n"));
7902       satSetSensePayload( pSense,
7903                           SCSI_SNSKEY_ILLEGAL_REQUEST,
7904                           0,
7905                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7906                           satIOContext);
7907 
7908       ostiInitiatorIOCompleted( tiRoot,
7909                                 tiIORequest,
7910                                 tiIOSuccess,
7911                                 SCSI_STAT_CHECK_CONDITION,
7912                                 satIOContext->pTiSenseData,
7913                                 satIOContext->interruptContext );
7914 
7915     return tiSuccess;
7916     }
7917   }
7918 
7919   if (pSatDevData->sat48BitSupport == agTRUE)
7920   {
7921     TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS_EXT\n"));
7922     fis->h.fisType        = 0x27;                   /* Reg host to device */
7923     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7924 
7925     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
7926     fis->h.features       = 0;                      /* FIS reserve */
7927     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7928     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7929     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7930     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
7931     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7932     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7933     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7934     fis->d.featuresExp    = 0;                      /* FIS reserve */
7935     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7936     fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
7937 
7938     fis->d.reserved4      = 0;
7939     fis->d.control        = 0;                      /* FIS HOB bit clear */
7940     fis->d.reserved5      = 0;
7941 
7942     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7943     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
7944   }
7945   else
7946   {
7947     TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS\n"));
7948     fis->h.fisType        = 0x27;                   /* Reg host to device */
7949     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7950     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
7951     fis->h.features       = 0;                      /* FIS reserve */
7952     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7953     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7954     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7955       /* FIS LBA mode set LBA (27:24) */
7956     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7957     fis->d.lbaLowExp      = 0;
7958     fis->d.lbaMidExp      = 0;
7959     fis->d.lbaHighExp     = 0;
7960     fis->d.featuresExp    = 0;
7961     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7962     fis->d.sectorCountExp = 0;
7963     fis->d.reserved4      = 0;
7964     fis->d.control        = 0;                      /* FIS HOB bit clear */
7965     fis->d.reserved5      = 0;
7966 
7967     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7968     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
7969 
7970  }
7971 
7972   satIOContext->currentLBA = lba;
7973   satIOContext->OrgTL = tl;
7974 
7975   /*
7976     computing number of loop and remainder for tl
7977     0xFF in case not ext
7978     0xFFFF in case EXT
7979   */
7980   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7981   {
7982     LoopNum = satComputeLoopNum(tl, 0xFF);
7983   }
7984   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
7985   {
7986     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7987     LoopNum = satComputeLoopNum(tl, 0xFFFF);
7988   }
7989   else
7990   {
7991     TI_DBG1(("satVerify10: error case 1!!!\n"));
7992     LoopNum = 1;
7993   }
7994 
7995   satIOContext->LoopNum = LoopNum;
7996 
7997   if (LoopNum == 1)
7998   {
7999     TI_DBG5(("satVerify10: NON CHAINED data\n"));
8000     /* Initialize CB for SATA completion.
8001      */
8002     satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8003   }
8004   else
8005   {
8006     TI_DBG1(("satVerify10: CHAINED data\n"));
8007     /* re-setting tl */
8008     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8009     {
8010        fis->d.sectorCount    = 0xFF;
8011     }
8012     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8013     {
8014       fis->d.sectorCount    = 0xFF;
8015       fis->d.sectorCountExp = 0xFF;
8016     }
8017     else
8018     {
8019       TI_DBG1(("satVerify10: error case 2!!!\n"));
8020     }
8021 
8022     /* Initialize CB for SATA completion.
8023      */
8024     satIOContext->satCompleteCB = &satChainedVerifyCB;
8025   }
8026 
8027 
8028   /*
8029    * Prepare SGL and send FIS to LL layer.
8030    */
8031   satIOContext->reqType = agRequestType;       /* Save it */
8032 
8033   status = sataLLIOStart( tiRoot,
8034                           tiIORequest,
8035                           tiDeviceHandle,
8036                           tiScsiRequest,
8037                           satIOContext);
8038   return (status);
8039 }
8040 
8041 GLOBAL bit32  satChainedVerify(
8042                    tiRoot_t                  *tiRoot,
8043                    tiIORequest_t             *tiIORequest,
8044                    tiDeviceHandle_t          *tiDeviceHandle,
8045                    tiScsiInitiatorRequest_t *tiScsiRequest,
8046                    satIOContext_t            *satIOContext)
8047 {
8048   bit32                     status;
8049   satIOContext_t            *satOrgIOContext = agNULL;
8050   agsaFisRegHostToDevice_t  *fis;
8051   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8052   bit32                     lba = 0;
8053   bit32                     DenomTL = 0xFF;
8054   bit32                     Remainder = 0;
8055   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
8056 
8057   TI_DBG2(("satChainedVerify: start\n"));
8058 
8059   fis             = satIOContext->pFis;
8060   satOrgIOContext = satIOContext->satOrgIOContext;
8061   osti_memset(LBA,0, sizeof(LBA));
8062 
8063   switch (satOrgIOContext->ATACmd)
8064   {
8065   case SAT_READ_VERIFY_SECTORS:
8066     DenomTL = 0xFF;
8067     break;
8068   case SAT_READ_VERIFY_SECTORS_EXT:
8069     DenomTL = 0xFFFF;
8070     break;
8071   default:
8072     TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8073     return tiError;
8074     break;
8075   }
8076 
8077   Remainder = satOrgIOContext->OrgTL % DenomTL;
8078   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
8079   lba = satOrgIOContext->currentLBA;
8080 
8081   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
8082   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
8083   LBA[2] = (bit8)((lba & 0xF0) >> 8);
8084   LBA[3] = (bit8)(lba & 0xF);               /* LSB */
8085 
8086   switch (satOrgIOContext->ATACmd)
8087   {
8088   case SAT_READ_VERIFY_SECTORS:
8089     fis->h.fisType        = 0x27;                   /* Reg host to device */
8090     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8091     fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
8092     fis->h.features       = 0;                      /* FIS reserve */
8093     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
8094     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
8095     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
8096 
8097     /* FIS LBA mode set LBA (27:24) */
8098     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
8099 
8100     fis->d.lbaLowExp      = 0;
8101     fis->d.lbaMidExp      = 0;
8102     fis->d.lbaHighExp     = 0;
8103     fis->d.featuresExp    = 0;
8104     if (satOrgIOContext->LoopNum == 1)
8105     {
8106       /* last loop */
8107       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
8108     }
8109     else
8110     {
8111       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
8112     }
8113     fis->d.sectorCountExp = 0;
8114     fis->d.reserved4      = 0;
8115     fis->d.control        = 0;                      /* FIS HOB bit clear */
8116     fis->d.reserved5      = 0;
8117 
8118     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8119 
8120     break;
8121   case SAT_READ_VERIFY_SECTORS_EXT:
8122     fis->h.fisType        = 0x27;                   /* Reg host to device */
8123     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8124     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
8125     fis->h.features       = 0;                      /* FIS reserve */
8126     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
8127     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
8128     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
8129     fis->d.device         = 0x40;                   /* FIS LBA mode set */
8130     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
8131     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
8132     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
8133     fis->d.featuresExp    = 0;                      /* FIS reserve */
8134     if (satOrgIOContext->LoopNum == 1)
8135     {
8136       /* last loop */
8137       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
8138       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
8139     }
8140     else
8141     {
8142       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
8143       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
8144     }
8145     fis->d.reserved4      = 0;
8146     fis->d.control        = 0;                       /* FIS HOB bit clear */
8147     fis->d.reserved5      = 0;
8148 
8149     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8150 
8151     break;
8152 
8153   default:
8154     TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8155     return tiError;
8156     break;
8157   }
8158 
8159   /* Initialize CB for SATA completion.
8160    */
8161   /* chained data */
8162   satIOContext->satCompleteCB = &satChainedVerifyCB;
8163 
8164 
8165   /*
8166    * Prepare SGL and send FIS to LL layer.
8167    */
8168   satIOContext->reqType = agRequestType;       /* Save it */
8169 
8170   status = sataLLIOStart( tiRoot,
8171                           tiIORequest,
8172                           tiDeviceHandle,
8173                           tiScsiRequest,
8174                           satIOContext);
8175 
8176   TI_DBG5(("satChainedVerify: return\n"));
8177   return (status);
8178 
8179 }
8180 
8181 
8182 /*****************************************************************************/
8183 /*! \brief SAT implementation for SCSI VERIFY (12).
8184  *
8185  *  SAT implementation for SCSI VERIFY (12).
8186  *
8187  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8188  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8189  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8190  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8191  *  \param   satIOContext_t:   Pointer to the SAT IO Context
8192  *
8193  *  \return If command is started successfully
8194  *    - \e tiSuccess:     I/O request successfully initiated.
8195  *    - \e tiBusy:        No resources available, try again later.
8196  *    - \e tiIONoDevice:  Invalid device handle.
8197  *    - \e tiError:       Other errors.
8198  */
8199 /*****************************************************************************/
8200 GLOBAL bit32  satVerify12(
8201                    tiRoot_t                  *tiRoot,
8202                    tiIORequest_t             *tiIORequest,
8203                    tiDeviceHandle_t          *tiDeviceHandle,
8204                    tiScsiInitiatorRequest_t *tiScsiRequest,
8205                    satIOContext_t            *satIOContext)
8206 {
8207   /*
8208     For simple implementation,
8209     no byte comparison supported as of 4/5/06
8210   */
8211   scsiRspSense_t            *pSense;
8212   tiIniScsiCmnd_t           *scsiCmnd;
8213   satDeviceData_t           *pSatDevData;
8214   agsaFisRegHostToDevice_t  *fis;
8215   bit32                     status;
8216   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8217   bit32                     lba = 0;
8218   bit32                     tl = 0;
8219   bit32                     LoopNum = 1;
8220   bit8                      LBA[4];
8221   bit8                      TL[4];
8222   bit32                     rangeChk = agFALSE; /* lba and tl range check */
8223 
8224   TI_DBG5(("satVerify12 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8225            tiDeviceHandle, tiIORequest));
8226 
8227   pSense            = satIOContext->pSense;
8228   scsiCmnd          = &tiScsiRequest->scsiCmnd;
8229   pSatDevData       = satIOContext->pSatDevData;
8230   fis               = satIOContext->pFis;
8231 
8232 
8233   /* checking BYTCHK */
8234   if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8235   {
8236     /*
8237       should do the byte check
8238       but not supported in this version
8239      */
8240     satSetSensePayload( pSense,
8241                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8242                         0,
8243                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8244                         satIOContext);
8245 
8246     ostiInitiatorIOCompleted( tiRoot,
8247                               tiIORequest,
8248                               tiIOSuccess,
8249                               SCSI_STAT_CHECK_CONDITION,
8250                               satIOContext->pTiSenseData,
8251                               satIOContext->interruptContext );
8252 
8253     TI_DBG1(("satVerify12: no byte checking \n"));
8254     return tiSuccess;
8255   }
8256 
8257   /* checking CONTROL */
8258   /* NACA == 1 or LINK == 1*/
8259   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
8260   {
8261     satSetSensePayload( pSense,
8262                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8263                         0,
8264                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8265                         satIOContext);
8266 
8267     ostiInitiatorIOCompleted( tiRoot,
8268                               tiIORequest,
8269                               tiIOSuccess,
8270                               SCSI_STAT_CHECK_CONDITION,
8271                               satIOContext->pTiSenseData,
8272                               satIOContext->interruptContext );
8273 
8274     TI_DBG1(("satVerify12: return control\n"));
8275     return tiSuccess;
8276   }
8277 
8278   osti_memset(LBA, 0, sizeof(LBA));
8279   osti_memset(TL, 0, sizeof(TL));
8280 
8281   /* do not use memcpy due to indexing in LBA and TL */
8282   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
8283   LBA[1] = scsiCmnd->cdb[3];
8284   LBA[2] = scsiCmnd->cdb[4];
8285   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
8286 
8287   TL[0] = scsiCmnd->cdb[6];   /* MSB */
8288   TL[1] = scsiCmnd->cdb[7];
8289   TL[2] = scsiCmnd->cdb[7];
8290   TL[3] = scsiCmnd->cdb[8];   /* LSB */
8291 
8292   rangeChk = satAddNComparebit32(LBA, TL);
8293 
8294   lba = satComputeCDB12LBA(satIOContext);
8295   tl = satComputeCDB12TL(satIOContext);
8296 
8297   if (pSatDevData->satNCQ != agTRUE &&
8298       pSatDevData->sat48BitSupport != agTRUE
8299       )
8300   {
8301     if (lba > SAT_TR_LBA_LIMIT - 1)
8302     {
8303       satSetSensePayload( pSense,
8304                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8305                           0,
8306                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8307                           satIOContext);
8308 
8309       ostiInitiatorIOCompleted( tiRoot,
8310                                 tiIORequest,
8311                                 tiIOSuccess,
8312                                 SCSI_STAT_CHECK_CONDITION,
8313                                 satIOContext->pTiSenseData,
8314                                 satIOContext->interruptContext );
8315 
8316     TI_DBG1(("satVerify12: return LBA out of range, not EXT\n"));
8317     TI_DBG1(("satVerify12: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
8318              scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
8319     TI_DBG1(("satVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
8320     return tiSuccess;
8321     }
8322 
8323     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
8324     {
8325       TI_DBG1(("satVerify12: return LBA+TL out of range, not EXT\n"));
8326       satSetSensePayload( pSense,
8327                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8328                           0,
8329                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8330                           satIOContext);
8331 
8332       ostiInitiatorIOCompleted( tiRoot,
8333                                 tiIORequest,
8334                                 tiIOSuccess,
8335                                 SCSI_STAT_CHECK_CONDITION,
8336                                 satIOContext->pTiSenseData,
8337                                 satIOContext->interruptContext );
8338 
8339     return tiSuccess;
8340     }
8341   }
8342 
8343   if (pSatDevData->sat48BitSupport == agTRUE)
8344   {
8345     TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS_EXT\n"));
8346     fis->h.fisType        = 0x27;                   /* Reg host to device */
8347     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8348 
8349     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8350     fis->h.features       = 0;                      /* FIS reserve */
8351     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8352     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8353     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8354     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8355     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
8356     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
8357     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
8358     fis->d.featuresExp    = 0;                      /* FIS reserve */
8359     fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8360     fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
8361 
8362     fis->d.reserved4      = 0;
8363     fis->d.control        = 0;                      /* FIS HOB bit clear */
8364     fis->d.reserved5      = 0;
8365 
8366     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8367     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8368   }
8369   else
8370   {
8371     TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8372     fis->h.fisType        = 0x27;                   /* Reg host to device */
8373     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8374     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8375     fis->h.features       = 0;                      /* FIS reserve */
8376     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8377     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8378     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8379       /* FIS LBA mode set LBA (27:24) */
8380     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
8381     fis->d.lbaLowExp      = 0;
8382     fis->d.lbaMidExp      = 0;
8383     fis->d.lbaHighExp     = 0;
8384     fis->d.featuresExp    = 0;
8385     fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8386     fis->d.sectorCountExp = 0;
8387     fis->d.reserved4      = 0;
8388     fis->d.control        = 0;                      /* FIS HOB bit clear */
8389     fis->d.reserved5      = 0;
8390 
8391     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8392     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8393 
8394  }
8395 
8396   satIOContext->currentLBA = lba;
8397   satIOContext->OrgTL = tl;
8398 
8399   /*
8400     computing number of loop and remainder for tl
8401     0xFF in case not ext
8402     0xFFFF in case EXT
8403   */
8404   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8405   {
8406     LoopNum = satComputeLoopNum(tl, 0xFF);
8407   }
8408   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8409   {
8410     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8411     LoopNum = satComputeLoopNum(tl, 0xFFFF);
8412   }
8413   else
8414   {
8415     TI_DBG1(("satVerify12: error case 1!!!\n"));
8416     LoopNum = 1;
8417   }
8418 
8419   satIOContext->LoopNum = LoopNum;
8420 
8421   if (LoopNum == 1)
8422   {
8423     TI_DBG5(("satVerify12: NON CHAINED data\n"));
8424     /* Initialize CB for SATA completion.
8425      */
8426     satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8427   }
8428   else
8429   {
8430     TI_DBG1(("satVerify12: CHAINED data\n"));
8431     /* re-setting tl */
8432     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8433     {
8434        fis->d.sectorCount    = 0xFF;
8435     }
8436     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8437     {
8438       fis->d.sectorCount    = 0xFF;
8439       fis->d.sectorCountExp = 0xFF;
8440     }
8441     else
8442     {
8443       TI_DBG1(("satVerify10: error case 2!!!\n"));
8444     }
8445 
8446     /* Initialize CB for SATA completion.
8447      */
8448     satIOContext->satCompleteCB = &satChainedVerifyCB;
8449   }
8450 
8451 
8452   /*
8453    * Prepare SGL and send FIS to LL layer.
8454    */
8455   satIOContext->reqType = agRequestType;       /* Save it */
8456 
8457   status = sataLLIOStart( tiRoot,
8458                           tiIORequest,
8459                           tiDeviceHandle,
8460                           tiScsiRequest,
8461                           satIOContext);
8462   return (status);
8463 }
8464 /*****************************************************************************/
8465 /*! \brief SAT implementation for SCSI VERIFY (16).
8466  *
8467  *  SAT implementation for SCSI VERIFY (16).
8468  *
8469  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8470  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8471  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8472  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8473  *  \param   satIOContext_t:   Pointer to the SAT IO Context
8474  *
8475  *  \return If command is started successfully
8476  *    - \e tiSuccess:     I/O request successfully initiated.
8477  *    - \e tiBusy:        No resources available, try again later.
8478  *    - \e tiIONoDevice:  Invalid device handle.
8479  *    - \e tiError:       Other errors.
8480  */
8481 /*****************************************************************************/
8482 GLOBAL bit32  satVerify16(
8483                    tiRoot_t                  *tiRoot,
8484                    tiIORequest_t             *tiIORequest,
8485                    tiDeviceHandle_t          *tiDeviceHandle,
8486                    tiScsiInitiatorRequest_t *tiScsiRequest,
8487                    satIOContext_t            *satIOContext)
8488 {
8489   /*
8490     For simple implementation,
8491     no byte comparison supported as of 4/5/06
8492   */
8493   scsiRspSense_t            *pSense;
8494   tiIniScsiCmnd_t           *scsiCmnd;
8495   satDeviceData_t           *pSatDevData;
8496   agsaFisRegHostToDevice_t  *fis;
8497   bit32                     status;
8498   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8499   bit32                     lba = 0;
8500   bit32                     tl = 0;
8501   bit32                     LoopNum = 1;
8502   bit8                      LBA[8];
8503   bit8                      TL[8];
8504   bit32                     rangeChk = agFALSE; /* lba and tl range check */
8505   bit32                     limitChk = agFALSE; /* lba and tl range check */
8506 
8507   TI_DBG5(("satVerify16 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8508       tiDeviceHandle, tiIORequest));
8509 
8510   pSense            = satIOContext->pSense;
8511   scsiCmnd          = &tiScsiRequest->scsiCmnd;
8512   pSatDevData       = satIOContext->pSatDevData;
8513   fis               = satIOContext->pFis;
8514 
8515   /* checking BYTCHK */
8516   if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8517   {
8518     /*
8519       should do the byte check
8520       but not supported in this version
8521      */
8522     satSetSensePayload( pSense,
8523                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8524                         0,
8525                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8526                         satIOContext);
8527 
8528     ostiInitiatorIOCompleted( tiRoot,
8529                               tiIORequest,
8530                               tiIOSuccess,
8531                               SCSI_STAT_CHECK_CONDITION,
8532                               satIOContext->pTiSenseData,
8533                               satIOContext->interruptContext );
8534 
8535     TI_DBG1(("satVerify16: no byte checking \n"));
8536     return tiSuccess;
8537   }
8538 
8539   /* checking CONTROL */
8540   /* NACA == 1 or LINK == 1*/
8541   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
8542   {
8543     satSetSensePayload( pSense,
8544                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8545                         0,
8546                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8547                         satIOContext);
8548 
8549     ostiInitiatorIOCompleted( tiRoot,
8550                               tiIORequest,
8551                               tiIOSuccess,
8552                               SCSI_STAT_CHECK_CONDITION,
8553                               satIOContext->pTiSenseData,
8554                               satIOContext->interruptContext );
8555 
8556     TI_DBG2(("satVerify16: return control\n"));
8557     return tiSuccess;
8558   }
8559 
8560   osti_memset(LBA, 0, sizeof(LBA));
8561   osti_memset(TL, 0, sizeof(TL));
8562 
8563 
8564   /* do not use memcpy due to indexing in LBA and TL */
8565   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
8566   LBA[1] = scsiCmnd->cdb[3];
8567   LBA[2] = scsiCmnd->cdb[4];
8568   LBA[3] = scsiCmnd->cdb[5];
8569   LBA[4] = scsiCmnd->cdb[6];
8570   LBA[5] = scsiCmnd->cdb[7];
8571   LBA[6] = scsiCmnd->cdb[8];
8572   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
8573 
8574   TL[0] = 0;
8575   TL[1] = 0;
8576   TL[2] = 0;
8577   TL[3] = 0;
8578   TL[4] = scsiCmnd->cdb[10];   /* MSB */
8579   TL[5] = scsiCmnd->cdb[11];
8580   TL[6] = scsiCmnd->cdb[12];
8581   TL[7] = scsiCmnd->cdb[13];   /* LSB */
8582 
8583   rangeChk = satAddNComparebit64(LBA, TL);
8584 
8585   limitChk = satCompareLBALimitbit(LBA);
8586 
8587   lba = satComputeCDB16LBA(satIOContext);
8588   tl = satComputeCDB16TL(satIOContext);
8589 
8590   if (pSatDevData->satNCQ != agTRUE &&
8591      pSatDevData->sat48BitSupport != agTRUE
8592      )
8593   {
8594     if (limitChk)
8595     {
8596       TI_DBG1(("satVerify16: return LBA out of range, not EXT\n"));
8597       satSetSensePayload( pSense,
8598                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8599                           0,
8600                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8601                           satIOContext);
8602 
8603       ostiInitiatorIOCompleted( tiRoot,
8604                                 tiIORequest,
8605                                 tiIOSuccess,
8606                                 SCSI_STAT_CHECK_CONDITION,
8607                                 satIOContext->pTiSenseData,
8608                                 satIOContext->interruptContext );
8609 
8610     return tiSuccess;
8611     }
8612     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
8613     {
8614       TI_DBG1(("satVerify16: return LBA+TL out of range, not EXT\n"));
8615       satSetSensePayload( pSense,
8616                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8617                           0,
8618                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8619                           satIOContext);
8620 
8621       ostiInitiatorIOCompleted( tiRoot,
8622                                 tiIORequest,
8623                                 tiIOSuccess,
8624                                 SCSI_STAT_CHECK_CONDITION,
8625                                 satIOContext->pTiSenseData,
8626                                 satIOContext->interruptContext );
8627 
8628     return tiSuccess;
8629     }
8630   }
8631 
8632   if (pSatDevData->sat48BitSupport == agTRUE)
8633   {
8634     TI_DBG5(("satVerify16: SAT_READ_VERIFY_SECTORS_EXT\n"));
8635     fis->h.fisType        = 0x27;                   /* Reg host to device */
8636     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8637 
8638     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8639     fis->h.features       = 0;                      /* FIS reserve */
8640     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8641     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8642     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8643     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8644     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
8645     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
8646     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
8647     fis->d.featuresExp    = 0;                      /* FIS reserve */
8648     fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8649     fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
8650 
8651     fis->d.reserved4      = 0;
8652     fis->d.control        = 0;                      /* FIS HOB bit clear */
8653     fis->d.reserved5      = 0;
8654 
8655     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8656     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8657   }
8658   else
8659   {
8660     TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8661     fis->h.fisType        = 0x27;                   /* Reg host to device */
8662     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8663     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8664     fis->h.features       = 0;                      /* FIS reserve */
8665     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8666     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8667     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8668       /* FIS LBA mode set LBA (27:24) */
8669     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
8670     fis->d.lbaLowExp      = 0;
8671     fis->d.lbaMidExp      = 0;
8672     fis->d.lbaHighExp     = 0;
8673     fis->d.featuresExp    = 0;
8674     fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8675     fis->d.sectorCountExp = 0;
8676     fis->d.reserved4      = 0;
8677     fis->d.control        = 0;                      /* FIS HOB bit clear */
8678     fis->d.reserved5      = 0;
8679 
8680     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8681     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8682 
8683  }
8684 
8685   satIOContext->currentLBA = lba;
8686   satIOContext->OrgTL = tl;
8687 
8688   /*
8689     computing number of loop and remainder for tl
8690     0xFF in case not ext
8691     0xFFFF in case EXT
8692   */
8693   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8694   {
8695     LoopNum = satComputeLoopNum(tl, 0xFF);
8696   }
8697   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8698   {
8699     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8700     LoopNum = satComputeLoopNum(tl, 0xFFFF);
8701   }
8702   else
8703   {
8704     TI_DBG1(("satVerify12: error case 1!!!\n"));
8705     LoopNum = 1;
8706   }
8707 
8708   satIOContext->LoopNum = LoopNum;
8709 
8710   if (LoopNum == 1)
8711   {
8712     TI_DBG5(("satVerify12: NON CHAINED data\n"));
8713     /* Initialize CB for SATA completion.
8714      */
8715     satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8716   }
8717   else
8718   {
8719     TI_DBG1(("satVerify12: CHAINED data\n"));
8720     /* re-setting tl */
8721     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8722     {
8723        fis->d.sectorCount    = 0xFF;
8724     }
8725     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8726     {
8727       fis->d.sectorCount    = 0xFF;
8728       fis->d.sectorCountExp = 0xFF;
8729     }
8730     else
8731     {
8732       TI_DBG1(("satVerify10: error case 2!!!\n"));
8733     }
8734 
8735     /* Initialize CB for SATA completion.
8736      */
8737     satIOContext->satCompleteCB = &satChainedVerifyCB;
8738   }
8739 
8740 
8741   /*
8742    * Prepare SGL and send FIS to LL layer.
8743    */
8744   satIOContext->reqType = agRequestType;       /* Save it */
8745 
8746   status = sataLLIOStart( tiRoot,
8747                           tiIORequest,
8748                           tiDeviceHandle,
8749                           tiScsiRequest,
8750                           satIOContext);
8751   return (status);
8752 }
8753 /*****************************************************************************/
8754 /*! \brief SAT implementation for SCSI satFormatUnit.
8755  *
8756  *  SAT implementation for SCSI satFormatUnit.
8757  *
8758  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8759  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8760  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8761  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8762  *  \param   satIOContext_t:   Pointer to the SAT IO Context
8763  *
8764  *  \return If command is started successfully
8765  *    - \e tiSuccess:     I/O request successfully initiated.
8766  *    - \e tiBusy:        No resources available, try again later.
8767  *    - \e tiIONoDevice:  Invalid device handle.
8768  *    - \e tiError:       Other errors.
8769  */
8770 /*****************************************************************************/
8771 GLOBAL bit32  satFormatUnit(
8772                    tiRoot_t                  *tiRoot,
8773                    tiIORequest_t             *tiIORequest,
8774                    tiDeviceHandle_t          *tiDeviceHandle,
8775                    tiScsiInitiatorRequest_t *tiScsiRequest,
8776                    satIOContext_t            *satIOContext)
8777 {
8778   /*
8779     note: we don't support media certification in this version and IP bit
8780     satDevData->satFormatState will be agFalse since SAT does not actually sends
8781     any ATA command
8782    */
8783 
8784   scsiRspSense_t          *pSense;
8785   tiIniScsiCmnd_t         *scsiCmnd;
8786   bit32                    index = 0;
8787 
8788   pSense        = satIOContext->pSense;
8789   scsiCmnd      = &tiScsiRequest->scsiCmnd;
8790 
8791   TI_DBG5(("satFormatUnit:start\n"));
8792 
8793   /*
8794     checking opcode
8795     1. FMTDATA bit == 0(no defect list header)
8796     2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided
8797     with DCRT bit set)
8798   */
8799   if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) ||
8800        ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8801         (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK))
8802        )
8803   {
8804     ostiInitiatorIOCompleted( tiRoot,
8805                               tiIORequest,
8806                               tiIOSuccess,
8807                               SCSI_STAT_GOOD,
8808                               agNULL,
8809                               satIOContext->interruptContext);
8810 
8811     TI_DBG2(("satFormatUnit: return opcode\n"));
8812     return tiSuccess;
8813   }
8814 
8815   /*
8816     checking DEFECT LIST FORMAT and defect list length
8817   */
8818   if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) ||
8819         ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) )
8820   {
8821     /* short parameter header */
8822     if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00)
8823     {
8824       index = 8;
8825     }
8826     /* long parameter header */
8827     if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01)
8828     {
8829       index = 10;
8830     }
8831     /* defect list length */
8832     if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0))
8833     {
8834       satSetSensePayload( pSense,
8835                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8836                           0,
8837                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8838                           satIOContext);
8839 
8840       ostiInitiatorIOCompleted( tiRoot,
8841                                 tiIORequest,
8842                                 tiIOSuccess,
8843                                 SCSI_STAT_CHECK_CONDITION,
8844                                 satIOContext->pTiSenseData,
8845                                 satIOContext->interruptContext );
8846 
8847       TI_DBG1(("satFormatUnit: return defect list format\n"));
8848       return tiSuccess;
8849     }
8850   }
8851 
8852    /* FMTDATA == 1 && CMPLIST == 1*/
8853   if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8854        (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
8855   {
8856     satSetSensePayload( pSense,
8857                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8858                         0,
8859                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8860                         satIOContext);
8861 
8862     ostiInitiatorIOCompleted( tiRoot,
8863                               tiIORequest,
8864                               tiIOSuccess,
8865                               SCSI_STAT_CHECK_CONDITION,
8866                               satIOContext->pTiSenseData,
8867                               satIOContext->interruptContext );
8868 
8869     TI_DBG1(("satFormatUnit: return cmplist\n"));
8870     return tiSuccess;
8871 
8872   }
8873 
8874  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8875   {
8876     satSetSensePayload( pSense,
8877                         SCSI_SNSKEY_ILLEGAL_REQUEST,
8878                         0,
8879                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8880                         satIOContext);
8881 
8882     ostiInitiatorIOCompleted( tiRoot,
8883                               tiIORequest,
8884                               tiIOSuccess,
8885                               SCSI_STAT_CHECK_CONDITION,
8886                               satIOContext->pTiSenseData,
8887                               satIOContext->interruptContext );
8888 
8889     TI_DBG1(("satFormatUnit: return control\n"));
8890     return tiSuccess;
8891   }
8892 
8893   /* defect list header filed, if exists, SAT rev8, Table 37, p48 */
8894   if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK)
8895   {
8896     /* case 1,2,3 */
8897     /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */
8898     if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) ||
8899          ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) ||
8900          ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8901            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8902            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK))
8903          )
8904     {
8905       ostiInitiatorIOCompleted( tiRoot,
8906                                 tiIORequest,
8907                                 tiIOSuccess,
8908                                 SCSI_STAT_GOOD,
8909                                 agNULL,
8910                                 satIOContext->interruptContext);
8911 
8912       TI_DBG5(("satFormatUnit: return defect list case 1\n"));
8913       return tiSuccess;
8914     }
8915     /* case 4,5,6 */
8916     /*
8917         1. IMMED 0, FOV 1, DCRT 0, IP 0
8918         2. IMMED 0, FOV 1, DCRT 0, IP 1
8919         3. IMMED 0, FOV 1, DCRT 1, IP 1
8920       */
8921 
8922     if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8923             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8924            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8925            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8926          ||
8927          ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8928             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8929            !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8930             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8931          ||
8932          ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8933             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8934             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8935             (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8936          )
8937     {
8938 
8939       satSetSensePayload( pSense,
8940                           SCSI_SNSKEY_ILLEGAL_REQUEST,
8941                           0,
8942                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
8943                           satIOContext);
8944 
8945       ostiInitiatorIOCompleted( tiRoot,
8946                                 tiIORequest,
8947                                 tiIOSuccess,
8948                                 SCSI_STAT_CHECK_CONDITION,
8949                                 satIOContext->pTiSenseData,
8950                                 satIOContext->interruptContext );
8951 
8952       TI_DBG5(("satFormatUnit: return defect list case 2\n"));
8953       return tiSuccess;
8954 
8955     }
8956   }
8957 
8958 
8959   /*
8960    * Send the completion response now.
8961    */
8962   ostiInitiatorIOCompleted( tiRoot,
8963                             tiIORequest,
8964                             tiIOSuccess,
8965                             SCSI_STAT_GOOD,
8966                             agNULL,
8967                             satIOContext->interruptContext);
8968 
8969   TI_DBG5(("satFormatUnit: return last\n"));
8970   return tiSuccess;
8971 }
8972 
8973 
8974 /*****************************************************************************/
8975 /*! \brief SAT implementation for SCSI satSendDiagnostic.
8976  *
8977  *  SAT implementation for SCSI satSendDiagnostic.
8978  *
8979  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8980  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8981  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8982  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8983  *  \param   satIOContext_t:   Pointer to the SAT IO Context
8984  *
8985  *  \return If command is started successfully
8986  *    - \e tiSuccess:     I/O request successfully initiated.
8987  *    - \e tiBusy:        No resources available, try again later.
8988  *    - \e tiIONoDevice:  Invalid device handle.
8989  *    - \e tiError:       Other errors.
8990  */
8991 /*****************************************************************************/
8992 GLOBAL bit32  satSendDiagnostic(
8993                    tiRoot_t                  *tiRoot,
8994                    tiIORequest_t             *tiIORequest,
8995                    tiDeviceHandle_t          *tiDeviceHandle,
8996                    tiScsiInitiatorRequest_t *tiScsiRequest,
8997                    satIOContext_t            *satIOContext)
8998 {
8999   bit32                     status;
9000   bit32                     agRequestType;
9001   satDeviceData_t           *pSatDevData;
9002   scsiRspSense_t            *pSense;
9003   tiIniScsiCmnd_t           *scsiCmnd;
9004   agsaFisRegHostToDevice_t  *fis;
9005   bit32                     parmLen;
9006 
9007   pSense        = satIOContext->pSense;
9008   pSatDevData   = satIOContext->pSatDevData;
9009   scsiCmnd      = &tiScsiRequest->scsiCmnd;
9010   fis           = satIOContext->pFis;
9011 
9012   TI_DBG5(("satSendDiagnostic:start\n"));
9013 
9014   /* reset satVerifyState */
9015   pSatDevData->satVerifyState = 0;
9016   /* no pending diagnostic in background */
9017   pSatDevData->satBGPendingDiag = agFALSE;
9018 
9019   /* table 27, 8.10 p39 SAT Rev8 */
9020   /*
9021     1. checking PF == 1
9022     2. checking DEVOFFL == 1
9023     3. checking UNITOFFL == 1
9024     4. checking PARAMETER LIST LENGTH != 0
9025 
9026   */
9027   if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) ||
9028        (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) ||
9029        (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) ||
9030        ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) )
9031        )
9032   {
9033     satSetSensePayload( pSense,
9034                         SCSI_SNSKEY_ILLEGAL_REQUEST,
9035                         0,
9036                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9037                         satIOContext);
9038 
9039     ostiInitiatorIOCompleted( tiRoot,
9040                               tiIORequest,
9041                               tiIOSuccess,
9042                               SCSI_STAT_CHECK_CONDITION,
9043                               satIOContext->pTiSenseData,
9044                               satIOContext->interruptContext );
9045 
9046     TI_DBG1(("satSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST\n"));
9047     return tiSuccess;
9048   }
9049 
9050   /* checking CONTROL */
9051   /* NACA == 1 or LINK == 1*/
9052   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9053   {
9054     satSetSensePayload( pSense,
9055                         SCSI_SNSKEY_ILLEGAL_REQUEST,
9056                         0,
9057                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9058                         satIOContext);
9059 
9060     ostiInitiatorIOCompleted( tiRoot,
9061                               tiIORequest,
9062                               tiIOSuccess,
9063                               SCSI_STAT_CHECK_CONDITION,
9064                               satIOContext->pTiSenseData,
9065                               satIOContext->interruptContext );
9066 
9067     TI_DBG2(("satSendDiagnostic: return control\n"));
9068     return tiSuccess;
9069   }
9070 
9071   parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
9072 
9073   /* checking SELFTEST bit*/
9074   /* table 29, 8.10.3, p41 SAT Rev8 */
9075   /* case 1 */
9076   if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9077        (pSatDevData->satSMARTSelfTest == agFALSE)
9078        )
9079   {
9080     satSetSensePayload( pSense,
9081                         SCSI_SNSKEY_ILLEGAL_REQUEST,
9082                         0,
9083                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9084                         satIOContext);
9085 
9086     ostiInitiatorIOCompleted( tiRoot,
9087                               tiIORequest,
9088                               tiIOSuccess,
9089                               SCSI_STAT_CHECK_CONDITION,
9090                               satIOContext->pTiSenseData,
9091                               satIOContext->interruptContext );
9092 
9093     TI_DBG1(("satSendDiagnostic: return Table 29 case 1\n"));
9094     return tiSuccess;
9095   }
9096 
9097   /* case 2 */
9098   if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9099        (pSatDevData->satSMARTSelfTest == agTRUE) &&
9100        (pSatDevData->satSMARTEnabled == agFALSE)
9101        )
9102   {
9103     satSetSensePayload( pSense,
9104                         SCSI_SNSKEY_ABORTED_COMMAND,
9105                         0,
9106                         SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
9107                         satIOContext);
9108 
9109     ostiInitiatorIOCompleted( tiRoot,
9110                               tiIORequest,
9111                               tiIOSuccess,
9112                               SCSI_STAT_CHECK_CONDITION,
9113                               satIOContext->pTiSenseData,
9114                               satIOContext->interruptContext );
9115 
9116     TI_DBG5(("satSendDiagnostic: return Table 29 case 2\n"));
9117     return tiSuccess;
9118   }
9119   /*
9120     case 3
9121      see SELF TEST CODE later
9122   */
9123 
9124 
9125 
9126   /* case 4 */
9127 
9128   /*
9129     sends three ATA verify commands
9130 
9131   */
9132   if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9133         (pSatDevData->satSMARTSelfTest == agFALSE))
9134        ||
9135        ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9136         (pSatDevData->satSMARTSelfTest == agTRUE) &&
9137         (pSatDevData->satSMARTEnabled == agFALSE))
9138        )
9139   {
9140     /*
9141       sector count 1, LBA 0
9142       sector count 1, LBA MAX
9143       sector count 1, LBA random
9144     */
9145     if (pSatDevData->sat48BitSupport == agTRUE)
9146     {
9147       /* sends READ VERIFY SECTOR(S) EXT*/
9148       fis->h.fisType        = 0x27;                   /* Reg host to device */
9149       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9150       fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9151       fis->h.features       = 0;                      /* FIS reserve */
9152       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9153       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9154       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9155       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9156       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9157       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9158       fis->d.featuresExp    = 0;                      /* FIS reserve */
9159       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9160       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9161       fis->d.reserved4      = 0;
9162       fis->d.device         = 0x40;                   /* 01000000 */
9163       fis->d.control        = 0;                      /* FIS HOB bit clear */
9164       fis->d.reserved5      = 0;
9165 
9166       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9167     }
9168     else
9169     {
9170       /* READ VERIFY SECTOR(S)*/
9171       fis->h.fisType        = 0x27;                   /* Reg host to device */
9172       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9173       fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9174       fis->h.features       = 0;                      /* FIS features NA       */
9175       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9176       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9177       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9178       fis->d.lbaLowExp      = 0;
9179       fis->d.lbaMidExp      = 0;
9180       fis->d.lbaHighExp     = 0;
9181       fis->d.featuresExp    = 0;
9182       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9183       fis->d.sectorCountExp = 0;
9184       fis->d.reserved4      = 0;
9185       fis->d.device         = 0x40;                   /* 01000000 */
9186       fis->d.control        = 0;                      /* FIS HOB bit clear */
9187       fis->d.reserved5      = 0;
9188 
9189       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9190     }
9191 
9192     /* Initialize CB for SATA completion.
9193      */
9194     satIOContext->satCompleteCB = &satSendDiagnosticCB;
9195 
9196     /*
9197      * Prepare SGL and send FIS to LL layer.
9198      */
9199     satIOContext->reqType = agRequestType;       /* Save it */
9200 
9201     status = sataLLIOStart( tiRoot,
9202                             tiIORequest,
9203                             tiDeviceHandle,
9204                             tiScsiRequest,
9205                             satIOContext);
9206 
9207 
9208     TI_DBG5(("satSendDiagnostic: return Table 29 case 4\n"));
9209     return (status);
9210   }
9211   /* case 5 */
9212   if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9213        (pSatDevData->satSMARTSelfTest == agTRUE) &&
9214        (pSatDevData->satSMARTEnabled == agTRUE)
9215        )
9216   {
9217     /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9218     fis->h.fisType        = 0x27;                   /* Reg host to device */
9219     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9220     fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0xB0 */
9221     fis->h.features       = 0xD4;                      /* FIS features NA       */
9222     fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
9223     fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9224     fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9225     fis->d.lbaLowExp      = 0;
9226     fis->d.lbaMidExp      = 0;
9227     fis->d.lbaHighExp     = 0;
9228     fis->d.featuresExp    = 0;
9229     fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9230     fis->d.sectorCountExp = 0;
9231     fis->d.reserved4      = 0;
9232     fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9233     fis->d.control        = 0;                         /* FIS HOB bit clear */
9234     fis->d.reserved5      = 0;
9235 
9236     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9237 
9238     /* Initialize CB for SATA completion.
9239      */
9240     satIOContext->satCompleteCB = &satSendDiagnosticCB;
9241 
9242     /*
9243      * Prepare SGL and send FIS to LL layer.
9244      */
9245     satIOContext->reqType = agRequestType;       /* Save it */
9246 
9247     status = sataLLIOStart( tiRoot,
9248                             tiIORequest,
9249                             tiDeviceHandle,
9250                             tiScsiRequest,
9251                             satIOContext);
9252 
9253 
9254     TI_DBG5(("satSendDiagnostic: return Table 29 case 5\n"));
9255     return (status);
9256   }
9257 
9258 
9259 
9260 
9261   /* SAT rev8 Table29 p41 case 3*/
9262   /* checking SELF TEST CODE*/
9263   if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9264        (pSatDevData->satSMARTSelfTest == agTRUE) &&
9265        (pSatDevData->satSMARTEnabled == agTRUE)
9266        )
9267   {
9268     /* SAT rev8 Table28 p40 */
9269     /* finding self-test code */
9270     switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5)
9271     {
9272     case 1:
9273       pSatDevData->satBGPendingDiag = agTRUE;
9274 
9275       ostiInitiatorIOCompleted( tiRoot,
9276                                 tiIORequest,
9277                                 tiIOSuccess,
9278                                 SCSI_STAT_GOOD,
9279                                 agNULL,
9280                                 satIOContext->interruptContext );
9281       /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9282       fis->h.fisType        = 0x27;                   /* Reg host to device */
9283       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9284       fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9285       fis->h.features       = 0xD4;                      /* FIS features NA       */
9286       fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
9287       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9288       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9289 
9290       fis->d.lbaLowExp      = 0;
9291       fis->d.lbaMidExp      = 0;
9292       fis->d.lbaHighExp     = 0;
9293       fis->d.featuresExp    = 0;
9294       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9295       fis->d.sectorCountExp = 0;
9296       fis->d.reserved4      = 0;
9297       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9298       fis->d.control        = 0;                         /* FIS HOB bit clear */
9299       fis->d.reserved5      = 0;
9300 
9301       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9302 
9303       /* Initialize CB for SATA completion.
9304        */
9305       satIOContext->satCompleteCB = &satSendDiagnosticCB;
9306 
9307       /*
9308        * Prepare SGL and send FIS to LL layer.
9309        */
9310       satIOContext->reqType = agRequestType;       /* Save it */
9311 
9312       status = sataLLIOStart( tiRoot,
9313                               tiIORequest,
9314                               tiDeviceHandle,
9315                               tiScsiRequest,
9316                               satIOContext);
9317 
9318 
9319       TI_DBG5(("satSendDiagnostic: return Table 28 case 1\n"));
9320       return (status);
9321     case 2:
9322       pSatDevData->satBGPendingDiag = agTRUE;
9323 
9324       ostiInitiatorIOCompleted( tiRoot,
9325                                 tiIORequest,
9326                                 tiIOSuccess,
9327                                 SCSI_STAT_GOOD,
9328                                 agNULL,
9329                                 satIOContext->interruptContext );
9330 
9331 
9332       /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9333       fis->h.fisType        = 0x27;                   /* Reg host to device */
9334       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9335       fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9336       fis->h.features       = 0xD4;                      /* FIS features NA       */
9337       fis->d.lbaLow         = 0x02;                      /* FIS LBA (7 :0 ) */
9338       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9339       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9340       fis->d.lbaLowExp      = 0;
9341       fis->d.lbaMidExp      = 0;
9342       fis->d.lbaHighExp     = 0;
9343       fis->d.featuresExp    = 0;
9344       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9345       fis->d.sectorCountExp = 0;
9346       fis->d.reserved4      = 0;
9347       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9348       fis->d.control        = 0;                         /* FIS HOB bit clear */
9349       fis->d.reserved5      = 0;
9350 
9351       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9352 
9353       /* Initialize CB for SATA completion.
9354        */
9355       satIOContext->satCompleteCB = &satSendDiagnosticCB;
9356 
9357       /*
9358        * Prepare SGL and send FIS to LL layer.
9359        */
9360       satIOContext->reqType = agRequestType;       /* Save it */
9361 
9362       status = sataLLIOStart( tiRoot,
9363                               tiIORequest,
9364                               tiDeviceHandle,
9365                               tiScsiRequest,
9366                               satIOContext);
9367 
9368 
9369       TI_DBG5(("satSendDiagnostic: return Table 28 case 2\n"));
9370       return (status);
9371     case 4:
9372       /* For simplicity, no abort is supported
9373          Returns good status
9374          need a flag in device data for previously sent background Send Diagnostic
9375       */
9376       if (parmLen != 0)
9377       {
9378         /* check condition */
9379         satSetSensePayload( pSense,
9380                             SCSI_SNSKEY_ILLEGAL_REQUEST,
9381                             0,
9382                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9383                             satIOContext);
9384 
9385         ostiInitiatorIOCompleted( tiRoot,
9386                                   tiIORequest,
9387                                   tiIOSuccess,
9388                                   SCSI_STAT_CHECK_CONDITION,
9389                                   satIOContext->pTiSenseData,
9390                                   satIOContext->interruptContext );
9391 
9392         TI_DBG1(("satSendDiagnostic: case 4, non zero ParmLen %d\n", parmLen));
9393         return tiSuccess;
9394       }
9395       if (pSatDevData->satBGPendingDiag == agTRUE)
9396       {
9397         /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */
9398         fis->h.fisType        = 0x27;                   /* Reg host to device */
9399         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9400         fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9401         fis->h.features       = 0xD4;                      /* FIS features NA       */
9402         fis->d.lbaLow         = 0x7F;                      /* FIS LBA (7 :0 ) */
9403         fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9404         fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9405 
9406         fis->d.lbaLowExp      = 0;
9407         fis->d.lbaMidExp      = 0;
9408         fis->d.lbaHighExp     = 0;
9409         fis->d.featuresExp    = 0;
9410         fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9411         fis->d.sectorCountExp = 0;
9412         fis->d.reserved4      = 0;
9413         fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9414         fis->d.control        = 0;                         /* FIS HOB bit clear */
9415         fis->d.reserved5      = 0;
9416 
9417         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9418 
9419         /* Initialize CB for SATA completion.
9420          */
9421         satIOContext->satCompleteCB = &satSendDiagnosticCB;
9422 
9423         /*
9424          * Prepare SGL and send FIS to LL layer.
9425          */
9426         satIOContext->reqType = agRequestType;       /* Save it */
9427 
9428         status = sataLLIOStart( tiRoot,
9429                                 tiIORequest,
9430                                 tiDeviceHandle,
9431                                 tiScsiRequest,
9432                                 satIOContext);
9433 
9434 
9435         TI_DBG5(("satSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
9436         TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9437         return (status);
9438       }
9439       else
9440       {
9441         /* check condition */
9442         satSetSensePayload( pSense,
9443                             SCSI_SNSKEY_ILLEGAL_REQUEST,
9444                             0,
9445                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9446                             satIOContext);
9447 
9448         ostiInitiatorIOCompleted( tiRoot,
9449                                   tiIORequest,
9450                                   tiIOSuccess,
9451                                   SCSI_STAT_CHECK_CONDITION,
9452                                   satIOContext->pTiSenseData,
9453                                   satIOContext->interruptContext );
9454 
9455         TI_DBG1(("satSendDiagnostic: case 4, no pending diagnostic in background\n"));
9456         TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9457         return tiSuccess;
9458       }
9459       break;
9460     case 5:
9461       /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9462       fis->h.fisType        = 0x27;                   /* Reg host to device */
9463       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9464       fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9465       fis->h.features       = 0xD4;                      /* FIS features NA       */
9466       fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
9467       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9468       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9469       fis->d.lbaLowExp      = 0;
9470       fis->d.lbaMidExp      = 0;
9471       fis->d.lbaHighExp     = 0;
9472       fis->d.featuresExp    = 0;
9473       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9474       fis->d.sectorCountExp = 0;
9475       fis->d.reserved4      = 0;
9476       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9477       fis->d.control        = 0;                         /* FIS HOB bit clear */
9478       fis->d.reserved5      = 0;
9479 
9480       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9481 
9482       /* Initialize CB for SATA completion.
9483        */
9484       satIOContext->satCompleteCB = &satSendDiagnosticCB;
9485 
9486       /*
9487        * Prepare SGL and send FIS to LL layer.
9488        */
9489       satIOContext->reqType = agRequestType;       /* Save it */
9490 
9491       status = sataLLIOStart( tiRoot,
9492                               tiIORequest,
9493                               tiDeviceHandle,
9494                               tiScsiRequest,
9495                               satIOContext);
9496 
9497 
9498       TI_DBG5(("satSendDiagnostic: return Table 28 case 5\n"));
9499       return (status);
9500     case 6:
9501       /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9502       fis->h.fisType        = 0x27;                   /* Reg host to device */
9503       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9504       fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9505       fis->h.features       = 0xD4;                      /* FIS features NA       */
9506       fis->d.lbaLow         = 0x82;                      /* FIS LBA (7 :0 ) */
9507       fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9508       fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9509       fis->d.lbaLowExp      = 0;
9510       fis->d.lbaMidExp      = 0;
9511       fis->d.lbaHighExp     = 0;
9512       fis->d.featuresExp    = 0;
9513       fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9514       fis->d.sectorCountExp = 0;
9515       fis->d.reserved4      = 0;
9516       fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9517       fis->d.control        = 0;                         /* FIS HOB bit clear */
9518       fis->d.reserved5      = 0;
9519 
9520       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9521 
9522       /* Initialize CB for SATA completion.
9523        */
9524       satIOContext->satCompleteCB = &satSendDiagnosticCB;
9525 
9526       /*
9527        * Prepare SGL and send FIS to LL layer.
9528        */
9529       satIOContext->reqType = agRequestType;       /* Save it */
9530 
9531       status = sataLLIOStart( tiRoot,
9532                               tiIORequest,
9533                               tiDeviceHandle,
9534                               tiScsiRequest,
9535                               satIOContext);
9536 
9537 
9538       TI_DBG5(("satSendDiagnostic: return Table 28 case 6\n"));
9539       return (status);
9540     case 0:
9541     case 3: /* fall through */
9542     case 7: /* fall through */
9543     default:
9544       break;
9545     }/* switch */
9546 
9547     /* returns the results of default self-testing, which is good */
9548     ostiInitiatorIOCompleted( tiRoot,
9549                               tiIORequest,
9550                               tiIOSuccess,
9551                               SCSI_STAT_GOOD,
9552                               agNULL,
9553                               satIOContext->interruptContext );
9554 
9555     TI_DBG5(("satSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
9556     return tiSuccess;
9557   }
9558 
9559 
9560   ostiInitiatorIOCompleted( tiRoot,
9561                             tiIORequest,
9562                             tiIOSuccess,
9563                             SCSI_STAT_GOOD,
9564                             agNULL,
9565                             satIOContext->interruptContext );
9566 
9567 
9568   TI_DBG5(("satSendDiagnostic: return last\n"));
9569   return tiSuccess;
9570 }
9571 
9572 /*****************************************************************************/
9573 /*! \brief SAT implementation for SCSI satSendDiagnostic_1.
9574  *
9575  *  SAT implementation for SCSI satSendDiagnostic_1.
9576  *  Sub function of satSendDiagnostic.
9577  *
9578  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
9579  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
9580  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
9581  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
9582  *  \param   satIOContext_t:   Pointer to the SAT IO Context
9583  *
9584  *  \return If command is started successfully
9585  *    - \e tiSuccess:     I/O request successfully initiated.
9586  *    - \e tiBusy:        No resources available, try again later.
9587  *    - \e tiIONoDevice:  Invalid device handle.
9588  *    - \e tiError:       Other errors.
9589  */
9590 /*****************************************************************************/
9591 GLOBAL bit32  satSendDiagnostic_1(
9592                    tiRoot_t                  *tiRoot,
9593                    tiIORequest_t             *tiIORequest,
9594                    tiDeviceHandle_t          *tiDeviceHandle,
9595                    tiScsiInitiatorRequest_t *tiScsiRequest,
9596                    satIOContext_t            *satIOContext)
9597 {
9598   /*
9599     SAT Rev9, Table29, p41
9600     send 2nd SAT_READ_VERIFY_SECTORS(_EXT)
9601   */
9602   bit32                     status;
9603   bit32                     agRequestType;
9604   satDeviceData_t           *pSatDevData;
9605   agsaFisRegHostToDevice_t  *fis;
9606 
9607   TI_DBG5(("satSendDiagnostic_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9608       tiDeviceHandle, tiIORequest));
9609 
9610   pSatDevData       = satIOContext->pSatDevData;
9611   fis               = satIOContext->pFis;
9612 
9613   /*
9614     sector count 1, LBA MAX
9615   */
9616   if (pSatDevData->sat48BitSupport == agTRUE)
9617   {
9618     /* sends READ VERIFY SECTOR(S) EXT*/
9619     fis->h.fisType        = 0x27;                   /* Reg host to device */
9620     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9621     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9622     fis->h.features       = 0;                      /* FIS reserve */
9623     fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9624     fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9625     fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9626     fis->d.lbaLowExp      = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */
9627     fis->d.lbaMidExp      = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */
9628     fis->d.lbaHighExp     = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */
9629     fis->d.featuresExp    = 0;                      /* FIS reserve */
9630     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9631     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9632     fis->d.reserved4      = 0;
9633     fis->d.device         = 0x40;                   /* 01000000 */
9634     fis->d.control        = 0;                      /* FIS HOB bit clear */
9635     fis->d.reserved5      = 0;
9636 
9637   }
9638   else
9639   {
9640     /* READ VERIFY SECTOR(S)*/
9641     fis->h.fisType        = 0x27;                   /* Reg host to device */
9642     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9643     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9644     fis->h.features       = 0;                      /* FIS features NA       */
9645     fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9646     fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9647     fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9648     fis->d.lbaLowExp      = 0;
9649     fis->d.lbaMidExp      = 0;
9650     fis->d.lbaHighExp     = 0;
9651     fis->d.featuresExp    = 0;
9652     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9653     fis->d.sectorCountExp = 0;
9654     fis->d.reserved4      = 0;
9655     fis->d.device         = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF));
9656                             /* DEV and LBA 27:24 */
9657     fis->d.control        = 0;                      /* FIS HOB bit clear */
9658     fis->d.reserved5      = 0;
9659 
9660   }
9661 
9662   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9663 
9664   /* Initialize CB for SATA completion.
9665    */
9666   satIOContext->satCompleteCB = &satSendDiagnosticCB;
9667 
9668   /*
9669    * Prepare SGL and send FIS to LL layer.
9670    */
9671   satIOContext->reqType = agRequestType;       /* Save it */
9672 
9673   status = sataLLIOStart( tiRoot,
9674                           tiIORequest,
9675                           tiDeviceHandle,
9676                           tiScsiRequest,
9677                           satIOContext);
9678 
9679 
9680   return status;
9681 }
9682 
9683 /*****************************************************************************/
9684 /*! \brief SAT implementation for SCSI satSendDiagnostic_2.
9685  *
9686  *  SAT implementation for SCSI satSendDiagnostic_2.
9687  *  Sub function of satSendDiagnostic.
9688  *
9689  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
9690  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
9691  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
9692  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
9693  *  \param   satIOContext_t:   Pointer to the SAT IO Context
9694  *
9695  *  \return If command is started successfully
9696  *    - \e tiSuccess:     I/O request successfully initiated.
9697  *    - \e tiBusy:        No resources available, try again later.
9698  *    - \e tiIONoDevice:  Invalid device handle.
9699  *    - \e tiError:       Other errors.
9700  */
9701 /*****************************************************************************/
9702 GLOBAL bit32  satSendDiagnostic_2(
9703                    tiRoot_t                  *tiRoot,
9704                    tiIORequest_t             *tiIORequest,
9705                    tiDeviceHandle_t          *tiDeviceHandle,
9706                    tiScsiInitiatorRequest_t *tiScsiRequest,
9707                    satIOContext_t            *satIOContext)
9708 {
9709   /*
9710     SAT Rev9, Table29, p41
9711     send 3rd SAT_READ_VERIFY_SECTORS(_EXT)
9712   */
9713   bit32                     status;
9714   bit32                     agRequestType;
9715   satDeviceData_t           *pSatDevData;
9716   agsaFisRegHostToDevice_t  *fis;
9717 
9718   TI_DBG5(("satSendDiagnostic_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9719       tiDeviceHandle, tiIORequest));
9720 
9721   pSatDevData       = satIOContext->pSatDevData;
9722   fis               = satIOContext->pFis;
9723 
9724   /*
9725     sector count 1, LBA Random
9726   */
9727   if (pSatDevData->sat48BitSupport == agTRUE)
9728   {
9729     /* sends READ VERIFY SECTOR(S) EXT*/
9730     fis->h.fisType        = 0x27;                   /* Reg host to device */
9731     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9732     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9733     fis->h.features       = 0;                      /* FIS reserve */
9734     fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
9735     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9736     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9737     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9738     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9739     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9740     fis->d.featuresExp    = 0;                      /* FIS reserve */
9741     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9742     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9743     fis->d.reserved4      = 0;
9744     fis->d.device         = 0x40;                   /* 01000000 */
9745     fis->d.control        = 0;                      /* FIS HOB bit clear */
9746     fis->d.reserved5      = 0;
9747 
9748   }
9749   else
9750   {
9751     /* READ VERIFY SECTOR(S)*/
9752     fis->h.fisType        = 0x27;                   /* Reg host to device */
9753     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9754     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9755     fis->h.features       = 0;                      /* FIS features NA       */
9756     fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
9757     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9758     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9759     fis->d.lbaLowExp      = 0;
9760     fis->d.lbaMidExp      = 0;
9761     fis->d.lbaHighExp     = 0;
9762     fis->d.featuresExp    = 0;
9763     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9764     fis->d.sectorCountExp = 0;
9765     fis->d.reserved4      = 0;
9766     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
9767     fis->d.control        = 0;                      /* FIS HOB bit clear */
9768     fis->d.reserved5      = 0;
9769 
9770   }
9771 
9772   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9773 
9774   /* Initialize CB for SATA completion.
9775    */
9776   satIOContext->satCompleteCB = &satSendDiagnosticCB;
9777 
9778   /*
9779    * Prepare SGL and send FIS to LL layer.
9780    */
9781   satIOContext->reqType = agRequestType;       /* Save it */
9782 
9783   status = sataLLIOStart( tiRoot,
9784                           tiIORequest,
9785                           tiDeviceHandle,
9786                           tiScsiRequest,
9787                           satIOContext);
9788 
9789 
9790   return status;
9791 }
9792 /*****************************************************************************/
9793 /*! \brief SAT implementation for SCSI satStartStopUnit.
9794  *
9795  *  SAT implementation for SCSI satStartStopUnit.
9796  *
9797  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
9798  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
9799  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
9800  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
9801  *  \param   satIOContext_t:   Pointer to the SAT IO Context
9802  *
9803  *  \return If command is started successfully
9804  *    - \e tiSuccess:     I/O request successfully initiated.
9805  *    - \e tiBusy:        No resources available, try again later.
9806  *    - \e tiIONoDevice:  Invalid device handle.
9807  *    - \e tiError:       Other errors.
9808  */
9809 /*****************************************************************************/
9810 GLOBAL bit32  satStartStopUnit(
9811                    tiRoot_t                  *tiRoot,
9812                    tiIORequest_t             *tiIORequest,
9813                    tiDeviceHandle_t          *tiDeviceHandle,
9814                    tiScsiInitiatorRequest_t *tiScsiRequest,
9815                    satIOContext_t            *satIOContext)
9816 {
9817   bit32                     status;
9818   bit32                     agRequestType;
9819   satDeviceData_t           *pSatDevData;
9820   scsiRspSense_t            *pSense;
9821   tiIniScsiCmnd_t           *scsiCmnd;
9822   agsaFisRegHostToDevice_t  *fis;
9823 
9824   pSense        = satIOContext->pSense;
9825   pSatDevData   = satIOContext->pSatDevData;
9826   scsiCmnd      = &tiScsiRequest->scsiCmnd;
9827   fis           = satIOContext->pFis;
9828 
9829   TI_DBG5(("satStartStopUnit:start\n"));
9830 
9831   /* checking CONTROL */
9832   /* NACA == 1 or LINK == 1*/
9833   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9834   {
9835     satSetSensePayload( pSense,
9836                         SCSI_SNSKEY_ILLEGAL_REQUEST,
9837                         0,
9838                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9839                         satIOContext);
9840 
9841     ostiInitiatorIOCompleted( tiRoot,
9842                               tiIORequest,
9843                               tiIOSuccess,
9844                               SCSI_STAT_CHECK_CONDITION,
9845                               satIOContext->pTiSenseData,
9846                               satIOContext->interruptContext );
9847 
9848     TI_DBG1(("satStartStopUnit: return control\n"));
9849     return tiSuccess;
9850   }
9851 
9852   /* Spec p55, Table 48 checking START and LOEJ bit */
9853   /* case 1 */
9854   if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9855   {
9856     if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9857     {
9858       /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9859       ostiInitiatorIOCompleted( tiRoot,
9860                                 tiIORequest,
9861                                 tiIOSuccess,
9862                                 SCSI_STAT_GOOD,
9863                                 agNULL,
9864                                 satIOContext->interruptContext );
9865       TI_DBG5(("satStartStopUnit: return table48 case 1-1\n"));
9866       return tiSuccess;
9867     }
9868     /* sends FLUSH CACHE or FLUSH CACHE EXT */
9869     if (pSatDevData->sat48BitSupport == agTRUE)
9870     {
9871       /* FLUSH CACHE EXT */
9872       fis->h.fisType        = 0x27;                   /* Reg host to device */
9873       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9874 
9875       fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
9876       fis->h.features       = 0;                      /* FIS reserve */
9877       fis->d.featuresExp    = 0;                      /* FIS reserve */
9878       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9879       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9880       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9881       fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9882       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9883       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9884       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9885       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9886       fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
9887       fis->d.control        = 0;                      /* FIS HOB bit clear */
9888       fis->d.reserved4      = 0;
9889       fis->d.reserved5      = 0;
9890 
9891       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9892     }
9893     else
9894     {
9895       /* FLUSH CACHE */
9896       fis->h.fisType        = 0x27;                   /* Reg host to device */
9897       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9898 
9899       fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
9900       fis->h.features       = 0;                      /* FIS features NA       */
9901       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9902       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9903       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9904       fis->d.lbaLowExp      = 0;
9905       fis->d.lbaMidExp      = 0;
9906       fis->d.lbaHighExp     = 0;
9907       fis->d.featuresExp    = 0;
9908       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9909       fis->d.sectorCountExp = 0;
9910       fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
9911       fis->d.control        = 0;                      /* FIS HOB bit clear */
9912       fis->d.reserved4      = 0;
9913       fis->d.reserved5      = 0;
9914 
9915       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9916     }
9917 
9918     /* Initialize CB for SATA completion.
9919      */
9920     satIOContext->satCompleteCB = &satStartStopUnitCB;
9921 
9922     /*
9923      * Prepare SGL and send FIS to LL layer.
9924      */
9925     satIOContext->reqType = agRequestType;       /* Save it */
9926 
9927     status = sataLLIOStart( tiRoot,
9928                             tiIORequest,
9929                             tiDeviceHandle,
9930                             tiScsiRequest,
9931                             satIOContext);
9932 
9933 
9934     TI_DBG5(("satStartStopUnit: return table48 case 1\n"));
9935     return (status);
9936   }
9937   /* case 2 */
9938   else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9939   {
9940     /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9941     if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9942     {
9943       ostiInitiatorIOCompleted( tiRoot,
9944                                 tiIORequest,
9945                                 tiIOSuccess,
9946                                 SCSI_STAT_GOOD,
9947                                 agNULL,
9948                                 satIOContext->interruptContext );
9949 
9950       TI_DBG5(("satStartStopUnit: return table48 case 2 1\n"));
9951       return tiSuccess;
9952     }
9953     /*
9954       sends READ_VERIFY_SECTORS(_EXT)
9955       sector count 1, any LBA between zero to Maximum
9956     */
9957     if (pSatDevData->sat48BitSupport == agTRUE)
9958     {
9959       /* READ VERIFY SECTOR(S) EXT*/
9960       fis->h.fisType        = 0x27;                   /* Reg host to device */
9961       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9962 
9963       fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9964       fis->h.features       = 0;                      /* FIS reserve */
9965       fis->d.lbaLow         = 0x01;                   /* FIS LBA (7 :0 ) */
9966       fis->d.lbaMid         = 0x00;                   /* FIS LBA (15:8 ) */
9967       fis->d.lbaHigh        = 0x00;                   /* FIS LBA (23:16) */
9968       fis->d.lbaLowExp      = 0x00;                   /* FIS LBA (31:24) */
9969       fis->d.lbaMidExp      = 0x00;                   /* FIS LBA (39:32) */
9970       fis->d.lbaHighExp     = 0x00;                   /* FIS LBA (47:40) */
9971       fis->d.featuresExp    = 0;                      /* FIS reserve */
9972       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9973       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9974       fis->d.reserved4      = 0;
9975       fis->d.device         = 0x40;                   /* 01000000 */
9976       fis->d.control        = 0;                      /* FIS HOB bit clear */
9977       fis->d.reserved5      = 0;
9978 
9979     }
9980     else
9981     {
9982       /* READ VERIFY SECTOR(S)*/
9983       fis->h.fisType        = 0x27;                   /* Reg host to device */
9984       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9985 
9986       fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9987       fis->h.features       = 0;                      /* FIS features NA       */
9988       fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
9989       fis->d.lbaMid         = 0x00;                      /* FIS LBA (15:8 ) */
9990       fis->d.lbaHigh        = 0x00;                      /* FIS LBA (23:16) */
9991       fis->d.lbaLowExp      = 0;
9992       fis->d.lbaMidExp      = 0;
9993       fis->d.lbaHighExp     = 0;
9994       fis->d.featuresExp    = 0;
9995       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9996       fis->d.sectorCountExp = 0;
9997       fis->d.reserved4      = 0;
9998       fis->d.device         = 0x40;                   /* 01000000 */
9999       fis->d.control        = 0;                      /* FIS HOB bit clear */
10000       fis->d.reserved5      = 0;
10001 
10002     }
10003 
10004     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10005 
10006     /* Initialize CB for SATA completion.
10007      */
10008     satIOContext->satCompleteCB = &satStartStopUnitCB;
10009 
10010     /*
10011      * Prepare SGL and send FIS to LL layer.
10012      */
10013     satIOContext->reqType = agRequestType;       /* Save it */
10014 
10015     status = sataLLIOStart( tiRoot,
10016                             tiIORequest,
10017                             tiDeviceHandle,
10018                             tiScsiRequest,
10019                             satIOContext);
10020 
10021     TI_DBG5(("satStartStopUnit: return table48 case 2 2\n"));
10022     return status;
10023   }
10024   /* case 3 */
10025   else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
10026   {
10027     if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
10028     {
10029       /* support for removal media */
10030       /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
10031       if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
10032       {
10033         ostiInitiatorIOCompleted( tiRoot,
10034                                   tiIORequest,
10035                                   tiIOSuccess,
10036                                   SCSI_STAT_GOOD,
10037                                   agNULL,
10038                                   satIOContext->interruptContext );
10039 
10040         TI_DBG5(("satStartStopUnit: return table48 case 3 1\n"));
10041         return tiSuccess;
10042       }
10043       /*
10044         sends MEDIA EJECT
10045       */
10046       /* Media Eject fis */
10047       fis->h.fisType        = 0x27;                   /* Reg host to device */
10048       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10049 
10050       fis->h.command        = SAT_MEDIA_EJECT;        /* 0xED */
10051       fis->h.features       = 0;                      /* FIS features NA       */
10052       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
10053       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
10054       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
10055       fis->d.lbaLowExp      = 0;
10056       fis->d.lbaMidExp      = 0;
10057       fis->d.lbaHighExp     = 0;
10058       fis->d.featuresExp    = 0;
10059       /* sector count zero */
10060       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
10061       fis->d.sectorCountExp = 0;
10062       fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
10063       fis->d.control        = 0;                      /* FIS HOB bit clear */
10064       fis->d.reserved4      = 0;
10065       fis->d.reserved5      = 0;
10066 
10067       agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10068 
10069       /* Initialize CB for SATA completion.
10070        */
10071       satIOContext->satCompleteCB = &satStartStopUnitCB;
10072 
10073       /*
10074        * Prepare SGL and send FIS to LL layer.
10075        */
10076       satIOContext->reqType = agRequestType;       /* Save it */
10077 
10078       status = sataLLIOStart( tiRoot,
10079                               tiIORequest,
10080                               tiDeviceHandle,
10081                               tiScsiRequest,
10082                               satIOContext);
10083 
10084       return status;
10085     }
10086     else
10087     {
10088       /* no support for removal media */
10089       satSetSensePayload( pSense,
10090                           SCSI_SNSKEY_ILLEGAL_REQUEST,
10091                           0,
10092                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10093                           satIOContext);
10094 
10095       ostiInitiatorIOCompleted( tiRoot,
10096                                 tiIORequest,
10097                                 tiIOSuccess,
10098                                 SCSI_STAT_CHECK_CONDITION,
10099                                 satIOContext->pTiSenseData,
10100                                 satIOContext->interruptContext );
10101 
10102       TI_DBG5(("satStartStopUnit: return Table 29 case 3 2\n"));
10103       return tiSuccess;
10104     }
10105 
10106   }
10107   /* case 4 */
10108   else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */
10109   {
10110     satSetSensePayload( pSense,
10111                         SCSI_SNSKEY_ILLEGAL_REQUEST,
10112                         0,
10113                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10114                         satIOContext);
10115 
10116     ostiInitiatorIOCompleted( tiRoot,
10117                               tiIORequest,
10118                               tiIOSuccess,
10119                               SCSI_STAT_CHECK_CONDITION,
10120                               satIOContext->pTiSenseData,
10121                               satIOContext->interruptContext );
10122 
10123     TI_DBG5(("satStartStopUnit: return Table 29 case 4\n"));
10124     return tiSuccess;
10125   }
10126 
10127 
10128 }
10129 
10130 
10131 /*****************************************************************************/
10132 /*! \brief SAT implementation for SCSI satStartStopUnit_1.
10133  *
10134  *  SAT implementation for SCSI satStartStopUnit_1.
10135  *  Sub function of satStartStopUnit
10136  *
10137  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10138  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10139  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10140  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10141  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10142  *
10143  *  \return If command is started successfully
10144  *    - \e tiSuccess:     I/O request successfully initiated.
10145  *    - \e tiBusy:        No resources available, try again later.
10146  *    - \e tiIONoDevice:  Invalid device handle.
10147  *    - \e tiError:       Other errors.
10148  */
10149 /*****************************************************************************/
10150 GLOBAL bit32  satStartStopUnit_1(
10151                    tiRoot_t                  *tiRoot,
10152                    tiIORequest_t             *tiIORequest,
10153                    tiDeviceHandle_t          *tiDeviceHandle,
10154                    tiScsiInitiatorRequest_t *tiScsiRequest,
10155                    satIOContext_t            *satIOContext)
10156 {
10157   /*
10158     SAT Rev 8, Table 48, 9.11.3 p55
10159     sends STANDBY
10160   */
10161   bit32                     status;
10162   bit32                     agRequestType;
10163   agsaFisRegHostToDevice_t  *fis;
10164 
10165   TI_DBG5(("satStartStopUnit_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10166       tiDeviceHandle, tiIORequest));
10167 
10168   fis               = satIOContext->pFis;
10169 
10170   /* STANDBY */
10171   fis->h.fisType        = 0x27;                   /* Reg host to device */
10172   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10173 
10174   fis->h.command        = SAT_STANDBY;            /* 0xE2 */
10175   fis->h.features       = 0;                      /* FIS features NA       */
10176   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
10177   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
10178   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
10179   fis->d.lbaLowExp      = 0;
10180   fis->d.lbaMidExp      = 0;
10181   fis->d.lbaHighExp     = 0;
10182   fis->d.featuresExp    = 0;
10183   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
10184   fis->d.sectorCountExp = 0;
10185   fis->d.reserved4      = 0;
10186   fis->d.device         = 0;                      /* 0 */
10187   fis->d.control        = 0;                      /* FIS HOB bit clear */
10188   fis->d.reserved5      = 0;
10189 
10190   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10191 
10192   /* Initialize CB for SATA completion.
10193    */
10194   satIOContext->satCompleteCB = &satStartStopUnitCB;
10195 
10196   /*
10197    * Prepare SGL and send FIS to LL layer.
10198    */
10199   satIOContext->reqType = agRequestType;       /* Save it */
10200 
10201   status = sataLLIOStart( tiRoot,
10202                           tiIORequest,
10203                           tiDeviceHandle,
10204                           tiScsiRequest,
10205                           satIOContext);
10206 
10207   TI_DBG5(("satStartStopUnit_1 return status %d\n", status));
10208   return status;
10209 }
10210 
10211 /*****************************************************************************/
10212 /*! \brief SAT implementation for SCSI satRead10_2.
10213  *
10214  *  SAT implementation for SCSI satRead10_2
10215  *  Sub function of satRead10
10216  *
10217  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10218  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10219  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10220  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10221  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10222  *
10223  *  \return If command is started successfully
10224  *    - \e tiSuccess:     I/O request successfully initiated.
10225  *    - \e tiBusy:        No resources available, try again later.
10226  *    - \e tiIONoDevice:  Invalid device handle.
10227  *    - \e tiError:       Other errors.
10228  */
10229 /*****************************************************************************/
10230 GLOBAL bit32  satRead10_2(
10231                           tiRoot_t                  *tiRoot,
10232                           tiIORequest_t             *tiIORequest,
10233                           tiDeviceHandle_t          *tiDeviceHandle,
10234                           tiScsiInitiatorRequest_t *tiScsiRequest,
10235                           satIOContext_t            *satIOContext)
10236 {
10237   /*
10238     externally generated ATA cmd, there is corresponding scsi cmnd
10239     called by satStartStopUnit() or maybe satRead10()
10240    */
10241 
10242   bit32                     status;
10243   bit32                     agRequestType;
10244   satDeviceData_t           *pSatDevData;
10245   agsaFisRegHostToDevice_t  *fis;
10246 
10247   pSatDevData   = satIOContext->pSatDevData;
10248   fis           = satIOContext->pFis;
10249 
10250   TI_DBG5(("satReadVerifySectorsNoChain: start\n"));
10251 
10252   /* specifying ReadVerifySectors has no chain */
10253   pSatDevData->satVerifyState = 0xFFFFFFFF;
10254 
10255   if (pSatDevData->sat48BitSupport == agTRUE)
10256   {
10257     /* READ VERIFY SECTOR(S) EXT*/
10258     fis->h.fisType        = 0x27;                   /* Reg host to device */
10259     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10260     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
10261     fis->h.features       = 0;                      /* FIS reserve */
10262     fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
10263     fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
10264     fis->d.lbaHigh        = 0x00;                   /* FIS LBA (23:16) */
10265     fis->d.lbaLowExp      = 0xF1;                   /* FIS LBA (31:24) */
10266     fis->d.lbaMidExp      = 0x5F;                   /* FIS LBA (39:32) */
10267     fis->d.lbaHighExp     = 0xFF;                   /* FIS LBA (47:40) */
10268     fis->d.featuresExp    = 0;                      /* FIS reserve */
10269     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10270     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10271     fis->d.reserved4      = 0;
10272     fis->d.device         = 0x4E;                   /* 01001110 */
10273     fis->d.control        = 0;                      /* FIS HOB bit clear */
10274     fis->d.reserved5      = 0;
10275 
10276     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10277   }
10278   else
10279   {
10280     /* READ VERIFY SECTOR(S)*/
10281     fis->h.fisType        = 0x27;                   /* Reg host to device */
10282     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10283     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
10284     fis->h.features       = 0;                      /* FIS features NA       */
10285     fis->d.lbaLow         = 0x7F;                      /* FIS LBA (7 :0 ) */
10286     fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
10287     fis->d.lbaHigh        = 0x00;                      /* FIS LBA (23:16) */
10288     fis->d.lbaLowExp      = 0;
10289     fis->d.lbaMidExp      = 0;
10290     fis->d.lbaHighExp     = 0;
10291     fis->d.featuresExp    = 0;
10292     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10293     fis->d.sectorCountExp = 0;
10294     fis->d.reserved4      = 0;
10295     fis->d.device         = 0x4E;                   /* 01001110 */
10296     fis->d.control        = 0;                      /* FIS HOB bit clear */
10297     fis->d.reserved5      = 0;
10298 
10299     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10300   }
10301 
10302   /* Initialize CB for SATA completion.
10303    */
10304   satIOContext->satCompleteCB = &satNonDataIOCB;
10305 
10306   /*
10307    * Prepare SGL and send FIS to LL layer.
10308    */
10309   satIOContext->reqType = agRequestType;       /* Save it */
10310 
10311   status = sataLLIOStart( tiRoot,
10312                           tiIORequest,
10313                           tiDeviceHandle,
10314                           tiScsiRequest,
10315                           satIOContext);
10316 
10317   TI_DBG5(("satReadVerifySectorsNoChain: return last\n"));
10318 
10319   return status;
10320 }
10321 
10322 
10323 /*****************************************************************************/
10324 /*! \brief SAT implementation for SCSI satWriteSame10.
10325  *
10326  *  SAT implementation for SCSI satWriteSame10.
10327  *
10328  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10329  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10330  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10331  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10332  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10333  *
10334  *  \return If command is started successfully
10335  *    - \e tiSuccess:     I/O request successfully initiated.
10336  *    - \e tiBusy:        No resources available, try again later.
10337  *    - \e tiIONoDevice:  Invalid device handle.
10338  *    - \e tiError:       Other errors.
10339  */
10340 /*****************************************************************************/
10341 GLOBAL bit32  satWriteSame10(
10342                    tiRoot_t                  *tiRoot,
10343                    tiIORequest_t             *tiIORequest,
10344                    tiDeviceHandle_t          *tiDeviceHandle,
10345                    tiScsiInitiatorRequest_t *tiScsiRequest,
10346                    satIOContext_t            *satIOContext)
10347 {
10348   bit32                     status;
10349   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10350   satDeviceData_t           *pSatDevData;
10351   scsiRspSense_t            *pSense;
10352   tiIniScsiCmnd_t           *scsiCmnd;
10353   agsaFisRegHostToDevice_t  *fis;
10354   bit32                     lba = 0;
10355   bit32                     tl = 0;
10356 
10357   pSense        = satIOContext->pSense;
10358   pSatDevData   = satIOContext->pSatDevData;
10359   scsiCmnd      = &tiScsiRequest->scsiCmnd;
10360   fis           = satIOContext->pFis;
10361 
10362   TI_DBG5(("satWriteSame10: start\n"));
10363 
10364   /* checking CONTROL */
10365     /* NACA == 1 or LINK == 1*/
10366   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
10367   {
10368     satSetSensePayload( pSense,
10369                         SCSI_SNSKEY_ILLEGAL_REQUEST,
10370                         0,
10371                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10372                         satIOContext);
10373 
10374     ostiInitiatorIOCompleted( tiRoot,
10375                               tiIORequest,
10376                               tiIOSuccess,
10377                               SCSI_STAT_CHECK_CONDITION,
10378                               satIOContext->pTiSenseData,
10379                               satIOContext->interruptContext );
10380 
10381     TI_DBG1(("satWriteSame10: return control\n"));
10382     return tiSuccess;
10383   }
10384 
10385 
10386   /* checking LBDATA and PBDATA */
10387   /* case 1 */
10388   if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10389        !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10390   {
10391     TI_DBG5(("satWriteSame10: case 1\n"));
10392     /* spec 9.26.2, Table 62, p64, case 1*/
10393     /*
10394       normal case
10395       just like write in 9.17.1
10396     */
10397 
10398     if ( pSatDevData->sat48BitSupport != agTRUE )
10399     {
10400       /*
10401         writeSame10 but no support for 48 bit addressing
10402         -> problem in transfer length. Therefore, return check condition
10403       */
10404       satSetSensePayload( pSense,
10405                           SCSI_SNSKEY_ILLEGAL_REQUEST,
10406                           0,
10407                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10408                           satIOContext);
10409 
10410       ostiInitiatorIOCompleted( tiRoot,
10411                                 tiIORequest,
10412                                 tiIOSuccess,
10413                                 SCSI_STAT_CHECK_CONDITION,
10414                                 satIOContext->pTiSenseData,
10415                                 satIOContext->interruptContext );
10416 
10417       TI_DBG1(("satWriteSame10: return internal checking\n"));
10418       return tiSuccess;
10419     }
10420 
10421     /* cdb10; computing LBA and transfer length */
10422     lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
10423       + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
10424     tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
10425 
10426 
10427     /* Table 34, 9.1, p 46 */
10428     /*
10429       note: As of 2/10/2006, no support for DMA QUEUED
10430     */
10431 
10432     /*
10433       Table 34, 9.1, p 46, b (footnote)
10434       When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
10435       return check condition
10436     */
10437     if (pSatDevData->satNCQ != agTRUE &&
10438         pSatDevData->sat48BitSupport != agTRUE
10439           )
10440     {
10441       if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */
10442       {
10443         satSetSensePayload( pSense,
10444                             SCSI_SNSKEY_ILLEGAL_REQUEST,
10445                             0,
10446                             SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
10447                             satIOContext);
10448 
10449         ostiInitiatorIOCompleted( tiRoot,
10450                                   tiIORequest,
10451                                   tiIOSuccess,
10452                                   SCSI_STAT_CHECK_CONDITION,
10453                                   satIOContext->pTiSenseData,
10454                                   satIOContext->interruptContext );
10455 
10456         TI_DBG1(("satWriteSame10: return LBA out of range\n"));
10457           return tiSuccess;
10458       }
10459     }
10460 
10461     if (lba + tl <= SAT_TR_LBA_LIMIT)
10462     {
10463       if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10464       {
10465         /* case 2 */
10466         /* WRITE DMA */
10467         /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10468         TI_DBG5(("satWriteSame10: case 1-2 !!! error due to writeSame10\n"));
10469         satSetSensePayload( pSense,
10470                             SCSI_SNSKEY_ILLEGAL_REQUEST,
10471                             0,
10472                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10473                             satIOContext);
10474 
10475         ostiInitiatorIOCompleted( tiRoot,
10476                                   tiIORequest,
10477                                   tiIOSuccess,
10478                                   SCSI_STAT_CHECK_CONDITION,
10479                                   satIOContext->pTiSenseData,
10480                                   satIOContext->interruptContext );
10481         return tiSuccess;
10482       }
10483       else
10484       {
10485         /* case 1 */
10486         /* WRITE MULTIPLE or WRITE SECTOR(S) */
10487         /* WRITE SECTORS is chosen for easier implemetation */
10488         /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10489         TI_DBG5(("satWriteSame10: case 1-1 !!! error due to writesame10\n"));
10490         satSetSensePayload( pSense,
10491                             SCSI_SNSKEY_ILLEGAL_REQUEST,
10492                             0,
10493                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10494                             satIOContext);
10495 
10496         ostiInitiatorIOCompleted( tiRoot,
10497                                   tiIORequest,
10498                                   tiIOSuccess,
10499                                   SCSI_STAT_CHECK_CONDITION,
10500                                   satIOContext->pTiSenseData,
10501                                   satIOContext->interruptContext );
10502         return tiSuccess;
10503       }
10504     } /* end of case 1 and 2 */
10505 
10506     /* case 3 and 4 */
10507     if (pSatDevData->sat48BitSupport == agTRUE)
10508     {
10509       if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10510       {
10511         /* case 3 */
10512         /* WRITE DMA EXT or WRITE DMA FUA EXT */
10513         /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */
10514         TI_DBG5(("satWriteSame10: case 1-3\n"));
10515         fis->h.fisType        = 0x27;                   /* Reg host to device */
10516         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10517 
10518         fis->h.command        = SAT_WRITE_DMA_EXT;          /* 0x35 */
10519 
10520         fis->h.features       = 0;                      /* FIS reserve */
10521         fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
10522         fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
10523         fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
10524         fis->d.device         = 0x40;                   /* FIS LBA mode set */
10525         fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
10526         fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10527         fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10528         fis->d.featuresExp    = 0;                      /* FIS reserve */
10529         if (tl == 0)
10530         {
10531           /* error check
10532              ATA spec, p125, 6.17.29
10533              pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10534              and allowed value is 0x0FFFFFFF - 1
10535           */
10536           if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10537           {
10538             TI_DBG5(("satWriteSame10: case 3 !!! warning can't fit sectors\n"));
10539             satSetSensePayload( pSense,
10540                                 SCSI_SNSKEY_ILLEGAL_REQUEST,
10541                                 0,
10542                                 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10543                                 satIOContext);
10544 
10545             ostiInitiatorIOCompleted( tiRoot,
10546                                       tiIORequest,
10547                                       tiIOSuccess,
10548                                       SCSI_STAT_CHECK_CONDITION,
10549                                       satIOContext->pTiSenseData,
10550                                       satIOContext->interruptContext );
10551             return tiSuccess;
10552           }
10553         }
10554         /* one sector at a time */
10555         fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10556         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10557         fis->d.reserved4      = 0;
10558         fis->d.control        = 0;                      /* FIS HOB bit clear */
10559         fis->d.reserved5      = 0;
10560 
10561         agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10562       }
10563       else
10564       {
10565         /* case 4 */
10566         /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
10567         /* WRITE SECTORS EXT is chosen for easier implemetation */
10568         TI_DBG5(("satWriteSame10: case 1-4\n"));
10569         fis->h.fisType        = 0x27;                   /* Reg host to device */
10570         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10571 
10572         fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
10573         fis->h.features       = 0;                      /* FIS reserve */
10574         fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
10575         fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
10576         fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
10577         fis->d.device         = 0x40;                   /* FIS LBA mode set */
10578         fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
10579         fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10580         fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10581         fis->d.featuresExp    = 0;                      /* FIS reserve */
10582         if (tl == 0)
10583         {
10584           /* error check
10585              ATA spec, p125, 6.17.29
10586              pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10587              and allowed value is 0x0FFFFFFF - 1
10588           */
10589           if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10590           {
10591             TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10592             satSetSensePayload( pSense,
10593                                 SCSI_SNSKEY_ILLEGAL_REQUEST,
10594                                 0,
10595                                 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10596                                 satIOContext);
10597 
10598             ostiInitiatorIOCompleted( tiRoot,
10599                                       tiIORequest,
10600                                       tiIOSuccess,
10601                                       SCSI_STAT_CHECK_CONDITION,
10602                                       satIOContext->pTiSenseData,
10603                                       satIOContext->interruptContext );
10604             return tiSuccess;
10605           }
10606         }
10607         /* one sector at a time */
10608         fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10609         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10610         fis->d.reserved4      = 0;
10611         fis->d.control        = 0;                      /* FIS HOB bit clear */
10612         fis->d.reserved5      = 0;
10613 
10614         agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10615       }
10616     }
10617 
10618     /* case 5 */
10619     if (pSatDevData->satNCQ == agTRUE)
10620     {
10621       /* WRITE FPDMA QUEUED */
10622       if (pSatDevData->sat48BitSupport != agTRUE)
10623       {
10624         TI_DBG5(("satWriteSame10: case 1-5 !!! error NCQ but 28 bit address support \n"));
10625         satSetSensePayload( pSense,
10626                             SCSI_SNSKEY_ILLEGAL_REQUEST,
10627                             0,
10628                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10629                             satIOContext);
10630 
10631         ostiInitiatorIOCompleted( tiRoot,
10632                                   tiIORequest,
10633                                   tiIOSuccess,
10634                                   SCSI_STAT_CHECK_CONDITION,
10635                                   satIOContext->pTiSenseData,
10636                                   satIOContext->interruptContext );
10637         return tiSuccess;
10638       }
10639       TI_DBG5(("satWriteSame10: case 1-5\n"));
10640 
10641       /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
10642 
10643       fis->h.fisType        = 0x27;                   /* Reg host to device */
10644       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10645       fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
10646 
10647       if (tl == 0)
10648       {
10649         /* error check
10650            ATA spec, p125, 6.17.29
10651            pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10652            and allowed value is 0x0FFFFFFF - 1
10653         */
10654         if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10655         {
10656           TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10657           satSetSensePayload( pSense,
10658                               SCSI_SNSKEY_ILLEGAL_REQUEST,
10659                               0,
10660                               SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10661                               satIOContext);
10662 
10663           ostiInitiatorIOCompleted( tiRoot,
10664                                     tiIORequest,
10665                                     tiIOSuccess,
10666                                     SCSI_STAT_CHECK_CONDITION,
10667                                     satIOContext->pTiSenseData,
10668                                     satIOContext->interruptContext );
10669           return tiSuccess;
10670         }
10671       }
10672       /* one sector at a time */
10673       fis->h.features       = 1;            /* FIS sector count (7:0) */
10674       fis->d.featuresExp    = 0;            /* FIS sector count (15:8) */
10675 
10676 
10677       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
10678       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
10679       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
10680 
10681       /* NO FUA bit in the WRITE SAME 10 */
10682       fis->d.device       = 0x40;                     /* FIS FUA clear */
10683 
10684       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
10685       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10686       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10687       fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
10688       fis->d.sectorCountExp = 0;
10689       fis->d.reserved4      = 0;
10690       fis->d.control        = 0;                      /* FIS HOB bit clear */
10691       fis->d.reserved5      = 0;
10692 
10693       agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
10694     }
10695     /* Initialize CB for SATA completion.
10696      */
10697     satIOContext->satCompleteCB = &satWriteSame10CB;
10698 
10699     /*
10700      * Prepare SGL and send FIS to LL layer.
10701      */
10702     satIOContext->reqType = agRequestType;       /* Save it */
10703 
10704     status = sataLLIOStart( tiRoot,
10705                             tiIORequest,
10706                             tiDeviceHandle,
10707                             tiScsiRequest,
10708                             satIOContext);
10709     return (status);
10710 
10711 
10712   } /* end of case 1 */
10713   else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10714              (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10715   {
10716     /* spec 9.26.2, Table 62, p64, case 2*/
10717     satSetSensePayload( pSense,
10718                         SCSI_SNSKEY_ILLEGAL_REQUEST,
10719                         0,
10720                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10721                         satIOContext);
10722 
10723     ostiInitiatorIOCompleted( tiRoot,
10724                               tiIORequest,
10725                               tiIOSuccess,
10726                               SCSI_STAT_CHECK_CONDITION,
10727                               satIOContext->pTiSenseData,
10728                               satIOContext->interruptContext );
10729 
10730     TI_DBG5(("satWriteSame10: return Table 62 case 2\n"));
10731     return tiSuccess;
10732   }
10733   else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10734            !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10735   {
10736     TI_DBG5(("satWriteSame10: Table 62 case 3\n"));
10737 
10738   }
10739   else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10740             (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */
10741   {
10742 
10743     /* spec 9.26.2, Table 62, p64, case 4*/
10744     satSetSensePayload( pSense,
10745                         SCSI_SNSKEY_ILLEGAL_REQUEST,
10746                         0,
10747                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10748                         satIOContext);
10749 
10750     ostiInitiatorIOCompleted( tiRoot,
10751                               tiIORequest,
10752                               tiIOSuccess,
10753                               SCSI_STAT_CHECK_CONDITION,
10754                               satIOContext->pTiSenseData,
10755                               satIOContext->interruptContext );
10756 
10757     TI_DBG5(("satWriteSame10: return Table 62 case 4\n"));
10758     return tiSuccess;
10759   }
10760 
10761 
10762   return tiSuccess;
10763 }
10764 
10765 /*****************************************************************************/
10766 /*! \brief SAT implementation for SCSI satWriteSame10_1.
10767  *
10768  *  SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10769  *  This is used when WRITESAME10 is divided into multiple ATA commands
10770  *
10771  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10772  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10773  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10774  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10775  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10776  *  \param   lba:              LBA
10777  *
10778  *  \return If command is started successfully
10779  *    - \e tiSuccess:     I/O request successfully initiated.
10780  *    - \e tiBusy:        No resources available, try again later.
10781  *    - \e tiIONoDevice:  Invalid device handle.
10782  *    - \e tiError:       Other errors.
10783  */
10784 /*****************************************************************************/
10785 GLOBAL bit32  satWriteSame10_1(
10786                    tiRoot_t                  *tiRoot,
10787                    tiIORequest_t             *tiIORequest,
10788                    tiDeviceHandle_t          *tiDeviceHandle,
10789                    tiScsiInitiatorRequest_t *tiScsiRequest,
10790                    satIOContext_t            *satIOContext,
10791                    bit32                     lba
10792                    )
10793 {
10794   /*
10795     sends SAT_WRITE_DMA_EXT
10796   */
10797 
10798   bit32                     status;
10799   bit32                     agRequestType;
10800   agsaFisRegHostToDevice_t  *fis;
10801   bit8                      lba1, lba2 ,lba3, lba4;
10802 
10803   TI_DBG5(("satWriteSame10_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10804            tiDeviceHandle, tiIORequest));
10805 
10806   fis               = satIOContext->pFis;
10807 
10808   /* MSB */
10809   lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10810   lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10811   lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10812   /* LSB */
10813   lba4 = (bit8)(lba & 0x000000FF);
10814 
10815   /* SAT_WRITE_DMA_EXT */
10816   fis->h.fisType        = 0x27;                   /* Reg host to device */
10817   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10818 
10819   fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
10820 
10821   fis->h.features       = 0;                      /* FIS reserve */
10822   fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
10823   fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
10824   fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
10825   fis->d.device         = 0x40;                   /* FIS LBA mode set */
10826   fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
10827   fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10828   fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10829   fis->d.featuresExp    = 0;                      /* FIS reserve */
10830   /* one sector at a time */
10831   fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10832   fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10833 
10834   fis->d.reserved4      = 0;
10835   fis->d.control        = 0;                      /* FIS HOB bit clear */
10836   fis->d.reserved5      = 0;
10837 
10838 
10839   agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10840 
10841   /* Initialize CB for SATA completion.
10842    */
10843   satIOContext->satCompleteCB = &satWriteSame10CB;
10844 
10845   /*
10846    * Prepare SGL and send FIS to LL layer.
10847    */
10848   satIOContext->reqType = agRequestType;       /* Save it */
10849 
10850   status = sataLLIOStart( tiRoot,
10851                           tiIORequest,
10852                           tiDeviceHandle,
10853                           tiScsiRequest,
10854                           satIOContext);
10855 
10856   TI_DBG5(("satWriteSame10_1 return status %d\n", status));
10857   return status;
10858 }
10859 
10860 /*****************************************************************************/
10861 /*! \brief SAT implementation for SCSI satWriteSame10_2.
10862  *
10863  *  SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10864  *  This is used when WRITESAME10 is divided into multiple ATA commands
10865  *
10866  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10867  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10868  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10869  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10870  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10871  *  \param   lba:              LBA
10872  *
10873  *  \return If command is started successfully
10874  *    - \e tiSuccess:     I/O request successfully initiated.
10875  *    - \e tiBusy:        No resources available, try again later.
10876  *    - \e tiIONoDevice:  Invalid device handle.
10877  *    - \e tiError:       Other errors.
10878  */
10879 /*****************************************************************************/
10880 GLOBAL bit32  satWriteSame10_2(
10881                    tiRoot_t                  *tiRoot,
10882                    tiIORequest_t             *tiIORequest,
10883                    tiDeviceHandle_t          *tiDeviceHandle,
10884                    tiScsiInitiatorRequest_t *tiScsiRequest,
10885                    satIOContext_t            *satIOContext,
10886                    bit32                     lba
10887                    )
10888 {
10889   /*
10890     sends SAT_WRITE_SECTORS_EXT
10891   */
10892 
10893   bit32                     status;
10894   bit32                     agRequestType;
10895   agsaFisRegHostToDevice_t  *fis;
10896   bit8                      lba1, lba2 ,lba3, lba4;
10897 
10898   TI_DBG5(("satWriteSame10_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10899            tiDeviceHandle, tiIORequest));
10900 
10901   fis               = satIOContext->pFis;
10902 
10903   /* MSB */
10904   lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10905   lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10906   lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10907   /* LSB */
10908   lba4 = (bit8)(lba & 0x000000FF);
10909 
10910 
10911   /* SAT_WRITE_SECTORS_EXT */
10912   fis->h.fisType        = 0x27;                   /* Reg host to device */
10913   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10914 
10915   fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
10916   fis->h.features       = 0;                      /* FIS reserve */
10917   fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
10918   fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
10919   fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
10920   fis->d.device         = 0x40;                   /* FIS LBA mode set */
10921   fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
10922   fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10923   fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10924   fis->d.featuresExp    = 0;                      /* FIS reserve */
10925   /* one sector at a time */
10926   fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10927   fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10928 
10929   fis->d.reserved4      = 0;
10930   fis->d.control        = 0;                      /* FIS HOB bit clear */
10931   fis->d.reserved5      = 0;
10932 
10933 
10934   agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10935 
10936   /* Initialize CB for SATA completion.
10937    */
10938   satIOContext->satCompleteCB = &satWriteSame10CB;
10939 
10940   /*
10941    * Prepare SGL and send FIS to LL layer.
10942    */
10943   satIOContext->reqType = agRequestType;       /* Save it */
10944 
10945   status = sataLLIOStart( tiRoot,
10946                           tiIORequest,
10947                           tiDeviceHandle,
10948                           tiScsiRequest,
10949                           satIOContext);
10950 
10951   TI_DBG5(("satWriteSame10_2 return status %d\n", status));
10952   return status;
10953 }
10954 
10955 /*****************************************************************************/
10956 /*! \brief SAT implementation for SCSI satWriteSame10_3.
10957  *
10958  *  SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10959  *  This is used when WRITESAME10 is divided into multiple ATA commands
10960  *
10961  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10962  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10963  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10964  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10965  *  \param   satIOContext_t:   Pointer to the SAT IO Context
10966  *  \param   lba:              LBA
10967  *
10968  *  \return If command is started successfully
10969  *    - \e tiSuccess:     I/O request successfully initiated.
10970  *    - \e tiBusy:        No resources available, try again later.
10971  *    - \e tiIONoDevice:  Invalid device handle.
10972  *    - \e tiError:       Other errors.
10973  */
10974 /*****************************************************************************/
10975 GLOBAL bit32  satWriteSame10_3(
10976                    tiRoot_t                  *tiRoot,
10977                    tiIORequest_t             *tiIORequest,
10978                    tiDeviceHandle_t          *tiDeviceHandle,
10979                    tiScsiInitiatorRequest_t *tiScsiRequest,
10980                    satIOContext_t            *satIOContext,
10981                    bit32                     lba
10982                    )
10983 {
10984   /*
10985     sends SAT_WRITE_FPDMA_QUEUED
10986   */
10987 
10988   bit32                     status;
10989   bit32                     agRequestType;
10990   agsaFisRegHostToDevice_t  *fis;
10991   bit8                      lba1, lba2 ,lba3, lba4;
10992 
10993   TI_DBG5(("satWriteSame10_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10994            tiDeviceHandle, tiIORequest));
10995 
10996   fis               = satIOContext->pFis;
10997 
10998   /* MSB */
10999   lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
11000   lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
11001   lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
11002   /* LSB */
11003   lba4 = (bit8)(lba & 0x000000FF);
11004 
11005   /* SAT_WRITE_FPDMA_QUEUED */
11006   fis->h.fisType        = 0x27;                   /* Reg host to device */
11007   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11008   fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
11009 
11010 
11011   /* one sector at a time */
11012   fis->h.features       = 1;                      /* FIS sector count (7:0) */
11013   fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
11014 
11015 
11016   fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
11017   fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
11018   fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
11019 
11020   /* NO FUA bit in the WRITE SAME 10 */
11021   fis->d.device         = 0x40;                   /* FIS FUA clear */
11022 
11023   fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
11024   fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
11025   fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
11026   fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
11027   fis->d.sectorCountExp = 0;
11028   fis->d.reserved4      = 0;
11029   fis->d.control        = 0;                      /* FIS HOB bit clear */
11030   fis->d.reserved5      = 0;
11031 
11032   agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
11033 
11034   /* Initialize CB for SATA completion.
11035    */
11036   satIOContext->satCompleteCB = &satWriteSame10CB;
11037 
11038   /*
11039    * Prepare SGL and send FIS to LL layer.
11040    */
11041   satIOContext->reqType = agRequestType;       /* Save it */
11042 
11043   status = sataLLIOStart( tiRoot,
11044                           tiIORequest,
11045                           tiDeviceHandle,
11046                           tiScsiRequest,
11047                           satIOContext);
11048 
11049   TI_DBG5(("satWriteSame10_2 return status %d\n", status));
11050   return status;
11051 }
11052 /*****************************************************************************/
11053 /*! \brief SAT implementation for SCSI satWriteSame16.
11054  *
11055  *  SAT implementation for SCSI satWriteSame16.
11056  *
11057  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11058  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11059  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11060  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11061  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11062  *
11063  *  \return If command is started successfully
11064  *    - \e tiSuccess:     I/O request successfully initiated.
11065  *    - \e tiBusy:        No resources available, try again later.
11066  *    - \e tiIONoDevice:  Invalid device handle.
11067  *    - \e tiError:       Other errors.
11068  */
11069 /*****************************************************************************/
11070 GLOBAL bit32  satWriteSame16(
11071                    tiRoot_t                  *tiRoot,
11072                    tiIORequest_t             *tiIORequest,
11073                    tiDeviceHandle_t          *tiDeviceHandle,
11074                    tiScsiInitiatorRequest_t *tiScsiRequest,
11075                    satIOContext_t            *satIOContext)
11076 {
11077   scsiRspSense_t            *pSense;
11078 
11079   pSense        = satIOContext->pSense;
11080 
11081   TI_DBG5(("satWriteSame16:start\n"));
11082 
11083 
11084   satSetSensePayload( pSense,
11085                       SCSI_SNSKEY_NO_SENSE,
11086                       0,
11087                       SCSI_SNSCODE_NO_ADDITIONAL_INFO,
11088                       satIOContext);
11089 
11090   ostiInitiatorIOCompleted( tiRoot,
11091                             tiIORequest, /* == &satIntIo->satOrgTiIORequest */
11092                             tiIOSuccess,
11093                             SCSI_STAT_CHECK_CONDITION,
11094                             satIOContext->pTiSenseData,
11095                             satIOContext->interruptContext );
11096   TI_DBG5(("satWriteSame16: return internal checking\n"));
11097   return tiSuccess;
11098 }
11099 
11100 /*****************************************************************************/
11101 /*! \brief SAT implementation for SCSI satLogSense_1.
11102  *
11103  *  Part of SAT implementation for SCSI satLogSense.
11104  *
11105  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11106  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11107  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11108  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11109  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11110  *
11111  *  \return If command is started successfully
11112  *    - \e tiSuccess:     I/O request successfully initiated.
11113  *    - \e tiBusy:        No resources available, try again later.
11114  *    - \e tiIONoDevice:  Invalid device handle.
11115  *    - \e tiError:       Other errors.
11116  */
11117 /*****************************************************************************/
11118 GLOBAL bit32  satLogSense_1(
11119                    tiRoot_t                  *tiRoot,
11120                    tiIORequest_t             *tiIORequest,
11121                    tiDeviceHandle_t          *tiDeviceHandle,
11122                    tiScsiInitiatorRequest_t *tiScsiRequest,
11123                    satIOContext_t            *satIOContext)
11124 {
11125   bit32                     status;
11126   bit32                     agRequestType;
11127   satDeviceData_t           *pSatDevData;
11128   agsaFisRegHostToDevice_t  *fis;
11129 
11130   pSatDevData   = satIOContext->pSatDevData;
11131   fis           = satIOContext->pFis;
11132 
11133   TI_DBG5(("satLogSense_1: start\n"));
11134 
11135 
11136   /* SAT Rev 8, 10.2.4 p74 */
11137   if ( pSatDevData->sat48BitSupport == agTRUE )
11138   {
11139     TI_DBG5(("satLogSense_1: case 2-1 sends READ LOG EXT\n"));
11140     /* sends READ LOG EXT */
11141     fis->h.fisType        = 0x27;                   /* Reg host to device */
11142     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11143 
11144     fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
11145     fis->h.features       = 0;                      /* FIS reserve */
11146     fis->d.lbaLow         = 0x07;                   /* 0x07 */
11147     fis->d.lbaMid         = 0;                      /*  */
11148     fis->d.lbaHigh        = 0;                      /*  */
11149     fis->d.device         = 0;                      /*  */
11150     fis->d.lbaLowExp      = 0;                      /*  */
11151     fis->d.lbaMidExp      = 0;                      /*  */
11152     fis->d.lbaHighExp     = 0;                      /*  */
11153     fis->d.featuresExp    = 0;                      /* FIS reserve */
11154     fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
11155     fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
11156     fis->d.reserved4      = 0;
11157     fis->d.control        = 0;                      /* FIS HOB bit clear */
11158     fis->d.reserved5      = 0;
11159 
11160     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11161 
11162     /* Initialize CB for SATA completion.
11163      */
11164     satIOContext->satCompleteCB = &satLogSenseCB;
11165 
11166     /*
11167      * Prepare SGL and send FIS to LL layer.
11168      */
11169     satIOContext->reqType = agRequestType;       /* Save it */
11170 
11171     status = sataLLIOStart( tiRoot,
11172                             tiIORequest,
11173                             tiDeviceHandle,
11174                             tiScsiRequest,
11175                             satIOContext);
11176     return status;
11177 
11178   }
11179   else
11180   {
11181     TI_DBG5(("satLogSense_1: case 2-2 sends SMART READ LOG\n"));
11182     /* sends SMART READ LOG */
11183     fis->h.fisType        = 0x27;                   /* Reg host to device */
11184     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11185 
11186     fis->h.command        = SAT_SMART_READ_LOG;     /* 0x2F */
11187     fis->h.features       = 0x00;                   /* 0xd5 */
11188     fis->d.lbaLow         = 0x06;                   /* 0x06 */
11189     fis->d.lbaMid         = 0x00;                   /* 0x4f */
11190     fis->d.lbaHigh        = 0x00;                   /* 0xc2 */
11191     fis->d.device         = 0;                      /*  */
11192     fis->d.lbaLowExp      = 0;                      /*  */
11193     fis->d.lbaMidExp      = 0;                      /*  */
11194     fis->d.lbaHighExp     = 0;                      /*  */
11195     fis->d.featuresExp    = 0;                      /* FIS reserve */
11196     fis->d.sectorCount    = 0x01;                      /*  */
11197     fis->d.sectorCountExp = 0x00;                      /*  */
11198     fis->d.reserved4      = 0;
11199     fis->d.control        = 0;                      /* FIS HOB bit clear */
11200     fis->d.reserved5      = 0;
11201 
11202     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11203 
11204     /* Initialize CB for SATA completion.
11205      */
11206     satIOContext->satCompleteCB = &satLogSenseCB;
11207 
11208     /*
11209      * Prepare SGL and send FIS to LL layer.
11210      */
11211     satIOContext->reqType = agRequestType;       /* Save it */
11212 
11213     status = sataLLIOStart( tiRoot,
11214                             tiIORequest,
11215                             tiDeviceHandle,
11216                             tiScsiRequest,
11217                             satIOContext);
11218     return status;
11219 
11220   }
11221 }
11222 
11223 /*****************************************************************************/
11224 /*! \brief SAT implementation for SCSI satSMARTEnable.
11225  *
11226  *  Part of SAT implementation for SCSI satLogSense.
11227  *
11228  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11229  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11230  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11231  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11232  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11233  *
11234  *  \return If command is started successfully
11235  *    - \e tiSuccess:     I/O request successfully initiated.
11236  *    - \e tiBusy:        No resources available, try again later.
11237  *    - \e tiIONoDevice:  Invalid device handle.
11238  *    - \e tiError:       Other errors.
11239  */
11240 /*****************************************************************************/
11241 GLOBAL bit32  satSMARTEnable(
11242                    tiRoot_t                  *tiRoot,
11243                    tiIORequest_t             *tiIORequest,
11244                    tiDeviceHandle_t          *tiDeviceHandle,
11245                    tiScsiInitiatorRequest_t *tiScsiRequest,
11246                    satIOContext_t            *satIOContext)
11247 {
11248   bit32                     status;
11249   bit32                     agRequestType;
11250   agsaFisRegHostToDevice_t  *fis;
11251 
11252   TI_DBG4(("satSMARTEnable entry: tiDeviceHandle=%p tiIORequest=%p\n",
11253       tiDeviceHandle, tiIORequest));
11254 
11255   fis               = satIOContext->pFis;
11256 
11257   /*
11258    * Send the SAT_SMART_ENABLE_OPERATIONS command.
11259    */
11260   fis->h.fisType        = 0x27;                   /* Reg host to device */
11261   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11262 
11263   fis->h.command        = SAT_SMART_ENABLE_OPERATIONS;   /* 0xB0 */
11264   fis->h.features       = 0xD8;
11265   fis->d.lbaLow         = 0;
11266   fis->d.lbaMid         = 0x4F;
11267   fis->d.lbaHigh        = 0xC2;
11268   fis->d.device         = 0;
11269   fis->d.lbaLowExp      = 0;
11270   fis->d.lbaMidExp      = 0;
11271   fis->d.lbaHighExp     = 0;
11272   fis->d.featuresExp    = 0;
11273   fis->d.sectorCount    = 0;
11274   fis->d.sectorCountExp = 0;
11275   fis->d.reserved4      = 0;
11276   fis->d.control        = 0;                      /* FIS HOB bit clear */
11277   fis->d.reserved5      = 0;
11278 
11279   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11280 
11281   /* Initialize CB for SATA completion.
11282    */
11283   satIOContext->satCompleteCB = &satSMARTEnableCB;
11284 
11285   /*
11286    * Prepare SGL and send FIS to LL layer.
11287    */
11288   satIOContext->reqType = agRequestType;       /* Save it */
11289 
11290   status = sataLLIOStart( tiRoot,
11291                           tiIORequest,
11292                           tiDeviceHandle,
11293                           tiScsiRequest,
11294                           satIOContext);
11295 
11296 
11297   return status;
11298 }
11299 
11300 /*****************************************************************************/
11301 /*! \brief SAT implementation for SCSI satLogSense_3.
11302  *
11303  *  Part of SAT implementation for SCSI satLogSense.
11304  *
11305  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11306  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11307  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11308  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11309  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11310  *
11311  *  \return If command is started successfully
11312  *    - \e tiSuccess:     I/O request successfully initiated.
11313  *    - \e tiBusy:        No resources available, try again later.
11314  *    - \e tiIONoDevice:  Invalid device handle.
11315  *    - \e tiError:       Other errors.
11316  */
11317 /*****************************************************************************/
11318 GLOBAL bit32  satLogSense_3(
11319                    tiRoot_t                  *tiRoot,
11320                    tiIORequest_t             *tiIORequest,
11321                    tiDeviceHandle_t          *tiDeviceHandle,
11322                    tiScsiInitiatorRequest_t *tiScsiRequest,
11323                    satIOContext_t            *satIOContext)
11324 {
11325   bit32                     status;
11326   bit32                     agRequestType;
11327   agsaFisRegHostToDevice_t  *fis;
11328 
11329   TI_DBG4(("satLogSense_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11330       tiDeviceHandle, tiIORequest));
11331 
11332   fis               = satIOContext->pFis;
11333   /* sends READ LOG EXT */
11334   fis->h.fisType        = 0x27;                   /* Reg host to device */
11335   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11336 
11337   fis->h.command        = SAT_SMART_READ_LOG;     /* 0x2F */
11338   fis->h.features       = 0xD5;                   /* 0xd5 */
11339   fis->d.lbaLow         = 0x06;                   /* 0x06 */
11340   fis->d.lbaMid         = 0x4F;                   /* 0x4f */
11341   fis->d.lbaHigh        = 0xC2;                   /* 0xc2 */
11342   fis->d.device         = 0;                      /*  */
11343   fis->d.lbaLowExp      = 0;                      /*  */
11344   fis->d.lbaMidExp      = 0;                      /*  */
11345   fis->d.lbaHighExp     = 0;                      /*  */
11346   fis->d.featuresExp    = 0;                      /* FIS reserve */
11347   fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
11348   fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
11349   fis->d.reserved4      = 0;
11350   fis->d.control        = 0;                      /* FIS HOB bit clear */
11351   fis->d.reserved5      = 0;
11352 
11353   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11354 
11355   /* Initialize CB for SATA completion.
11356    */
11357   satIOContext->satCompleteCB = &satLogSenseCB;
11358 
11359   /*
11360    * Prepare SGL and send FIS to LL layer.
11361    */
11362   satIOContext->reqType = agRequestType;       /* Save it */
11363 
11364   status = sataLLIOStart( tiRoot,
11365                           tiIORequest,
11366                           tiDeviceHandle,
11367                           tiScsiRequest,
11368                           satIOContext);
11369   return status;
11370 }
11371 
11372 /*****************************************************************************/
11373 /*! \brief SAT implementation for SCSI satLogSense_2.
11374  *
11375  *  Part of SAT implementation for SCSI satLogSense.
11376  *
11377  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11378  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11379  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11380  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11381  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11382  *
11383  *  \return If command is started successfully
11384  *    - \e tiSuccess:     I/O request successfully initiated.
11385  *    - \e tiBusy:        No resources available, try again later.
11386  *    - \e tiIONoDevice:  Invalid device handle.
11387  *    - \e tiError:       Other errors.
11388  */
11389 /*****************************************************************************/
11390 GLOBAL bit32  satLogSense_2(
11391                    tiRoot_t                  *tiRoot,
11392                    tiIORequest_t             *tiIORequest,
11393                    tiDeviceHandle_t          *tiDeviceHandle,
11394                    tiScsiInitiatorRequest_t *tiScsiRequest,
11395                    satIOContext_t            *satIOContext)
11396 {
11397   bit32                     status;
11398   bit32                     agRequestType;
11399   agsaFisRegHostToDevice_t  *fis;
11400 
11401   TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11402       tiDeviceHandle, tiIORequest));
11403 
11404   fis               = satIOContext->pFis;
11405   /* sends READ LOG EXT */
11406   fis->h.fisType        = 0x27;                   /* Reg host to device */
11407   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11408 
11409   fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
11410   fis->h.features       = 0;                      /* FIS reserve */
11411   fis->d.lbaLow         = 0x07;                   /* 0x07 */
11412   fis->d.lbaMid         = 0;                      /*  */
11413   fis->d.lbaHigh        = 0;                      /*  */
11414   fis->d.device         = 0;                      /*  */
11415   fis->d.lbaLowExp      = 0;                      /*  */
11416   fis->d.lbaMidExp      = 0;                      /*  */
11417   fis->d.lbaHighExp     = 0;                      /*  */
11418   fis->d.featuresExp    = 0;                      /* FIS reserve */
11419   fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
11420   fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
11421   fis->d.reserved4      = 0;
11422   fis->d.control        = 0;                      /* FIS HOB bit clear */
11423   fis->d.reserved5      = 0;
11424 
11425   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11426 
11427   /* Initialize CB for SATA completion.
11428    */
11429   satIOContext->satCompleteCB = &satLogSenseCB;
11430 
11431   /*
11432    * Prepare SGL and send FIS to LL layer.
11433    */
11434   satIOContext->reqType = agRequestType;       /* Save it */
11435 
11436   status = sataLLIOStart( tiRoot,
11437                           tiIORequest,
11438                           tiDeviceHandle,
11439                           tiScsiRequest,
11440                           satIOContext);
11441   return status;
11442 }
11443 
11444 /*****************************************************************************/
11445 /*! \brief SAT implementation for SCSI satLogSenseAllocate.
11446  *
11447  *  Part of SAT implementation for SCSI satLogSense.
11448  *
11449  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11450  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11451  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11452  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11453  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11454  *  \param   payloadSize:      size of payload to be allocated.
11455  *  \param   flag:             flag value
11456  *
11457  *  \return If command is started successfully
11458  *    - \e tiSuccess:     I/O request successfully initiated.
11459  *    - \e tiBusy:        No resources available, try again later.
11460  *    - \e tiIONoDevice:  Invalid device handle.
11461  *    - \e tiError:       Other errors.
11462  *  \note
11463  *    - flag values: LOG_SENSE_0, LOG_SENSE_1, LOG_SENSE_2
11464  */
11465 /*****************************************************************************/
11466 GLOBAL bit32  satLogSenseAllocate(
11467                    tiRoot_t                  *tiRoot,
11468                    tiIORequest_t             *tiIORequest,
11469                    tiDeviceHandle_t          *tiDeviceHandle,
11470                    tiScsiInitiatorRequest_t *tiScsiRequest,
11471                    satIOContext_t            *satIOContext,
11472                    bit32                      payloadSize,
11473                    bit32                      flag
11474                    )
11475 {
11476   satDeviceData_t           *pSatDevData;
11477   tdIORequestBody_t         *tdIORequestBody;
11478   satInternalIo_t           *satIntIo = agNULL;
11479   satIOContext_t            *satIOContext2;
11480   bit32                     status;
11481 
11482   TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11483       tiDeviceHandle, tiIORequest));
11484 
11485   pSatDevData       = satIOContext->pSatDevData;
11486 
11487   /* create internal satIOContext */
11488   satIntIo = satAllocIntIoResource( tiRoot,
11489                                     tiIORequest, /* original request */
11490                                     pSatDevData,
11491                                     payloadSize,
11492                                     satIntIo);
11493 
11494   if (satIntIo == agNULL)
11495   {
11496     /* memory allocation failure */
11497     satFreeIntIoResource( tiRoot,
11498                           pSatDevData,
11499                           satIntIo);
11500 
11501     ostiInitiatorIOCompleted( tiRoot,
11502                               tiIORequest,
11503                               tiIOFailed,
11504                               tiDetailOtherError,
11505                               agNULL,
11506                               satIOContext->interruptContext );
11507 
11508     TI_DBG4(("satLogSense_2: fail in allocation\n"));
11509     return tiSuccess;
11510   } /* end of memory allocation failure */
11511 
11512   satIntIo->satOrgTiIORequest = tiIORequest;
11513   tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
11514   satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
11515 
11516   satIOContext2->pSatDevData   = pSatDevData;
11517   satIOContext2->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
11518   satIOContext2->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
11519   satIOContext2->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
11520   satIOContext2->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
11521   satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
11522   satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
11523   satIOContext2->interruptContext = satIOContext->interruptContext;
11524   satIOContext2->satIntIoContext  = satIntIo;
11525   satIOContext2->ptiDeviceHandle = tiDeviceHandle;
11526   satIOContext2->satOrgIOContext = satIOContext;
11527 
11528   if (flag == LOG_SENSE_0)
11529   {
11530     /* SAT_SMART_ENABLE_OPERATIONS */
11531     status = satSMARTEnable( tiRoot,
11532                          &(satIntIo->satIntTiIORequest),
11533                          tiDeviceHandle,
11534                          &(satIntIo->satIntTiScsiXchg),
11535                          satIOContext2);
11536   }
11537   else if (flag == LOG_SENSE_1)
11538   {
11539     /* SAT_READ_LOG_EXT */
11540     status = satLogSense_2( tiRoot,
11541                          &(satIntIo->satIntTiIORequest),
11542                          tiDeviceHandle,
11543                          &(satIntIo->satIntTiScsiXchg),
11544                          satIOContext2);
11545   }
11546   else
11547   {
11548     /* SAT_SMART_READ_LOG */
11549     /* SAT_READ_LOG_EXT */
11550     status = satLogSense_3( tiRoot,
11551                          &(satIntIo->satIntTiIORequest),
11552                          tiDeviceHandle,
11553                          &(satIntIo->satIntTiScsiXchg),
11554                          satIOContext2);
11555 
11556   }
11557   if (status != tiSuccess)
11558   {
11559     satFreeIntIoResource( tiRoot,
11560                           pSatDevData,
11561                           satIntIo);
11562 
11563     ostiInitiatorIOCompleted( tiRoot,
11564                               tiIORequest,
11565                               tiIOFailed,
11566                               tiDetailOtherError,
11567                               agNULL,
11568                               satIOContext->interruptContext );
11569     return tiSuccess;
11570   }
11571 
11572 
11573   return tiSuccess;
11574 }
11575 
11576 
11577 /*****************************************************************************/
11578 /*! \brief SAT implementation for SCSI satLogSense.
11579  *
11580  *  SAT implementation for SCSI satLogSense.
11581  *
11582  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11583  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11584  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11585  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11586  *  \param   satIOContext_t:   Pointer to the SAT IO Context
11587  *
11588  *  \return If command is started successfully
11589  *    - \e tiSuccess:     I/O request successfully initiated.
11590  *    - \e tiBusy:        No resources available, try again later.
11591  *    - \e tiIONoDevice:  Invalid device handle.
11592  *    - \e tiError:       Other errors.
11593  */
11594 /*****************************************************************************/
11595 GLOBAL bit32  satLogSense(
11596                    tiRoot_t                  *tiRoot,
11597                    tiIORequest_t             *tiIORequest,
11598                    tiDeviceHandle_t          *tiDeviceHandle,
11599                    tiScsiInitiatorRequest_t *tiScsiRequest,
11600                    satIOContext_t            *satIOContext)
11601 {
11602   bit32                     status;
11603   bit32                     agRequestType;
11604   satDeviceData_t           *pSatDevData;
11605   scsiRspSense_t            *pSense;
11606   tiIniScsiCmnd_t           *scsiCmnd;
11607   agsaFisRegHostToDevice_t  *fis;
11608   bit8                      *pLogPage;    /* Log Page data buffer */
11609   bit32                     flag = 0;
11610   bit16                     AllocLen = 0;       /* allocation length */
11611   bit8                      AllLogPages[8];
11612   bit16                     lenRead = 0;
11613 
11614   pSense        = satIOContext->pSense;
11615   pSatDevData   = satIOContext->pSatDevData;
11616   scsiCmnd      = &tiScsiRequest->scsiCmnd;
11617   fis           = satIOContext->pFis;
11618   pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
11619 
11620   TI_DBG5(("satLogSense: start\n"));
11621 
11622   osti_memset(&AllLogPages, 0, 8);
11623   /* checking CONTROL */
11624   /* NACA == 1 or LINK == 1*/
11625   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
11626   {
11627     satSetSensePayload( pSense,
11628                         SCSI_SNSKEY_ILLEGAL_REQUEST,
11629                         0,
11630                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11631                         satIOContext);
11632 
11633     ostiInitiatorIOCompleted( tiRoot,
11634                               tiIORequest,
11635                               tiIOSuccess,
11636                               SCSI_STAT_CHECK_CONDITION,
11637                               satIOContext->pTiSenseData,
11638                               satIOContext->interruptContext );
11639 
11640     TI_DBG2(("satLogSense: return control\n"));
11641     return tiSuccess;
11642   }
11643 
11644 
11645   AllocLen = (bit8)((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
11646 
11647   /* checking PC (Page Control) */
11648   /* nothing */
11649 
11650   /* special cases */
11651   if (AllocLen == 4)
11652   {
11653     TI_DBG1(("satLogSense: AllocLen is 4\n"));
11654     switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11655     {
11656       case LOGSENSE_SUPPORTED_LOG_PAGES:
11657         TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11658 
11659         /* SAT Rev 8, 10.2.5 p76 */
11660         if (pSatDevData->satSMARTFeatureSet == agTRUE)
11661         {
11662           /* add informational exception log */
11663           flag = 1;
11664           if (pSatDevData->satSMARTSelfTest == agTRUE)
11665           {
11666             /* add Self-Test results log page */
11667             flag = 2;
11668           }
11669         }
11670         else
11671         {
11672           /* only supported, no informational exception log, no  Self-Test results log page */
11673           flag = 0;
11674         }
11675         lenRead = 4;
11676         AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES;          /* page code */
11677         AllLogPages[1] = 0;          /* reserved  */
11678         switch (flag)
11679         {
11680           case 0:
11681             /* only supported */
11682             AllLogPages[2] = 0;          /* page length */
11683             AllLogPages[3] = 1;          /* page length */
11684             break;
11685           case 1:
11686             /* supported and informational exception log */
11687             AllLogPages[2] = 0;          /* page length */
11688             AllLogPages[3] = 2;          /* page length */
11689             break;
11690           case 2:
11691             /* supported and informational exception log */
11692             AllLogPages[2] = 0;          /* page length */
11693             AllLogPages[3] = 3;          /* page length */
11694             break;
11695           default:
11696             TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11697             break;
11698         }
11699         osti_memcpy(pLogPage, &AllLogPages, lenRead);
11700         break;
11701       case LOGSENSE_SELFTEST_RESULTS_PAGE:
11702         TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11703         lenRead = 4;
11704         AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE;          /* page code */
11705         AllLogPages[1] = 0;          /* reserved  */
11706         /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */
11707         AllLogPages[2] = 0x01;
11708         AllLogPages[3] = 0x90;       /* page length */
11709         osti_memcpy(pLogPage, &AllLogPages, lenRead);
11710 
11711         break;
11712       case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11713         TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11714         lenRead = 4;
11715         AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE;          /* page code */
11716         AllLogPages[1] = 0;          /* reserved  */
11717         AllLogPages[2] = 0;          /* page length */
11718         AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3;       /* page length */
11719         osti_memcpy(pLogPage, &AllLogPages, lenRead);
11720         break;
11721       default:
11722         TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11723         satSetSensePayload( pSense,
11724                             SCSI_SNSKEY_ILLEGAL_REQUEST,
11725                             0,
11726                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11727                             satIOContext);
11728 
11729         ostiInitiatorIOCompleted( tiRoot,
11730                                   tiIORequest,
11731                                   tiIOSuccess,
11732                                   SCSI_STAT_CHECK_CONDITION,
11733                                   satIOContext->pTiSenseData,
11734                                   satIOContext->interruptContext );
11735         return tiSuccess;
11736     }
11737     ostiInitiatorIOCompleted( tiRoot,
11738                                 tiIORequest,
11739                                 tiIOSuccess,
11740                                 SCSI_STAT_GOOD,
11741                                 agNULL,
11742                                 satIOContext->interruptContext);
11743     return tiSuccess;
11744 
11745   } /* if */
11746 
11747   /* SAT rev8 Table 11  p30*/
11748   /* checking Page Code */
11749   switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11750   {
11751     case LOGSENSE_SUPPORTED_LOG_PAGES:
11752       TI_DBG5(("satLogSense: case 1\n"));
11753 
11754       /* SAT Rev 8, 10.2.5 p76 */
11755 
11756       if (pSatDevData->satSMARTFeatureSet == agTRUE)
11757       {
11758         /* add informational exception log */
11759         flag = 1;
11760         if (pSatDevData->satSMARTSelfTest == agTRUE)
11761         {
11762           /* add Self-Test results log page */
11763           flag = 2;
11764         }
11765       }
11766       else
11767       {
11768         /* only supported, no informational exception log, no  Self-Test results log page */
11769         flag = 0;
11770       }
11771       AllLogPages[0] = 0;          /* page code */
11772       AllLogPages[1] = 0;          /* reserved  */
11773       switch (flag)
11774       {
11775       case 0:
11776         /* only supported */
11777         AllLogPages[2] = 0;          /* page length */
11778         AllLogPages[3] = 1;          /* page length */
11779         AllLogPages[4] = 0x00;       /* supported page list */
11780         lenRead = (bit8)(MIN(AllocLen, 5));
11781         break;
11782       case 1:
11783         /* supported and informational exception log */
11784         AllLogPages[2] = 0;          /* page length */
11785         AllLogPages[3] = 2;          /* page length */
11786         AllLogPages[4] = 0x00;       /* supported page list */
11787         AllLogPages[5] = 0x10;       /* supported page list */
11788         lenRead = (bit8)(MIN(AllocLen, 6));
11789         break;
11790       case 2:
11791         /* supported and informational exception log */
11792         AllLogPages[2] = 0;          /* page length */
11793         AllLogPages[3] = 3;          /* page length */
11794         AllLogPages[4] = 0x00;       /* supported page list */
11795         AllLogPages[5] = 0x10;       /* supported page list */
11796         AllLogPages[6] = 0x2F;       /* supported page list */
11797        lenRead = (bit8)(MIN(AllocLen, 7));
11798        break;
11799       default:
11800         TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11801         break;
11802       }
11803 
11804       osti_memcpy(pLogPage, &AllLogPages, lenRead);
11805       /* comparing allocation length to Log Page byte size */
11806       /* SPC-4, 4.3.4.6, p28 */
11807       if (AllocLen > lenRead )
11808       {
11809         TI_DBG1(("satLogSense reporting underrun lenRead=0x%x AllocLen=0x%x tiIORequest=%p\n", lenRead, AllocLen, tiIORequest));
11810        ostiInitiatorIOCompleted( tiRoot,
11811                                   tiIORequest,
11812                                   tiIOUnderRun,
11813                                   AllocLen - lenRead,
11814                                   agNULL,
11815                                   satIOContext->interruptContext );
11816       }
11817       else
11818       {
11819         ostiInitiatorIOCompleted( tiRoot,
11820                                   tiIORequest,
11821                                   tiIOSuccess,
11822                                   SCSI_STAT_GOOD,
11823                                   agNULL,
11824                                   satIOContext->interruptContext);
11825       }
11826       break;
11827     case LOGSENSE_SELFTEST_RESULTS_PAGE:
11828       TI_DBG5(("satLogSense: case 2\n"));
11829       /* checking SMART self-test */
11830       if (pSatDevData->satSMARTSelfTest == agFALSE)
11831       {
11832         TI_DBG5(("satLogSense: case 2 no SMART Self Test\n"));
11833         satSetSensePayload( pSense,
11834                             SCSI_SNSKEY_ILLEGAL_REQUEST,
11835                             0,
11836                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11837                             satIOContext);
11838 
11839         ostiInitiatorIOCompleted( tiRoot,
11840                                   tiIORequest,
11841                                   tiIOSuccess,
11842                                   SCSI_STAT_CHECK_CONDITION,
11843                                   satIOContext->pTiSenseData,
11844                                   satIOContext->interruptContext );
11845       }
11846       else
11847       {
11848         /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */
11849         if (pSatDevData->satSMARTEnabled == agFALSE)
11850         {
11851           TI_DBG5(("satLogSense: case 2 calling satSMARTEnable\n"));
11852           status = satLogSenseAllocate(tiRoot,
11853                                        tiIORequest,
11854                                        tiDeviceHandle,
11855                                        tiScsiRequest,
11856                                        satIOContext,
11857                                        0,
11858                                        LOG_SENSE_0
11859                                        );
11860 
11861           return status;
11862 
11863         }
11864         else
11865         {
11866         /* SAT Rev 8, 10.2.4 p74 */
11867         if ( pSatDevData->sat48BitSupport == agTRUE )
11868         {
11869           TI_DBG5(("satLogSense: case 2-1 sends READ LOG EXT\n"));
11870           status = satLogSenseAllocate(tiRoot,
11871                                        tiIORequest,
11872                                        tiDeviceHandle,
11873                                        tiScsiRequest,
11874                                        satIOContext,
11875                                        512,
11876                                        LOG_SENSE_1
11877                                        );
11878 
11879           return status;
11880         }
11881         else
11882         {
11883           TI_DBG5(("satLogSense: case 2-2 sends SMART READ LOG\n"));
11884           status = satLogSenseAllocate(tiRoot,
11885                                        tiIORequest,
11886                                        tiDeviceHandle,
11887                                        tiScsiRequest,
11888                                        satIOContext,
11889                                        512,
11890                                        LOG_SENSE_2
11891                                        );
11892 
11893           return status;
11894         }
11895       }
11896       }
11897       break;
11898     case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11899       TI_DBG5(("satLogSense: case 3\n"));
11900       /* checking SMART feature set */
11901       if (pSatDevData->satSMARTFeatureSet == agFALSE)
11902       {
11903         satSetSensePayload( pSense,
11904                             SCSI_SNSKEY_ILLEGAL_REQUEST,
11905                             0,
11906                             SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11907                             satIOContext);
11908 
11909         ostiInitiatorIOCompleted( tiRoot,
11910                                   tiIORequest,
11911                                   tiIOSuccess,
11912                                   SCSI_STAT_CHECK_CONDITION,
11913                                   satIOContext->pTiSenseData,
11914                                   satIOContext->interruptContext );
11915       }
11916       else
11917       {
11918         /* checking SMART feature enabled */
11919         if (pSatDevData->satSMARTEnabled == agFALSE)
11920         {
11921           satSetSensePayload( pSense,
11922                               SCSI_SNSKEY_ABORTED_COMMAND,
11923                               0,
11924                               SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
11925                               satIOContext);
11926 
11927           ostiInitiatorIOCompleted( tiRoot,
11928                                     tiIORequest,
11929                                     tiIOSuccess,
11930                                     SCSI_STAT_CHECK_CONDITION,
11931                                     satIOContext->pTiSenseData,
11932                                     satIOContext->interruptContext );
11933         }
11934         else
11935         {
11936           /* SAT Rev 8, 10.2.3 p72 */
11937           TI_DBG5(("satLogSense: case 3 sends SMART RETURN STATUS\n"));
11938 
11939           /* sends SMART RETURN STATUS */
11940           fis->h.fisType        = 0x27;                   /* Reg host to device */
11941           fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11942 
11943           fis->h.command        = SAT_SMART_RETURN_STATUS;/* 0xB0 */
11944           fis->h.features       = 0xDA;                   /* FIS features */
11945           fis->d.featuresExp    = 0;                      /* FIS reserve */
11946           fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
11947           fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
11948           fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
11949           fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
11950           fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
11951           fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
11952           fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
11953           fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
11954           fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
11955           fis->d.control        = 0;                      /* FIS HOB bit clear */
11956           fis->d.reserved4      = 0;
11957           fis->d.reserved5      = 0;
11958 
11959           agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11960           /* Initialize CB for SATA completion.
11961            */
11962           satIOContext->satCompleteCB = &satLogSenseCB;
11963 
11964           /*
11965            * Prepare SGL and send FIS to LL layer.
11966            */
11967           satIOContext->reqType = agRequestType;       /* Save it */
11968 
11969           status = sataLLIOStart( tiRoot,
11970                                   tiIORequest,
11971                                   tiDeviceHandle,
11972                                   tiScsiRequest,
11973                                   satIOContext);
11974 
11975 
11976           return status;
11977         }
11978       }
11979       break;
11980     default:
11981       TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11982       satSetSensePayload( pSense,
11983                           SCSI_SNSKEY_ILLEGAL_REQUEST,
11984                           0,
11985                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11986                           satIOContext);
11987 
11988       ostiInitiatorIOCompleted( tiRoot,
11989                                 tiIORequest,
11990                                 tiIOSuccess,
11991                                 SCSI_STAT_CHECK_CONDITION,
11992                                 satIOContext->pTiSenseData,
11993                                 satIOContext->interruptContext );
11994 
11995       break;
11996   } /* end switch */
11997 
11998   return tiSuccess;
11999 
12000 
12001 }
12002 
12003 /*****************************************************************************/
12004 /*! \brief SAT implementation for SCSI satModeSelect6.
12005  *
12006  *  SAT implementation for SCSI satModeSelect6.
12007  *
12008  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
12009  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
12010  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
12011  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
12012  *  \param   satIOContext_t:   Pointer to the SAT IO Context
12013  *
12014  *  \return If command is started successfully
12015  *    - \e tiSuccess:     I/O request successfully initiated.
12016  *    - \e tiBusy:        No resources available, try again later.
12017  *    - \e tiIONoDevice:  Invalid device handle.
12018  *    - \e tiError:       Other errors.
12019  */
12020 /*****************************************************************************/
12021 GLOBAL bit32  satModeSelect6(
12022                    tiRoot_t                  *tiRoot,
12023                    tiIORequest_t             *tiIORequest,
12024                    tiDeviceHandle_t          *tiDeviceHandle,
12025                    tiScsiInitiatorRequest_t *tiScsiRequest,
12026                    satIOContext_t            *satIOContext)
12027 {
12028   bit32                     status;
12029   bit32                     agRequestType;
12030   satDeviceData_t           *pSatDevData;
12031   scsiRspSense_t            *pSense;
12032   tiIniScsiCmnd_t           *scsiCmnd;
12033   agsaFisRegHostToDevice_t  *fis;
12034   bit8                      *pLogPage;    /* Log Page data buffer */
12035   bit32                     StartingIndex = 0;
12036   bit8                      PageCode = 0;
12037   bit32                     chkCnd = agFALSE;
12038 
12039   pSense        = satIOContext->pSense;
12040   pSatDevData   = satIOContext->pSatDevData;
12041   scsiCmnd      = &tiScsiRequest->scsiCmnd;
12042   fis           = satIOContext->pFis;
12043   pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
12044 
12045   TI_DBG5(("satModeSelect6: start\n"));
12046 
12047   /* checking CONTROL */
12048   /* NACA == 1 or LINK == 1*/
12049   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
12050   {
12051     satSetSensePayload( pSense,
12052                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12053                         0,
12054                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12055                         satIOContext);
12056 
12057     ostiInitiatorIOCompleted( tiRoot,
12058                               tiIORequest,
12059                               tiIOSuccess,
12060                               SCSI_STAT_CHECK_CONDITION,
12061                               satIOContext->pTiSenseData,
12062                               satIOContext->interruptContext );
12063 
12064     TI_DBG2(("satModeSelect6: return control\n"));
12065     return tiSuccess;
12066   }
12067 
12068   /* checking PF bit */
12069   if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
12070   {
12071     satSetSensePayload( pSense,
12072                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12073                         0,
12074                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12075                         satIOContext);
12076 
12077     ostiInitiatorIOCompleted( tiRoot,
12078                               tiIORequest,
12079                               tiIOSuccess,
12080                               SCSI_STAT_CHECK_CONDITION,
12081                               satIOContext->pTiSenseData,
12082                               satIOContext->interruptContext );
12083 
12084     TI_DBG1(("satModeSelect6: PF bit check \n"));
12085     return tiSuccess;
12086 
12087   }
12088 
12089   /* checking Block Descriptor Length on Mode parameter header(6)*/
12090   if (pLogPage[3] == 8)
12091   {
12092     /* mode parameter block descriptor exists */
12093     PageCode = (bit8)(pLogPage[12] & 0x3F);   /* page code and index is 4 + 8 */
12094     StartingIndex = 12;
12095   }
12096   else if (pLogPage[3] == 0)
12097   {
12098     /* mode parameter block descriptor does not exist */
12099     PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */
12100     StartingIndex = 4;
12101     ostiInitiatorIOCompleted( tiRoot,
12102                               tiIORequest,
12103                               tiIOSuccess,
12104                               SCSI_STAT_GOOD,
12105                               agNULL,
12106                               satIOContext->interruptContext);
12107     return tiSuccess;
12108   }
12109   else
12110   {
12111     TI_DBG1(("satModeSelect6: return mode parameter block descriptor 0x%x\n", pLogPage[3]));
12112     /* no more than one mode parameter block descriptor shall be supported */
12113     satSetSensePayload( pSense,
12114                         SCSI_SNSKEY_NO_SENSE,
12115                         0,
12116                         SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12117                         satIOContext);
12118 
12119     ostiInitiatorIOCompleted( tiRoot,
12120                               tiIORequest,
12121                               tiIOSuccess,
12122                               SCSI_STAT_CHECK_CONDITION,
12123                               satIOContext->pTiSenseData,
12124                               satIOContext->interruptContext );
12125     return tiSuccess;
12126   }
12127 
12128 
12129 
12130   switch (PageCode) /* page code */
12131   {
12132   case MODESELECT_CONTROL_PAGE:
12133     TI_DBG1(("satModeSelect6: Control mode page\n"));
12134     /*
12135       compare pLogPage to expected value (SAT Table 65, p67)
12136       If not match, return check condition
12137      */
12138     if ( pLogPage[StartingIndex+1] != 0x0A ||
12139          pLogPage[StartingIndex+2] != 0x02 ||
12140          (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12141          (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12142          (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12143          (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12144          (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12145 
12146          (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12147          (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12148          (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12149          (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12150 
12151          pLogPage[StartingIndex+8] != 0xFF ||
12152          pLogPage[StartingIndex+9] != 0xFF ||
12153          pLogPage[StartingIndex+10] != 0x00 ||
12154          pLogPage[StartingIndex+11] != 0x00
12155        )
12156     {
12157       chkCnd = agTRUE;
12158     }
12159     if (chkCnd == agTRUE)
12160     {
12161       satSetSensePayload( pSense,
12162                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12163                         0,
12164                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12165                         satIOContext);
12166 
12167       ostiInitiatorIOCompleted( tiRoot,
12168                               tiIORequest,
12169                               tiIOSuccess,
12170                               SCSI_STAT_CHECK_CONDITION,
12171                               satIOContext->pTiSenseData,
12172                               satIOContext->interruptContext );
12173 
12174       TI_DBG1(("satModeSelect10: unexpected values\n"));
12175     }
12176     else
12177     {
12178       ostiInitiatorIOCompleted( tiRoot,
12179                                 tiIORequest,
12180                                 tiIOSuccess,
12181                                 SCSI_STAT_GOOD,
12182                                 agNULL,
12183                                 satIOContext->interruptContext);
12184     }
12185     return tiSuccess;
12186     break;
12187   case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12188     TI_DBG1(("satModeSelect6: Read-Write Error Recovery mode page\n"));
12189 
12190     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) ||
12191          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) ||
12192          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) ||
12193          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) ||
12194          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) ||
12195          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) ||
12196          (pLogPage[StartingIndex + 10]) ||
12197          (pLogPage[StartingIndex + 11])
12198          )
12199     {
12200       TI_DBG5(("satModeSelect6: return check condition \n"));
12201 
12202       satSetSensePayload( pSense,
12203                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12204                           0,
12205                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12206                           satIOContext);
12207 
12208       ostiInitiatorIOCompleted( tiRoot,
12209                                 tiIORequest,
12210                                 tiIOSuccess,
12211                                 SCSI_STAT_CHECK_CONDITION,
12212                                 satIOContext->pTiSenseData,
12213                                 satIOContext->interruptContext );
12214       return tiSuccess;
12215     }
12216     else
12217     {
12218       TI_DBG5(("satModeSelect6: return GOOD \n"));
12219       ostiInitiatorIOCompleted( tiRoot,
12220                                 tiIORequest,
12221                                 tiIOSuccess,
12222                                 SCSI_STAT_GOOD,
12223                                 agNULL,
12224                                 satIOContext->interruptContext);
12225       return tiSuccess;
12226     }
12227 
12228     break;
12229   case MODESELECT_CACHING:
12230     /* SAT rev8 Table67, p69*/
12231     TI_DBG5(("satModeSelect6: Caching mode page\n"));
12232     if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12233          (pLogPage[StartingIndex + 3]) ||
12234          (pLogPage[StartingIndex + 4]) ||
12235          (pLogPage[StartingIndex + 5]) ||
12236          (pLogPage[StartingIndex + 6]) ||
12237          (pLogPage[StartingIndex + 7]) ||
12238          (pLogPage[StartingIndex + 8]) ||
12239          (pLogPage[StartingIndex + 9]) ||
12240          (pLogPage[StartingIndex + 10]) ||
12241          (pLogPage[StartingIndex + 11]) ||
12242 
12243          (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12244          (pLogPage[StartingIndex + 13]) ||
12245          (pLogPage[StartingIndex + 14]) ||
12246          (pLogPage[StartingIndex + 15])
12247          )
12248     {
12249       TI_DBG1(("satModeSelect6: return check condition \n"));
12250 
12251       satSetSensePayload( pSense,
12252                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12253                           0,
12254                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12255                           satIOContext);
12256 
12257       ostiInitiatorIOCompleted( tiRoot,
12258                                 tiIORequest,
12259                                 tiIOSuccess,
12260                                 SCSI_STAT_CHECK_CONDITION,
12261                                 satIOContext->pTiSenseData,
12262                                 satIOContext->interruptContext );
12263       return tiSuccess;
12264 
12265     }
12266     else
12267     {
12268       /* sends ATA SET FEATURES based on WCE bit */
12269       if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
12270       {
12271         TI_DBG5(("satModeSelect6: disable write cache\n"));
12272         /* sends SET FEATURES */
12273         fis->h.fisType        = 0x27;                   /* Reg host to device */
12274         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12275 
12276         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12277         fis->h.features       = 0x82;                   /* disable write cache */
12278         fis->d.lbaLow         = 0;                      /* */
12279         fis->d.lbaMid         = 0;                      /* */
12280         fis->d.lbaHigh        = 0;                      /* */
12281         fis->d.device         = 0;                      /* */
12282         fis->d.lbaLowExp      = 0;                      /* */
12283         fis->d.lbaMidExp      = 0;                      /* */
12284         fis->d.lbaHighExp     = 0;                      /* */
12285         fis->d.featuresExp    = 0;                      /* */
12286         fis->d.sectorCount    = 0;                      /* */
12287         fis->d.sectorCountExp = 0;                      /* */
12288         fis->d.reserved4      = 0;
12289         fis->d.control        = 0;                      /* FIS HOB bit clear */
12290         fis->d.reserved5      = 0;
12291 
12292         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12293 
12294         /* Initialize CB for SATA completion.
12295          */
12296         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12297 
12298         /*
12299          * Prepare SGL and send FIS to LL layer.
12300          */
12301         satIOContext->reqType = agRequestType;       /* Save it */
12302 
12303         status = sataLLIOStart( tiRoot,
12304                                 tiIORequest,
12305                                 tiDeviceHandle,
12306                                 tiScsiRequest,
12307                                 satIOContext);
12308         return status;
12309       }
12310       else
12311       {
12312         TI_DBG5(("satModeSelect6: enable write cache\n"));
12313         /* sends SET FEATURES */
12314         fis->h.fisType        = 0x27;                   /* Reg host to device */
12315         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12316 
12317         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12318         fis->h.features       = 0x02;                   /* enable write cache */
12319         fis->d.lbaLow         = 0;                      /* */
12320         fis->d.lbaMid         = 0;                      /* */
12321         fis->d.lbaHigh        = 0;                      /* */
12322         fis->d.device         = 0;                      /* */
12323         fis->d.lbaLowExp      = 0;                      /* */
12324         fis->d.lbaMidExp      = 0;                      /* */
12325         fis->d.lbaHighExp     = 0;                      /* */
12326         fis->d.featuresExp    = 0;                      /* */
12327         fis->d.sectorCount    = 0;                      /* */
12328         fis->d.sectorCountExp = 0;                      /* */
12329         fis->d.reserved4      = 0;
12330         fis->d.control        = 0;                      /* FIS HOB bit clear */
12331         fis->d.reserved5      = 0;
12332 
12333         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12334 
12335         /* Initialize CB for SATA completion.
12336          */
12337         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12338 
12339         /*
12340          * Prepare SGL and send FIS to LL layer.
12341          */
12342         satIOContext->reqType = agRequestType;       /* Save it */
12343 
12344         status = sataLLIOStart( tiRoot,
12345                                 tiIORequest,
12346                                 tiDeviceHandle,
12347                                 tiScsiRequest,
12348                                 satIOContext);
12349         return status;
12350 
12351       }
12352     }
12353     break;
12354   case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
12355     TI_DBG5(("satModeSelect6: Informational Exception Control mode page\n"));
12356     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
12357          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
12358          )
12359     {
12360       TI_DBG1(("satModeSelect6: return check condition \n"));
12361 
12362       satSetSensePayload( pSense,
12363                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12364                           0,
12365                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12366                           satIOContext);
12367 
12368       ostiInitiatorIOCompleted( tiRoot,
12369                                 tiIORequest,
12370                                 tiIOSuccess,
12371                                 SCSI_STAT_CHECK_CONDITION,
12372                                 satIOContext->pTiSenseData,
12373                                 satIOContext->interruptContext );
12374       return tiSuccess;
12375     }
12376     else
12377     {
12378       /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
12379       if ( !(pLogPage[StartingIndex + 2] & 0x08) )
12380       {
12381         TI_DBG5(("satModeSelect6: enable information exceptions reporting\n"));
12382         /* sends SMART ENABLE OPERATIONS */
12383         fis->h.fisType        = 0x27;                   /* Reg host to device */
12384         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12385 
12386         fis->h.command        = SAT_SMART_ENABLE_OPERATIONS;       /* 0xB0 */
12387         fis->h.features       = 0xD8;                   /* enable */
12388         fis->d.lbaLow         = 0;                      /* */
12389         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
12390         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
12391         fis->d.device         = 0;                      /* */
12392         fis->d.lbaLowExp      = 0;                      /* */
12393         fis->d.lbaMidExp      = 0;                      /* */
12394         fis->d.lbaHighExp     = 0;                      /* */
12395         fis->d.featuresExp    = 0;                      /* */
12396         fis->d.sectorCount    = 0;                      /* */
12397         fis->d.sectorCountExp = 0;                      /* */
12398         fis->d.reserved4      = 0;
12399         fis->d.control        = 0;                      /* FIS HOB bit clear */
12400         fis->d.reserved5      = 0;
12401 
12402         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12403 
12404         /* Initialize CB for SATA completion.
12405          */
12406         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12407 
12408         /*
12409          * Prepare SGL and send FIS to LL layer.
12410          */
12411         satIOContext->reqType = agRequestType;       /* Save it */
12412 
12413         status = sataLLIOStart( tiRoot,
12414                                 tiIORequest,
12415                                 tiDeviceHandle,
12416                                 tiScsiRequest,
12417                                 satIOContext);
12418         return status;
12419       }
12420       else
12421       {
12422         TI_DBG5(("satModeSelect6: disable information exceptions reporting\n"));
12423         /* sends SMART DISABLE OPERATIONS */
12424         fis->h.fisType        = 0x27;                   /* Reg host to device */
12425         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12426 
12427         fis->h.command        = SAT_SMART_DISABLE_OPERATIONS;       /* 0xB0 */
12428         fis->h.features       = 0xD9;                   /* disable */
12429         fis->d.lbaLow         = 0;                      /* */
12430         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
12431         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
12432         fis->d.device         = 0;                      /* */
12433         fis->d.lbaLowExp      = 0;                      /* */
12434         fis->d.lbaMidExp      = 0;                      /* */
12435         fis->d.lbaHighExp     = 0;                      /* */
12436         fis->d.featuresExp    = 0;                      /* */
12437         fis->d.sectorCount    = 0;                      /* */
12438         fis->d.sectorCountExp = 0;                      /* */
12439         fis->d.reserved4      = 0;
12440         fis->d.control        = 0;                      /* FIS HOB bit clear */
12441         fis->d.reserved5      = 0;
12442 
12443         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12444 
12445         /* Initialize CB for SATA completion.
12446          */
12447         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12448 
12449         /*
12450          * Prepare SGL and send FIS to LL layer.
12451          */
12452         satIOContext->reqType = agRequestType;       /* Save it */
12453 
12454         status = sataLLIOStart( tiRoot,
12455                                 tiIORequest,
12456                                 tiDeviceHandle,
12457                                 tiScsiRequest,
12458                                 satIOContext);
12459         return status;
12460 
12461       }
12462     }
12463     break;
12464   default:
12465     TI_DBG1(("satModeSelect6: Error unknown page code 0x%x\n", pLogPage[12]));
12466     satSetSensePayload( pSense,
12467                         SCSI_SNSKEY_NO_SENSE,
12468                         0,
12469                         SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12470                         satIOContext);
12471 
12472     ostiInitiatorIOCompleted( tiRoot,
12473                               tiIORequest,
12474                               tiIOSuccess,
12475                               SCSI_STAT_CHECK_CONDITION,
12476                               satIOContext->pTiSenseData,
12477                               satIOContext->interruptContext );
12478     return tiSuccess;
12479   }
12480 
12481 }
12482 
12483 /*****************************************************************************/
12484 /*! \brief SAT implementation for SCSI satModeSelect6n10_1.
12485  *
12486  *  This function is part of implementation of ModeSelect6 and ModeSelect10.
12487  *  When ModeSelect6 or ModeSelect10 is coverted into multiple ATA commands,
12488  *  this function is used.
12489  *
12490  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
12491  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
12492  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
12493  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
12494  *  \param   satIOContext_t:   Pointer to the SAT IO Context
12495  *
12496  *  \return If command is started successfully
12497  *    - \e tiSuccess:     I/O request successfully initiated.
12498  *    - \e tiBusy:        No resources available, try again later.
12499  *    - \e tiIONoDevice:  Invalid device handle.
12500  *    - \e tiError:       Other errors.
12501  */
12502 /*****************************************************************************/
12503 GLOBAL bit32  satModeSelect6n10_1(
12504                    tiRoot_t                  *tiRoot,
12505                    tiIORequest_t             *tiIORequest,
12506                    tiDeviceHandle_t          *tiDeviceHandle,
12507                    tiScsiInitiatorRequest_t *tiScsiRequest,
12508                    satIOContext_t            *satIOContext)
12509 {
12510   /* sends either ATA SET FEATURES based on DRA bit */
12511   bit32                     status;
12512   bit32                     agRequestType;
12513   agsaFisRegHostToDevice_t  *fis;
12514   bit8                      *pLogPage;    /* Log Page data buffer */
12515   bit32                     StartingIndex = 0;
12516 
12517   fis           = satIOContext->pFis;
12518   pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
12519   TI_DBG5(("satModeSelect6_1: start\n"));
12520   /* checking Block Descriptor Length on Mode parameter header(6)*/
12521   if (pLogPage[3] == 8)
12522   {
12523     /* mode parameter block descriptor exists */
12524     StartingIndex = 12;
12525   }
12526   else
12527   {
12528     /* mode parameter block descriptor does not exist */
12529     StartingIndex = 4;
12530   }
12531 
12532   /* sends ATA SET FEATURES based on DRA bit */
12533   if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
12534   {
12535     TI_DBG5(("satModeSelect6_1: enable read look-ahead feature\n"));
12536     /* sends SET FEATURES */
12537     fis->h.fisType        = 0x27;                   /* Reg host to device */
12538     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12539 
12540     fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12541     fis->h.features       = 0xAA;                   /* enable read look-ahead */
12542     fis->d.lbaLow         = 0;                      /* */
12543     fis->d.lbaMid         = 0;                      /* */
12544     fis->d.lbaHigh        = 0;                      /* */
12545     fis->d.device         = 0;                      /* */
12546     fis->d.lbaLowExp      = 0;                      /* */
12547     fis->d.lbaMidExp      = 0;                      /* */
12548     fis->d.lbaHighExp     = 0;                      /* */
12549     fis->d.featuresExp    = 0;                      /* */
12550     fis->d.sectorCount    = 0;                      /* */
12551     fis->d.sectorCountExp = 0;                      /* */
12552     fis->d.reserved4      = 0;
12553     fis->d.control        = 0;                      /* FIS HOB bit clear */
12554     fis->d.reserved5      = 0;
12555 
12556     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12557 
12558     /* Initialize CB for SATA completion.
12559      */
12560     satIOContext->satCompleteCB = &satModeSelect6n10CB;
12561 
12562     /*
12563      * Prepare SGL and send FIS to LL layer.
12564      */
12565     satIOContext->reqType = agRequestType;       /* Save it */
12566 
12567     status = sataLLIOStart( tiRoot,
12568                             tiIORequest,
12569                             tiDeviceHandle,
12570                             tiScsiRequest,
12571                             satIOContext);
12572     return status;
12573   }
12574   else
12575   {
12576     TI_DBG5(("satModeSelect6_1: disable read look-ahead feature\n"));
12577         /* sends SET FEATURES */
12578     fis->h.fisType        = 0x27;                   /* Reg host to device */
12579     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12580 
12581     fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12582     fis->h.features       = 0x55;                   /* disable read look-ahead */
12583     fis->d.lbaLow         = 0;                      /* */
12584     fis->d.lbaMid         = 0;                      /* */
12585     fis->d.lbaHigh        = 0;                      /* */
12586     fis->d.device         = 0;                      /* */
12587     fis->d.lbaLowExp      = 0;                      /* */
12588     fis->d.lbaMidExp      = 0;                      /* */
12589     fis->d.lbaHighExp     = 0;                      /* */
12590     fis->d.featuresExp    = 0;                      /* */
12591     fis->d.sectorCount    = 0;                      /* */
12592     fis->d.sectorCountExp = 0;                      /* */
12593     fis->d.reserved4      = 0;
12594     fis->d.control        = 0;                      /* FIS HOB bit clear */
12595     fis->d.reserved5      = 0;
12596 
12597     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12598 
12599     /* Initialize CB for SATA completion.
12600      */
12601     satIOContext->satCompleteCB = &satModeSelect6n10CB;
12602 
12603     /*
12604      * Prepare SGL and send FIS to LL layer.
12605      */
12606     satIOContext->reqType = agRequestType;       /* Save it */
12607 
12608     status = sataLLIOStart( tiRoot,
12609                             tiIORequest,
12610                             tiDeviceHandle,
12611                             tiScsiRequest,
12612                             satIOContext);
12613     return status;
12614   }
12615 
12616 }
12617 
12618 
12619 /*****************************************************************************/
12620 /*! \brief SAT implementation for SCSI satModeSelect10.
12621  *
12622  *  SAT implementation for SCSI satModeSelect10.
12623  *
12624  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
12625  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
12626  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
12627  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
12628  *  \param   satIOContext_t:   Pointer to the SAT IO Context
12629  *
12630  *  \return If command is started successfully
12631  *    - \e tiSuccess:     I/O request successfully initiated.
12632  *    - \e tiBusy:        No resources available, try again later.
12633  *    - \e tiIONoDevice:  Invalid device handle.
12634  *    - \e tiError:       Other errors.
12635  */
12636 /*****************************************************************************/
12637 GLOBAL bit32  satModeSelect10(
12638                    tiRoot_t                  *tiRoot,
12639                    tiIORequest_t             *tiIORequest,
12640                    tiDeviceHandle_t          *tiDeviceHandle,
12641                    tiScsiInitiatorRequest_t *tiScsiRequest,
12642                    satIOContext_t            *satIOContext)
12643 {
12644   bit32                     status;
12645   bit32                     agRequestType;
12646   satDeviceData_t           *pSatDevData;
12647   scsiRspSense_t            *pSense;
12648   tiIniScsiCmnd_t           *scsiCmnd;
12649   agsaFisRegHostToDevice_t  *fis;
12650   bit8                      *pLogPage;    /* Log Page data buffer */
12651   bit16                     BlkDescLen = 0;     /* Block Descriptor Length */
12652   bit32                     StartingIndex = 0;
12653   bit8                      PageCode = 0;
12654   bit32                     chkCnd = agFALSE;
12655 
12656   pSense        = satIOContext->pSense;
12657   pSatDevData   = satIOContext->pSatDevData;
12658   scsiCmnd      = &tiScsiRequest->scsiCmnd;
12659   fis           = satIOContext->pFis;
12660   pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
12661 
12662   TI_DBG5(("satModeSelect10: start\n"));
12663 
12664   /* checking CONTROL */
12665   /* NACA == 1 or LINK == 1*/
12666   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
12667   {
12668     satSetSensePayload( pSense,
12669                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12670                         0,
12671                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12672                         satIOContext);
12673 
12674     ostiInitiatorIOCompleted( tiRoot,
12675                               tiIORequest,
12676                               tiIOSuccess,
12677                               SCSI_STAT_CHECK_CONDITION,
12678                               satIOContext->pTiSenseData,
12679                               satIOContext->interruptContext );
12680 
12681     TI_DBG2(("satModeSelect10: return control\n"));
12682     return tiSuccess;
12683   }
12684 
12685   /* checking PF bit */
12686   if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
12687   {
12688     satSetSensePayload( pSense,
12689                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12690                         0,
12691                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12692                         satIOContext);
12693 
12694     ostiInitiatorIOCompleted( tiRoot,
12695                               tiIORequest,
12696                               tiIOSuccess,
12697                               SCSI_STAT_CHECK_CONDITION,
12698                               satIOContext->pTiSenseData,
12699                               satIOContext->interruptContext );
12700 
12701     TI_DBG1(("satModeSelect10: PF bit check \n"));
12702     return tiSuccess;
12703 
12704   }
12705 
12706   BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]);
12707 
12708   /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/
12709   if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12710   {
12711     /* mode parameter block descriptor exists and length is 8 byte */
12712     PageCode = (bit8)(pLogPage[16] & 0x3F);   /* page code and index is 8 + 8 */
12713     StartingIndex = 16;
12714   }
12715   else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12716   {
12717     /* mode parameter block descriptor exists and length is 16 byte */
12718     PageCode = (bit8)(pLogPage[24] & 0x3F);   /* page code and index is 8 + 16 */
12719     StartingIndex = 24;
12720   }
12721   else if (BlkDescLen == 0)
12722   {
12723     /*
12724       mode parameter block descriptor does not exist
12725       */
12726     PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */
12727     StartingIndex = 8;
12728     ostiInitiatorIOCompleted( tiRoot,
12729                               tiIORequest,
12730                               tiIOSuccess,
12731                               SCSI_STAT_GOOD,
12732                               agNULL,
12733                               satIOContext->interruptContext);
12734     return tiSuccess;
12735   }
12736   else
12737   {
12738     TI_DBG1(("satModeSelect10: return mode parameter block descriptor 0x%x\n",  BlkDescLen));
12739     /* no more than one mode parameter block descriptor shall be supported */
12740     satSetSensePayload( pSense,
12741                         SCSI_SNSKEY_NO_SENSE,
12742                         0,
12743                         SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12744                         satIOContext);
12745 
12746     ostiInitiatorIOCompleted( tiRoot,
12747                               tiIORequest,
12748                               tiIOSuccess,
12749                               SCSI_STAT_CHECK_CONDITION,
12750                               satIOContext->pTiSenseData,
12751                               satIOContext->interruptContext );
12752     return tiSuccess;
12753   }
12754   /*
12755     for debugging only
12756   */
12757   if (StartingIndex == 8)
12758   {
12759     tdhexdump("startingindex 8", (bit8 *)pLogPage, 8);
12760   }
12761   else if(StartingIndex == 16)
12762   {
12763     if (PageCode == MODESELECT_CACHING)
12764     {
12765       tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
12766     }
12767     else
12768     {
12769       tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
12770     }
12771   }
12772   else
12773   {
12774     if (PageCode == MODESELECT_CACHING)
12775     {
12776       tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
12777     }
12778     else
12779     {
12780       tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
12781     }
12782   }
12783   switch (PageCode) /* page code */
12784   {
12785   case MODESELECT_CONTROL_PAGE:
12786     TI_DBG5(("satModeSelect10: Control mode page\n"));
12787     /*
12788       compare pLogPage to expected value (SAT Table 65, p67)
12789       If not match, return check condition
12790      */
12791     if ( pLogPage[StartingIndex+1] != 0x0A ||
12792          pLogPage[StartingIndex+2] != 0x02 ||
12793          (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12794          (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12795          (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12796          (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12797          (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12798 
12799          (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12800          (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12801          (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12802          (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12803 
12804          pLogPage[StartingIndex+8] != 0xFF ||
12805          pLogPage[StartingIndex+9] != 0xFF ||
12806          pLogPage[StartingIndex+10] != 0x00 ||
12807          pLogPage[StartingIndex+11] != 0x00
12808        )
12809     {
12810       chkCnd = agTRUE;
12811     }
12812     if (chkCnd == agTRUE)
12813     {
12814       satSetSensePayload( pSense,
12815                         SCSI_SNSKEY_ILLEGAL_REQUEST,
12816                         0,
12817                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12818                         satIOContext);
12819 
12820       ostiInitiatorIOCompleted( tiRoot,
12821                               tiIORequest,
12822                               tiIOSuccess,
12823                               SCSI_STAT_CHECK_CONDITION,
12824                               satIOContext->pTiSenseData,
12825                               satIOContext->interruptContext );
12826 
12827       TI_DBG1(("satModeSelect10: unexpected values\n"));
12828     }
12829     else
12830     {
12831       ostiInitiatorIOCompleted( tiRoot,
12832                               tiIORequest,
12833                               tiIOSuccess,
12834                               SCSI_STAT_GOOD,
12835                               agNULL,
12836                               satIOContext->interruptContext);
12837     }
12838     return tiSuccess;
12839     break;
12840   case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12841     TI_DBG5(("satModeSelect10: Read-Write Error Recovery mode page\n"));
12842     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) ||
12843          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) ||
12844          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) ||
12845          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) ||
12846          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) ||
12847          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) ||
12848          (pLogPage[StartingIndex + 10]) ||
12849          (pLogPage[StartingIndex + 11])
12850          )
12851     {
12852       TI_DBG1(("satModeSelect10: return check condition \n"));
12853 
12854       satSetSensePayload( pSense,
12855                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12856                           0,
12857                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12858                           satIOContext);
12859 
12860       ostiInitiatorIOCompleted( tiRoot,
12861                                 tiIORequest,
12862                                 tiIOSuccess,
12863                                 SCSI_STAT_CHECK_CONDITION,
12864                                 satIOContext->pTiSenseData,
12865                                 satIOContext->interruptContext );
12866       return tiSuccess;
12867     }
12868     else
12869     {
12870       TI_DBG2(("satModeSelect10: return GOOD \n"));
12871       ostiInitiatorIOCompleted( tiRoot,
12872                                 tiIORequest,
12873                                 tiIOSuccess,
12874                                 SCSI_STAT_GOOD,
12875                                 agNULL,
12876                                 satIOContext->interruptContext);
12877       return tiSuccess;
12878     }
12879 
12880     break;
12881   case MODESELECT_CACHING:
12882     /* SAT rev8 Table67, p69*/
12883     TI_DBG5(("satModeSelect10: Caching mode page\n"));
12884     if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12885          (pLogPage[StartingIndex + 3]) ||
12886          (pLogPage[StartingIndex + 4]) ||
12887          (pLogPage[StartingIndex + 5]) ||
12888          (pLogPage[StartingIndex + 6]) ||
12889          (pLogPage[StartingIndex + 7]) ||
12890          (pLogPage[StartingIndex + 8]) ||
12891          (pLogPage[StartingIndex + 9]) ||
12892          (pLogPage[StartingIndex + 10]) ||
12893          (pLogPage[StartingIndex + 11]) ||
12894 
12895          (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12896          (pLogPage[StartingIndex + 13]) ||
12897          (pLogPage[StartingIndex + 14]) ||
12898          (pLogPage[StartingIndex + 15])
12899          )
12900     {
12901       TI_DBG1(("satModeSelect10: return check condition \n"));
12902 
12903       satSetSensePayload( pSense,
12904                           SCSI_SNSKEY_ILLEGAL_REQUEST,
12905                           0,
12906                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12907                           satIOContext);
12908 
12909       ostiInitiatorIOCompleted( tiRoot,
12910                                 tiIORequest,
12911                                 tiIOSuccess,
12912                                 SCSI_STAT_CHECK_CONDITION,
12913                                 satIOContext->pTiSenseData,
12914                                 satIOContext->interruptContext );
12915       return tiSuccess;
12916 
12917     }
12918     else
12919     {
12920       /* sends ATA SET FEATURES based on WCE bit */
12921       if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
12922       {
12923         TI_DBG5(("satModeSelect10: disable write cache\n"));
12924         /* sends SET FEATURES */
12925         fis->h.fisType        = 0x27;                   /* Reg host to device */
12926         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12927 
12928         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12929         fis->h.features       = 0x82;                   /* disable write cache */
12930         fis->d.lbaLow         = 0;                      /* */
12931         fis->d.lbaMid         = 0;                      /* */
12932         fis->d.lbaHigh        = 0;                      /* */
12933         fis->d.device         = 0;                      /* */
12934         fis->d.lbaLowExp      = 0;                      /* */
12935         fis->d.lbaMidExp      = 0;                      /* */
12936         fis->d.lbaHighExp     = 0;                      /* */
12937         fis->d.featuresExp    = 0;                      /* */
12938         fis->d.sectorCount    = 0;                      /* */
12939         fis->d.sectorCountExp = 0;                      /* */
12940         fis->d.reserved4      = 0;
12941         fis->d.control        = 0;                      /* FIS HOB bit clear */
12942         fis->d.reserved5      = 0;
12943 
12944         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12945 
12946         /* Initialize CB for SATA completion.
12947          */
12948         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12949 
12950         /*
12951          * Prepare SGL and send FIS to LL layer.
12952          */
12953         satIOContext->reqType = agRequestType;       /* Save it */
12954 
12955         status = sataLLIOStart( tiRoot,
12956                                 tiIORequest,
12957                                 tiDeviceHandle,
12958                                 tiScsiRequest,
12959                                 satIOContext);
12960         return status;
12961       }
12962       else
12963       {
12964         TI_DBG5(("satModeSelect10: enable write cache\n"));
12965         /* sends SET FEATURES */
12966         fis->h.fisType        = 0x27;                   /* Reg host to device */
12967         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12968 
12969         fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12970         fis->h.features       = 0x02;                   /* enable write cache */
12971         fis->d.lbaLow         = 0;                      /* */
12972         fis->d.lbaMid         = 0;                      /* */
12973         fis->d.lbaHigh        = 0;                      /* */
12974         fis->d.device         = 0;                      /* */
12975         fis->d.lbaLowExp      = 0;                      /* */
12976         fis->d.lbaMidExp      = 0;                      /* */
12977         fis->d.lbaHighExp     = 0;                      /* */
12978         fis->d.featuresExp    = 0;                      /* */
12979         fis->d.sectorCount    = 0;                      /* */
12980         fis->d.sectorCountExp = 0;                      /* */
12981         fis->d.reserved4      = 0;
12982         fis->d.control        = 0;                      /* FIS HOB bit clear */
12983         fis->d.reserved5      = 0;
12984 
12985         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12986 
12987         /* Initialize CB for SATA completion.
12988          */
12989         satIOContext->satCompleteCB = &satModeSelect6n10CB;
12990 
12991         /*
12992          * Prepare SGL and send FIS to LL layer.
12993          */
12994         satIOContext->reqType = agRequestType;       /* Save it */
12995 
12996         status = sataLLIOStart( tiRoot,
12997                                 tiIORequest,
12998                                 tiDeviceHandle,
12999                                 tiScsiRequest,
13000                                 satIOContext);
13001         return status;
13002 
13003       }
13004     }
13005     break;
13006   case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
13007     TI_DBG5(("satModeSelect10: Informational Exception Control mode page\n"));
13008 
13009     if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
13010          (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
13011          )
13012     {
13013       TI_DBG1(("satModeSelect10: return check condition \n"));
13014 
13015       satSetSensePayload( pSense,
13016                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13017                           0,
13018                           SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13019                           satIOContext);
13020 
13021       ostiInitiatorIOCompleted( tiRoot,
13022                                 tiIORequest,
13023                                 tiIOSuccess,
13024                                 SCSI_STAT_CHECK_CONDITION,
13025                                 satIOContext->pTiSenseData,
13026                                 satIOContext->interruptContext );
13027       return tiSuccess;
13028     }
13029     else
13030     {
13031       /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
13032       if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
13033       {
13034         TI_DBG5(("satModeSelect10: enable information exceptions reporting\n"));
13035         /* sends SMART ENABLE OPERATIONS */
13036         fis->h.fisType        = 0x27;                   /* Reg host to device */
13037         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13038 
13039         fis->h.command        = SAT_SMART_ENABLE_OPERATIONS;       /* 0xB0 */
13040         fis->h.features       = 0xD8;                   /* enable */
13041         fis->d.lbaLow         = 0;                      /* */
13042         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
13043         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
13044         fis->d.device         = 0;                      /* */
13045         fis->d.lbaLowExp      = 0;                      /* */
13046         fis->d.lbaMidExp      = 0;                      /* */
13047         fis->d.lbaHighExp     = 0;                      /* */
13048         fis->d.featuresExp    = 0;                      /* */
13049         fis->d.sectorCount    = 0;                      /* */
13050         fis->d.sectorCountExp = 0;                      /* */
13051         fis->d.reserved4      = 0;
13052         fis->d.control        = 0;                      /* FIS HOB bit clear */
13053         fis->d.reserved5      = 0;
13054 
13055         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13056 
13057         /* Initialize CB for SATA completion.
13058          */
13059         satIOContext->satCompleteCB = &satModeSelect6n10CB;
13060 
13061         /*
13062          * Prepare SGL and send FIS to LL layer.
13063          */
13064         satIOContext->reqType = agRequestType;       /* Save it */
13065 
13066         status = sataLLIOStart( tiRoot,
13067                                 tiIORequest,
13068                                 tiDeviceHandle,
13069                                 tiScsiRequest,
13070                                 satIOContext);
13071         return status;
13072       }
13073       else
13074       {
13075         TI_DBG5(("satModeSelect10: disable information exceptions reporting\n"));
13076         /* sends SMART DISABLE OPERATIONS */
13077         fis->h.fisType        = 0x27;                   /* Reg host to device */
13078         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13079 
13080         fis->h.command        = SAT_SMART_DISABLE_OPERATIONS;       /* 0xB0 */
13081         fis->h.features       = 0xD9;                   /* disable */
13082         fis->d.lbaLow         = 0;                      /* */
13083         fis->d.lbaMid         = 0x4F;                   /* 0x4F */
13084         fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
13085         fis->d.device         = 0;                      /* */
13086         fis->d.lbaLowExp      = 0;                      /* */
13087         fis->d.lbaMidExp      = 0;                      /* */
13088         fis->d.lbaHighExp     = 0;                      /* */
13089         fis->d.featuresExp    = 0;                      /* */
13090         fis->d.sectorCount    = 0;                      /* */
13091         fis->d.sectorCountExp = 0;                      /* */
13092         fis->d.reserved4      = 0;
13093         fis->d.control        = 0;                      /* FIS HOB bit clear */
13094         fis->d.reserved5      = 0;
13095 
13096         agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13097 
13098         /* Initialize CB for SATA completion.
13099          */
13100         satIOContext->satCompleteCB = &satModeSelect6n10CB;
13101 
13102         /*
13103          * Prepare SGL and send FIS to LL layer.
13104          */
13105         satIOContext->reqType = agRequestType;       /* Save it */
13106 
13107         status = sataLLIOStart( tiRoot,
13108                                 tiIORequest,
13109                                 tiDeviceHandle,
13110                                 tiScsiRequest,
13111                                 satIOContext);
13112         return status;
13113 
13114       }
13115     }
13116     break;
13117   default:
13118     TI_DBG1(("satModeSelect10: Error unknown page code 0x%x\n", pLogPage[12]));
13119     satSetSensePayload( pSense,
13120                         SCSI_SNSKEY_NO_SENSE,
13121                         0,
13122                         SCSI_SNSCODE_NO_ADDITIONAL_INFO,
13123                         satIOContext);
13124 
13125     ostiInitiatorIOCompleted( tiRoot,
13126                               tiIORequest,
13127                               tiIOSuccess,
13128                               SCSI_STAT_CHECK_CONDITION,
13129                               satIOContext->pTiSenseData,
13130                               satIOContext->interruptContext );
13131     return tiSuccess;
13132   }
13133 
13134 }
13135 
13136 
13137 /*****************************************************************************/
13138 /*! \brief SAT implementation for SCSI satSynchronizeCache10.
13139  *
13140  *  SAT implementation for SCSI satSynchronizeCache10.
13141  *
13142  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
13143  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
13144  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
13145  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
13146  *  \param   satIOContext_t:   Pointer to the SAT IO Context
13147  *
13148  *  \return If command is started successfully
13149  *    - \e tiSuccess:     I/O request successfully initiated.
13150  *    - \e tiBusy:        No resources available, try again later.
13151  *    - \e tiIONoDevice:  Invalid device handle.
13152  *    - \e tiError:       Other errors.
13153  */
13154 /*****************************************************************************/
13155 GLOBAL bit32  satSynchronizeCache10(
13156                    tiRoot_t                  *tiRoot,
13157                    tiIORequest_t             *tiIORequest,
13158                    tiDeviceHandle_t          *tiDeviceHandle,
13159                    tiScsiInitiatorRequest_t *tiScsiRequest,
13160                    satIOContext_t            *satIOContext)
13161 {
13162   bit32                     status;
13163   bit32                     agRequestType;
13164   satDeviceData_t           *pSatDevData;
13165   scsiRspSense_t            *pSense;
13166   tiIniScsiCmnd_t           *scsiCmnd;
13167   agsaFisRegHostToDevice_t  *fis;
13168 
13169   pSense        = satIOContext->pSense;
13170   pSatDevData   = satIOContext->pSatDevData;
13171   scsiCmnd      = &tiScsiRequest->scsiCmnd;
13172   fis           = satIOContext->pFis;
13173 
13174   TI_DBG5(("satSynchronizeCache10: start\n"));
13175 
13176   /* checking CONTROL */
13177   /* NACA == 1 or LINK == 1*/
13178   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13179   {
13180     satSetSensePayload( pSense,
13181                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13182                         0,
13183                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13184                         satIOContext);
13185 
13186     ostiInitiatorIOCompleted( tiRoot,
13187                               tiIORequest,
13188                               tiIOSuccess,
13189                               SCSI_STAT_CHECK_CONDITION,
13190                               satIOContext->pTiSenseData,
13191                               satIOContext->interruptContext );
13192 
13193     TI_DBG2(("satSynchronizeCache10: return control\n"));
13194     return tiSuccess;
13195   }
13196 
13197   /* checking IMMED bit */
13198   if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13199   {
13200     TI_DBG1(("satSynchronizeCache10: GOOD status due to IMMED bit\n"));
13201 
13202     /* return GOOD status first here */
13203     ostiInitiatorIOCompleted( tiRoot,
13204                               tiIORequest,
13205                               tiIOSuccess,
13206                               SCSI_STAT_GOOD,
13207                               agNULL,
13208                               satIOContext->interruptContext);
13209   }
13210 
13211   /* sends FLUSH CACHE or FLUSH CACHE EXT */
13212   if (pSatDevData->sat48BitSupport == agTRUE)
13213   {
13214     TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE EXT\n"));
13215     /* FLUSH CACHE EXT */
13216     fis->h.fisType        = 0x27;                   /* Reg host to device */
13217     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13218 
13219     fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
13220     fis->h.features       = 0;                      /* FIS reserve */
13221     fis->d.featuresExp    = 0;                      /* FIS reserve */
13222     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13223     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
13224     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13225     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
13226     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13227     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13228     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13229     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13230     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13231     fis->d.control        = 0;                      /* FIS HOB bit clear */
13232     fis->d.reserved4      = 0;
13233     fis->d.reserved5      = 0;
13234 
13235   }
13236   else
13237   {
13238     TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE\n"));
13239     /* FLUSH CACHE */
13240     fis->h.fisType        = 0x27;                   /* Reg host to device */
13241     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13242 
13243     fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
13244     fis->h.features       = 0;                      /* FIS features NA       */
13245     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13246     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13247     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13248     fis->d.lbaLowExp      = 0;
13249     fis->d.lbaMidExp      = 0;
13250     fis->d.lbaHighExp     = 0;
13251     fis->d.featuresExp    = 0;
13252     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13253     fis->d.sectorCountExp = 0;
13254     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13255     fis->d.control        = 0;                      /* FIS HOB bit clear */
13256     fis->d.reserved4      = 0;
13257     fis->d.reserved5      = 0;
13258 
13259   }
13260 
13261   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13262 
13263   /* Initialize CB for SATA completion.
13264    */
13265   satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13266 
13267   /*
13268    * Prepare SGL and send FIS to LL layer.
13269    */
13270   satIOContext->reqType = agRequestType;       /* Save it */
13271 
13272   status = sataLLIOStart( tiRoot,
13273                           tiIORequest,
13274                           tiDeviceHandle,
13275                           tiScsiRequest,
13276                           satIOContext);
13277 
13278 
13279   return (status);
13280 }
13281 
13282 /*****************************************************************************/
13283 /*! \brief SAT implementation for SCSI satSynchronizeCache16.
13284  *
13285  *  SAT implementation for SCSI satSynchronizeCache16.
13286  *
13287  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
13288  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
13289  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
13290  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
13291  *  \param   satIOContext_t:   Pointer to the SAT IO Context
13292  *
13293  *  \return If command is started successfully
13294  *    - \e tiSuccess:     I/O request successfully initiated.
13295  *    - \e tiBusy:        No resources available, try again later.
13296  *    - \e tiIONoDevice:  Invalid device handle.
13297  *    - \e tiError:       Other errors.
13298  */
13299 /*****************************************************************************/
13300 GLOBAL bit32  satSynchronizeCache16(
13301                    tiRoot_t                  *tiRoot,
13302                    tiIORequest_t             *tiIORequest,
13303                    tiDeviceHandle_t          *tiDeviceHandle,
13304                    tiScsiInitiatorRequest_t *tiScsiRequest,
13305                    satIOContext_t            *satIOContext)
13306 {
13307   bit32                     status;
13308   bit32                     agRequestType;
13309   satDeviceData_t           *pSatDevData;
13310   scsiRspSense_t            *pSense;
13311   tiIniScsiCmnd_t           *scsiCmnd;
13312   agsaFisRegHostToDevice_t  *fis;
13313 
13314   pSense        = satIOContext->pSense;
13315   pSatDevData   = satIOContext->pSatDevData;
13316   scsiCmnd      = &tiScsiRequest->scsiCmnd;
13317   fis           = satIOContext->pFis;
13318 
13319   TI_DBG5(("satSynchronizeCache16: start\n"));
13320 
13321   /* checking CONTROL */
13322   /* NACA == 1 or LINK == 1*/
13323   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
13324   {
13325     satSetSensePayload( pSense,
13326                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13327                         0,
13328                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13329                         satIOContext);
13330 
13331     ostiInitiatorIOCompleted( tiRoot,
13332                               tiIORequest,
13333                               tiIOSuccess,
13334                               SCSI_STAT_CHECK_CONDITION,
13335                               satIOContext->pTiSenseData,
13336                               satIOContext->interruptContext );
13337 
13338     TI_DBG1(("satSynchronizeCache16: return control\n"));
13339     return tiSuccess;
13340   }
13341 
13342 
13343   /* checking IMMED bit */
13344   if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13345   {
13346     TI_DBG1(("satSynchronizeCache16: GOOD status due to IMMED bit\n"));
13347 
13348     /* return GOOD status first here */
13349     ostiInitiatorIOCompleted( tiRoot,
13350                               tiIORequest,
13351                               tiIOSuccess,
13352                               SCSI_STAT_GOOD,
13353                               agNULL,
13354                               satIOContext->interruptContext);
13355   }
13356 
13357   /* sends FLUSH CACHE or FLUSH CACHE EXT */
13358   if (pSatDevData->sat48BitSupport == agTRUE)
13359   {
13360     TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE EXT\n"));
13361     /* FLUSH CACHE EXT */
13362     fis->h.fisType        = 0x27;                   /* Reg host to device */
13363     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13364 
13365     fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
13366     fis->h.features       = 0;                      /* FIS reserve */
13367     fis->d.featuresExp    = 0;                      /* FIS reserve */
13368     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13369     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
13370     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13371     fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
13372     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13373     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13374     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13375     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13376     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13377     fis->d.control        = 0;                      /* FIS HOB bit clear */
13378     fis->d.reserved4      = 0;
13379     fis->d.reserved5      = 0;
13380 
13381   }
13382   else
13383   {
13384     TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE\n"));
13385     /* FLUSH CACHE */
13386     fis->h.fisType        = 0x27;                   /* Reg host to device */
13387     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13388 
13389     fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
13390     fis->h.features       = 0;                      /* FIS features NA       */
13391     fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13392     fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13393     fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13394     fis->d.lbaLowExp      = 0;
13395     fis->d.lbaMidExp      = 0;
13396     fis->d.lbaHighExp     = 0;
13397     fis->d.featuresExp    = 0;
13398     fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13399     fis->d.sectorCountExp = 0;
13400     fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13401     fis->d.control        = 0;                      /* FIS HOB bit clear */
13402     fis->d.reserved4      = 0;
13403     fis->d.reserved5      = 0;
13404 
13405   }
13406 
13407   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13408 
13409   /* Initialize CB for SATA completion.
13410    */
13411   satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13412 
13413   /*
13414    * Prepare SGL and send FIS to LL layer.
13415    */
13416   satIOContext->reqType = agRequestType;       /* Save it */
13417 
13418   status = sataLLIOStart( tiRoot,
13419                           tiIORequest,
13420                           tiDeviceHandle,
13421                           tiScsiRequest,
13422                           satIOContext);
13423 
13424 
13425   return (status);
13426 }
13427 
13428 
13429 /*****************************************************************************/
13430 /*! \brief SAT implementation for SCSI satWriteAndVerify10.
13431  *
13432  *  SAT implementation for SCSI satWriteAndVerify10.
13433  *
13434  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
13435  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
13436  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
13437  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
13438  *  \param   satIOContext_t:   Pointer to the SAT IO Context
13439  *
13440  *  \return If command is started successfully
13441  *    - \e tiSuccess:     I/O request successfully initiated.
13442  *    - \e tiBusy:        No resources available, try again later.
13443  *    - \e tiIONoDevice:  Invalid device handle.
13444  *    - \e tiError:       Other errors.
13445  */
13446 /*****************************************************************************/
13447 GLOBAL bit32  satWriteAndVerify10(
13448                    tiRoot_t                  *tiRoot,
13449                    tiIORequest_t             *tiIORequest,
13450                    tiDeviceHandle_t          *tiDeviceHandle,
13451                    tiScsiInitiatorRequest_t *tiScsiRequest,
13452                    satIOContext_t            *satIOContext)
13453 {
13454   /*
13455     combination of write10 and verify10
13456   */
13457 
13458   bit32                     status;
13459   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13460   satDeviceData_t           *pSatDevData;
13461   scsiRspSense_t            *pSense;
13462   tiIniScsiCmnd_t           *scsiCmnd;
13463   agsaFisRegHostToDevice_t  *fis;
13464   bit32                     lba = 0;
13465   bit32                     tl = 0;
13466   bit32                     LoopNum = 1;
13467   bit8                      LBA[4];
13468   bit8                      TL[4];
13469   bit32                     rangeChk = agFALSE; /* lba and tl range check */
13470 
13471   pSense        = satIOContext->pSense;
13472   pSatDevData   = satIOContext->pSatDevData;
13473   scsiCmnd      = &tiScsiRequest->scsiCmnd;
13474   fis           = satIOContext->pFis;
13475 
13476   TI_DBG5(("satWriteAndVerify10: start\n"));
13477 
13478 
13479   /* checking BYTCHK bit */
13480   if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13481   {
13482     satSetSensePayload( pSense,
13483                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13484                         0,
13485                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13486                         satIOContext);
13487 
13488     ostiInitiatorIOCompleted( tiRoot,
13489                               tiIORequest,
13490                               tiIOSuccess,
13491                               SCSI_STAT_CHECK_CONDITION,
13492                               satIOContext->pTiSenseData,
13493                               satIOContext->interruptContext );
13494 
13495     TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13496     return tiSuccess;
13497   }
13498 
13499 
13500   /* checking CONTROL */
13501   /* NACA == 1 or LINK == 1*/
13502   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13503   {
13504     satSetSensePayload( pSense,
13505                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13506                         0,
13507                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13508                         satIOContext);
13509 
13510     ostiInitiatorIOCompleted( tiRoot,
13511                               tiIORequest,
13512                               tiIOSuccess,
13513                               SCSI_STAT_CHECK_CONDITION,
13514                               satIOContext->pTiSenseData,
13515                               satIOContext->interruptContext );
13516 
13517     TI_DBG1(("satWriteAndVerify10: return control\n"));
13518     return tiSuccess;
13519   }
13520 
13521   osti_memset(LBA, 0, sizeof(LBA));
13522   osti_memset(TL, 0, sizeof(TL));
13523 
13524   /* do not use memcpy due to indexing in LBA and TL */
13525   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
13526   LBA[1] = scsiCmnd->cdb[3];
13527   LBA[2] = scsiCmnd->cdb[4];
13528   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
13529 
13530   TL[0] = 0;
13531   TL[1] = 0;
13532   TL[2] = scsiCmnd->cdb[7];  /* MSB */
13533   TL[3] = scsiCmnd->cdb[8];  /* LSB */
13534 
13535   rangeChk = satAddNComparebit32(LBA, TL);
13536 
13537   /* cbd10; computing LBA and transfer length */
13538   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13539     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13540   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13541 
13542 
13543   /* Table 34, 9.1, p 46 */
13544   /*
13545     note: As of 2/10/2006, no support for DMA QUEUED
13546    */
13547 
13548   /*
13549     Table 34, 9.1, p 46, b
13550     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13551     return check condition
13552   */
13553   if (pSatDevData->satNCQ != agTRUE &&
13554       pSatDevData->sat48BitSupport != agTRUE
13555       )
13556   {
13557     if (lba > SAT_TR_LBA_LIMIT - 1)
13558     {
13559       satSetSensePayload( pSense,
13560                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13561                           0,
13562                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13563                           satIOContext);
13564 
13565       ostiInitiatorIOCompleted( tiRoot,
13566                                 tiIORequest,
13567                                 tiIOSuccess,
13568                                 SCSI_STAT_CHECK_CONDITION,
13569                                 satIOContext->pTiSenseData,
13570                                 satIOContext->interruptContext );
13571 
13572     TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13573     return tiSuccess;
13574     }
13575 
13576     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
13577     {
13578       TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
13579       satSetSensePayload( pSense,
13580                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13581                           0,
13582                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13583                           satIOContext);
13584 
13585       ostiInitiatorIOCompleted( tiRoot,
13586                                 tiIORequest,
13587                                 tiIOSuccess,
13588                                 SCSI_STAT_CHECK_CONDITION,
13589                                 satIOContext->pTiSenseData,
13590                                 satIOContext->interruptContext );
13591 
13592     return tiSuccess;
13593     }
13594   }
13595 
13596 
13597   /* case 1 and 2 */
13598   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
13599   {
13600     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13601     {
13602       /* case 2 */
13603       /* WRITE DMA*/
13604       /* can't fit the transfer length */
13605       TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
13606       fis->h.fisType        = 0x27;                   /* Reg host to device */
13607       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
13608       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
13609       fis->h.features       = 0;                      /* FIS reserve */
13610       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13611       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13612       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13613 
13614       /* FIS LBA mode set LBA (27:24) */
13615       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13616 
13617       fis->d.lbaLowExp      = 0;
13618       fis->d.lbaMidExp      = 0;
13619       fis->d.lbaHighExp     = 0;
13620       fis->d.featuresExp    = 0;
13621       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13622       fis->d.sectorCountExp = 0;
13623       fis->d.reserved4      = 0;
13624       fis->d.control        = 0;                      /* FIS HOB bit clear */
13625       fis->d.reserved5      = 0;
13626 
13627       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13628       satIOContext->ATACmd = SAT_WRITE_DMA;
13629     }
13630     else
13631     {
13632       /* case 1 */
13633       /* WRITE MULTIPLE or WRITE SECTOR(S) */
13634       /* WRITE SECTORS for easier implemetation */
13635       /* can't fit the transfer length */
13636       TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
13637       fis->h.fisType        = 0x27;                   /* Reg host to device */
13638       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
13639       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
13640       fis->h.features       = 0;                      /* FIS reserve */
13641       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13642       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13643       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13644 
13645       /* FIS LBA mode set LBA (27:24) */
13646       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13647 
13648       fis->d.lbaLowExp      = 0;
13649       fis->d.lbaMidExp      = 0;
13650       fis->d.lbaHighExp     = 0;
13651       fis->d.featuresExp    = 0;
13652       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13653       fis->d.sectorCountExp = 0;
13654       fis->d.reserved4      = 0;
13655       fis->d.control        = 0;                      /* FIS HOB bit clear */
13656       fis->d.reserved5      = 0;
13657 
13658       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13659       satIOContext->ATACmd = SAT_WRITE_SECTORS;
13660 
13661     }
13662   }
13663 
13664   /* case 3 and 4 */
13665   if (pSatDevData->sat48BitSupport == agTRUE)
13666   {
13667     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13668     {
13669       /* case 3 */
13670       /* WRITE DMA EXT or WRITE DMA FUA EXT */
13671       TI_DBG5(("satWriteAndVerify10: case 3\n"));
13672       fis->h.fisType        = 0x27;                   /* Reg host to device */
13673       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13674 
13675       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
13676       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
13677 
13678       fis->h.features       = 0;                      /* FIS reserve */
13679       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13680       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13681       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13682       fis->d.device         = 0x40;                   /* FIS LBA mode set */
13683       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
13684       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13685       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13686       fis->d.featuresExp    = 0;                      /* FIS reserve */
13687       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13688       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
13689       fis->d.reserved4      = 0;
13690       fis->d.control        = 0;                      /* FIS HOB bit clear */
13691       fis->d.reserved5      = 0;
13692 
13693       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13694       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
13695     }
13696     else
13697     {
13698       /* case 4 */
13699       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
13700       /* WRITE SECTORS EXT for easier implemetation */
13701       TI_DBG5(("satWriteAndVerify10: case 4\n"));
13702       fis->h.fisType        = 0x27;                   /* Reg host to device */
13703       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13704       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
13705 
13706       fis->h.features       = 0;                      /* FIS reserve */
13707       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13708       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13709       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13710       fis->d.device         = 0x40;                   /* FIS LBA mode set */
13711       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
13712       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13713       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13714       fis->d.featuresExp    = 0;                      /* FIS reserve */
13715       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13716       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
13717       fis->d.reserved4      = 0;
13718       fis->d.control        = 0;                      /* FIS HOB bit clear */
13719       fis->d.reserved5      = 0;
13720 
13721       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13722       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
13723     }
13724   }
13725   /* case 5 */
13726   if (pSatDevData->satNCQ == agTRUE)
13727   {
13728     /* WRITE FPDMA QUEUED */
13729     if (pSatDevData->sat48BitSupport != agTRUE)
13730     {
13731       TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
13732       satSetSensePayload( pSense,
13733                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13734                           0,
13735                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13736                           satIOContext);
13737 
13738       ostiInitiatorIOCompleted( tiRoot,
13739                                 tiIORequest,
13740                                 tiIOSuccess,
13741                                 SCSI_STAT_CHECK_CONDITION,
13742                                 satIOContext->pTiSenseData,
13743                                 satIOContext->interruptContext );
13744       return tiSuccess;
13745     }
13746     TI_DBG5(("satWriteAndVerify10: case 5\n"));
13747 
13748     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
13749 
13750     fis->h.fisType        = 0x27;                   /* Reg host to device */
13751     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13752     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
13753     fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13754     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13755     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13756     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13757 
13758     /* Check FUA bit */
13759     if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
13760       fis->d.device       = 0xC0;                   /* FIS FUA set */
13761     else
13762       fis->d.device       = 0x40;                   /* FIS FUA clear */
13763 
13764     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
13765     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13766     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13767     fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
13768     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
13769     fis->d.sectorCountExp = 0;
13770     fis->d.reserved4      = 0;
13771     fis->d.control        = 0;                      /* FIS HOB bit clear */
13772     fis->d.reserved5      = 0;
13773 
13774     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
13775     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
13776   }
13777 
13778   satIOContext->currentLBA = lba;
13779   satIOContext->OrgTL = tl;
13780 
13781   /*
13782     computing number of loop and remainder for tl
13783     0xFF in case not ext
13784     0xFFFF in case EXT
13785   */
13786   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13787   {
13788     LoopNum = satComputeLoopNum(tl, 0xFF);
13789   }
13790   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13791            fis->h.command == SAT_WRITE_DMA_EXT     ||
13792            fis->h.command == SAT_WRITE_DMA_FUA_EXT
13793            )
13794   {
13795     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
13796     LoopNum = satComputeLoopNum(tl, 0xFFFF);
13797   }
13798   else
13799   {
13800     /* SAT_WRITE_FPDMA_QUEUED */
13801     LoopNum = satComputeLoopNum(tl, 0xFFFF);
13802   }
13803 
13804   satIOContext->LoopNum = LoopNum;
13805 
13806 
13807   if (LoopNum == 1)
13808   {
13809     TI_DBG5(("satWriteAndVerify10: NON CHAINED data\n"));
13810     /* Initialize CB for SATA completion.
13811      */
13812     satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
13813   }
13814   else
13815   {
13816     TI_DBG1(("satWriteAndVerify10: CHAINED data\n"));
13817     /* re-setting tl */
13818     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13819     {
13820        fis->d.sectorCount    = 0xFF;
13821     }
13822     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13823              fis->h.command == SAT_WRITE_DMA_EXT ||
13824              fis->h.command == SAT_WRITE_DMA_FUA_EXT
13825              )
13826     {
13827       fis->d.sectorCount    = 0xFF;
13828       fis->d.sectorCountExp = 0xFF;
13829     }
13830     else
13831     {
13832       /* SAT_WRITE_FPDMA_QUEUED */
13833       fis->h.features       = 0xFF;
13834       fis->d.featuresExp    = 0xFF;
13835     }
13836 
13837     /* Initialize CB for SATA completion.
13838      */
13839     satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
13840   }
13841 
13842 
13843   /*
13844    * Prepare SGL and send FIS to LL layer.
13845    */
13846   satIOContext->reqType = agRequestType;       /* Save it */
13847 
13848   status = sataLLIOStart( tiRoot,
13849                           tiIORequest,
13850                           tiDeviceHandle,
13851                           tiScsiRequest,
13852                           satIOContext);
13853   return (status);
13854 
13855 }
13856 
13857 
13858 
13859 
13860 
13861 
13862 #ifdef REMOVED
13863 GLOBAL bit32  satWriteAndVerify10(
13864                    tiRoot_t                  *tiRoot,
13865                    tiIORequest_t             *tiIORequest,
13866                    tiDeviceHandle_t          *tiDeviceHandle,
13867                    tiScsiInitiatorRequest_t *tiScsiRequest,
13868                    satIOContext_t            *satIOContext)
13869 {
13870   /*
13871     combination of write10 and verify10
13872   */
13873 
13874   bit32                     status;
13875   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13876   satDeviceData_t           *pSatDevData;
13877   scsiRspSense_t            *pSense;
13878   tiIniScsiCmnd_t           *scsiCmnd;
13879   agsaFisRegHostToDevice_t  *fis;
13880   bit32                     lba = 0;
13881   bit32                     tl = 0;
13882 
13883   pSense        = satIOContext->pSense;
13884   pSatDevData   = satIOContext->pSatDevData;
13885   scsiCmnd      = &tiScsiRequest->scsiCmnd;
13886   fis           = satIOContext->pFis;
13887 
13888   TI_DBG5(("satWriteAndVerify10: start\n"));
13889 
13890 
13891   /* checking BYTCHK bit */
13892   if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13893   {
13894     satSetSensePayload( pSense,
13895                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13896                         0,
13897                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13898                         satIOContext);
13899 
13900     ostiInitiatorIOCompleted( tiRoot,
13901                               tiIORequest,
13902                               tiIOSuccess,
13903                               SCSI_STAT_CHECK_CONDITION,
13904                               satIOContext->pTiSenseData,
13905                               satIOContext->interruptContext );
13906 
13907     TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13908     return tiSuccess;
13909   }
13910 
13911 
13912   /* checking CONTROL */
13913   /* NACA == 1 or LINK == 1*/
13914   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13915   {
13916     satSetSensePayload( pSense,
13917                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13918                         0,
13919                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13920                         satIOContext);
13921 
13922     ostiInitiatorIOCompleted( tiRoot,
13923                               tiIORequest,
13924                               tiIOSuccess,
13925                               SCSI_STAT_CHECK_CONDITION,
13926                               satIOContext->pTiSenseData,
13927                               satIOContext->interruptContext );
13928 
13929     TI_DBG2(("satWriteAndVerify10: return control\n"));
13930     return tiSuccess;
13931   }
13932 
13933   /* let's do write10 */
13934   if ( pSatDevData->sat48BitSupport != agTRUE )
13935   {
13936     /*
13937       writeandverify10 but no support for 48 bit addressing -> problem in transfer
13938       length(sector count)
13939     */
13940     satSetSensePayload( pSense,
13941                         SCSI_SNSKEY_ILLEGAL_REQUEST,
13942                         0,
13943                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13944                         satIOContext);
13945 
13946     ostiInitiatorIOCompleted( tiRoot,
13947                               tiIORequest,
13948                               tiIOSuccess,
13949                               SCSI_STAT_CHECK_CONDITION,
13950                               satIOContext->pTiSenseData,
13951                               satIOContext->interruptContext );
13952 
13953     TI_DBG1(("satWriteAndVerify10: return internal checking\n"));
13954     return tiSuccess;
13955   }
13956 
13957   /* cbd10; computing LBA and transfer length */
13958   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13959     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13960   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13961 
13962 
13963   /* Table 34, 9.1, p 46 */
13964   /*
13965     note: As of 2/10/2006, no support for DMA QUEUED
13966    */
13967 
13968   /*
13969     Table 34, 9.1, p 46, b
13970     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13971     return check condition
13972   */
13973   if (pSatDevData->satNCQ != agTRUE &&
13974       pSatDevData->sat48BitSupport != agTRUE
13975       )
13976   {
13977     if (lba > SAT_TR_LBA_LIMIT - 1)
13978     {
13979       satSetSensePayload( pSense,
13980                           SCSI_SNSKEY_ILLEGAL_REQUEST,
13981                           0,
13982                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13983                           satIOContext);
13984 
13985       ostiInitiatorIOCompleted( tiRoot,
13986                                 tiIORequest,
13987                                 tiIOSuccess,
13988                                 SCSI_STAT_CHECK_CONDITION,
13989                                 satIOContext->pTiSenseData,
13990                                 satIOContext->interruptContext );
13991 
13992     TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13993     return tiSuccess;
13994     }
13995   }
13996 
13997 
13998   /* case 1 and 2 */
13999   if (lba + tl <= SAT_TR_LBA_LIMIT)
14000   {
14001     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14002     {
14003       /* case 2 */
14004       /* WRITE DMA*/
14005       /* can't fit the transfer length */
14006       TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
14007       fis->h.fisType        = 0x27;                   /* Reg host to device */
14008       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14009       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
14010       fis->h.features       = 0;                      /* FIS reserve */
14011       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14012       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14013       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14014 
14015       /* FIS LBA mode set LBA (27:24) */
14016       fis->d.device         = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14017 
14018       fis->d.lbaLowExp      = 0;
14019       fis->d.lbaMidExp      = 0;
14020       fis->d.lbaHighExp     = 0;
14021       fis->d.featuresExp    = 0;
14022       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14023       fis->d.sectorCountExp = 0;
14024       fis->d.reserved4      = 0;
14025       fis->d.control        = 0;                      /* FIS HOB bit clear */
14026       fis->d.reserved5      = 0;
14027 
14028       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14029       satIOContext->ATACmd = SAT_WRITE_DMA;
14030     }
14031     else
14032     {
14033       /* case 1 */
14034       /* WRITE MULTIPLE or WRITE SECTOR(S) */
14035       /* WRITE SECTORS for easier implemetation */
14036       /* can't fit the transfer length */
14037       TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
14038       fis->h.fisType        = 0x27;                   /* Reg host to device */
14039       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14040       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
14041       fis->h.features       = 0;                      /* FIS reserve */
14042       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14043       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14044       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14045 
14046       /* FIS LBA mode set LBA (27:24) */
14047       fis->d.device         = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14048 
14049       fis->d.lbaLowExp      = 0;
14050       fis->d.lbaMidExp      = 0;
14051       fis->d.lbaHighExp     = 0;
14052       fis->d.featuresExp    = 0;
14053       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14054       fis->d.sectorCountExp = 0;
14055       fis->d.reserved4      = 0;
14056       fis->d.control        = 0;                      /* FIS HOB bit clear */
14057       fis->d.reserved5      = 0;
14058 
14059       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14060       satIOContext->ATACmd = SAT_WRITE_SECTORS;
14061 
14062     }
14063   }
14064 
14065   /* case 3 and 4 */
14066   if (pSatDevData->sat48BitSupport == agTRUE)
14067   {
14068     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14069     {
14070       /* case 3 */
14071       /* WRITE DMA EXT or WRITE DMA FUA EXT */
14072       TI_DBG5(("satWriteAndVerify10: case 3\n"));
14073       fis->h.fisType        = 0x27;                   /* Reg host to device */
14074       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14075 
14076       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14077       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
14078 
14079       fis->h.features       = 0;                      /* FIS reserve */
14080       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14081       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14082       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14083       fis->d.device         = 0x40;                   /* FIS LBA mode set */
14084       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14085       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14086       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14087       fis->d.featuresExp    = 0;                      /* FIS reserve */
14088       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14089       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14090       fis->d.reserved4      = 0;
14091       fis->d.control        = 0;                      /* FIS HOB bit clear */
14092       fis->d.reserved5      = 0;
14093 
14094       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14095     }
14096     else
14097     {
14098       /* case 4 */
14099       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14100       /* WRITE SECTORS EXT for easier implemetation */
14101       TI_DBG5(("satWriteAndVerify10: case 4\n"));
14102       fis->h.fisType        = 0x27;                   /* Reg host to device */
14103       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14104       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
14105 
14106       fis->h.features       = 0;                      /* FIS reserve */
14107       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14108       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14109       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14110       fis->d.device         = 0x40;                   /* FIS LBA mode set */
14111       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14112       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14113       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14114       fis->d.featuresExp    = 0;                      /* FIS reserve */
14115       fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14116       fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14117       fis->d.reserved4      = 0;
14118       fis->d.control        = 0;                      /* FIS HOB bit clear */
14119       fis->d.reserved5      = 0;
14120 
14121       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14122     }
14123   }
14124   /* case 5 */
14125   if (pSatDevData->satNCQ == agTRUE)
14126   {
14127     /* WRITE FPDMA QUEUED */
14128     if (pSatDevData->sat48BitSupport != agTRUE)
14129     {
14130       TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
14131       satSetSensePayload( pSense,
14132                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14133                           0,
14134                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14135                           satIOContext);
14136 
14137       ostiInitiatorIOCompleted( tiRoot,
14138                                 tiIORequest,
14139                                 tiIOSuccess,
14140                                 SCSI_STAT_CHECK_CONDITION,
14141                                 satIOContext->pTiSenseData,
14142                                 satIOContext->interruptContext );
14143       return tiSuccess;
14144     }
14145     TI_DBG5(("satWriteAndVerify10: case 5\n"));
14146 
14147     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14148 
14149     fis->h.fisType        = 0x27;                   /* Reg host to device */
14150     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14151     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14152     fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14153     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14154     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14155     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14156 
14157     /* Check FUA bit */
14158     if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
14159       fis->d.device       = 0xC0;                   /* FIS FUA set */
14160     else
14161       fis->d.device       = 0x40;                   /* FIS FUA clear */
14162 
14163     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14164     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14165     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14166     fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14167     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
14168     fis->d.sectorCountExp = 0;
14169     fis->d.reserved4      = 0;
14170     fis->d.control        = 0;                      /* FIS HOB bit clear */
14171     fis->d.reserved5      = 0;
14172 
14173     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14174   }
14175 
14176   /* Initialize CB for SATA completion.
14177    */
14178   satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14179 
14180   /*
14181    * Prepare SGL and send FIS to LL layer.
14182    */
14183   satIOContext->reqType = agRequestType;       /* Save it */
14184 
14185   status = sataLLIOStart( tiRoot,
14186                           tiIORequest,
14187                           tiDeviceHandle,
14188                           tiScsiRequest,
14189                           satIOContext);
14190   return (status);
14191 
14192 }
14193 #endif /* REMOVED */
14194 
14195 #ifdef REMOVED
14196 /*****************************************************************************/
14197 /*! \brief SAT implementation for SCSI satWriteAndVerify10_1.
14198  *
14199  *  SAT implementation for SCSI satWriteAndVerify10_1.
14200  *  Sub function of satWriteAndVerify10
14201  *
14202  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
14203  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
14204  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
14205  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
14206  *  \param   satIOContext_t:   Pointer to the SAT IO Context
14207  *
14208  *  \return If command is started successfully
14209  *    - \e tiSuccess:     I/O request successfully initiated.
14210  *    - \e tiBusy:        No resources available, try again later.
14211  *    - \e tiIONoDevice:  Invalid device handle.
14212  *    - \e tiError:       Other errors.
14213  */
14214 /*****************************************************************************/
14215 GLOBAL bit32  satWriteAndVerify10_1(
14216                    tiRoot_t                  *tiRoot,
14217                    tiIORequest_t             *tiIORequest,
14218                    tiDeviceHandle_t          *tiDeviceHandle,
14219                    tiScsiInitiatorRequest_t *tiScsiRequest,
14220                    satIOContext_t            *satIOContext)
14221 {
14222   bit32                     status;
14223   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14224   satDeviceData_t           *pSatDevData;
14225   scsiRspSense_t            *pSense;
14226   tiIniScsiCmnd_t           *scsiCmnd;
14227   agsaFisRegHostToDevice_t  *fis;
14228 
14229   pSense        = satIOContext->pSense;
14230   pSatDevData   = satIOContext->pSatDevData;
14231   scsiCmnd      = &tiScsiRequest->scsiCmnd;
14232   fis           = satIOContext->pFis;
14233 
14234   TI_DBG5(("satWriteAndVerify10_1: start\n"));
14235 
14236   if (pSatDevData->sat48BitSupport == agTRUE)
14237   {
14238     fis->h.fisType        = 0x27;                   /* Reg host to device */
14239     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14240 
14241     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14242     fis->h.features       = 0;                      /* FIS reserve */
14243     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14244     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14245     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14246     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
14247     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14248     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14249     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14250     fis->d.featuresExp    = 0;                      /* FIS reserve */
14251     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14252     fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14253 
14254     fis->d.reserved4      = 0;
14255     fis->d.control        = 0;                      /* FIS HOB bit clear */
14256     fis->d.reserved5      = 0;
14257 
14258     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14259 
14260     /* Initialize CB for SATA completion.
14261      */
14262     satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14263 
14264     /*
14265      * Prepare SGL and send FIS to LL layer.
14266      */
14267     satIOContext->reqType = agRequestType;       /* Save it */
14268 
14269     status = sataLLIOStart( tiRoot,
14270                             tiIORequest,
14271                             tiDeviceHandle,
14272                             tiScsiRequest,
14273                             satIOContext);
14274 
14275 
14276     TI_DBG1(("satWriteAndVerify10_1: return status %d\n", status));
14277     return (status);
14278   }
14279   else
14280   {
14281     /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14282     TI_DBG1(("satWriteAndVerify10_1: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14283     return tiError;
14284   }
14285 
14286 
14287   return tiSuccess;
14288 }
14289 #endif /* REMOVED */
14290 
14291 /*****************************************************************************/
14292 /*! \brief SAT implementation for SCSI satWriteAndVerify12.
14293  *
14294  *  SAT implementation for SCSI satWriteAndVerify12.
14295  *
14296  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
14297  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
14298  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
14299  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
14300  *  \param   satIOContext_t:   Pointer to the SAT IO Context
14301  *
14302  *  \return If command is started successfully
14303  *    - \e tiSuccess:     I/O request successfully initiated.
14304  *    - \e tiBusy:        No resources available, try again later.
14305  *    - \e tiIONoDevice:  Invalid device handle.
14306  *    - \e tiError:       Other errors.
14307  */
14308 /*****************************************************************************/
14309 GLOBAL bit32  satWriteAndVerify12(
14310                    tiRoot_t                  *tiRoot,
14311                    tiIORequest_t             *tiIORequest,
14312                    tiDeviceHandle_t          *tiDeviceHandle,
14313                    tiScsiInitiatorRequest_t *tiScsiRequest,
14314                    satIOContext_t            *satIOContext)
14315 {
14316   /*
14317     combination of write12 and verify12
14318     temp: since write12 is not support (due to internal checking), no support
14319   */
14320   bit32                     status;
14321   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14322   satDeviceData_t           *pSatDevData;
14323   scsiRspSense_t            *pSense;
14324   tiIniScsiCmnd_t           *scsiCmnd;
14325   agsaFisRegHostToDevice_t  *fis;
14326   bit32                     lba = 0;
14327   bit32                     tl = 0;
14328   bit32                     LoopNum = 1;
14329   bit8                      LBA[4];
14330   bit8                      TL[4];
14331   bit32                     rangeChk = agFALSE; /* lba and tl range check */
14332 
14333   pSense        = satIOContext->pSense;
14334   pSatDevData   = satIOContext->pSatDevData;
14335   scsiCmnd      = &tiScsiRequest->scsiCmnd;
14336   fis           = satIOContext->pFis;
14337 
14338   TI_DBG5(("satWriteAndVerify12: start\n"));
14339 
14340   /* checking BYTCHK bit */
14341   if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
14342   {
14343     satSetSensePayload( pSense,
14344                         SCSI_SNSKEY_ILLEGAL_REQUEST,
14345                         0,
14346                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14347                         satIOContext);
14348 
14349     ostiInitiatorIOCompleted( tiRoot,
14350                               tiIORequest,
14351                               tiIOSuccess,
14352                               SCSI_STAT_CHECK_CONDITION,
14353                               satIOContext->pTiSenseData,
14354                               satIOContext->interruptContext );
14355 
14356     TI_DBG1(("satWriteAndVerify12: BYTCHK bit checking \n"));
14357     return tiSuccess;
14358   }
14359 
14360   /* checking CONTROL */
14361   /* NACA == 1 or LINK == 1*/
14362   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
14363   {
14364     satSetSensePayload( pSense,
14365                         SCSI_SNSKEY_ILLEGAL_REQUEST,
14366                         0,
14367                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14368                         satIOContext);
14369 
14370     ostiInitiatorIOCompleted( tiRoot,
14371                               tiIORequest,
14372                               tiIOSuccess,
14373                               SCSI_STAT_CHECK_CONDITION,
14374                               satIOContext->pTiSenseData,
14375                               satIOContext->interruptContext );
14376 
14377     TI_DBG2(("satWriteAndVerify12: return control\n"));
14378     return tiSuccess;
14379   }
14380 
14381   osti_memset(LBA, 0, sizeof(LBA));
14382   osti_memset(TL, 0, sizeof(TL));
14383 
14384   /* do not use memcpy due to indexing in LBA and TL */
14385   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
14386   LBA[1] = scsiCmnd->cdb[3];
14387   LBA[2] = scsiCmnd->cdb[4];
14388   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
14389 
14390   TL[0] = scsiCmnd->cdb[6];   /* MSB */
14391   TL[1] = scsiCmnd->cdb[7];
14392   TL[2] = scsiCmnd->cdb[7];
14393   TL[3] = scsiCmnd->cdb[8];   /* LSB */
14394 
14395   rangeChk = satAddNComparebit32(LBA, TL);
14396 
14397   lba = satComputeCDB12LBA(satIOContext);
14398   tl = satComputeCDB12TL(satIOContext);
14399 
14400 
14401   /* Table 34, 9.1, p 46 */
14402   /*
14403     note: As of 2/10/2006, no support for DMA QUEUED
14404    */
14405 
14406   /*
14407     Table 34, 9.1, p 46, b
14408     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
14409     return check condition
14410   */
14411   if (pSatDevData->satNCQ != agTRUE &&
14412       pSatDevData->sat48BitSupport != agTRUE
14413       )
14414   {
14415     if (lba > SAT_TR_LBA_LIMIT - 1)
14416     {
14417       satSetSensePayload( pSense,
14418                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14419                           0,
14420                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14421                           satIOContext);
14422 
14423       ostiInitiatorIOCompleted( tiRoot,
14424                                 tiIORequest,
14425                                 tiIOSuccess,
14426                                 SCSI_STAT_CHECK_CONDITION,
14427                                 satIOContext->pTiSenseData,
14428                                 satIOContext->interruptContext );
14429 
14430     TI_DBG1(("satWriteAndVerify12: return LBA out of range, not EXT\n"));
14431     return tiSuccess;
14432     }
14433 
14434     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
14435     {
14436       TI_DBG1(("satWriteAndVerify12: return LBA+TL out of range, not EXT\n"));
14437       satSetSensePayload( pSense,
14438                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14439                           0,
14440                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14441                           satIOContext);
14442 
14443       ostiInitiatorIOCompleted( tiRoot,
14444                                 tiIORequest,
14445                                 tiIOSuccess,
14446                                 SCSI_STAT_CHECK_CONDITION,
14447                                 satIOContext->pTiSenseData,
14448                                 satIOContext->interruptContext );
14449 
14450     return tiSuccess;
14451     }
14452   }
14453 
14454   /* case 1 and 2 */
14455   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
14456   {
14457     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14458     {
14459       /* case 2 */
14460       /* WRITE DMA*/
14461       /* In case that we can't fit the transfer length, we loop */
14462       TI_DBG5(("satWriteAndVerify12: case 2\n"));
14463       fis->h.fisType        = 0x27;                   /* Reg host to device */
14464       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14465       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
14466       fis->h.features       = 0;                      /* FIS reserve */
14467       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14468       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14469       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14470 
14471       /* FIS LBA mode set LBA (27:24) */
14472       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14473 
14474       fis->d.lbaLowExp      = 0;
14475       fis->d.lbaMidExp      = 0;
14476       fis->d.lbaHighExp     = 0;
14477       fis->d.featuresExp    = 0;
14478       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14479       fis->d.sectorCountExp = 0;
14480       fis->d.reserved4      = 0;
14481       fis->d.control        = 0;                      /* FIS HOB bit clear */
14482       fis->d.reserved5      = 0;
14483 
14484       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14485       satIOContext->ATACmd = SAT_WRITE_DMA;
14486     }
14487     else
14488     {
14489       /* case 1 */
14490       /* WRITE MULTIPLE or WRITE SECTOR(S) */
14491       /* WRITE SECTORS for easier implemetation */
14492       /* In case that we can't fit the transfer length, we loop */
14493       TI_DBG5(("satWriteAndVerify12: case 1\n"));
14494       fis->h.fisType        = 0x27;                   /* Reg host to device */
14495       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14496       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
14497       fis->h.features       = 0;                      /* FIS reserve */
14498       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14499       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14500       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14501 
14502       /* FIS LBA mode set LBA (27:24) */
14503       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14504 
14505       fis->d.lbaLowExp      = 0;
14506       fis->d.lbaMidExp      = 0;
14507       fis->d.lbaHighExp     = 0;
14508       fis->d.featuresExp    = 0;
14509       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14510       fis->d.sectorCountExp = 0;
14511       fis->d.reserved4      = 0;
14512       fis->d.control        = 0;                      /* FIS HOB bit clear */
14513       fis->d.reserved5      = 0;
14514 
14515       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14516       satIOContext->ATACmd = SAT_WRITE_SECTORS;
14517     }
14518   }
14519 
14520   /* case 3 and 4 */
14521   if (pSatDevData->sat48BitSupport == agTRUE)
14522   {
14523     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14524     {
14525       /* case 3 */
14526       /* WRITE DMA EXT or WRITE DMA FUA EXT */
14527       TI_DBG5(("satWriteAndVerify12: case 3\n"));
14528       fis->h.fisType        = 0x27;                   /* Reg host to device */
14529       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14530 
14531       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14532       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
14533 
14534       fis->h.features       = 0;                      /* FIS reserve */
14535       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14536       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14537       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14538       fis->d.device         = 0x40;                   /* FIS LBA mode set */
14539       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14540       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14541       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14542       fis->d.featuresExp    = 0;                      /* FIS reserve */
14543       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14544       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
14545       fis->d.reserved4      = 0;
14546       fis->d.control        = 0;                      /* FIS HOB bit clear */
14547       fis->d.reserved5      = 0;
14548 
14549       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14550       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
14551     }
14552     else
14553     {
14554       /* case 4 */
14555       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14556       /* WRITE SECTORS EXT for easier implemetation */
14557       TI_DBG5(("satWriteAndVerify12: case 4\n"));
14558       fis->h.fisType        = 0x27;                   /* Reg host to device */
14559       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14560       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
14561 
14562       fis->h.features       = 0;                      /* FIS reserve */
14563       fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14564       fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14565       fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14566       fis->d.device         = 0x40;                   /* FIS LBA mode set */
14567       fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14568       fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14569       fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14570       fis->d.featuresExp    = 0;                      /* FIS reserve */
14571       fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14572       fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
14573       fis->d.reserved4      = 0;
14574       fis->d.control        = 0;                      /* FIS HOB bit clear */
14575       fis->d.reserved5      = 0;
14576 
14577       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14578       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
14579     }
14580   }
14581 
14582   /* case 5 */
14583   if (pSatDevData->satNCQ == agTRUE)
14584   {
14585     /* WRITE FPDMA QUEUED */
14586     if (pSatDevData->sat48BitSupport != agTRUE)
14587     {
14588       TI_DBG5(("satWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support \n"));
14589        satSetSensePayload( pSense,
14590                           SCSI_SNSKEY_ILLEGAL_REQUEST,
14591                           0,
14592                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14593                           satIOContext);
14594 
14595       ostiInitiatorIOCompleted( tiRoot,
14596                                 tiIORequest,
14597                                 tiIOSuccess,
14598                                 SCSI_STAT_CHECK_CONDITION,
14599                                 satIOContext->pTiSenseData,
14600                                 satIOContext->interruptContext );
14601       return tiSuccess;
14602     }
14603     TI_DBG6(("satWriteAndVerify12: case 5\n"));
14604 
14605     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14606 
14607     fis->h.fisType        = 0x27;                   /* Reg host to device */
14608     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14609     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14610     fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14611     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14612     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14613     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14614 
14615     /* Check FUA bit */
14616     if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
14617       fis->d.device       = 0xC0;                   /* FIS FUA set */
14618     else
14619       fis->d.device       = 0x40;                   /* FIS FUA clear */
14620 
14621     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14622     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14623     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14624     fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
14625     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
14626     fis->d.sectorCountExp = 0;
14627     fis->d.reserved4      = 0;
14628     fis->d.control        = 0;                      /* FIS HOB bit clear */
14629     fis->d.reserved5      = 0;
14630 
14631     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14632     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
14633   }
14634 
14635   satIOContext->currentLBA = lba;
14636 //  satIOContext->OrgLBA = lba;
14637   satIOContext->OrgTL = tl;
14638 
14639   /*
14640     computing number of loop and remainder for tl
14641     0xFF in case not ext
14642     0xFFFF in case EXT
14643   */
14644   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14645   {
14646     LoopNum = satComputeLoopNum(tl, 0xFF);
14647   }
14648   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14649            fis->h.command == SAT_WRITE_DMA_EXT     ||
14650            fis->h.command == SAT_WRITE_DMA_FUA_EXT
14651            )
14652   {
14653     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
14654     LoopNum = satComputeLoopNum(tl, 0xFFFF);
14655   }
14656   else
14657   {
14658     /* SAT_WRITE_FPDMA_QUEUEDK */
14659     LoopNum = satComputeLoopNum(tl, 0xFFFF);
14660   }
14661 
14662   satIOContext->LoopNum = LoopNum;
14663   satIOContext->LoopNum2 = LoopNum;
14664 
14665 
14666   if (LoopNum == 1)
14667   {
14668     TI_DBG5(("satWriteAndVerify12: NON CHAINED data\n"));
14669     /* Initialize CB for SATA completion.
14670      */
14671     satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14672   }
14673   else
14674   {
14675     TI_DBG1(("satWriteAndVerify12: CHAINED data\n"));
14676     /* re-setting tl */
14677     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14678     {
14679        fis->d.sectorCount    = 0xFF;
14680     }
14681     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14682              fis->h.command == SAT_WRITE_DMA_EXT ||
14683              fis->h.command == SAT_WRITE_DMA_FUA_EXT
14684              )
14685     {
14686       fis->d.sectorCount    = 0xFF;
14687       fis->d.sectorCountExp = 0xFF;
14688     }
14689     else
14690     {
14691       /* SAT_WRITE_FPDMA_QUEUED */
14692       fis->h.features       = 0xFF;
14693       fis->d.featuresExp    = 0xFF;
14694     }
14695 
14696     /* Initialize CB for SATA completion.
14697      */
14698     satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
14699   }
14700 
14701 
14702   /*
14703    * Prepare SGL and send FIS to LL layer.
14704    */
14705   satIOContext->reqType = agRequestType;       /* Save it */
14706 
14707   status = sataLLIOStart( tiRoot,
14708                           tiIORequest,
14709                           tiDeviceHandle,
14710                           tiScsiRequest,
14711                           satIOContext);
14712   return (status);
14713 }
14714 
14715 GLOBAL bit32  satNonChainedWriteNVerify_Verify(
14716                    tiRoot_t                  *tiRoot,
14717                    tiIORequest_t             *tiIORequest,
14718                    tiDeviceHandle_t          *tiDeviceHandle,
14719                    tiScsiInitiatorRequest_t *tiScsiRequest,
14720                    satIOContext_t            *satIOContext)
14721 {
14722   bit32                     status;
14723   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14724   satDeviceData_t           *pSatDevData;
14725   tiIniScsiCmnd_t           *scsiCmnd;
14726   agsaFisRegHostToDevice_t  *fis;
14727 
14728   pSatDevData   = satIOContext->pSatDevData;
14729   scsiCmnd      = &tiScsiRequest->scsiCmnd;
14730   fis           = satIOContext->pFis;
14731 
14732   TI_DBG5(("satNonChainedWriteNVerify_Verify: start\n"));
14733 
14734   if (pSatDevData->sat48BitSupport == agTRUE)
14735   {
14736     fis->h.fisType        = 0x27;                   /* Reg host to device */
14737     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14738 
14739     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14740     fis->h.features       = 0;                      /* FIS reserve */
14741     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14742     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14743     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14744     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
14745     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14746     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14747     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14748     fis->d.featuresExp    = 0;                      /* FIS reserve */
14749     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14750     fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14751 
14752     fis->d.reserved4      = 0;
14753     fis->d.control        = 0;                      /* FIS HOB bit clear */
14754     fis->d.reserved5      = 0;
14755 
14756     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14757 
14758     /* Initialize CB for SATA completion.
14759      */
14760     satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14761 
14762     /*
14763      * Prepare SGL and send FIS to LL layer.
14764      */
14765     satIOContext->reqType = agRequestType;       /* Save it */
14766 
14767     status = sataLLIOStart( tiRoot,
14768                             tiIORequest,
14769                             tiDeviceHandle,
14770                             tiScsiRequest,
14771                             satIOContext);
14772 
14773 
14774     TI_DBG1(("satNonChainedWriteNVerify_Verify: return status %d\n", status));
14775     return (status);
14776   }
14777   else
14778   {
14779     /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14780     TI_DBG1(("satNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14781     return tiError;
14782   }
14783 
14784 }
14785 
14786 GLOBAL bit32  satChainedWriteNVerify_Write(
14787                    tiRoot_t                  *tiRoot,
14788                    tiIORequest_t             *tiIORequest,
14789                    tiDeviceHandle_t          *tiDeviceHandle,
14790                    tiScsiInitiatorRequest_t *tiScsiRequest,
14791                    satIOContext_t            *satIOContext)
14792 {
14793   /*
14794     Assumption: error check on lba and tl has been done in satWrite*()
14795     lba = lba + tl;
14796   */
14797   bit32                     status;
14798   satIOContext_t            *satOrgIOContext = agNULL;
14799   tiIniScsiCmnd_t           *scsiCmnd;
14800   agsaFisRegHostToDevice_t  *fis;
14801   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14802   bit32                     lba = 0;
14803   bit32                     DenomTL = 0xFF;
14804   bit32                     Remainder = 0;
14805   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
14806 
14807   TI_DBG1(("satChainedWriteNVerify_Write: start\n"));
14808 
14809   fis             = satIOContext->pFis;
14810   satOrgIOContext = satIOContext->satOrgIOContext;
14811   scsiCmnd        = satOrgIOContext->pScsiCmnd;
14812 
14813   osti_memset(LBA,0, sizeof(LBA));
14814 
14815   switch (satOrgIOContext->ATACmd)
14816   {
14817   case SAT_WRITE_DMA:
14818     DenomTL = 0xFF;
14819     break;
14820   case SAT_WRITE_SECTORS:
14821     DenomTL = 0xFF;
14822     break;
14823   case SAT_WRITE_DMA_EXT:
14824     DenomTL = 0xFFFF;
14825     break;
14826   case SAT_WRITE_DMA_FUA_EXT:
14827     DenomTL = 0xFFFF;
14828     break;
14829   case SAT_WRITE_SECTORS_EXT:
14830     DenomTL = 0xFFFF;
14831     break;
14832   case SAT_WRITE_FPDMA_QUEUED:
14833     DenomTL = 0xFFFF;
14834     break;
14835   default:
14836     TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
14837     return tiError;
14838     break;
14839   }
14840 
14841   Remainder = satOrgIOContext->OrgTL % DenomTL;
14842   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
14843   lba = satOrgIOContext->currentLBA;
14844 
14845   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
14846   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
14847   LBA[2] = (bit8)((lba & 0xF0) >> 8);
14848   LBA[3] = (bit8)(lba & 0xF);               /* LSB */
14849 
14850   switch (satOrgIOContext->ATACmd)
14851   {
14852   case SAT_WRITE_DMA:
14853     fis->h.fisType        = 0x27;                   /* Reg host to device */
14854     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14855     fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
14856     fis->h.features       = 0;                      /* FIS reserve */
14857     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14858     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14859     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14860 
14861     /* FIS LBA mode set LBA (27:24) */
14862     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14863 
14864     fis->d.lbaLowExp      = 0;
14865     fis->d.lbaMidExp      = 0;
14866     fis->d.lbaHighExp     = 0;
14867     fis->d.featuresExp    = 0;
14868     if (satOrgIOContext->LoopNum == 1)
14869     {
14870       /* last loop */
14871       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
14872     }
14873     else
14874     {
14875       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
14876     }
14877     fis->d.sectorCountExp = 0;
14878     fis->d.reserved4      = 0;
14879     fis->d.control        = 0;                      /* FIS HOB bit clear */
14880     fis->d.reserved5      = 0;
14881 
14882     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14883 
14884     break;
14885   case SAT_WRITE_SECTORS:
14886     fis->h.fisType        = 0x27;                   /* Reg host to device */
14887     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14888     fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
14889     fis->h.features       = 0;                      /* FIS reserve */
14890     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14891     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14892     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14893 
14894     /* FIS LBA mode set LBA (27:24) */
14895     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14896 
14897     fis->d.lbaLowExp      = 0;
14898     fis->d.lbaMidExp      = 0;
14899     fis->d.lbaHighExp     = 0;
14900     fis->d.featuresExp    = 0;
14901     if (satOrgIOContext->LoopNum == 1)
14902     {
14903       /* last loop */
14904       fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
14905     }
14906     else
14907     {
14908       fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
14909     }
14910     fis->d.sectorCountExp = 0;
14911     fis->d.reserved4      = 0;
14912     fis->d.control        = 0;                      /* FIS HOB bit clear */
14913     fis->d.reserved5      = 0;
14914 
14915     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14916 
14917     break;
14918   case SAT_WRITE_DMA_EXT:
14919     fis->h.fisType        = 0x27;                   /* Reg host to device */
14920     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14921     fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
14922     fis->h.features       = 0;                      /* FIS reserve */
14923     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14924     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14925     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14926     fis->d.device         = 0x40;                   /* FIS LBA mode set */
14927     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
14928     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14929     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14930     fis->d.featuresExp    = 0;                      /* FIS reserve */
14931     if (satOrgIOContext->LoopNum == 1)
14932     {
14933       /* last loop */
14934       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
14935       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
14936     }
14937     else
14938     {
14939       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
14940       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
14941     }
14942     fis->d.reserved4      = 0;
14943     fis->d.control        = 0;                       /* FIS HOB bit clear */
14944     fis->d.reserved5      = 0;
14945 
14946     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14947 
14948     break;
14949   case SAT_WRITE_SECTORS_EXT:
14950     fis->h.fisType        = 0x27;                   /* Reg host to device */
14951     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14952     fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
14953 
14954     fis->h.features       = 0;                      /* FIS reserve */
14955     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14956     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14957     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14958     fis->d.device         = 0x40;                   /* FIS LBA mode set */
14959     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
14960     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14961     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14962     fis->d.featuresExp    = 0;                      /* FIS reserve */
14963     if (satOrgIOContext->LoopNum == 1)
14964     {
14965       /* last loop */
14966       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
14967       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
14968     }
14969     else
14970     {
14971       fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
14972       fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
14973     }
14974     fis->d.reserved4      = 0;
14975     fis->d.control        = 0;                      /* FIS HOB bit clear */
14976     fis->d.reserved5      = 0;
14977 
14978     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14979 
14980     break;
14981   case SAT_WRITE_FPDMA_QUEUED:
14982     fis->h.fisType        = 0x27;                   /* Reg host to device */
14983     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14984     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14985     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14986     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14987     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14988 
14989     /* Check FUA bit */
14990     if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
14991       fis->d.device       = 0xC0;                   /* FIS FUA set */
14992     else
14993       fis->d.device       = 0x40;                   /* FIS FUA clear */
14994 
14995     fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
14996     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14997     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14998     if (satOrgIOContext->LoopNum == 1)
14999     {
15000       /* last loop */
15001       fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
15002       fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
15003     }
15004     else
15005     {
15006       fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
15007       fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
15008     }
15009     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15010     fis->d.sectorCountExp = 0;
15011     fis->d.reserved4      = 0;
15012     fis->d.control        = 0;                      /* FIS HOB bit clear */
15013     fis->d.reserved5      = 0;
15014 
15015     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15016     break;
15017 
15018   default:
15019     TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15020     return tiError;
15021     break;
15022   }
15023 
15024   /* Initialize CB for SATA completion.
15025    */
15026   /* chained data */
15027   satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15028 
15029 
15030   /*
15031    * Prepare SGL and send FIS to LL layer.
15032    */
15033   satIOContext->reqType = agRequestType;       /* Save it */
15034 
15035   status = sataLLIOStart( tiRoot,
15036                           tiIORequest,
15037                           tiDeviceHandle,
15038                           tiScsiRequest,
15039                           satIOContext);
15040 
15041   TI_DBG5(("satChainedWriteNVerify_Write: return\n"));
15042   return (status);
15043 
15044 }
15045 
15046 /*
15047   similar to write12 and verify10;
15048   this will be similar to verify12
15049   */
15050 GLOBAL bit32  satChainedWriteNVerify_Start_Verify(
15051                    tiRoot_t                  *tiRoot,
15052                    tiIORequest_t             *tiIORequest,
15053                    tiDeviceHandle_t          *tiDeviceHandle,
15054                    tiScsiInitiatorRequest_t *tiScsiRequest,
15055                    satIOContext_t            *satIOContext)
15056 {
15057   /*
15058     deal with transfer length; others have been handled previously at this point;
15059     no LBA check; no range check;
15060   */
15061   bit32                     status;
15062   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15063   satDeviceData_t           *pSatDevData;
15064   tiIniScsiCmnd_t           *scsiCmnd;
15065   agsaFisRegHostToDevice_t  *fis;
15066   bit32                     lba = 0;
15067   bit32                     tl = 0;
15068   bit32                     LoopNum = 1;
15069   bit8                      LBA[4];
15070   bit8                      TL[4];
15071 
15072   pSatDevData   = satIOContext->pSatDevData;
15073   scsiCmnd      = &tiScsiRequest->scsiCmnd;
15074   fis           = satIOContext->pFis;
15075 
15076   TI_DBG5(("satChainedWriteNVerify_Start_Verify: start\n"));
15077 
15078   osti_memset(LBA, 0, sizeof(LBA));
15079   osti_memset(TL, 0, sizeof(TL));
15080 
15081   /* do not use memcpy due to indexing in LBA and TL */
15082   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
15083   LBA[1] = scsiCmnd->cdb[3];
15084   LBA[2] = scsiCmnd->cdb[4];
15085   LBA[3] = scsiCmnd->cdb[5];  /* LSB */
15086 
15087   TL[0] = scsiCmnd->cdb[6];   /* MSB */
15088   TL[1] = scsiCmnd->cdb[7];
15089   TL[2] = scsiCmnd->cdb[7];
15090   TL[3] = scsiCmnd->cdb[8];   /* LSB */
15091 
15092   lba = satComputeCDB12LBA(satIOContext);
15093   tl = satComputeCDB12TL(satIOContext);
15094 
15095   if (pSatDevData->sat48BitSupport == agTRUE)
15096   {
15097     TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n"));
15098     fis->h.fisType        = 0x27;                   /* Reg host to device */
15099     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15100 
15101     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
15102     fis->h.features       = 0;                      /* FIS reserve */
15103     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15104     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15105     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15106     fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
15107     fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15108     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15109     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15110     fis->d.featuresExp    = 0;                      /* FIS reserve */
15111     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15112     fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15113 
15114     fis->d.reserved4      = 0;
15115     fis->d.control        = 0;                      /* FIS HOB bit clear */
15116     fis->d.reserved5      = 0;
15117 
15118     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15119     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
15120   }
15121   else
15122   {
15123     TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n"));
15124     fis->h.fisType        = 0x27;                   /* Reg host to device */
15125     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15126     fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
15127     fis->h.features       = 0;                      /* FIS reserve */
15128     fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15129     fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15130     fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15131       /* FIS LBA mode set LBA (27:24) */
15132     fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15133     fis->d.lbaLowExp      = 0;
15134     fis->d.lbaMidExp      = 0;
15135     fis->d.lbaHighExp     = 0;
15136     fis->d.featuresExp    = 0;
15137     fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15138     fis->d.sectorCountExp = 0;
15139     fis->d.reserved4      = 0;
15140     fis->d.control        = 0;                      /* FIS HOB bit clear */
15141     fis->d.reserved5      = 0;
15142 
15143     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15144     satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
15145 
15146  }
15147 
15148   satIOContext->currentLBA = lba;
15149   satIOContext->OrgTL = tl;
15150 
15151   /*
15152     computing number of loop and remainder for tl
15153     0xFF in case not ext
15154     0xFFFF in case EXT
15155   */
15156   if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15157   {
15158     LoopNum = satComputeLoopNum(tl, 0xFF);
15159   }
15160   else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15161   {
15162     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15163     LoopNum = satComputeLoopNum(tl, 0xFFFF);
15164   }
15165   else
15166   {
15167     TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
15168     LoopNum = 1;
15169   }
15170 
15171   satIOContext->LoopNum = LoopNum;
15172 
15173   if (LoopNum == 1)
15174   {
15175     TI_DBG5(("satChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
15176     /* Initialize CB for SATA completion.
15177      */
15178     satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15179   }
15180   else
15181   {
15182     TI_DBG1(("satChainedWriteNVerify_Start_Verify: CHAINED data\n"));
15183     /* re-setting tl */
15184     if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15185     {
15186        fis->d.sectorCount    = 0xFF;
15187     }
15188     else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15189     {
15190       fis->d.sectorCount    = 0xFF;
15191       fis->d.sectorCountExp = 0xFF;
15192     }
15193     else
15194     {
15195       TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
15196     }
15197 
15198     /* Initialize CB for SATA completion.
15199      */
15200     satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15201   }
15202 
15203 
15204   /*
15205    * Prepare SGL and send FIS to LL layer.
15206    */
15207   satIOContext->reqType = agRequestType;       /* Save it */
15208 
15209   status = sataLLIOStart( tiRoot,
15210                           tiIORequest,
15211                           tiDeviceHandle,
15212                           tiScsiRequest,
15213                           satIOContext);
15214   return (status);
15215 }
15216 
15217 GLOBAL bit32  satChainedWriteNVerify_Verify(
15218                    tiRoot_t                  *tiRoot,
15219                    tiIORequest_t             *tiIORequest,
15220                    tiDeviceHandle_t          *tiDeviceHandle,
15221                    tiScsiInitiatorRequest_t *tiScsiRequest,
15222                    satIOContext_t            *satIOContext)
15223 {
15224   bit32                     status;
15225   satIOContext_t            *satOrgIOContext = agNULL;
15226   agsaFisRegHostToDevice_t  *fis;
15227   bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15228   bit32                     lba = 0;
15229   bit32                     DenomTL = 0xFF;
15230   bit32                     Remainder = 0;
15231   bit8                      LBA[4]; /* 0 MSB, 3 LSB */
15232 
15233   TI_DBG2(("satChainedWriteNVerify_Verify: start\n"));
15234 
15235   fis             = satIOContext->pFis;
15236   satOrgIOContext = satIOContext->satOrgIOContext;
15237 
15238   osti_memset(LBA,0, sizeof(LBA));
15239 
15240   switch (satOrgIOContext->ATACmd)
15241   {
15242   case SAT_READ_VERIFY_SECTORS:
15243     DenomTL = 0xFF;
15244     break;
15245   case SAT_READ_VERIFY_SECTORS_EXT:
15246     DenomTL = 0xFFFF;
15247     break;
15248   default:
15249     TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15250     return tiError;
15251     break;
15252   }
15253 
15254   Remainder = satOrgIOContext->OrgTL % DenomTL;
15255   satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
15256   lba = satOrgIOContext->currentLBA;
15257 
15258   LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
15259   LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
15260   LBA[2] = (bit8)((lba & 0xF0) >> 8);
15261   LBA[3] = (bit8)(lba & 0xF);               /* LSB */
15262 
15263   switch (satOrgIOContext->ATACmd)
15264   {
15265   case SAT_READ_VERIFY_SECTORS:
15266     fis->h.fisType        = 0x27;                   /* Reg host to device */
15267     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15268     fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
15269     fis->h.features       = 0;                      /* FIS reserve */
15270     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
15271     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
15272     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
15273 
15274     /* FIS LBA mode set LBA (27:24) */
15275     fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
15276 
15277     fis->d.lbaLowExp      = 0;
15278     fis->d.lbaMidExp      = 0;
15279     fis->d.lbaHighExp     = 0;
15280     fis->d.featuresExp    = 0;
15281     if (satOrgIOContext->LoopNum == 1)
15282     {
15283       /* last loop */
15284       fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
15285     }
15286     else
15287     {
15288       fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
15289     }
15290     fis->d.sectorCountExp = 0;
15291     fis->d.reserved4      = 0;
15292     fis->d.control        = 0;                      /* FIS HOB bit clear */
15293     fis->d.reserved5      = 0;
15294 
15295     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15296 
15297     break;
15298   case SAT_READ_VERIFY_SECTORS_EXT:
15299     fis->h.fisType        = 0x27;                   /* Reg host to device */
15300     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15301     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
15302     fis->h.features       = 0;                      /* FIS reserve */
15303     fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
15304     fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
15305     fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
15306     fis->d.device         = 0x40;                   /* FIS LBA mode set */
15307     fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
15308     fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15309     fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15310     fis->d.featuresExp    = 0;                      /* FIS reserve */
15311     if (satOrgIOContext->LoopNum == 1)
15312     {
15313       /* last loop */
15314       fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
15315       fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
15316     }
15317     else
15318     {
15319       fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
15320       fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
15321     }
15322     fis->d.reserved4      = 0;
15323     fis->d.control        = 0;                       /* FIS HOB bit clear */
15324     fis->d.reserved5      = 0;
15325 
15326     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15327 
15328     break;
15329 
15330   default:
15331     TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15332     return tiError;
15333     break;
15334   }
15335 
15336   /* Initialize CB for SATA completion.
15337    */
15338   /* chained data */
15339   satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15340 
15341 
15342   /*
15343    * Prepare SGL and send FIS to LL layer.
15344    */
15345   satIOContext->reqType = agRequestType;       /* Save it */
15346 
15347   status = sataLLIOStart( tiRoot,
15348                           tiIORequest,
15349                           tiDeviceHandle,
15350                           tiScsiRequest,
15351                           satIOContext);
15352 
15353   TI_DBG5(("satChainedWriteNVerify_Verify: return\n"));
15354   return (status);
15355 
15356 }
15357 
15358 
15359 /*****************************************************************************/
15360 /*! \brief SAT implementation for SCSI satWriteAndVerify16.
15361  *
15362  *  SAT implementation for SCSI satWriteAndVerify16.
15363  *
15364  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
15365  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
15366  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
15367  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
15368  *  \param   satIOContext_t:   Pointer to the SAT IO Context
15369  *
15370  *  \return If command is started successfully
15371  *    - \e tiSuccess:     I/O request successfully initiated.
15372  *    - \e tiBusy:        No resources available, try again later.
15373  *    - \e tiIONoDevice:  Invalid device handle.
15374  *    - \e tiError:       Other errors.
15375  */
15376 /*****************************************************************************/
15377 GLOBAL bit32  satWriteAndVerify16(
15378                    tiRoot_t                  *tiRoot,
15379                    tiIORequest_t             *tiIORequest,
15380                    tiDeviceHandle_t          *tiDeviceHandle,
15381                    tiScsiInitiatorRequest_t *tiScsiRequest,
15382                    satIOContext_t            *satIOContext)
15383 {
15384   /*
15385     combination of write16 and verify16
15386     since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support
15387   */
15388   bit32                     status;
15389   bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15390   satDeviceData_t           *pSatDevData;
15391   scsiRspSense_t            *pSense;
15392   tiIniScsiCmnd_t           *scsiCmnd;
15393   agsaFisRegHostToDevice_t  *fis;
15394   bit32                     lba = 0;
15395   bit32                     tl = 0;
15396   bit32                     LoopNum = 1;
15397   bit8                      LBA[8];
15398   bit8                      TL[8];
15399   bit32                     rangeChk = agFALSE; /* lba and tl range check */
15400   bit32                     limitChk = agFALSE; /* lba and tl range check */
15401 
15402   pSense        = satIOContext->pSense;
15403   pSatDevData   = satIOContext->pSatDevData;
15404   scsiCmnd      = &tiScsiRequest->scsiCmnd;
15405   fis           = satIOContext->pFis;
15406   TI_DBG5(("satWriteAndVerify16:start\n"));
15407 
15408   /* checking BYTCHK bit */
15409   if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15410   {
15411     satSetSensePayload( pSense,
15412                         SCSI_SNSKEY_ILLEGAL_REQUEST,
15413                         0,
15414                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15415                         satIOContext);
15416 
15417     ostiInitiatorIOCompleted( tiRoot,
15418                               tiIORequest,
15419                               tiIOSuccess,
15420                               SCSI_STAT_CHECK_CONDITION,
15421                               satIOContext->pTiSenseData,
15422                               satIOContext->interruptContext );
15423 
15424     TI_DBG1(("satWriteAndVerify16: BYTCHK bit checking \n"));
15425     return tiSuccess;
15426   }
15427 
15428 
15429   /* checking CONTROL */
15430   /* NACA == 1 or LINK == 1*/
15431   if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
15432   {
15433     satSetSensePayload( pSense,
15434                         SCSI_SNSKEY_ILLEGAL_REQUEST,
15435                         0,
15436                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15437                         satIOContext);
15438 
15439     ostiInitiatorIOCompleted( tiRoot,
15440                               tiIORequest,
15441                               tiIOSuccess,
15442                               SCSI_STAT_CHECK_CONDITION,
15443                               satIOContext->pTiSenseData,
15444                               satIOContext->interruptContext );
15445 
15446     TI_DBG2(("satWriteAndVerify16: return control\n"));
15447     return tiSuccess;
15448   }
15449 
15450   osti_memset(LBA, 0, sizeof(LBA));
15451   osti_memset(TL, 0, sizeof(TL));
15452 
15453 
15454   /* do not use memcpy due to indexing in LBA and TL */
15455   LBA[0] = scsiCmnd->cdb[2];  /* MSB */
15456   LBA[1] = scsiCmnd->cdb[3];
15457   LBA[2] = scsiCmnd->cdb[4];
15458   LBA[3] = scsiCmnd->cdb[5];
15459   LBA[4] = scsiCmnd->cdb[6];
15460   LBA[5] = scsiCmnd->cdb[7];
15461   LBA[6] = scsiCmnd->cdb[8];
15462   LBA[7] = scsiCmnd->cdb[9];  /* LSB */
15463 
15464   TL[0] = 0;
15465   TL[1] = 0;
15466   TL[2] = 0;
15467   TL[3] = 0;
15468   TL[4] = scsiCmnd->cdb[10];   /* MSB */
15469   TL[5] = scsiCmnd->cdb[11];
15470   TL[6] = scsiCmnd->cdb[12];
15471   TL[7] = scsiCmnd->cdb[13];   /* LSB */
15472 
15473   rangeChk = satAddNComparebit64(LBA, TL);
15474 
15475   limitChk = satCompareLBALimitbit(LBA);
15476 
15477   lba = satComputeCDB16LBA(satIOContext);
15478   tl = satComputeCDB16TL(satIOContext);
15479 
15480 
15481   /* Table 34, 9.1, p 46 */
15482   /*
15483     note: As of 2/10/2006, no support for DMA QUEUED
15484   */
15485 
15486   /*
15487     Table 34, 9.1, p 46, b
15488     When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15489     return check condition
15490   */
15491   if (pSatDevData->satNCQ != agTRUE &&
15492      pSatDevData->sat48BitSupport != agTRUE
15493      )
15494   {
15495     if (limitChk)
15496     {
15497       TI_DBG1(("satWriteAndVerify16: return LBA out of range, not EXT\n"));
15498       satSetSensePayload( pSense,
15499                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15500                           0,
15501                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15502                           satIOContext);
15503 
15504       ostiInitiatorIOCompleted( tiRoot,
15505                                 tiIORequest,
15506                                 tiIOSuccess,
15507                                 SCSI_STAT_CHECK_CONDITION,
15508                                 satIOContext->pTiSenseData,
15509                                 satIOContext->interruptContext );
15510 
15511     return tiSuccess;
15512     }
15513     if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
15514     {
15515       TI_DBG1(("satWriteAndVerify16: return LBA+TL out of range, not EXT\n"));
15516       satSetSensePayload( pSense,
15517                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15518                           0,
15519                           SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15520                           satIOContext);
15521 
15522       ostiInitiatorIOCompleted( tiRoot,
15523                                 tiIORequest,
15524                                 tiIOSuccess,
15525                                 SCSI_STAT_CHECK_CONDITION,
15526                                 satIOContext->pTiSenseData,
15527                                 satIOContext->interruptContext );
15528 
15529     return tiSuccess;
15530     }
15531   }
15532 
15533 
15534   /* case 1 and 2 */
15535   if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
15536   {
15537     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15538     {
15539       /* case 2 */
15540       /* WRITE DMA*/
15541       /* In case that we can't fit the transfer length, we loop */
15542       TI_DBG5(("satWriteAndVerify16: case 2\n"));
15543       fis->h.fisType        = 0x27;                   /* Reg host to device */
15544       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15545       fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
15546       fis->h.features       = 0;                      /* FIS reserve */
15547       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15548       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15549       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15550 
15551       /* FIS LBA mode set LBA (27:24) */
15552       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15553 
15554       fis->d.lbaLowExp      = 0;
15555       fis->d.lbaMidExp      = 0;
15556       fis->d.lbaHighExp     = 0;
15557       fis->d.featuresExp    = 0;
15558       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15559       fis->d.sectorCountExp = 0;
15560       fis->d.reserved4      = 0;
15561       fis->d.control        = 0;                      /* FIS HOB bit clear */
15562       fis->d.reserved5      = 0;
15563 
15564       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15565       satIOContext->ATACmd = SAT_WRITE_DMA;
15566     }
15567     else
15568     {
15569       /* case 1 */
15570       /* WRITE MULTIPLE or WRITE SECTOR(S) */
15571       /* WRITE SECTORS for easier implemetation */
15572       /* In case that we can't fit the transfer length, we loop */
15573       TI_DBG5(("satWriteAndVerify16: case 1\n"));
15574       fis->h.fisType        = 0x27;                   /* Reg host to device */
15575       fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15576       fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
15577       fis->h.features       = 0;                      /* FIS reserve */
15578       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15579       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15580       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15581 
15582       /* FIS LBA mode set LBA (27:24) */
15583       fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15584 
15585       fis->d.lbaLowExp      = 0;
15586       fis->d.lbaMidExp      = 0;
15587       fis->d.lbaHighExp     = 0;
15588       fis->d.featuresExp    = 0;
15589       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15590       fis->d.sectorCountExp = 0;
15591       fis->d.reserved4      = 0;
15592       fis->d.control        = 0;                      /* FIS HOB bit clear */
15593       fis->d.reserved5      = 0;
15594 
15595       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15596       satIOContext->ATACmd = SAT_WRITE_SECTORS;
15597     }
15598   }
15599 
15600   /* case 3 and 4 */
15601   if (pSatDevData->sat48BitSupport == agTRUE)
15602   {
15603     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15604     {
15605       /* case 3 */
15606       /* WRITE DMA EXT or WRITE DMA FUA EXT */
15607       TI_DBG5(("satWriteAndVerify16: case 3\n"));
15608       fis->h.fisType        = 0x27;                   /* Reg host to device */
15609       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15610 
15611       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15612       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
15613 
15614       fis->h.features       = 0;                      /* FIS reserve */
15615       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15616       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15617       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15618       fis->d.device         = 0x40;                   /* FIS LBA mode set */
15619       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
15620       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
15621       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
15622       fis->d.featuresExp    = 0;                      /* FIS reserve */
15623       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15624       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
15625       fis->d.reserved4      = 0;
15626       fis->d.control        = 0;                      /* FIS HOB bit clear */
15627       fis->d.reserved5      = 0;
15628 
15629       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15630       satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15631     }
15632     else
15633     {
15634       /* case 4 */
15635       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15636       /* WRITE SECTORS EXT for easier implemetation */
15637       TI_DBG5(("satWriteAndVerify16: case 4\n"));
15638       fis->h.fisType        = 0x27;                   /* Reg host to device */
15639       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15640       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
15641 
15642       fis->h.features       = 0;                      /* FIS reserve */
15643       fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15644       fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15645       fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15646       fis->d.device         = 0x40;                   /* FIS LBA mode set */
15647       fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
15648       fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
15649       fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
15650       fis->d.featuresExp    = 0;                      /* FIS reserve */
15651       fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15652       fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
15653       fis->d.reserved4      = 0;
15654       fis->d.control        = 0;                      /* FIS HOB bit clear */
15655       fis->d.reserved5      = 0;
15656 
15657       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15658       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15659     }
15660   }
15661 
15662   /* case 5 */
15663   if (pSatDevData->satNCQ == agTRUE)
15664   {
15665     /* WRITE FPDMA QUEUED */
15666     if (pSatDevData->sat48BitSupport != agTRUE)
15667     {
15668       TI_DBG5(("satWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support \n"));
15669       satSetSensePayload( pSense,
15670                           SCSI_SNSKEY_ILLEGAL_REQUEST,
15671                           0,
15672                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15673                           satIOContext);
15674 
15675       ostiInitiatorIOCompleted( tiRoot,
15676                                 tiIORequest,
15677                                 tiIOSuccess,
15678                                 SCSI_STAT_CHECK_CONDITION,
15679                                 satIOContext->pTiSenseData,
15680                                 satIOContext->interruptContext );
15681       return tiSuccess;
15682     }
15683     TI_DBG6(("satWriteAndVerify16: case 5\n"));
15684 
15685     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15686 
15687     fis->h.fisType        = 0x27;                   /* Reg host to device */
15688     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15689     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15690     fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15691     fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15692     fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15693     fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15694 
15695     /* Check FUA bit */
15696     if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
15697       fis->d.device       = 0xC0;                   /* FIS FUA set */
15698     else
15699       fis->d.device       = 0x40;                   /* FIS FUA clear */
15700 
15701     fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
15702     fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
15703     fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
15704     fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
15705     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15706     fis->d.sectorCountExp = 0;
15707     fis->d.reserved4      = 0;
15708     fis->d.control        = 0;                      /* FIS HOB bit clear */
15709     fis->d.reserved5      = 0;
15710 
15711     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15712     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15713   }
15714 
15715   satIOContext->currentLBA = lba;
15716   satIOContext->OrgTL = tl;
15717 
15718   /*
15719     computing number of loop and remainder for tl
15720     0xFF in case not ext
15721     0xFFFF in case EXT
15722   */
15723   if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15724   {
15725     LoopNum = satComputeLoopNum(tl, 0xFF);
15726   }
15727   else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15728            fis->h.command == SAT_WRITE_DMA_EXT     ||
15729            fis->h.command == SAT_WRITE_DMA_FUA_EXT
15730            )
15731   {
15732     /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15733     LoopNum = satComputeLoopNum(tl, 0xFFFF);
15734   }
15735   else
15736   {
15737     /* SAT_WRITE_FPDMA_QUEUEDK */
15738     LoopNum = satComputeLoopNum(tl, 0xFFFF);
15739   }
15740 
15741   satIOContext->LoopNum = LoopNum;
15742 
15743 
15744   if (LoopNum == 1)
15745   {
15746     TI_DBG5(("satWriteAndVerify16: NON CHAINED data\n"));
15747     /* Initialize CB for SATA completion.
15748      */
15749     satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15750   }
15751   else
15752   {
15753     TI_DBG1(("satWriteAndVerify16: CHAINED data\n"));
15754     /* re-setting tl */
15755     if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15756     {
15757        fis->d.sectorCount    = 0xFF;
15758     }
15759     else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15760              fis->h.command == SAT_WRITE_DMA_EXT ||
15761              fis->h.command == SAT_WRITE_DMA_FUA_EXT
15762              )
15763     {
15764       fis->d.sectorCount    = 0xFF;
15765       fis->d.sectorCountExp = 0xFF;
15766     }
15767     else
15768     {
15769       /* SAT_WRITE_FPDMA_QUEUED */
15770       fis->h.features       = 0xFF;
15771       fis->d.featuresExp    = 0xFF;
15772     }
15773 
15774     /* Initialize CB for SATA completion.
15775      */
15776     satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15777   }
15778 
15779 
15780   /*
15781    * Prepare SGL and send FIS to LL layer.
15782    */
15783   satIOContext->reqType = agRequestType;       /* Save it */
15784 
15785   status = sataLLIOStart( tiRoot,
15786                           tiIORequest,
15787                           tiDeviceHandle,
15788                           tiScsiRequest,
15789                           satIOContext);
15790   return (status);
15791 }
15792 
15793 /*****************************************************************************/
15794 /*! \brief SAT implementation for SCSI satReadMediaSerialNumber.
15795  *
15796  *  SAT implementation for SCSI Read Media Serial Number.
15797  *
15798  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
15799  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
15800  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
15801  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
15802  *  \param   satIOContext_t:   Pointer to the SAT IO Context
15803  *
15804  *  \return If command is started successfully
15805  *    - \e tiSuccess:     I/O request successfully initiated.
15806  *    - \e tiBusy:        No resources available, try again later.
15807  *    - \e tiIONoDevice:  Invalid device handle.
15808  *    - \e tiError:       Other errors.
15809  */
15810 /*****************************************************************************/
15811 GLOBAL bit32  satReadMediaSerialNumber(
15812                    tiRoot_t                  *tiRoot,
15813                    tiIORequest_t             *tiIORequest,
15814                    tiDeviceHandle_t          *tiDeviceHandle,
15815                    tiScsiInitiatorRequest_t  *tiScsiRequest,
15816                    satIOContext_t            *satIOContext)
15817 {
15818   bit32                     status;
15819   bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15820   satDeviceData_t           *pSatDevData;
15821   scsiRspSense_t            *pSense;
15822   tiIniScsiCmnd_t           *scsiCmnd;
15823   agsaFisRegHostToDevice_t  *fis;
15824   agsaSATAIdentifyData_t    *pSATAIdData;
15825   bit8                      *pSerialNumber;
15826 
15827   pSense        = satIOContext->pSense;
15828   pSatDevData   = satIOContext->pSatDevData;
15829   scsiCmnd      = &tiScsiRequest->scsiCmnd;
15830   fis           = satIOContext->pFis;
15831   pSATAIdData   = &(pSatDevData->satIdentifyData);
15832   pSerialNumber = (bit8 *) tiScsiRequest->sglVirtualAddr;
15833 
15834 
15835   TI_DBG1(("satReadMediaSerialNumber: start\n"));
15836 
15837   /* checking CONTROL */
15838   /* NACA == 1 or LINK == 1*/
15839   if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
15840   {
15841     satSetSensePayload( pSense,
15842                         SCSI_SNSKEY_ILLEGAL_REQUEST,
15843                         0,
15844                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15845                         satIOContext);
15846 
15847     ostiInitiatorIOCompleted( tiRoot,
15848                               tiIORequest,
15849                               tiIOSuccess,
15850                               SCSI_STAT_CHECK_CONDITION,
15851                               satIOContext->pTiSenseData,
15852                               satIOContext->interruptContext );
15853 
15854     TI_DBG1(("satReadMediaSerialNumber: return control\n"));
15855     return tiSuccess;
15856   }
15857 
15858   if (tiScsiRequest->scsiCmnd.expDataLength == 4)
15859   {
15860     if (pSATAIdData->commandSetFeatureDefault & 0x4)
15861     {
15862       TI_DBG1(("satReadMediaSerialNumber: Media serial number returning only length\n"));
15863       /* SPC-3 6.16 p192; filling in length */
15864       pSerialNumber[0] = 0;
15865       pSerialNumber[1] = 0;
15866       pSerialNumber[2] = 0;
15867       pSerialNumber[3] = 0x3C;
15868     }
15869     else
15870     {
15871       /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/
15872       pSerialNumber[0] = 0;
15873       pSerialNumber[1] = 0;
15874       pSerialNumber[2] = 0x1;
15875       pSerialNumber[3] = 0xfc;
15876     }
15877 
15878     ostiInitiatorIOCompleted( tiRoot,
15879                               tiIORequest,
15880                               tiIOSuccess,
15881                               SCSI_STAT_GOOD,
15882                               agNULL,
15883                               satIOContext->interruptContext);
15884 
15885     return tiSuccess;
15886   }
15887 
15888   if ( pSatDevData->IDDeviceValid == agTRUE)
15889   {
15890     if (pSATAIdData->commandSetFeatureDefault & 0x4)
15891     {
15892       /* word87 bit2 Media serial number is valid */
15893       /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/
15894       tdhexdump("ID satReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
15895       /* SPC-3 6.16 p192; filling in length */
15896       pSerialNumber[0] = 0;
15897       pSerialNumber[1] = 0;
15898       pSerialNumber[2] = 0;
15899       pSerialNumber[3] = 0x3C;
15900       osti_memcpy(&pSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
15901       tdhexdump("satReadMediaSerialNumber", (bit8*)pSerialNumber, 2*30 + 4);
15902 
15903       ostiInitiatorIOCompleted( tiRoot,
15904                                 tiIORequest,
15905                                 tiIOSuccess,
15906                                 SCSI_STAT_GOOD,
15907                                 agNULL,
15908                                 satIOContext->interruptContext);
15909       return tiSuccess;
15910 
15911 
15912     }
15913     else
15914     {
15915      /* word87 bit2 Media serial number is NOT valid */
15916       TI_DBG1(("satReadMediaSerialNumber: Media serial number is NOT valid \n"));
15917 
15918       if (pSatDevData->sat48BitSupport == agTRUE)
15919       {
15920         /* READ VERIFY SECTORS EXT */
15921         fis->h.fisType        = 0x27;                   /* Reg host to device */
15922         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15923         fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
15924 
15925         fis->h.features       = 0;                      /* FIS reserve */
15926         fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
15927         fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
15928         fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
15929         fis->d.device         = 0x40;                   /* FIS LBA mode set */
15930         fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
15931         fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15932         fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15933         fis->d.featuresExp    = 0;                      /* FIS reserve */
15934         fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
15935         fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
15936         fis->d.reserved4      = 0;
15937         fis->d.control        = 0;                      /* FIS HOB bit clear */
15938         fis->d.reserved5      = 0;
15939 
15940         agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15941       }
15942       else
15943       {
15944         /* READ VERIFY SECTORS */
15945         fis->h.fisType        = 0x27;                   /* Reg host to device */
15946         fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15947         fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
15948         fis->h.features       = 0;                      /* FIS reserve */
15949         fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
15950         fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
15951         fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
15952         fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
15953         fis->d.lbaLowExp      = 0;
15954         fis->d.lbaMidExp      = 0;
15955         fis->d.lbaHighExp     = 0;
15956         fis->d.featuresExp    = 0;
15957         fis->d.sectorCount    = 1;                       /* FIS sector count (7:0) */
15958         fis->d.sectorCountExp = 0;
15959         fis->d.reserved4      = 0;
15960         fis->d.control        = 0;                      /* FIS HOB bit clear */
15961         fis->d.reserved5      = 0;
15962 
15963 
15964         agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15965       }
15966       satIOContext->satCompleteCB = &satReadMediaSerialNumberCB;
15967       satIOContext->reqType = agRequestType;       /* Save it */
15968       status = sataLLIOStart( tiRoot,
15969                              tiIORequest,
15970                              tiDeviceHandle,
15971                              tiScsiRequest,
15972                              satIOContext);
15973 
15974       return status;
15975     }
15976   }
15977   else
15978   {
15979      /* temporary failure */
15980     ostiInitiatorIOCompleted( tiRoot,
15981                               tiIORequest,
15982                               tiIOFailed,
15983                               tiDetailOtherError,
15984                               agNULL,
15985                               satIOContext->interruptContext);
15986 
15987     return tiSuccess;
15988 
15989   }
15990 
15991 }
15992 
15993 /*****************************************************************************/
15994 /*! \brief SAT implementation for SCSI satReadBuffer.
15995  *
15996  *  SAT implementation for SCSI Read Buffer.
15997  *
15998  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
15999  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16000  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16001  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16002  *  \param   satIOContext_t:   Pointer to the SAT IO Context
16003  *
16004  *  \return If command is started successfully
16005  *    - \e tiSuccess:     I/O request successfully initiated.
16006  *    - \e tiBusy:        No resources available, try again later.
16007  *    - \e tiIONoDevice:  Invalid device handle.
16008  *    - \e tiError:       Other errors.
16009  */
16010 /*****************************************************************************/
16011 /* SAT-2, Revision 00*/
16012 GLOBAL bit32  satReadBuffer(
16013                    tiRoot_t                  *tiRoot,
16014                    tiIORequest_t             *tiIORequest,
16015                    tiDeviceHandle_t          *tiDeviceHandle,
16016                    tiScsiInitiatorRequest_t *tiScsiRequest,
16017                    satIOContext_t            *satIOContext)
16018 {
16019   bit32                     status = tiSuccess;
16020   bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16021   scsiRspSense_t            *pSense;
16022   tiIniScsiCmnd_t           *scsiCmnd;
16023   agsaFisRegHostToDevice_t  *fis;
16024   bit32                     bufferOffset;
16025   bit32                     tl;
16026   bit8                      mode;
16027   bit8                      bufferID;
16028   bit8                      *pBuff;
16029 
16030   pSense        = satIOContext->pSense;
16031   scsiCmnd      = &tiScsiRequest->scsiCmnd;
16032   fis           = satIOContext->pFis;
16033   pBuff         = (bit8 *) tiScsiRequest->sglVirtualAddr;
16034 
16035   TI_DBG2(("satReadBuffer: start\n"));
16036   /* checking CONTROL */
16037   /* NACA == 1 or LINK == 1*/
16038   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16039   {
16040     satSetSensePayload( pSense,
16041                         SCSI_SNSKEY_ILLEGAL_REQUEST,
16042                         0,
16043                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16044                         satIOContext);
16045     ostiInitiatorIOCompleted( tiRoot,
16046                               tiIORequest,
16047                               tiIOSuccess,
16048                               SCSI_STAT_CHECK_CONDITION,
16049                               satIOContext->pTiSenseData,
16050                               satIOContext->interruptContext );
16051     TI_DBG1(("satReadBuffer: return control\n"));
16052     return tiSuccess;
16053   }
16054 
16055   bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16056   tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16057 
16058   mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16059   bufferID = scsiCmnd->cdb[2];
16060 
16061   if (mode == READ_BUFFER_DATA_MODE) /* 2 */
16062   {
16063     if (bufferID == 0 && bufferOffset == 0 && tl == 512)
16064     {
16065       /* send ATA READ BUFFER */
16066       fis->h.fisType        = 0x27;                   /* Reg host to device */
16067       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16068       fis->h.command        = SAT_READ_BUFFER;        /* 0xE4 */
16069       fis->h.features       = 0;                      /* FIS reserve */
16070       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16071       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16072       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16073       fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16074       fis->d.lbaLowExp      = 0;
16075       fis->d.lbaMidExp      = 0;
16076       fis->d.lbaHighExp     = 0;
16077       fis->d.featuresExp    = 0;
16078       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16079       fis->d.sectorCountExp = 0;
16080       fis->d.reserved4      = 0;
16081       fis->d.control        = 0;                      /* FIS HOB bit clear */
16082       fis->d.reserved5      = 0;
16083 
16084       agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16085       satIOContext->satCompleteCB = &satReadBufferCB;
16086       satIOContext->reqType = agRequestType;       /* Save it */
16087 
16088       status = sataLLIOStart( tiRoot,
16089                               tiIORequest,
16090                               tiDeviceHandle,
16091                               tiScsiRequest,
16092                               satIOContext);
16093       return status;
16094     }
16095     if (bufferID == 0 && bufferOffset == 0 && tl != 512)
16096     {
16097       satSetSensePayload( pSense,
16098                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16099                           0,
16100                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16101                           satIOContext);
16102       ostiInitiatorIOCompleted( tiRoot,
16103                                 tiIORequest,
16104                                 tiIOSuccess,
16105                                 SCSI_STAT_CHECK_CONDITION,
16106                                 satIOContext->pTiSenseData,
16107                                 satIOContext->interruptContext );
16108       TI_DBG1(("satReadBuffer: allocation length is not 512; it is %d\n", tl));
16109       return tiSuccess;
16110     }
16111     if (bufferID == 0 && bufferOffset != 0)
16112     {
16113       satSetSensePayload( pSense,
16114                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16115                           0,
16116                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16117                           satIOContext);
16118       ostiInitiatorIOCompleted( tiRoot,
16119                                 tiIORequest,
16120                                 tiIOSuccess,
16121                                 SCSI_STAT_CHECK_CONDITION,
16122                                 satIOContext->pTiSenseData,
16123                                 satIOContext->interruptContext );
16124       TI_DBG1(("satReadBuffer: buffer offset is not 0; it is %d\n", bufferOffset));
16125       return tiSuccess;
16126     }
16127     /* all other cases unsupported */
16128     TI_DBG1(("satReadBuffer: unsupported case 1\n"));
16129     satSetSensePayload( pSense,
16130                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16131                           0,
16132                           SCSI_SNSCODE_INVALID_COMMAND,
16133                           satIOContext);
16134 
16135     ostiInitiatorIOCompleted( tiRoot,
16136                                 tiIORequest,
16137                                 tiIOSuccess,
16138                                 SCSI_STAT_CHECK_CONDITION,
16139                                 satIOContext->pTiSenseData,
16140                                 satIOContext->interruptContext );
16141     return tiSuccess;
16142   }
16143   else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */
16144   {
16145     if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */
16146     {
16147       satSetSensePayload( pSense,
16148                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16149                           0,
16150                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16151                           satIOContext);
16152       ostiInitiatorIOCompleted( tiRoot,
16153                                 tiIORequest,
16154                                 tiIOSuccess,
16155                                 SCSI_STAT_CHECK_CONDITION,
16156                                 satIOContext->pTiSenseData,
16157                                 satIOContext->interruptContext );
16158       TI_DBG1(("satReadBuffer: tl < 4; tl is %d\n", tl));
16159       return tiSuccess;
16160     }
16161     if (bufferID == 0)
16162     {
16163       /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/
16164       pBuff[0] = 0xFF;
16165       pBuff[1] = 0x00;
16166       pBuff[2] = 0x02;
16167       pBuff[3] = 0x00;
16168       if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
16169       {
16170         /* underrrun */
16171         TI_DBG1(("satReadBuffer: underrun tl %d data %d\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
16172         ostiInitiatorIOCompleted( tiRoot,
16173                                 tiIORequest,
16174                                 tiIOUnderRun,
16175                                 tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
16176                                 agNULL,
16177                                 satIOContext->interruptContext );
16178         return tiSuccess;
16179       }
16180       else
16181       {
16182         ostiInitiatorIOCompleted( tiRoot,
16183                                   tiIORequest,
16184                                   tiIOSuccess,
16185                                   SCSI_STAT_GOOD,
16186                                   agNULL,
16187                                   satIOContext->interruptContext);
16188         return tiSuccess;
16189       }
16190     }
16191     else
16192     {
16193       /* We don't support other than bufferID 0 */
16194       satSetSensePayload( pSense,
16195                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16196                           0,
16197                           SCSI_SNSCODE_INVALID_COMMAND,
16198                           satIOContext);
16199 
16200       ostiInitiatorIOCompleted( tiRoot,
16201                                 tiIORequest,
16202                                 tiIOSuccess,
16203                                 SCSI_STAT_CHECK_CONDITION,
16204                                 satIOContext->pTiSenseData,
16205                                 satIOContext->interruptContext );
16206       return tiSuccess;
16207     }
16208   }
16209   else
16210   {
16211     /* We don't support any other mode */
16212     TI_DBG1(("satReadBuffer: unsupported mode %d\n", mode));
16213     satSetSensePayload( pSense,
16214                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16215                           0,
16216                           SCSI_SNSCODE_INVALID_COMMAND,
16217                           satIOContext);
16218 
16219     ostiInitiatorIOCompleted( tiRoot,
16220                                 tiIORequest,
16221                                 tiIOSuccess,
16222                                 SCSI_STAT_CHECK_CONDITION,
16223                                 satIOContext->pTiSenseData,
16224                                 satIOContext->interruptContext );
16225     return tiSuccess;
16226   }
16227 }
16228 
16229 /*****************************************************************************/
16230 /*! \brief SAT implementation for SCSI satWriteBuffer.
16231  *
16232  *  SAT implementation for SCSI Write Buffer.
16233  *
16234  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16235  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16236  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16237  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16238  *  \param   satIOContext_t:   Pointer to the SAT IO Context
16239  *
16240  *  \return If command is started successfully
16241  *    - \e tiSuccess:     I/O request successfully initiated.
16242  *    - \e tiBusy:        No resources available, try again later.
16243  *    - \e tiIONoDevice:  Invalid device handle.
16244  *    - \e tiError:       Other errors.
16245  */
16246 /*****************************************************************************/
16247 /* SAT-2, Revision 00*/
16248 GLOBAL bit32  satWriteBuffer(
16249                    tiRoot_t                  *tiRoot,
16250                    tiIORequest_t             *tiIORequest,
16251                    tiDeviceHandle_t          *tiDeviceHandle,
16252                    tiScsiInitiatorRequest_t *tiScsiRequest,
16253                    satIOContext_t            *satIOContext)
16254 {
16255 #ifdef NOT_YET
16256   bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16257 #endif
16258   scsiRspSense_t            *pSense;
16259   tiIniScsiCmnd_t           *scsiCmnd;
16260   bit32                     bufferOffset;
16261   bit32                     parmLen;
16262   bit8                      mode;
16263   bit8                      bufferID;
16264   bit8                      *pBuff;
16265 
16266   pSense        = satIOContext->pSense;
16267   scsiCmnd      = &tiScsiRequest->scsiCmnd;
16268   pBuff         = (bit8 *) tiScsiRequest->sglVirtualAddr;
16269 
16270   TI_DBG2(("satWriteBuffer: start\n"));
16271 
16272   /* checking CONTROL */
16273   /* NACA == 1 or LINK == 1*/
16274   if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16275   {
16276     satSetSensePayload( pSense,
16277                         SCSI_SNSKEY_ILLEGAL_REQUEST,
16278                         0,
16279                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16280                         satIOContext);
16281 
16282     ostiInitiatorIOCompleted( tiRoot,
16283                               tiIORequest,
16284                               tiIOSuccess,
16285                               SCSI_STAT_CHECK_CONDITION,
16286                               satIOContext->pTiSenseData,
16287                               satIOContext->interruptContext );
16288 
16289     TI_DBG1(("satWriteBuffer: return control\n"));
16290     return tiSuccess;
16291   }
16292 
16293   bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16294   parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16295 
16296   mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16297   bufferID = scsiCmnd->cdb[2];
16298 
16299   /* for debugging only */
16300   tdhexdump("satWriteBuffer pBuff", (bit8 *)pBuff, 24);
16301 
16302   if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */
16303   {
16304     if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
16305     {
16306       TI_DBG1(("satWriteBuffer: sending ATA WRITE BUFFER\n"));
16307       /* send ATA WRITE BUFFER */
16308 #ifdef NOT_YET
16309       fis->h.fisType        = 0x27;                   /* Reg host to device */
16310       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16311       fis->h.command        = SAT_WRITE_BUFFER;       /* 0xE8 */
16312       fis->h.features       = 0;                      /* FIS reserve */
16313       fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16314       fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16315       fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16316       fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16317       fis->d.lbaLowExp      = 0;
16318       fis->d.lbaMidExp      = 0;
16319       fis->d.lbaHighExp     = 0;
16320       fis->d.featuresExp    = 0;
16321       fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16322       fis->d.sectorCountExp = 0;
16323       fis->d.reserved4      = 0;
16324       fis->d.control        = 0;                      /* FIS HOB bit clear */
16325       fis->d.reserved5      = 0;
16326 
16327 
16328       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16329 
16330       satIOContext->satCompleteCB = &satWriteBufferCB;
16331 
16332       satIOContext->reqType = agRequestType;       /* Save it */
16333 
16334       status = sataLLIOStart( tiRoot,
16335                               tiIORequest,
16336                               tiDeviceHandle,
16337                               tiScsiRequest,
16338                               satIOContext);
16339       return status;
16340 #endif
16341       /* temp */
16342       ostiInitiatorIOCompleted( tiRoot,
16343                                   tiIORequest,
16344                                   tiIOSuccess,
16345                                   SCSI_STAT_GOOD,
16346                                   agNULL,
16347                                   satIOContext->interruptContext);
16348       return tiSuccess;
16349     }
16350     if ( (bufferID == 0 && bufferOffset != 0) ||
16351          (bufferID == 0 && parmLen != 512)
16352         )
16353     {
16354       satSetSensePayload( pSense,
16355                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16356                           0,
16357                           SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16358                           satIOContext);
16359 
16360       ostiInitiatorIOCompleted( tiRoot,
16361                                 tiIORequest,
16362                                 tiIOSuccess,
16363                                 SCSI_STAT_CHECK_CONDITION,
16364                                 satIOContext->pTiSenseData,
16365                                 satIOContext->interruptContext );
16366 
16367       TI_DBG1(("satWriteBuffer: wrong buffer offset %d or parameter length parmLen %d\n", bufferOffset, parmLen));
16368       return tiSuccess;
16369     }
16370 
16371     /* all other cases unsupported */
16372     TI_DBG1(("satWriteBuffer: unsupported case 1\n"));
16373     satSetSensePayload( pSense,
16374                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16375                           0,
16376                           SCSI_SNSCODE_INVALID_COMMAND,
16377                           satIOContext);
16378 
16379     ostiInitiatorIOCompleted( tiRoot,
16380                                 tiIORequest,
16381                                 tiIOSuccess,
16382                                 SCSI_STAT_CHECK_CONDITION,
16383                                 satIOContext->pTiSenseData,
16384                                 satIOContext->interruptContext );
16385 
16386     return tiSuccess;
16387 
16388   }
16389   else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */
16390   {
16391     TI_DBG1(("satWriteBuffer: not yet supported mode %d\n", mode));
16392     satSetSensePayload( pSense,
16393                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16394                           0,
16395                           SCSI_SNSCODE_INVALID_COMMAND,
16396                           satIOContext);
16397 
16398     ostiInitiatorIOCompleted( tiRoot,
16399                                 tiIORequest,
16400                                 tiIOSuccess,
16401                                 SCSI_STAT_CHECK_CONDITION,
16402                                 satIOContext->pTiSenseData,
16403                                 satIOContext->interruptContext );
16404 
16405     return tiSuccess;
16406   }
16407   else
16408   {
16409     /* We don't support any other mode */
16410     TI_DBG1(("satWriteBuffer: unsupported mode %d\n", mode));
16411     satSetSensePayload( pSense,
16412                           SCSI_SNSKEY_ILLEGAL_REQUEST,
16413                           0,
16414                           SCSI_SNSCODE_INVALID_COMMAND,
16415                           satIOContext);
16416 
16417     ostiInitiatorIOCompleted( tiRoot,
16418                                 tiIORequest,
16419                                 tiIOSuccess,
16420                                 SCSI_STAT_CHECK_CONDITION,
16421                                 satIOContext->pTiSenseData,
16422                                 satIOContext->interruptContext );
16423 
16424     return tiSuccess;
16425   }
16426 
16427 }
16428 
16429 /*****************************************************************************/
16430 /*! \brief SAT implementation for SCSI satReassignBlocks.
16431  *
16432  *  SAT implementation for SCSI Reassign Blocks.
16433  *
16434  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16435  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16436  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16437  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16438  *  \param   satIOContext_t:   Pointer to the SAT IO Context
16439  *
16440  *  \return If command is started successfully
16441  *    - \e tiSuccess:     I/O request successfully initiated.
16442  *    - \e tiBusy:        No resources available, try again later.
16443  *    - \e tiIONoDevice:  Invalid device handle.
16444  *    - \e tiError:       Other errors.
16445  */
16446 /*****************************************************************************/
16447 GLOBAL bit32  satReassignBlocks(
16448                    tiRoot_t                  *tiRoot,
16449                    tiIORequest_t             *tiIORequest,
16450                    tiDeviceHandle_t          *tiDeviceHandle,
16451                    tiScsiInitiatorRequest_t *tiScsiRequest,
16452                    satIOContext_t            *satIOContext)
16453 {
16454   /*
16455     assumes all LBA fits in ATA command; no boundary condition is checked here yet
16456   */
16457   bit32                     status;
16458   bit32                     agRequestType;
16459   satDeviceData_t           *pSatDevData;
16460   scsiRspSense_t            *pSense;
16461   tiIniScsiCmnd_t           *scsiCmnd;
16462   agsaFisRegHostToDevice_t  *fis;
16463   bit8                      *pParmList;    /* Log Page data buffer */
16464   bit8                      LongLBA;
16465   bit8                      LongList;
16466   bit32                     defectListLen;
16467   bit8                      LBA[8];
16468   bit32                     startingIndex;
16469 
16470   pSense        = satIOContext->pSense;
16471   pSatDevData   = satIOContext->pSatDevData;
16472   scsiCmnd      = &tiScsiRequest->scsiCmnd;
16473   fis           = satIOContext->pFis;
16474   pParmList     = (bit8 *) tiScsiRequest->sglVirtualAddr;
16475 
16476   TI_DBG5(("satReassignBlocks: start\n"));
16477 
16478   /* checking CONTROL */
16479   /* NACA == 1 or LINK == 1*/
16480   if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
16481   {
16482     satSetSensePayload( pSense,
16483                         SCSI_SNSKEY_ILLEGAL_REQUEST,
16484                         0,
16485                         SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16486                         satIOContext);
16487 
16488     ostiInitiatorIOCompleted( tiRoot,
16489                               tiIORequest,
16490                               tiIOSuccess,
16491                               SCSI_STAT_CHECK_CONDITION,
16492                               satIOContext->pTiSenseData,
16493                               satIOContext->interruptContext );
16494 
16495     TI_DBG1(("satReassignBlocks: return control\n"));
16496     return tiSuccess;
16497   }
16498 
16499   osti_memset(satIOContext->LBA, 0, 8);
16500   satIOContext->ParmIndex = 0;
16501   satIOContext->ParmLen = 0;
16502 
16503   LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK);
16504   LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16505   osti_memset(LBA, 0, sizeof(LBA));
16506 
16507   if (LongList == 0)
16508   {
16509     defectListLen = (pParmList[2] << 8) + pParmList[3];
16510   }
16511   else
16512   {
16513     defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2))
16514                   + (pParmList[2] << 8) + pParmList[3];
16515   }
16516   /* SBC 5.16.2, p61*/
16517   satIOContext->ParmLen = defectListLen + 4 /* header size */;
16518 
16519   startingIndex = 4;
16520 
16521   if (LongLBA == 0)
16522   {
16523     LBA[4] = pParmList[startingIndex];   /* MSB */
16524     LBA[5] = pParmList[startingIndex+1];
16525     LBA[6] = pParmList[startingIndex+2];
16526     LBA[7] = pParmList[startingIndex+3];  /* LSB */
16527     startingIndex = startingIndex + 4;
16528   }
16529   else
16530   {
16531     LBA[0] = pParmList[startingIndex];    /* MSB */
16532     LBA[1] = pParmList[startingIndex+1];
16533     LBA[2] = pParmList[startingIndex+2];
16534     LBA[3] = pParmList[startingIndex+3];
16535     LBA[4] = pParmList[startingIndex+4];
16536     LBA[5] = pParmList[startingIndex+5];
16537     LBA[6] = pParmList[startingIndex+6];
16538     LBA[7] = pParmList[startingIndex+7];  /* LSB */
16539     startingIndex = startingIndex + 8;
16540   }
16541 
16542   tdhexdump("satReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen);
16543 
16544   if (pSatDevData->sat48BitSupport == agTRUE)
16545   {
16546     /* sends READ VERIFY SECTOR(S) EXT*/
16547     fis->h.fisType        = 0x27;                   /* Reg host to device */
16548     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16549     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16550     fis->h.features       = 0;                      /* FIS reserve */
16551     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16552     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16553     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16554     fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16555     fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16556     fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16557     fis->d.featuresExp    = 0;                      /* FIS reserve */
16558     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16559     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16560     fis->d.reserved4      = 0;
16561     fis->d.device         = 0x40;                   /* 01000000 */
16562     fis->d.control        = 0;                      /* FIS HOB bit clear */
16563     fis->d.reserved5      = 0;
16564   }
16565   else
16566   {
16567     /* READ VERIFY SECTOR(S)*/
16568     fis->h.fisType        = 0x27;                   /* Reg host to device */
16569     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16570     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16571     fis->h.features       = 0;                      /* FIS features NA       */
16572     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16573     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16574     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16575     fis->d.lbaLowExp      = 0;
16576     fis->d.lbaMidExp      = 0;
16577     fis->d.lbaHighExp     = 0;
16578     fis->d.featuresExp    = 0;
16579     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16580     fis->d.sectorCountExp = 0;
16581     fis->d.reserved4      = 0;
16582     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16583                             /* DEV and LBA 27:24 */
16584     fis->d.control        = 0;                      /* FIS HOB bit clear */
16585     fis->d.reserved5      = 0;
16586   }
16587 
16588   osti_memcpy(satIOContext->LBA, LBA, 8);
16589   satIOContext->ParmIndex = startingIndex;
16590 
16591   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16592 
16593   /* Initialize CB for SATA completion.
16594    */
16595   satIOContext->satCompleteCB = &satReassignBlocksCB;
16596 
16597   /*
16598    * Prepare SGL and send FIS to LL layer.
16599    */
16600   satIOContext->reqType = agRequestType;       /* Save it */
16601 
16602   status = sataLLIOStart( tiRoot,
16603                           tiIORequest,
16604                           tiDeviceHandle,
16605                           tiScsiRequest,
16606                           satIOContext);
16607 
16608   return status;
16609 }
16610 
16611 /*****************************************************************************/
16612 /*! \brief SAT implementation for SCSI satReassignBlocks_1.
16613  *
16614  *  SAT implementation for SCSI Reassign Blocks. This is helper function for
16615  *  satReassignBlocks and satReassignBlocksCB. This sends ATA verify command.
16616  *
16617  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16618  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16619  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16620  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16621  *  \param   satIOContext_t:   Pointer to the SAT IO Context
16622  *
16623  *  \return If command is started successfully
16624  *    - \e tiSuccess:     I/O request successfully initiated.
16625  *    - \e tiBusy:        No resources available, try again later.
16626  *    - \e tiIONoDevice:  Invalid device handle.
16627  *    - \e tiError:       Other errors.
16628  */
16629 /*****************************************************************************/
16630 /* next LBA; sends READ VERIFY SECTOR; update LBA and ParmIdx */
16631 GLOBAL bit32  satReassignBlocks_1(
16632                    tiRoot_t                  *tiRoot,
16633                    tiIORequest_t             *tiIORequest,
16634                    tiDeviceHandle_t          *tiDeviceHandle,
16635                    tiScsiInitiatorRequest_t *tiScsiRequest,
16636                    satIOContext_t            *satIOContext,
16637                    satIOContext_t            *satOrgIOContext
16638                    )
16639 {
16640   /*
16641     assumes all LBA fits in ATA command; no boundary condition is checked here yet
16642     tiScsiRequest is OS generated; needs for accessing parameter list
16643   */
16644   bit32                     agRequestType;
16645   satDeviceData_t           *pSatDevData;
16646   tiIniScsiCmnd_t           *scsiCmnd;
16647   agsaFisRegHostToDevice_t  *fis;
16648   bit8                      *pParmList;    /* Log Page data buffer */
16649   bit8                      LongLBA;
16650   bit8                      LBA[8];
16651   bit32                     startingIndex;
16652 
16653   pSatDevData   = satIOContext->pSatDevData;
16654   scsiCmnd      = &tiScsiRequest->scsiCmnd;
16655   fis           = satIOContext->pFis;
16656   pParmList     = (bit8 *) tiScsiRequest->sglVirtualAddr;
16657 
16658   TI_DBG5(("satReassignBlocks_1: start\n"));
16659 
16660   LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16661   osti_memset(LBA, 0, sizeof(LBA));
16662 
16663   startingIndex = satOrgIOContext->ParmIndex;
16664 
16665   if (LongLBA == 0)
16666   {
16667     LBA[4] = pParmList[startingIndex];
16668     LBA[5] = pParmList[startingIndex+1];
16669     LBA[6] = pParmList[startingIndex+2];
16670     LBA[7] = pParmList[startingIndex+3];
16671     startingIndex = startingIndex + 4;
16672   }
16673   else
16674   {
16675     LBA[0] = pParmList[startingIndex];
16676     LBA[1] = pParmList[startingIndex+1];
16677     LBA[2] = pParmList[startingIndex+2];
16678     LBA[3] = pParmList[startingIndex+3];
16679     LBA[4] = pParmList[startingIndex+4];
16680     LBA[5] = pParmList[startingIndex+5];
16681     LBA[6] = pParmList[startingIndex+6];
16682     LBA[7] = pParmList[startingIndex+7];
16683     startingIndex = startingIndex + 8;
16684   }
16685 
16686   if (pSatDevData->sat48BitSupport == agTRUE)
16687   {
16688     /* sends READ VERIFY SECTOR(S) EXT*/
16689     fis->h.fisType        = 0x27;                   /* Reg host to device */
16690     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16691     fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16692     fis->h.features       = 0;                      /* FIS reserve */
16693     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16694     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16695     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16696     fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16697     fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16698     fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16699     fis->d.featuresExp    = 0;                      /* FIS reserve */
16700     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16701     fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16702     fis->d.reserved4      = 0;
16703     fis->d.device         = 0x40;                   /* 01000000 */
16704     fis->d.control        = 0;                      /* FIS HOB bit clear */
16705     fis->d.reserved5      = 0;
16706   }
16707   else
16708   {
16709     /* READ VERIFY SECTOR(S)*/
16710     fis->h.fisType        = 0x27;                   /* Reg host to device */
16711     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16712     fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16713     fis->h.features       = 0;                      /* FIS features NA       */
16714     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16715     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16716     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16717     fis->d.lbaLowExp      = 0;
16718     fis->d.lbaMidExp      = 0;
16719     fis->d.lbaHighExp     = 0;
16720     fis->d.featuresExp    = 0;
16721     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16722     fis->d.sectorCountExp = 0;
16723     fis->d.reserved4      = 0;
16724     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16725                             /* DEV and LBA 27:24 */
16726     fis->d.control        = 0;                      /* FIS HOB bit clear */
16727     fis->d.reserved5      = 0;
16728   }
16729   osti_memcpy(satOrgIOContext->LBA, LBA, 8);
16730   satOrgIOContext->ParmIndex = startingIndex;
16731   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16732   /* Initialize CB for SATA completion.
16733    */
16734   satIOContext->satCompleteCB = &satReassignBlocksCB;
16735   /*
16736    * Prepare SGL and send FIS to LL layer.
16737    */
16738   satIOContext->reqType = agRequestType;       /* Save it */
16739 
16740   sataLLIOStart( tiRoot,
16741                  tiIORequest,
16742                  tiDeviceHandle,
16743                  tiScsiRequest,
16744                  satIOContext );
16745   return tiSuccess;
16746 }
16747 
16748 /*****************************************************************************/
16749 /*! \brief SAT implementation for SCSI satReassignBlocks_2.
16750  *
16751  *  SAT implementation for SCSI Reassign Blocks. This is helper function for
16752  *  satReassignBlocks and satReassignBlocksCB. This sends ATA write command.
16753  *
16754  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16755  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16756  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16757  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16758  *  \param   satIOContext_t:   Pointer to the SAT IO Context
16759  *  \param   LBA:              Pointer to the LBA to be processed
16760  *
16761  *  \return If command is started successfully
16762  *    - \e tiSuccess:     I/O request successfully initiated.
16763  *    - \e tiBusy:        No resources available, try again later.
16764  *    - \e tiIONoDevice:  Invalid device handle.
16765  *    - \e tiError:       Other errors.
16766  */
16767 /*****************************************************************************/
16768 /* current LBA; sends WRITE */
16769 GLOBAL bit32  satReassignBlocks_2(
16770                    tiRoot_t                  *tiRoot,
16771                    tiIORequest_t             *tiIORequest,
16772                    tiDeviceHandle_t          *tiDeviceHandle,
16773                    tiScsiInitiatorRequest_t *tiScsiRequest,
16774                    satIOContext_t            *satIOContext,
16775                    bit8                      *LBA
16776                    )
16777 {
16778   /*
16779     assumes all LBA fits in ATA command; no boundary condition is checked here yet
16780     tiScsiRequest is TD generated for writing
16781   */
16782   bit32                     status;
16783   bit32                     agRequestType;
16784   satDeviceData_t           *pSatDevData;
16785   scsiRspSense_t            *pSense;
16786   agsaFisRegHostToDevice_t  *fis;
16787 
16788   pSense        = satIOContext->pSense;
16789   pSatDevData   = satIOContext->pSatDevData;
16790   fis           = satIOContext->pFis;
16791 
16792   if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16793   {
16794     /* case 2 */
16795     /* WRITE DMA*/
16796     /* can't fit the transfer length */
16797     TI_DBG5(("satReassignBlocks_2: case 2\n"));
16798     fis->h.fisType        = 0x27;                   /* Reg host to device */
16799     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16800     fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
16801     fis->h.features       = 0;                      /* FIS reserve */
16802     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16803     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16804     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16805 
16806     /* FIS LBA mode set LBA (27:24) */
16807     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16808 
16809     fis->d.lbaLowExp      = 0;
16810     fis->d.lbaMidExp      = 0;
16811     fis->d.lbaHighExp     = 0;
16812     fis->d.featuresExp    = 0;
16813     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16814     fis->d.sectorCountExp = 0;
16815     fis->d.reserved4      = 0;
16816     fis->d.control        = 0;                      /* FIS HOB bit clear */
16817     fis->d.reserved5      = 0;
16818 
16819     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16820     satIOContext->ATACmd = SAT_WRITE_DMA;
16821   }
16822   else
16823   {
16824     /* case 1 */
16825     /* WRITE MULTIPLE or WRITE SECTOR(S) */
16826     /* WRITE SECTORS for easier implemetation */
16827     /* can't fit the transfer length */
16828     TI_DBG5(("satReassignBlocks_2: case 1\n"));
16829     fis->h.fisType        = 0x27;                   /* Reg host to device */
16830     fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16831     fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
16832     fis->h.features       = 0;                      /* FIS reserve */
16833     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16834     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16835     fis->d.lbaHigh        = LBA[7];                 /* FIS LBA (23:16) */
16836 
16837     /* FIS LBA mode set LBA (27:24) */
16838     fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16839 
16840     fis->d.lbaLowExp      = 0;
16841     fis->d.lbaMidExp      = 0;
16842     fis->d.lbaHighExp     = 0;
16843     fis->d.featuresExp    = 0;
16844     fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16845     fis->d.sectorCountExp = 0;
16846     fis->d.reserved4      = 0;
16847     fis->d.control        = 0;                      /* FIS HOB bit clear */
16848     fis->d.reserved5      = 0;
16849 
16850     agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16851     satIOContext->ATACmd = SAT_WRITE_SECTORS;
16852   }
16853 
16854   /* case 3 and 4 */
16855   if (pSatDevData->sat48BitSupport == agTRUE)
16856   {
16857     if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16858     {
16859       /* case 3 */
16860       /* WRITE DMA EXT or WRITE DMA FUA EXT */
16861       TI_DBG5(("satReassignBlocks_2: case 3\n"));
16862       fis->h.fisType        = 0x27;                   /* Reg host to device */
16863       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16864 
16865       /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
16866       fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
16867       satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
16868 
16869       fis->h.features       = 0;                      /* FIS reserve */
16870       fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16871       fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16872       fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16873       fis->d.device         = 0x40;                   /* FIS LBA mode set */
16874       fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16875       fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16876       fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16877       fis->d.featuresExp    = 0;                      /* FIS reserve */
16878       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16879       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16880       fis->d.reserved4      = 0;
16881       fis->d.control        = 0;                      /* FIS HOB bit clear */
16882       fis->d.reserved5      = 0;
16883 
16884       agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16885     }
16886     else
16887     {
16888       /* case 4 */
16889       /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
16890       /* WRITE SECTORS EXT for easier implemetation */
16891       TI_DBG5(("satReassignBlocks_2: case 4\n"));
16892       fis->h.fisType        = 0x27;                   /* Reg host to device */
16893       fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16894       fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
16895 
16896       fis->h.features       = 0;                      /* FIS reserve */
16897       fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16898       fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16899       fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16900       fis->d.device         = 0x40;                   /* FIS LBA mode set */
16901       fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16902       fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16903       fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16904       fis->d.featuresExp    = 0;                      /* FIS reserve */
16905       fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16906       fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16907       fis->d.reserved4      = 0;
16908       fis->d.control        = 0;                      /* FIS HOB bit clear */
16909       fis->d.reserved5      = 0;
16910 
16911       agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16912       satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
16913     }
16914   }
16915   /* case 5 */
16916   if (pSatDevData->satNCQ == agTRUE)
16917   {
16918     /* WRITE FPDMA QUEUED */
16919     if (pSatDevData->sat48BitSupport != agTRUE)
16920     {
16921       TI_DBG5(("satReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
16922       satSetSensePayload( pSense,
16923                           SCSI_SNSKEY_HARDWARE_ERROR,
16924                           0,
16925                           SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
16926                           satIOContext);
16927 
16928       ostiInitiatorIOCompleted( tiRoot,
16929                                 tiIORequest,
16930                                 tiIOSuccess,
16931                                 SCSI_STAT_CHECK_CONDITION,
16932                                 satIOContext->pTiSenseData,
16933                                 satIOContext->interruptContext );
16934       return tiSuccess;
16935     }
16936     TI_DBG6(("satWrite10: case 5\n"));
16937 
16938     /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
16939 
16940     fis->h.fisType        = 0x27;                   /* Reg host to device */
16941     fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16942     fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
16943     fis->h.features       = 1;                      /* FIS sector count (7:0) */
16944     fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16945     fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16946     fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16947 
16948     /* Check FUA bit */
16949     fis->d.device       = 0x40;                     /* FIS FUA clear */
16950 
16951     fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16952     fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16953     fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16954     fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
16955     fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
16956     fis->d.sectorCountExp = 0;
16957     fis->d.reserved4      = 0;
16958     fis->d.control        = 0;                      /* FIS HOB bit clear */
16959     fis->d.reserved5      = 0;
16960 
16961     agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
16962     satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
16963   }
16964 
16965   satIOContext->satCompleteCB = &satReassignBlocksCB;
16966 
16967   /*
16968    * Prepare SGL and send FIS to LL layer.
16969    */
16970   satIOContext->reqType = agRequestType;       /* Save it */
16971 
16972   status = sataLLIOStart( tiRoot,
16973                           tiIORequest,
16974                           tiDeviceHandle,
16975                           /* not the original, should be the TD generated one */
16976                           tiScsiRequest,
16977                           satIOContext);
16978   return (status);
16979 }
16980 
16981 
16982 /*****************************************************************************/
16983 /*! \brief SAT implementation for SCSI satPrepareNewIO.
16984  *
16985  *  This function fills in the fields of internal IO generated by TD layer.
16986  *  This is mostly used in the callback functions.
16987  *
16988  *  \param   satNewIntIo:      Pointer to the internal IO structure.
16989  *  \param   tiOrgIORequest:   Pointer to the original tiIOrequest sent by OS layer
16990  *  \param   satDevData:       Pointer to the device data.
16991  *  \param   scsiCmnd:         Pointer to SCSI command.
16992  *  \param   satOrgIOContext:  Pointer to the original SAT IO Context
16993  *
16994  *  \return
16995  *    - \e Pointer to the new SAT IO Context
16996  */
16997 /*****************************************************************************/
16998 GLOBAL satIOContext_t *satPrepareNewIO(
16999                             satInternalIo_t         *satNewIntIo,
17000                             tiIORequest_t           *tiOrgIORequest,
17001                             satDeviceData_t         *satDevData,
17002                             tiIniScsiCmnd_t         *scsiCmnd,
17003                             satIOContext_t          *satOrgIOContext
17004                             )
17005 {
17006   satIOContext_t          *satNewIOContext;
17007   tdIORequestBody_t       *tdNewIORequestBody;
17008 
17009   TI_DBG2(("satPrepareNewIO: start\n"));
17010 
17011   /* the one to be used; good 8/2/07 */
17012   satNewIntIo->satOrgTiIORequest = tiOrgIORequest; /* this is already done in
17013                                                         satAllocIntIoResource() */
17014 
17015   tdNewIORequestBody = (tdIORequestBody_t *)satNewIntIo->satIntRequestBody;
17016   satNewIOContext = &(tdNewIORequestBody->transport.SATA.satIOContext);
17017 
17018   satNewIOContext->pSatDevData   = satDevData;
17019   satNewIOContext->pFis          = &(tdNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
17020   satNewIOContext->pScsiCmnd     = &(satNewIntIo->satIntTiScsiXchg.scsiCmnd);
17021   if (scsiCmnd != agNULL)
17022   {
17023     /* saves only CBD; not scsi command for LBA and number of blocks */
17024     osti_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
17025   }
17026   satNewIOContext->pSense        = &(tdNewIORequestBody->transport.SATA.sensePayload);
17027   satNewIOContext->pTiSenseData  = &(tdNewIORequestBody->transport.SATA.tiSenseData);
17028   satNewIOContext->pTiSenseData->senseData = satNewIOContext->pSense;
17029   satNewIOContext->tiRequestBody = satNewIntIo->satIntRequestBody;
17030   satNewIOContext->interruptContext = satNewIOContext->interruptContext;
17031   satNewIOContext->satIntIoContext  = satNewIntIo;
17032   satNewIOContext->ptiDeviceHandle = satOrgIOContext->ptiDeviceHandle;
17033   satNewIOContext->satOrgIOContext = satOrgIOContext;
17034   /* saves tiScsiXchg; only for writesame10() */
17035   satNewIOContext->tiScsiXchg = satOrgIOContext->tiScsiXchg;
17036 
17037   return satNewIOContext;
17038 }
17039 /*****************************************************************************
17040  *! \brief  satIOAbort
17041  *
17042  *   This routine is called to initiate a I/O abort to SATL.
17043  *   This routine is independent of HW/LL API.
17044  *
17045  *  \param  tiRoot:     Pointer to TISA initiator driver/port instance.
17046  *  \param  taskTag:    Pointer to TISA I/O request context/tag to be aborted.
17047  *
17048  *  \return:
17049  *
17050  *  \e tiSuccess:     I/O request successfully initiated.
17051  *  \e tiBusy:        No resources available, try again later.
17052  *  \e tiError:       Other errors that prevent the I/O request to be started.
17053  *
17054  *
17055  *****************************************************************************/
17056 GLOBAL bit32 satIOAbort(
17057                           tiRoot_t      *tiRoot,
17058                           tiIORequest_t *taskTag )
17059 {
17060 
17061   tdsaRoot_t          *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
17062   tdsaContext_t       *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
17063   agsaRoot_t          *agRoot;
17064   tdIORequestBody_t   *tdIORequestBody;
17065   tdIORequestBody_t   *tdIONewRequestBody;
17066   agsaIORequest_t     *agIORequest;
17067   bit32               status;
17068   agsaIORequest_t     *agAbortIORequest;
17069   tdIORequestBody_t   *tdAbortIORequestBody;
17070   bit32               PhysUpper32;
17071   bit32               PhysLower32;
17072   bit32               memAllocStatus;
17073   void                *osMemHandle;
17074   satIOContext_t      *satIOContext;
17075   satInternalIo_t     *satIntIo;
17076 
17077   TI_DBG2(("satIOAbort: start\n"));
17078 
17079   agRoot          = &(tdsaAllShared->agRootNonInt);
17080   tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData;
17081 
17082   /* needs to distinguish internally generated or externally generated */
17083   satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17084   satIntIo     = satIOContext->satIntIoContext;
17085   if (satIntIo == agNULL)
17086   {
17087     TI_DBG1(("satIOAbort: External, OS generated\n"));
17088     agIORequest     = &(tdIORequestBody->agIORequest);
17089   }
17090   else
17091   {
17092     TI_DBG1(("satIOAbort: Internal, TD generated\n"));
17093     tdIONewRequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
17094     agIORequest     = &(tdIONewRequestBody->agIORequest);
17095   }
17096 
17097   /* allocating agIORequest for abort itself */
17098   memAllocStatus = ostiAllocMemory(
17099                                    tiRoot,
17100                                    &osMemHandle,
17101                                    (void **)&tdAbortIORequestBody,
17102                                    &PhysUpper32,
17103                                    &PhysLower32,
17104                                    8,
17105                                    sizeof(tdIORequestBody_t),
17106                                    agTRUE
17107                                    );
17108   if (memAllocStatus != tiSuccess)
17109   {
17110     /* let os process IO */
17111     TI_DBG1(("satIOAbort: ostiAllocMemory failed...\n"));
17112     return tiError;
17113   }
17114 
17115   if (tdAbortIORequestBody == agNULL)
17116   {
17117     /* let os process IO */
17118     TI_DBG1(("satIOAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17119     return tiError;
17120   }
17121 
17122   /* setup task management structure */
17123   tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17124   tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
17125 
17126   /* initialize agIORequest */
17127   agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17128   agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17129   agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17130 
17131   /* remember IO to be aborted */
17132   tdAbortIORequestBody->tiIOToBeAbortedRequest = taskTag;
17133 
17134   status = saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, agNULL );
17135 
17136   TI_DBG5(("satIOAbort: return status=0x%x\n", status));
17137 
17138   if (status == AGSA_RC_SUCCESS)
17139     return tiSuccess;
17140   else
17141     return tiError;
17142 
17143 }
17144 
17145 
17146 /*****************************************************************************
17147  *! \brief  satTM
17148  *
17149  *   This routine is called to initiate a TM request to SATL.
17150  *   This routine is independent of HW/LL API.
17151  *
17152  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17153  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17154  *  \param  task:             SAM-3 task management request.
17155  *  \param  lun:              Pointer to LUN.
17156  *  \param  taskTag:          Pointer to the associated task where the TM
17157  *                            command is to be applied.
17158  *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17159  *
17160  *  \return:
17161  *
17162  *  \e tiSuccess:     I/O request successfully initiated.
17163  *  \e tiBusy:        No resources available, try again later.
17164  *  \e tiIONoDevice:  Invalid device handle.
17165  *  \e tiError:       Other errors that prevent the I/O request to be started.
17166  *
17167  *
17168  *****************************************************************************/
17169  /* save task in satIOContext */
17170 osGLOBAL bit32 satTM(
17171                         tiRoot_t          *tiRoot,
17172                         tiDeviceHandle_t  *tiDeviceHandle,
17173                         bit32             task,
17174                         tiLUN_t           *lun,
17175                         tiIORequest_t     *taskTag,
17176                         tiIORequest_t     *currentTaskTag,
17177                         tdIORequestBody_t *tiRequestBody,
17178                         bit32              NotifyOS
17179                         )
17180 {
17181   tdIORequestBody_t           *tdIORequestBody = agNULL;
17182   satIOContext_t              *satIOContext = agNULL;
17183   tdsaDeviceData_t            *oneDeviceData = agNULL;
17184   bit32                       status;
17185 
17186   TI_DBG3(("satTM: tiDeviceHandle=%p task=0x%x\n", tiDeviceHandle, task ));
17187 
17188   /* set satIOContext fields and etc */
17189   oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17190 
17191 
17192   tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
17193   satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17194 
17195   satIOContext->pSatDevData   = &oneDeviceData->satDevData;
17196   satIOContext->pFis          =
17197     &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
17198 
17199 
17200   satIOContext->tiRequestBody = tiRequestBody;
17201   satIOContext->ptiDeviceHandle = tiDeviceHandle;
17202   satIOContext->satIntIoContext  = agNULL;
17203   satIOContext->satOrgIOContext  = agNULL;
17204 
17205   /* followings are used only for internal IO */
17206   satIOContext->currentLBA = 0;
17207   satIOContext->OrgTL = 0;
17208 
17209   /* saving task in satIOContext */
17210   satIOContext->TMF = task;
17211 
17212   satIOContext->satToBeAbortedIOContext = agNULL;
17213 
17214   if (NotifyOS == agTRUE)
17215   {
17216     satIOContext->NotifyOS = agTRUE;
17217   }
17218   else
17219   {
17220     satIOContext->NotifyOS = agFALSE;
17221   }
17222   /*
17223    * Our SAT supports RESET LUN and partially support ABORT TASK (only if there
17224    * is no more than one I/O pending on the drive.
17225    */
17226 
17227   if (task == AG_LOGICAL_UNIT_RESET)
17228   {
17229     status = satTmResetLUN( tiRoot,
17230                             currentTaskTag,
17231                             tiDeviceHandle,
17232                             agNULL,
17233                             satIOContext,
17234                             lun);
17235     return status;
17236   }
17237 #ifdef TO_BE_REMOVED
17238   else if (task == AG_TARGET_WARM_RESET)
17239   {
17240     status = satTmWarmReset( tiRoot,
17241                              currentTaskTag,
17242                              tiDeviceHandle,
17243                              agNULL,
17244                              satIOContext);
17245 
17246     return status;
17247   }
17248 #endif
17249   else if (task == AG_ABORT_TASK)
17250   {
17251     status = satTmAbortTask( tiRoot,
17252                              currentTaskTag,
17253                              tiDeviceHandle,
17254                              agNULL,
17255                              satIOContext,
17256                              taskTag);
17257 
17258     return status;
17259   }
17260   else if (task == TD_INTERNAL_TM_RESET)
17261   {
17262     status = satTDInternalTmReset( tiRoot,
17263                                    currentTaskTag,
17264                                    tiDeviceHandle,
17265                                    agNULL,
17266                                    satIOContext);
17267    return status;
17268   }
17269   else
17270   {
17271     TI_DBG1(("satTM: tiDeviceHandle=%p UNSUPPORTED TM task=0x%x\n",
17272         tiDeviceHandle, task ));
17273 
17274     /* clean up TD layer's IORequestBody */
17275     ostiFreeMemory(
17276                    tiRoot,
17277                    tiRequestBody->IOType.InitiatorTMIO.osMemHandle,
17278                    sizeof(tdIORequestBody_t)
17279                    );
17280     return tiError;
17281   }
17282 
17283 }
17284 
17285 
17286 /*****************************************************************************
17287  *! \brief  satTmResetLUN
17288  *
17289  *   This routine is called to initiate a TM RESET LUN request to SATL.
17290  *   This routine is independent of HW/LL API.
17291  *
17292  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17293  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17294  *  \param  lun:              Pointer to LUN.
17295  *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17296  *
17297  *  \return:
17298  *
17299  *  \e tiSuccess:     I/O request successfully initiated.
17300  *  \e tiBusy:        No resources available, try again later.
17301  *  \e tiIONoDevice:  Invalid device handle.
17302  *  \e tiError:       Other errors that prevent the I/O request to be started.
17303  *
17304  *
17305  *****************************************************************************/
17306 osGLOBAL bit32 satTmResetLUN(
17307                             tiRoot_t                  *tiRoot,
17308                             tiIORequest_t             *tiIORequest, /* current task tag */
17309                             tiDeviceHandle_t          *tiDeviceHandle,
17310                             tiScsiInitiatorRequest_t *tiScsiRequest,
17311                             satIOContext_t            *satIOContext,
17312                             tiLUN_t                   *lun)
17313 {
17314 
17315   tdsaDeviceData_t        *tdsaDeviceData;
17316   satDeviceData_t         *satDevData;
17317 
17318   tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17319   satDevData      = &tdsaDeviceData->satDevData;
17320 
17321   TI_DBG1(("satTmResetLUN: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17322 
17323   /*
17324    * Only support LUN 0
17325    */
17326   if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
17327         lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
17328   {
17329     TI_DBG1(("satTmResetLUN: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n",
17330                 tiDeviceHandle));
17331     return tiError;
17332   }
17333 
17334   /*
17335    * Check if there is other TM request pending
17336    */
17337   if (satDevData->satTmTaskTag != agNULL)
17338   {
17339     TI_DBG1(("satTmResetLUN: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17340                 tiDeviceHandle));
17341     return tiError;
17342   }
17343 
17344   /*
17345    * Save tiIORequest, will be returned at device reset completion to return
17346    * the TM completion.
17347    */
17348    satDevData->satTmTaskTag = tiIORequest;
17349 
17350   /*
17351    * Set flag to indicate device in recovery mode.
17352    */
17353   satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17354 
17355   /*
17356    * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17357    * at the completion of SATA device reset.
17358    */
17359   satDevData->satAbortAfterReset = agFALSE;
17360 
17361   /* SAT rev8 6.3.6 p22 */
17362   satStartResetDevice(
17363                       tiRoot,
17364                       tiIORequest, /* currentTaskTag */
17365                       tiDeviceHandle,
17366                       tiScsiRequest,
17367                       satIOContext
17368                       );
17369 
17370 
17371   return tiSuccess;
17372 
17373 }
17374 
17375 /*****************************************************************************
17376  *! \brief  satTmWarmReset
17377  *
17378  *   This routine is called to initiate a TM warm RESET request to SATL.
17379  *   This routine is independent of HW/LL API.
17380  *
17381  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17382  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17383  *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17384  *
17385  *  \return:
17386  *
17387  *  \e tiSuccess:     I/O request successfully initiated.
17388  *  \e tiBusy:        No resources available, try again later.
17389  *  \e tiIONoDevice:  Invalid device handle.
17390  *  \e tiError:       Other errors that prevent the I/O request to be started.
17391  *
17392  *
17393  *****************************************************************************/
17394 osGLOBAL bit32 satTmWarmReset(
17395                             tiRoot_t                  *tiRoot,
17396                             tiIORequest_t             *tiIORequest, /* current task tag */
17397                             tiDeviceHandle_t          *tiDeviceHandle,
17398                             tiScsiInitiatorRequest_t *tiScsiRequest,
17399                             satIOContext_t            *satIOContext)
17400 {
17401 
17402   tdsaDeviceData_t        *tdsaDeviceData;
17403   satDeviceData_t         *satDevData;
17404 
17405   tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17406   satDevData      = &tdsaDeviceData->satDevData;
17407 
17408   TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17409 
17410   /*
17411    * Check if there is other TM request pending
17412    */
17413   if (satDevData->satTmTaskTag != agNULL)
17414   {
17415     TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17416                 tiDeviceHandle));
17417     return tiError;
17418   }
17419 
17420   /*
17421    * Save tiIORequest, will be returned at device reset completion to return
17422    * the TM completion.
17423    */
17424    satDevData->satTmTaskTag = tiIORequest;
17425 
17426   /*
17427    * Set flag to indicate device in recovery mode.
17428    */
17429   satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17430 
17431   /*
17432    * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17433    * at the completion of SATA device reset.
17434    */
17435   satDevData->satAbortAfterReset = agFALSE;
17436 
17437   /* SAT rev8 6.3.6 p22 */
17438   satStartResetDevice(
17439                       tiRoot,
17440                       tiIORequest, /* currentTaskTag */
17441                       tiDeviceHandle,
17442                       tiScsiRequest,
17443                       satIOContext
17444                       );
17445 
17446   return tiSuccess;
17447 
17448 }
17449 
17450 osGLOBAL bit32 satTDInternalTmReset(
17451                             tiRoot_t                  *tiRoot,
17452                             tiIORequest_t             *tiIORequest, /* current task tag */
17453                             tiDeviceHandle_t          *tiDeviceHandle,
17454                             tiScsiInitiatorRequest_t *tiScsiRequest,
17455                             satIOContext_t            *satIOContext)
17456 {
17457 
17458   tdsaDeviceData_t        *tdsaDeviceData;
17459   satDeviceData_t         *satDevData;
17460 
17461   tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17462   satDevData      = &tdsaDeviceData->satDevData;
17463 
17464   TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17465 
17466   /*
17467    * Check if there is other TM request pending
17468    */
17469   if (satDevData->satTmTaskTag != agNULL)
17470   {
17471     TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17472                 tiDeviceHandle));
17473     return tiError;
17474   }
17475 
17476   /*
17477    * Save tiIORequest, will be returned at device reset completion to return
17478    * the TM completion.
17479    */
17480    satDevData->satTmTaskTag = tiIORequest;
17481 
17482   /*
17483    * Set flag to indicate device in recovery mode.
17484    */
17485   satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17486 
17487   /*
17488    * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17489    * at the completion of SATA device reset.
17490    */
17491   satDevData->satAbortAfterReset = agFALSE;
17492 
17493   /* SAT rev8 6.3.6 p22 */
17494   satStartResetDevice(
17495                       tiRoot,
17496                       tiIORequest, /* currentTaskTag */
17497                       tiDeviceHandle,
17498                       tiScsiRequest,
17499                       satIOContext
17500                       );
17501 
17502   return tiSuccess;
17503 
17504 }
17505 
17506 /*****************************************************************************
17507  *! \brief  satTmAbortTask
17508  *
17509  *   This routine is called to initiate a TM ABORT TASK request to SATL.
17510  *   This routine is independent of HW/LL API.
17511  *
17512  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17513  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17514  *  \param  taskTag:          Pointer to the associated task where the TM
17515  *                            command is to be applied.
17516  *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17517  *
17518  *  \return:
17519  *
17520  *  \e tiSuccess:     I/O request successfully initiated.
17521  *  \e tiBusy:        No resources available, try again later.
17522  *  \e tiIONoDevice:  Invalid device handle.
17523  *  \e tiError:       Other errors that prevent the I/O request to be started.
17524  *
17525  *
17526  *****************************************************************************/
17527 osGLOBAL bit32 satTmAbortTask(
17528                             tiRoot_t                  *tiRoot,
17529                             tiIORequest_t             *tiIORequest,  /* current task tag */
17530                             tiDeviceHandle_t          *tiDeviceHandle,
17531                             tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */
17532                             satIOContext_t            *satIOContext,
17533                             tiIORequest_t             *taskTag)
17534 {
17535 
17536   tdsaDeviceData_t        *tdsaDeviceData;
17537   satDeviceData_t         *satDevData;
17538   satIOContext_t          *satTempIOContext = agNULL;
17539   tdIORequestBody_t       *tdIORequestBody;
17540   tdIORequestBody_t       *TMtdIORequestBody;
17541   tdList_t                *elementHdr;
17542   bit32                   found = agFALSE;
17543   tiIORequest_t           *tiIOReq;
17544 
17545   tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17546   satDevData      = &tdsaDeviceData->satDevData;
17547   TMtdIORequestBody = (tdIORequestBody_t *)tiIORequest->tdData;
17548 
17549   TI_DBG1(("satTmAbortTask: tiDeviceHandle=%p taskTag=%p.\n", tiDeviceHandle, taskTag ));
17550   /*
17551    * Check if there is other TM request pending
17552    */
17553   if (satDevData->satTmTaskTag != agNULL)
17554   {
17555     TI_DBG1(("satTmAbortTask: REJECT other TM pending, tiDeviceHandle=%p\n",
17556                 tiDeviceHandle));
17557     /* clean up TD layer's IORequestBody */
17558     ostiFreeMemory(
17559                    tiRoot,
17560                    TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17561                    sizeof(tdIORequestBody_t)
17562                    );
17563     return tiError;
17564   }
17565 
17566 #ifdef REMOVED
17567   /*
17568    * Check if there is only one I/O pending.
17569    */
17570   if (satDevData->satPendingIO > 0)
17571   {
17572     TI_DBG1(("satTmAbortTask: REJECT num pending I/O, tiDeviceHandle=%p, satPendingIO=0x%x\n",
17573                 tiDeviceHandle, satDevData->satPendingIO));
17574     /* clean up TD layer's IORequestBody */
17575     ostiFreeMemory(
17576                    tiRoot,
17577                    TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17578                    sizeof(tdIORequestBody_t)
17579                    );
17580 
17581     return tiError;
17582   }
17583 #endif
17584 
17585   /*
17586    * Check that the only pending I/O matches taskTag. If not return tiError.
17587    */
17588   elementHdr = satDevData->satIoLinkList.flink;
17589 
17590   while (elementHdr != &satDevData->satIoLinkList)
17591   {
17592     satTempIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17593                                            satIoContextLink,
17594                                            elementHdr );
17595 
17596     tdIORequestBody = (tdIORequestBody_t *) satTempIOContext->tiRequestBody;
17597     tiIOReq = tdIORequestBody->tiIORequest;
17598 
17599     elementHdr = elementHdr->flink;   /* for the next while loop  */
17600 
17601     /*
17602      * Check if the tag matches
17603      */
17604     if ( tiIOReq == taskTag)
17605     {
17606       found = agTRUE;
17607       satIOContext->satToBeAbortedIOContext = satTempIOContext;
17608       TI_DBG1(("satTmAbortTask: found matching tag.\n"));
17609 
17610       break;
17611 
17612     } /* if matching tag */
17613 
17614   } /* while loop */
17615 
17616 
17617   if (found == agFALSE )
17618   {
17619     TI_DBG1(("satTmAbortTask: *** REJECT *** no match, tiDeviceHandle=%p\n",
17620                 tiDeviceHandle ));
17621 
17622     /* clean up TD layer's IORequestBody */
17623     ostiFreeMemory(
17624                    tiRoot,
17625                    TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17626                    sizeof(tdIORequestBody_t)
17627                    );
17628 
17629     return tiError;
17630   }
17631 
17632   /*
17633    * Save tiIORequest, will be returned at device reset completion to return
17634    * the TM completion.
17635    */
17636    satDevData->satTmTaskTag = tiIORequest;
17637 
17638   /*
17639    * Set flag to indicate device in recovery mode.
17640    */
17641   satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17642 
17643 
17644   /*
17645    * Issue SATA device reset or check power mode. Set flag to to automatically abort
17646    * at the completion of SATA device reset.
17647    * SAT r09 p25
17648    */
17649   satDevData->satAbortAfterReset = agTRUE;
17650 
17651   if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
17652        (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
17653       )
17654   {
17655     TI_DBG1(("satTmAbortTask: calling satStartCheckPowerMode\n"));
17656     /* send check power mode */
17657     satStartCheckPowerMode(
17658                       tiRoot,
17659                       tiIORequest, /* currentTaskTag */
17660                       tiDeviceHandle,
17661                       tiScsiRequest,
17662                       satIOContext
17663                       );
17664   }
17665   else
17666   {
17667     TI_DBG1(("satTmAbortTask: calling satStartResetDevice\n"));
17668     /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */
17669     satStartResetDevice(
17670                       tiRoot,
17671                       tiIORequest, /* currentTaskTag */
17672                       tiDeviceHandle,
17673                       tiScsiRequest,
17674                       satIOContext
17675                       );
17676   }
17677 
17678 
17679   return tiSuccess;
17680 }
17681 
17682 /*****************************************************************************
17683  *! \brief  osSatResetCB
17684  *
17685  *   This routine is called to notify the completion of SATA device reset
17686  *   which was initiated previously through the call to sataLLReset().
17687  *   This routine is independent of HW/LL API.
17688  *
17689  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17690  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17691  *  \param  resetStatus:      Reset status either tiSuccess or tiError.
17692  *  \param  respFis:          Pointer to the Register Device-To-Host FIS
17693  *                            received from the device.
17694  *
17695  *  \return: None
17696  *
17697  *****************************************************************************/
17698 osGLOBAL void osSatResetCB(
17699                 tiRoot_t          *tiRoot,
17700                 tiDeviceHandle_t  *tiDeviceHandle,
17701                 bit32             resetStatus,
17702                 void              *respFis)
17703 {
17704 
17705   agsaRoot_t              *agRoot;
17706   tdsaDeviceData_t        *tdsaDeviceData;
17707   satDeviceData_t         *satDevData;
17708   satIOContext_t          *satIOContext;
17709   tdIORequestBody_t       *tdIORequestBodyTmp;
17710   tdList_t                *elementHdr;
17711   agsaIORequest_t         *agAbortIORequest;
17712   tdIORequestBody_t       *tdAbortIORequestBody;
17713   bit32                   PhysUpper32;
17714   bit32                   PhysLower32;
17715   bit32                   memAllocStatus;
17716   void                    *osMemHandle;
17717 
17718   tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17719   agRoot          = tdsaDeviceData->agRoot;
17720   satDevData      = &tdsaDeviceData->satDevData;
17721 
17722   TI_DBG5(("osSatResetCB: tiDeviceHandle=%p resetStatus=0x%x\n",
17723       tiDeviceHandle, resetStatus ));
17724 
17725   /* We may need to check FIS to check device operating condition */
17726 
17727 
17728   /*
17729    * Check if need to abort all pending I/Os
17730    */
17731   if ( satDevData->satAbortAfterReset == agTRUE )
17732   {
17733     /*
17734      * Issue abort to LL layer to all other pending I/Os for the same SATA drive
17735      */
17736     elementHdr = satDevData->satIoLinkList.flink;
17737     while (elementHdr != &satDevData->satIoLinkList)
17738     {
17739       satIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17740                                          satIoContextLink,
17741                                          elementHdr );
17742 
17743       tdIORequestBodyTmp = (tdIORequestBody_t *)satIOContext->tiRequestBody;
17744 
17745       /*
17746        * Issue abort
17747        */
17748       TI_DBG5(("osSatResetCB: issuing ABORT tiDeviceHandle=%p agIORequest=%p\n",
17749       tiDeviceHandle, &tdIORequestBodyTmp->agIORequest ));
17750 
17751       /* allocating agIORequest for abort itself */
17752       memAllocStatus = ostiAllocMemory(
17753                                        tiRoot,
17754                                        &osMemHandle,
17755                                        (void **)&tdAbortIORequestBody,
17756                                        &PhysUpper32,
17757                                        &PhysLower32,
17758                                        8,
17759                                        sizeof(tdIORequestBody_t),
17760                                        agTRUE
17761                                        );
17762 
17763       if (memAllocStatus != tiSuccess)
17764       {
17765         /* let os process IO */
17766         TI_DBG1(("osSatResetCB: ostiAllocMemory failed...\n"));
17767         return;
17768       }
17769 
17770       if (tdAbortIORequestBody == agNULL)
17771       {
17772         /* let os process IO */
17773         TI_DBG1(("osSatResetCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17774         return;
17775       }
17776       /* setup task management structure */
17777       tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17778       tdAbortIORequestBody->tiDevHandle = tiDeviceHandle;
17779 
17780       /* initialize agIORequest */
17781       agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17782       agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17783       agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17784 
17785       saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, &(tdIORequestBodyTmp->agIORequest), agNULL );
17786       elementHdr = elementHdr->flink;   /* for the next while loop  */
17787 
17788     } /* while */
17789 
17790     /* Reset flag */
17791     satDevData->satAbortAfterReset = agFALSE;
17792 
17793   }
17794 
17795 
17796   /*
17797    * Check if the device reset if the result of TM request.
17798    */
17799   if ( satDevData->satTmTaskTag != agNULL )
17800   {
17801     TI_DBG5(("osSatResetCB: calling TM completion tiDeviceHandle=%p satTmTaskTag=%p\n",
17802     tiDeviceHandle, satDevData->satTmTaskTag ));
17803 
17804     ostiInitiatorEvent( tiRoot,
17805                         agNULL,               /* portalContext not used */
17806                         tiDeviceHandle,
17807                         tiIntrEventTypeTaskManagement,
17808                         tiTMOK,
17809                         satDevData->satTmTaskTag);
17810     /*
17811      * Reset flag
17812      */
17813     satDevData->satTmTaskTag = agNULL;
17814   }
17815 
17816 }
17817 
17818 
17819 /*****************************************************************************
17820  *! \brief  osSatIOCompleted
17821  *
17822  *   This routine is a callback for SATA completion that required FIS status
17823  *   translation to SCSI status.
17824  *
17825  *  \param   tiRoot:          Pointer to TISA initiator driver/port instance.
17826  *  \param   tiIORequest:     Pointer to TISA I/O request context for this I/O.
17827  *  \param   respFis:         Pointer to status FIS to read.
17828  *  \param   respFisLen:      Length of response FIS to read.
17829  *  \param   satIOContext:    Pointer to SAT context.
17830  *  \param   interruptContext:      Interrupt context
17831  *
17832  *  \return: None
17833  *
17834  *****************************************************************************/
17835 osGLOBAL void osSatIOCompleted(
17836                           tiRoot_t           *tiRoot,
17837                           tiIORequest_t      *tiIORequest,
17838                           agsaFisHeader_t    *agFirstDword,
17839                           bit32              respFisLen,
17840                           agsaFrameHandle_t  agFrameHandle,
17841                           satIOContext_t     *satIOContext,
17842                           bit32              interruptContext)
17843 
17844 {
17845   satDeviceData_t           *pSatDevData;
17846   scsiRspSense_t            *pSense;
17847 #ifdef  TD_DEBUG_ENABLE
17848   tiIniScsiCmnd_t           *pScsiCmnd;
17849 #endif
17850   agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
17851   bit32                     ataStatus = 0;
17852   bit32                     ataError;
17853   satInternalIo_t           *satIntIo = agNULL;
17854   bit32                     status;
17855   tiDeviceHandle_t          *tiDeviceHandle;
17856   satIOContext_t            *satIOContext2;
17857   tdIORequestBody_t         *tdIORequestBody;
17858   agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
17859   agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL;
17860   tiIORequest_t             tiIORequestTMP;
17861 
17862   pSense          = satIOContext->pSense;
17863   pSatDevData     = satIOContext->pSatDevData;
17864 #ifdef  TD_DEBUG_ENABLE
17865   pScsiCmnd       = satIOContext->pScsiCmnd;
17866 #endif
17867   hostToDevFis    = satIOContext->pFis;
17868 
17869   tiDeviceHandle  = &((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->tiDeviceHandle;
17870   /*
17871    * Find out the type of response FIS:
17872    * Set Device Bit FIS or Reg Device To Host FIS.
17873    */
17874 
17875   /* First assume it is Reg Device to Host FIS */
17876   statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
17877   ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
17878   ataError      = statDevToHostFisHeader->error;    /* ATA Eror register   */
17879 
17880   /* for debugging */
17881   TI_DBG1(("osSatIOCompleted: H to D command 0x%x\n", hostToDevFis->h.command));
17882   TI_DBG1(("osSatIOCompleted: D to H fistype 0x%x\n", statDevToHostFisHeader->fisType));
17883 
17884 
17885   if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS)
17886   {
17887     /* It is Set Device Bits FIS */
17888     statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H);
17889     /* Get ATA Status register */
17890     ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70);               /* bits 4,5,6 */
17891     ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07);   /* bits 0,1,2 */
17892 
17893     /* ATA Eror register   */
17894     ataError  = statSetDevBitFisHeader->error;
17895 
17896     statDevToHostFisHeader = agNULL;
17897   }
17898 
17899   else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
17900   {
17901     TI_DBG1(("osSatIOCompleted: *** UNEXPECTED RESP FIS TYPE 0x%x *** tiIORequest=%p\n",
17902                  statDevToHostFisHeader->fisType, tiIORequest));
17903 
17904     satSetSensePayload( pSense,
17905                         SCSI_SNSKEY_HARDWARE_ERROR,
17906                         0,
17907                         SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
17908                         satIOContext);
17909 
17910     ostiInitiatorIOCompleted( tiRoot,
17911                               tiIORequest,
17912                               tiIOSuccess,
17913                               SCSI_STAT_CHECK_CONDITION,
17914                               satIOContext->pTiSenseData,
17915                               interruptContext );
17916     return;
17917 
17918   }
17919 
17920   if ( ataStatus & DF_ATA_STATUS_MASK )
17921   {
17922     pSatDevData->satDeviceFaultState = agTRUE;
17923   }
17924   else
17925   {
17926     pSatDevData->satDeviceFaultState = agFALSE;
17927   }
17928 
17929   TI_DBG5(("osSatIOCompleted: tiIORequest=%p  CDB=0x%x ATA CMD =0x%x\n",
17930     tiIORequest, pScsiCmnd->cdb[0], hostToDevFis->h.command));
17931 
17932   /*
17933    * Decide which ATA command is the translation needed
17934    */
17935   switch(hostToDevFis->h.command)
17936   {
17937     case SAT_READ_FPDMA_QUEUED:
17938     case SAT_WRITE_FPDMA_QUEUED:
17939 
17940       /************************************************************************
17941        *
17942        * !!!! See Section 13.5.2.4 of SATA 2.5 specs.                      !!!!
17943        * !!!! If the NCQ error ends up here, it means that the device sent !!!!
17944        * !!!! Set Device Bit FIS (which has SActive register) instead of   !!!!
17945        * !!!! Register Device To Host FIS (which does not have SActive     !!!!
17946        * !!!! register). The callback ossaSATAEvent() deals with the case  !!!!
17947        * !!!! where Register Device To Host FIS was sent by the device.    !!!!
17948        *
17949        * For NCQ we need to issue READ LOG EXT command with log page 10h
17950        * to get the error and to allow other I/Os to continue.
17951        *
17952        * Here is the basic flow or sequence of error recovery, note that due
17953        * to the SATA HW assist that we have, this sequence is slighly different
17954        * from the one described in SATA 2.5:
17955        *
17956        * 1. Set SATA device flag to indicate error condition and returning busy
17957        *    for all new request.
17958        *   return tiSuccess;
17959 
17960        * 2. Because the HW/LL layer received Set Device Bit FIS, it can get the
17961        *    tag or I/O context for NCQ request, SATL would translate the ATA error
17962        *    to SCSI status and return the original NCQ I/O with the appopriate
17963        *    SCSI status.
17964        *
17965        * 3. Prepare READ LOG EXT page 10h command. Set flag to indicate that
17966        *    the failed I/O has been returned to the OS Layer. Send command.
17967        *
17968        * 4. When the device receives READ LOG EXT page 10h request all other
17969        *    pending I/O are implicitly aborted. No completion (aborted) status
17970        *    will be sent to the host for these aborted commands.
17971        *
17972        * 5. SATL receives the completion for READ LOG EXT command in
17973        *    satReadLogExtCB(). Steps 6,7,8,9 below are the step 1,2,3,4 in
17974        *    satReadLogExtCB().
17975        *
17976        * 6. Check flag that indicates whether the failed I/O has been returned
17977        *    to the OS Layer. If not, search the I/O context in device data
17978        *    looking for a matched tag. Then return the completion of the failed
17979        *    NCQ command with the appopriate/trasnlated SCSI status.
17980        *
17981        * 7. Issue abort to LL layer to all other pending I/Os for the same SATA
17982        *    drive.
17983        *
17984        * 8. Free resource allocated for the internally generated READ LOG EXT.
17985        *
17986        * 9. At the completion of abort, in the context of ossaSATACompleted(),
17987        *    return the I/O with error status to the OS-App Specific layer.
17988        *    When all I/O aborts are completed, clear SATA device flag to
17989        *    indicate ready to process new request.
17990        *
17991        ***********************************************************************/
17992 
17993       TI_DBG1(("osSatIOCompleted: NCQ ERROR tiIORequest=%p ataStatus=0x%x ataError=0x%x\n",
17994           tiIORequest, ataStatus, ataError ));
17995 
17996       /* Set flag to indicate we are in recovery */
17997       pSatDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17998 
17999       /* Return the failed NCQ I/O to OS-Apps Specifiic layer */
18000       osSatDefaultTranslation( tiRoot,
18001                                tiIORequest,
18002                                satIOContext,
18003                                pSense,
18004                                (bit8)ataStatus,
18005                                (bit8)ataError,
18006                                interruptContext );
18007 
18008       /*
18009        * Allocate resource for READ LOG EXT page 10h
18010        */
18011       satIntIo = satAllocIntIoResource( tiRoot,
18012                                         &(tiIORequestTMP), /* anything but NULL */
18013                                         pSatDevData,
18014                                         sizeof (satReadLogExtPage10h_t),
18015                                         satIntIo);
18016 
18017       if (satIntIo == agNULL)
18018       {
18019         TI_DBG1(("osSatIOCompleted: can't send RLE due to resource lack\n"));
18020 
18021         /* Abort I/O after completion of device reset */
18022         pSatDevData->satAbortAfterReset = agTRUE;
18023 #ifdef NOT_YET
18024         /* needs further investigation */
18025         /* no report to OS layer */
18026         satSubTM(tiRoot,
18027                  tiDeviceHandle,
18028                  TD_INTERNAL_TM_RESET,
18029                  agNULL,
18030                  agNULL,
18031                  agNULL,
18032                  agFALSE);
18033 #endif
18034 
18035 
18036         TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 1\n"));
18037         return;
18038       }
18039 
18040 
18041       /*
18042        * Set flag to indicate that the failed I/O has been returned to the
18043        * OS-App specific Layer.
18044        */
18045       satIntIo->satIntFlag = AG_SAT_INT_IO_FLAG_ORG_IO_COMPLETED;
18046 
18047       /* compare to satPrepareNewIO() */
18048       /* Send READ LOG EXIT page 10h command */
18049 
18050       /*
18051        * Need to initialize all the fields within satIOContext except
18052        * reqType and satCompleteCB which will be set depending on cmd.
18053        */
18054 
18055       tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
18056       satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
18057 
18058       satIOContext2->pSatDevData   = pSatDevData;
18059       satIOContext2->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
18060       satIOContext2->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
18061       satIOContext2->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
18062       satIOContext2->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
18063       satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
18064 
18065       satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
18066       satIOContext2->interruptContext = interruptContext;
18067       satIOContext2->satIntIoContext  = satIntIo;
18068 
18069       satIOContext2->ptiDeviceHandle = tiDeviceHandle;
18070       satIOContext2->satOrgIOContext = agNULL;
18071       satIOContext2->tiScsiXchg = agNULL;
18072 
18073       status = satSendReadLogExt( tiRoot,
18074                                   &satIntIo->satIntTiIORequest,
18075                                   tiDeviceHandle,
18076                                   &satIntIo->satIntTiScsiXchg,
18077                                   satIOContext2);
18078 
18079       if (status != tiSuccess)
18080       {
18081         TI_DBG1(("osSatIOCompleted: can't send RLE due to LL api failure\n"));
18082         satFreeIntIoResource( tiRoot,
18083                               pSatDevData,
18084                               satIntIo);
18085 
18086         /* Abort I/O after completion of device reset */
18087         pSatDevData->satAbortAfterReset = agTRUE;
18088 #ifdef NOT_YET
18089         /* needs further investigation */
18090         /* no report to OS layer */
18091         satSubTM(tiRoot,
18092                  tiDeviceHandle,
18093                  TD_INTERNAL_TM_RESET,
18094                  agNULL,
18095                  agNULL,
18096                  agNULL,
18097                  agFALSE);
18098 #endif
18099 
18100         TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 2\n"));
18101         return;
18102       }
18103 
18104       break;
18105 
18106     case SAT_READ_DMA_EXT:
18107       /* fall through */
18108       /* Use default status/error translation */
18109 
18110     case SAT_READ_DMA:
18111       /* fall through */
18112       /* Use default status/error translation */
18113 
18114     default:
18115       osSatDefaultTranslation( tiRoot,
18116                                tiIORequest,
18117                                satIOContext,
18118                                pSense,
18119                                (bit8)ataStatus,
18120                                (bit8)ataError,
18121                                interruptContext );
18122       break;
18123 
18124   }  /* end switch  */
18125 }
18126 
18127 
18128 /*****************************************************************************/
18129 /*! \brief SAT implementation for SCSI STANDARD INQUIRY.
18130  *
18131  *  SAT implementation for SCSI STANDARD INQUIRY.
18132  *
18133  *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18134  *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18135  *
18136  *  \return None.
18137  */
18138 /*****************************************************************************/
18139 GLOBAL void  satInquiryStandard(
18140                                 bit8                    *pInquiry,
18141                                 agsaSATAIdentifyData_t  *pSATAIdData,
18142                                 tiIniScsiCmnd_t          *scsiCmnd
18143                                 )
18144 {
18145   tiLUN_t       *pLun;
18146   pLun          = &scsiCmnd->lun;
18147 
18148   /*
18149     Assumption: Basic Task Mangement is supported
18150     -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147
18151   */
18152  /*
18153     See SPC-4, 6.4.2, p 143
18154     and SAT revision 8, 8.1.2, p 28
18155    */
18156 
18157   TI_DBG5(("satInquiryStandard: start\n"));
18158 
18159   if (pInquiry == agNULL)
18160   {
18161     TI_DBG1(("satInquiryStandard: pInquiry is NULL, wrong\n"));
18162     return;
18163   }
18164   else
18165   {
18166     TI_DBG5(("satInquiryStandard: pInquiry is NOT NULL\n"));
18167   }
18168   /*
18169    * Reject all other LUN other than LUN 0.
18170    */
18171   if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
18172          pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) )
18173   {
18174     /* SAT Spec Table 8, p27, footnote 'a' */
18175     pInquiry[0] = 0x7F;
18176 
18177   }
18178   else
18179   {
18180     pInquiry[0] = 0x00;
18181   }
18182 
18183   if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
18184   {
18185     pInquiry[1] = 0x80;
18186   }
18187   else
18188   {
18189     pInquiry[1] = 0x00;
18190   }
18191   pInquiry[2] = 0x05;   /* SPC-3 */
18192   pInquiry[3] = 0x12;   /* set HiSup 1; resp data format set to 2 */
18193   pInquiry[4] = 0x1F;   /* 35 - 4 = 31; Additional length */
18194   pInquiry[5] = 0x00;
18195   /* The following two are for task management. SAT Rev8, p20 */
18196   if (pSATAIdData->sataCapabilities & 0x100)
18197   {
18198     /* NCQ supported; multiple outstanding SCSI IO are supported */
18199     pInquiry[6] = 0x00;   /* BQUE bit is not set */
18200     pInquiry[7] = 0x02;   /* CMDQUE bit is set */
18201   }
18202   else
18203   {
18204     pInquiry[6] = 0x80;   /* BQUE bit is set */
18205     pInquiry[7] = 0x00;   /* CMDQUE bit is not set */
18206   }
18207   /*
18208    * Vendor ID.
18209    */
18210   osti_strncpy((char*)&pInquiry[8],  AG_SAT_VENDOR_ID_STRING,8);   /* 8 bytes   */
18211 
18212   /*
18213    * Product ID
18214    */
18215   /* when flipped by LL */
18216   pInquiry[16] = pSATAIdData->modelNumber[1];
18217   pInquiry[17] = pSATAIdData->modelNumber[0];
18218   pInquiry[18] = pSATAIdData->modelNumber[3];
18219   pInquiry[19] = pSATAIdData->modelNumber[2];
18220   pInquiry[20] = pSATAIdData->modelNumber[5];
18221   pInquiry[21] = pSATAIdData->modelNumber[4];
18222   pInquiry[22] = pSATAIdData->modelNumber[7];
18223   pInquiry[23] = pSATAIdData->modelNumber[6];
18224   pInquiry[24] = pSATAIdData->modelNumber[9];
18225   pInquiry[25] = pSATAIdData->modelNumber[8];
18226   pInquiry[26] = pSATAIdData->modelNumber[11];
18227   pInquiry[27] = pSATAIdData->modelNumber[10];
18228   pInquiry[28] = pSATAIdData->modelNumber[13];
18229   pInquiry[29] = pSATAIdData->modelNumber[12];
18230   pInquiry[30] = pSATAIdData->modelNumber[15];
18231   pInquiry[31] = pSATAIdData->modelNumber[14];
18232 
18233   /* when flipped */
18234   /*
18235    * Product Revision level.
18236    */
18237 
18238   /*
18239    * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18240    * device are ASCII spaces (20h), do this translation.
18241    */
18242   if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18243        (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18244        (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18245        (pSATAIdData->firmwareVersion[7] == 0x00 )
18246        )
18247   {
18248     pInquiry[32] = pSATAIdData->firmwareVersion[1];
18249     pInquiry[33] = pSATAIdData->firmwareVersion[0];
18250     pInquiry[34] = pSATAIdData->firmwareVersion[3];
18251     pInquiry[35] = pSATAIdData->firmwareVersion[2];
18252   }
18253   else
18254   {
18255     pInquiry[32] = pSATAIdData->firmwareVersion[5];
18256     pInquiry[33] = pSATAIdData->firmwareVersion[4];
18257     pInquiry[34] = pSATAIdData->firmwareVersion[7];
18258     pInquiry[35] = pSATAIdData->firmwareVersion[6];
18259   }
18260 
18261 
18262 #ifdef REMOVED
18263   /*
18264    * Product ID
18265    */
18266   /* when flipped by LL */
18267   pInquiry[16] = pSATAIdData->modelNumber[0];
18268   pInquiry[17] = pSATAIdData->modelNumber[1];
18269   pInquiry[18] = pSATAIdData->modelNumber[2];
18270   pInquiry[19] = pSATAIdData->modelNumber[3];
18271   pInquiry[20] = pSATAIdData->modelNumber[4];
18272   pInquiry[21] = pSATAIdData->modelNumber[5];
18273   pInquiry[22] = pSATAIdData->modelNumber[6];
18274   pInquiry[23] = pSATAIdData->modelNumber[7];
18275   pInquiry[24] = pSATAIdData->modelNumber[8];
18276   pInquiry[25] = pSATAIdData->modelNumber[9];
18277   pInquiry[26] = pSATAIdData->modelNumber[10];
18278   pInquiry[27] = pSATAIdData->modelNumber[11];
18279   pInquiry[28] = pSATAIdData->modelNumber[12];
18280   pInquiry[29] = pSATAIdData->modelNumber[13];
18281   pInquiry[30] = pSATAIdData->modelNumber[14];
18282   pInquiry[31] = pSATAIdData->modelNumber[15];
18283 
18284   /* when flipped */
18285   /*
18286    * Product Revision level.
18287    */
18288 
18289   /*
18290    * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18291    * device are ASCII spaces (20h), do this translation.
18292    */
18293   if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18294        (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18295        (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18296        (pSATAIdData->firmwareVersion[7] == 0x00 )
18297        )
18298   {
18299     pInquiry[32] = pSATAIdData->firmwareVersion[0];
18300     pInquiry[33] = pSATAIdData->firmwareVersion[1];
18301     pInquiry[34] = pSATAIdData->firmwareVersion[2];
18302     pInquiry[35] = pSATAIdData->firmwareVersion[3];
18303   }
18304   else
18305   {
18306     pInquiry[32] = pSATAIdData->firmwareVersion[4];
18307     pInquiry[33] = pSATAIdData->firmwareVersion[5];
18308     pInquiry[34] = pSATAIdData->firmwareVersion[6];
18309     pInquiry[35] = pSATAIdData->firmwareVersion[7];
18310   }
18311 #endif
18312 
18313   TI_DBG5(("satInquiryStandard: end\n"));
18314 
18315 }
18316 
18317 
18318 /*****************************************************************************/
18319 /*! \brief SAT implementation for SCSI INQUIRY page 0.
18320  *
18321  *  SAT implementation for SCSI INQUIRY page 0.
18322  *
18323  *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18324  *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18325  *
18326  *  \return None.
18327  */
18328 /*****************************************************************************/
18329 GLOBAL void  satInquiryPage0(
18330                     bit8                    *pInquiry,
18331                     agsaSATAIdentifyData_t  *pSATAIdData)
18332 {
18333 
18334   TI_DBG5(("satInquiryPage0: entry\n"));
18335 
18336   /*
18337     See SPC-4, 7.6.9, p 345
18338     and SAT revision 8, 10.3.2, p 77
18339    */
18340   pInquiry[0] = 0x00;
18341   pInquiry[1] = 0x00; /* page code */
18342   pInquiry[2] = 0x00; /* reserved */
18343   pInquiry[3] = 7 - 3; /* last index(in this case, 6) - 3; page length */
18344 
18345   /* supported vpd page list */
18346   pInquiry[4] = 0x00; /* page 0x00 supported */
18347   pInquiry[5] = 0x80; /* page 0x80 supported */
18348   pInquiry[6] = 0x83; /* page 0x83 supported */
18349   pInquiry[7] = 0x89; /* page 0x89 supported */
18350 
18351 }
18352 
18353 
18354 /*****************************************************************************/
18355 /*! \brief SAT implementation for SCSI INQUIRY page 83.
18356  *
18357  *  SAT implementation for SCSI INQUIRY page 83.
18358  *
18359  *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18360  *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18361  *
18362  *  \return None.
18363  */
18364 /*****************************************************************************/
18365 GLOBAL void  satInquiryPage83(
18366                     bit8                    *pInquiry,
18367                     agsaSATAIdentifyData_t  *pSATAIdData,
18368                     satDeviceData_t         *pSatDevData)
18369 {
18370 
18371   satSimpleSATAIdentifyData_t   *pSimpleData;
18372 
18373   /*
18374    * When translating the fields, in some cases using the simple form of SATA
18375    * Identify Device Data is easier. So we define it here.
18376    * Both pSimpleData and pSATAIdData points to the same data.
18377    */
18378   pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18379 
18380   TI_DBG5(("satInquiryPage83: entry\n"));
18381 
18382   pInquiry[0] = 0x00;
18383   pInquiry[1] = 0x83; /* page code */
18384   pInquiry[2] = 0;    /* Reserved */
18385 
18386   /*
18387    * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE
18388    * data indicating that it supports the WORLD WIDE NAME field
18389    * (i.e., words 108-111), the SATL shall include an identification descriptor
18390    * containing a logical unit name.
18391    */
18392   if ( pSatDevData->satWWNSupport)
18393   {
18394     /* Fill in SAT Rev8 Table85 */
18395     /*
18396      * Logical unit name derived from the world wide name.
18397      */
18398     pInquiry[3] = 12;         /* 15-3; page length, no addition ID descriptor assumed*/
18399 
18400     /*
18401      * Identifier descriptor
18402      */
18403     pInquiry[4]  = 0x01;                        /* Code set: binary codes */
18404     pInquiry[5]  = 0x03;                        /* Identifier type : NAA  */
18405     pInquiry[6]  = 0x00;                        /* Reserved               */
18406     pInquiry[7]  = 0x08;                        /* Identifier length      */
18407 
18408     /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
18409     pInquiry[8]  = (bit8)((pSATAIdData->namingAuthority) >> 8);
18410     pInquiry[9]  = (bit8)((pSATAIdData->namingAuthority) & 0xFF);           /* IEEE Company ID */
18411     pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8);            /* IEEE Company ID */
18412     /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
18413     pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
18414     pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8);       /* Vendor Specific ID  */
18415     pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF);     /* Vendor Specific ID  */
18416     pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8);        /* Vendor Specific ID  */
18417     pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF);      /* Vendor Specific ID  */
18418 
18419   }
18420   else
18421   {
18422     /* Fill in SAT Rev8 Table86 */
18423     /*
18424      * Logical unit name derived from the model number and serial number.
18425      */
18426     pInquiry[3] = 72;    /* 75 - 3; page length */
18427 
18428     /*
18429      * Identifier descriptor
18430      */
18431     pInquiry[4] = 0x02;             /* Code set: ASCII codes */
18432     pInquiry[5] = 0x01;             /* Identifier type : T10 vendor ID based */
18433     pInquiry[6] = 0x00;             /* Reserved */
18434     pInquiry[7] = 0x44;               /* 0x44, 68 Identifier length */
18435 
18436     /* Byte 8 to 15 is the vendor id string 'ATA     '. */
18437     osti_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
18438 
18439 
18440         /*
18441      * Byte 16 to 75 is vendor specific id
18442      */
18443     pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
18444     pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
18445     pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
18446     pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
18447     pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
18448     pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
18449     pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
18450     pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
18451     pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
18452     pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
18453     pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
18454     pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
18455     pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
18456     pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
18457     pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
18458     pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
18459     pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
18460     pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
18461     pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
18462     pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
18463     pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
18464     pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
18465     pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
18466     pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
18467     pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
18468     pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
18469     pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
18470     pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
18471     pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
18472     pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
18473     pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
18474     pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
18475     pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
18476     pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
18477     pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
18478     pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
18479     pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
18480     pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
18481     pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
18482     pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
18483 
18484     pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
18485     pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
18486     pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
18487     pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
18488     pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
18489     pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
18490     pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
18491     pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
18492     pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
18493     pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
18494     pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
18495     pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
18496     pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
18497     pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
18498     pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
18499     pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
18500     pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
18501     pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
18502     pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
18503     pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
18504   }
18505 
18506 }
18507 
18508 /*****************************************************************************/
18509 /*! \brief SAT implementation for SCSI INQUIRY page 89.
18510  *
18511  *  SAT implementation for SCSI INQUIRY page 89.
18512  *
18513  *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18514  *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18515  *  \param   pSatDevData       Pointer to internal device data structure
18516  *
18517  *  \return None.
18518  */
18519 /*****************************************************************************/
18520 GLOBAL void  satInquiryPage89(
18521                     bit8                    *pInquiry,
18522                     agsaSATAIdentifyData_t  *pSATAIdData,
18523                     satDeviceData_t         *pSatDevData)
18524 {
18525   /*
18526     SAT revision 8, 10.3.5, p 83
18527    */
18528   satSimpleSATAIdentifyData_t   *pSimpleData;
18529 
18530   /*
18531    * When translating the fields, in some cases using the simple form of SATA
18532    * Identify Device Data is easier. So we define it here.
18533    * Both pSimpleData and pSATAIdData points to the same data.
18534    */
18535   pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18536 
18537   TI_DBG5(("satInquiryPage89: start\n"));
18538 
18539   pInquiry[0] = 0x00;   /* Peripheral Qualifier and Peripheral Device Type */
18540   pInquiry[1] = 0x89;   /* page code */
18541 
18542   /* Page length 0x238 */
18543   pInquiry[2] = 0x02;
18544   pInquiry[3] = 0x38;
18545 
18546   pInquiry[4] = 0x0;    /* reserved */
18547   pInquiry[5] = 0x0;    /* reserved */
18548   pInquiry[6] = 0x0;    /* reserved */
18549   pInquiry[7] = 0x0;    /* reserved */
18550 
18551   /* SAT Vendor Identification */
18552   osti_strncpy((char*)&pInquiry[8],  "PMC-SIERRA", 8);   /* 8 bytes   */
18553 
18554   /* SAT Product Idetification */
18555   osti_strncpy((char*)&pInquiry[16],  "Tachyon-SPC    ", 16);   /* 16 bytes   */
18556 
18557   /* SAT Product Revision Level */
18558   osti_strncpy((char*)&pInquiry[32],  "01", 4);   /* 4 bytes   */
18559 
18560   /* Signature, SAT revision8, Table88, p85 */
18561 
18562 
18563   pInquiry[36] = 0x34;    /* FIS type */
18564   if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18565   {
18566     /* interrupt assume to be 0 */
18567     pInquiry[37] = (bit8)((pSatDevData->satPMField) >> (4 * 7)); /* first four bits of PM field */
18568   }
18569   else
18570   {
18571     /* interrupt assume to be 1 */
18572     pInquiry[37] = (bit8)(0x40 + (bit8)(((pSatDevData->satPMField) >> (4 * 7)))); /* first four bits of PM field */
18573   }
18574   pInquiry[38] = 0;
18575   pInquiry[39] = 0;
18576 
18577   if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18578   {
18579     pInquiry[40] = 0x01; /* LBA Low          */
18580     pInquiry[41] = 0x00; /* LBA Mid          */
18581     pInquiry[42] = 0x00; /* LBA High         */
18582     pInquiry[43] = 0x00; /* Device           */
18583     pInquiry[44] = 0x00; /* LBA Low Exp      */
18584     pInquiry[45] = 0x00; /* LBA Mid Exp      */
18585     pInquiry[46] = 0x00; /* LBA High Exp     */
18586     pInquiry[47] = 0x00; /* Reserved         */
18587     pInquiry[48] = 0x01; /* Sector Count     */
18588     pInquiry[49] = 0x00; /* Sector Count Exp */
18589   }
18590   else
18591   {
18592     pInquiry[40] = 0x01; /* LBA Low          */
18593     pInquiry[41] = 0x00; /* LBA Mid          */
18594     pInquiry[42] = 0x00; /* LBA High         */
18595     pInquiry[43] = 0x00; /* Device           */
18596     pInquiry[44] = 0x00; /* LBA Low Exp      */
18597     pInquiry[45] = 0x00; /* LBA Mid Exp      */
18598     pInquiry[46] = 0x00; /* LBA High Exp     */
18599     pInquiry[47] = 0x00; /* Reserved         */
18600     pInquiry[48] = 0x01; /* Sector Count     */
18601     pInquiry[49] = 0x00; /* Sector Count Exp */
18602   }
18603 
18604   /* Reserved */
18605   pInquiry[50] = 0x00;
18606   pInquiry[51] = 0x00;
18607   pInquiry[52] = 0x00;
18608   pInquiry[53] = 0x00;
18609   pInquiry[54] = 0x00;
18610   pInquiry[55] = 0x00;
18611 
18612   /* Command Code */
18613   if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18614   {
18615     pInquiry[56] = 0xEC;    /* IDENTIFY DEVICE */
18616   }
18617   else
18618   {
18619     pInquiry[56] = 0xA1;    /* IDENTIFY PACKET DEVICE */
18620   }
18621   /* Reserved */
18622   pInquiry[57] = 0x0;
18623   pInquiry[58] = 0x0;
18624   pInquiry[59] = 0x0;
18625 
18626   /* Identify Device */
18627   osti_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
18628   return;
18629 }
18630 
18631 /*****************************************************************************/
18632 /*! \brief SAT implementation for SCSI INQUIRY page 0.
18633  *
18634  *  SAT implementation for SCSI INQUIRY page 0.
18635  *
18636  *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18637  *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18638  *
18639  *  \return None.
18640  */
18641 /*****************************************************************************/
18642 GLOBAL void  satInquiryPage80(
18643                     bit8                    *pInquiry,
18644                     agsaSATAIdentifyData_t  *pSATAIdData)
18645 {
18646 
18647   TI_DBG5(("satInquiryPage80: entry\n"));
18648 
18649   /*
18650     See SPC-4, 7.6.9, p 345
18651     and SAT revision 8, 10.3.3, p 77
18652    */
18653   pInquiry[0] = 0x00;
18654   pInquiry[1] = 0x80; /* page code */
18655   pInquiry[2] = 0x00; /* reserved */
18656   pInquiry[3] = 0x14; /* page length */
18657 
18658   /* supported vpd page list */
18659   pInquiry[4] = pSATAIdData->serialNumber[1];
18660   pInquiry[5] = pSATAIdData->serialNumber[0];
18661   pInquiry[6] = pSATAIdData->serialNumber[3];
18662   pInquiry[7] = pSATAIdData->serialNumber[2];
18663   pInquiry[8] = pSATAIdData->serialNumber[5];
18664   pInquiry[9] = pSATAIdData->serialNumber[4];
18665   pInquiry[10] = pSATAIdData->serialNumber[7];
18666   pInquiry[11] = pSATAIdData->serialNumber[6];
18667   pInquiry[12] = pSATAIdData->serialNumber[9];
18668   pInquiry[13] = pSATAIdData->serialNumber[8];
18669   pInquiry[14] = pSATAIdData->serialNumber[11];
18670   pInquiry[15] = pSATAIdData->serialNumber[10];
18671   pInquiry[16] = pSATAIdData->serialNumber[13];
18672   pInquiry[17] = pSATAIdData->serialNumber[12];
18673   pInquiry[18] = pSATAIdData->serialNumber[15];
18674   pInquiry[19] = pSATAIdData->serialNumber[14];
18675   pInquiry[20] = pSATAIdData->serialNumber[17];
18676   pInquiry[21] = pSATAIdData->serialNumber[16];
18677   pInquiry[22] = pSATAIdData->serialNumber[19];
18678   pInquiry[23] = pSATAIdData->serialNumber[18];
18679 
18680 
18681 }
18682 
18683 
18684 
18685 /*****************************************************************************/
18686 /*! \brief  Send READ LOG EXT ATA PAGE 10h command to sata drive.
18687  *
18688  *  Send READ LOG EXT ATA command PAGE 10h request to LL layer.
18689  *
18690  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
18691  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
18692  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
18693  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
18694  *  \param   satIOContext_t:   Pointer to the SAT IO Context
18695  *
18696  *  \return If command is started successfully
18697  *    - \e tiSuccess:     I/O request successfully initiated.
18698  *    - \e tiBusy:        No resources available, try again later.
18699  *    - \e tiIONoDevice:  Invalid device handle.
18700  *    - \e tiError:       Other errors.
18701  */
18702 /*****************************************************************************/
18703 GLOBAL bit32  satSendReadLogExt(
18704                    tiRoot_t                  *tiRoot,
18705                    tiIORequest_t             *tiIORequest,
18706                    tiDeviceHandle_t          *tiDeviceHandle,
18707                    tiScsiInitiatorRequest_t *tiScsiRequest,
18708                    satIOContext_t            *satIOContext)
18709 
18710 {
18711 
18712   bit32                     status;
18713   bit32                     agRequestType;
18714   agsaFisRegHostToDevice_t  *fis;
18715 
18716   fis           = satIOContext->pFis;
18717 
18718   TI_DBG1(("satSendReadLogExt: tiDeviceHandle=%p tiIORequest=%p\n",
18719       tiDeviceHandle, tiIORequest));
18720 
18721   fis->h.fisType        = 0x27;                   /* Reg host to device */
18722   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18723   fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
18724   fis->h.features       = 0;                      /* FIS reserve */
18725   fis->d.lbaLow         = 0x10;                   /* Page number */
18726   fis->d.lbaMid         = 0;                      /*  */
18727   fis->d.lbaHigh        = 0;                      /*  */
18728   fis->d.device         = 0;                      /* DEV is ignored in SATA */
18729   fis->d.lbaLowExp      = 0;                      /*  */
18730   fis->d.lbaMidExp      = 0;                      /*  */
18731   fis->d.lbaHighExp     = 0;                      /*  */
18732   fis->d.featuresExp    = 0;                      /* FIS reserve */
18733   fis->d.sectorCount    = 0x01;                   /*  1 sector counts*/
18734   fis->d.sectorCountExp = 0x00;                   /*  1 sector counts */
18735   fis->d.reserved4      = 0;
18736   fis->d.control        = 0;                      /* FIS HOB bit clear */
18737   fis->d.reserved5      = 0;
18738 
18739   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
18740 
18741   /* Initialize CB for SATA completion.
18742    */
18743   satIOContext->satCompleteCB = &satReadLogExtCB;
18744 
18745   /*
18746    * Prepare SGL and send FIS to LL layer.
18747    */
18748   satIOContext->reqType = agRequestType;       /* Save it */
18749 
18750   status = sataLLIOStart( tiRoot,
18751                           tiIORequest,
18752                           tiDeviceHandle,
18753                           tiScsiRequest,
18754                           satIOContext);
18755 
18756   TI_DBG1(("satSendReadLogExt: end status %d\n", status));
18757 
18758   return (status);
18759 
18760 }
18761 
18762 
18763 /*****************************************************************************/
18764 /*! \brief  SAT default ATA status and ATA error translation to SCSI.
18765  *
18766  *  SSAT default ATA status and ATA error translation to SCSI.
18767  *
18768  *  \param   tiRoot:        Pointer to TISA initiator driver/port instance.
18769  *  \param   tiIORequest:   Pointer to TISA I/O request context for this I/O.
18770  *  \param   satIOContext:  Pointer to the SAT IO Context
18771  *  \param   pSense:        Pointer to scsiRspSense_t
18772  *  \param   ataStatus:     ATA status register
18773  *  \param   ataError:      ATA error register
18774  *  \param   interruptContext:    Interrupt context
18775  *
18776  *  \return  None
18777  */
18778 /*****************************************************************************/
18779 GLOBAL void  osSatDefaultTranslation(
18780                    tiRoot_t             *tiRoot,
18781                    tiIORequest_t        *tiIORequest,
18782                    satIOContext_t       *satIOContext,
18783                    scsiRspSense_t       *pSense,
18784                    bit8                 ataStatus,
18785                    bit8                 ataError,
18786                    bit32                interruptContext )
18787 {
18788 
18789   /*
18790    * Check for device fault case
18791    */
18792   if ( ataStatus & DF_ATA_STATUS_MASK )
18793   {
18794     satSetSensePayload( pSense,
18795                         SCSI_SNSKEY_HARDWARE_ERROR,
18796                         0,
18797                         SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18798                         satIOContext);
18799 
18800     ostiInitiatorIOCompleted( tiRoot,
18801                               tiIORequest,
18802                               tiIOSuccess,
18803                               SCSI_STAT_CHECK_CONDITION,
18804                               satIOContext->pTiSenseData,
18805                               interruptContext );
18806     return;
18807   }
18808 
18809   /*
18810    * If status error bit it set, need to check the error register
18811    */
18812   if ( ataStatus & ERR_ATA_STATUS_MASK )
18813   {
18814     if ( ataError & NM_ATA_ERROR_MASK )
18815     {
18816       TI_DBG1(("osSatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18817                  ataError, tiIORequest));
18818       satSetSensePayload( pSense,
18819                           SCSI_SNSKEY_NOT_READY,
18820                           0,
18821                           SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
18822                           satIOContext);
18823     }
18824 
18825     else if (ataError & UNC_ATA_ERROR_MASK)
18826     {
18827       TI_DBG1(("osSatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18828                  ataError, tiIORequest));
18829       satSetSensePayload( pSense,
18830                           SCSI_SNSKEY_MEDIUM_ERROR,
18831                           0,
18832                           SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
18833                           satIOContext);
18834     }
18835 
18836     else if (ataError & IDNF_ATA_ERROR_MASK)
18837     {
18838       TI_DBG1(("osSatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18839                  ataError, tiIORequest));
18840       satSetSensePayload( pSense,
18841                           SCSI_SNSKEY_MEDIUM_ERROR,
18842                           0,
18843                           SCSI_SNSCODE_RECORD_NOT_FOUND,
18844                           satIOContext);
18845     }
18846 
18847     else if (ataError & MC_ATA_ERROR_MASK)
18848     {
18849       TI_DBG1(("osSatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18850                  ataError, tiIORequest));
18851       satSetSensePayload( pSense,
18852                           SCSI_SNSKEY_UNIT_ATTENTION,
18853                           0,
18854                           SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
18855                           satIOContext);
18856     }
18857 
18858     else if (ataError & MCR_ATA_ERROR_MASK)
18859     {
18860       TI_DBG1(("osSatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18861                  ataError, tiIORequest));
18862       satSetSensePayload( pSense,
18863                           SCSI_SNSKEY_UNIT_ATTENTION,
18864                           0,
18865                           SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
18866                           satIOContext);
18867     }
18868 
18869     else if (ataError & ICRC_ATA_ERROR_MASK)
18870     {
18871       TI_DBG1(("osSatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18872                  ataError, tiIORequest));
18873       satSetSensePayload( pSense,
18874                           SCSI_SNSKEY_ABORTED_COMMAND,
18875                           0,
18876                           SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
18877                           satIOContext);
18878     }
18879 
18880     else if (ataError & ABRT_ATA_ERROR_MASK)
18881     {
18882       TI_DBG1(("osSatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18883                  ataError, tiIORequest));
18884       satSetSensePayload( pSense,
18885                           SCSI_SNSKEY_ABORTED_COMMAND,
18886                           0,
18887                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
18888                           satIOContext);
18889     }
18890 
18891     else
18892     {
18893       TI_DBG1(("osSatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, tiIORequest=%p\n",
18894                  ataError, tiIORequest));
18895       satSetSensePayload( pSense,
18896                           SCSI_SNSKEY_HARDWARE_ERROR,
18897                           0,
18898                           SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18899                           satIOContext);
18900     }
18901 
18902     /* Send the completion response now */
18903     ostiInitiatorIOCompleted( tiRoot,
18904                               tiIORequest,
18905                               tiIOSuccess,
18906                               SCSI_STAT_CHECK_CONDITION,
18907                               satIOContext->pTiSenseData,
18908                               interruptContext );
18909     return;
18910 
18911 
18912   }
18913 
18914   else /*  (ataStatus & ERR_ATA_STATUS_MASK ) is false */
18915   {
18916     /* This case should never happen */
18917     TI_DBG1(("osSatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** tiIORequest=%p\n",
18918                  ataStatus, tiIORequest));
18919     satSetSensePayload( pSense,
18920                         SCSI_SNSKEY_HARDWARE_ERROR,
18921                         0,
18922                         SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18923                         satIOContext);
18924 
18925     ostiInitiatorIOCompleted( tiRoot,
18926                               tiIORequest,
18927                               tiIOSuccess,
18928                               SCSI_STAT_CHECK_CONDITION,
18929                               satIOContext->pTiSenseData,
18930                               interruptContext );
18931     return;
18932 
18933   }
18934 
18935 
18936 }
18937 
18938 /*****************************************************************************/
18939 /*! \brief  Allocate resource for SAT intervally generated I/O.
18940  *
18941  *  Allocate resource for SAT intervally generated I/O.
18942  *
18943  *  \param   tiRoot:      Pointer to TISA driver/port instance.
18944  *  \param   satDevData:  Pointer to SAT specific device data.
18945  *  \param   allocLength: Length in byte of the DMA mem to allocate, upto
18946  *                        one page size.
18947  *  \param   satIntIo:    Pointer (output) to context for SAT internally
18948  *                        generated I/O that is allocated by this routine.
18949  *
18950  *  \return If command is started successfully
18951  *    - \e tiSuccess:     Success.
18952  *    - \e tiError:       Failed allocating resource.
18953  */
18954 /*****************************************************************************/
18955 GLOBAL satInternalIo_t * satAllocIntIoResource(
18956                     tiRoot_t              *tiRoot,
18957                     tiIORequest_t         *tiIORequest,
18958                     satDeviceData_t       *satDevData,
18959                     bit32                 dmaAllocLength,
18960                     satInternalIo_t       *satIntIo)
18961 {
18962   tdList_t          *tdList = agNULL;
18963   bit32             memAllocStatus;
18964 
18965   TI_DBG1(("satAllocIntIoResource: start\n"));
18966   TI_DBG6(("satAllocIntIoResource: satIntIo %p\n", satIntIo));
18967   if (satDevData == agNULL)
18968   {
18969     TI_DBG1(("satAllocIntIoResource: ***** ASSERT satDevData is null\n"));
18970     return agNULL;
18971   }
18972 
18973   tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
18974   if (!TDLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
18975   {
18976     TDLIST_DEQUEUE_FROM_HEAD(&tdList, &(satDevData->satFreeIntIoLinkList));
18977   }
18978   else
18979   {
18980     tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18981     TI_DBG1(("satAllocIntIoResource() no more internal free link.\n"));
18982     return agNULL;
18983   }
18984 
18985   if (tdList == agNULL)
18986   {
18987     tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18988     TI_DBG1(("satAllocIntIoResource() FAIL to alloc satIntIo.\n"));
18989     return agNULL;
18990   }
18991 
18992   satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
18993   TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
18994 
18995   /* Put in active list */
18996   TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
18997   TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
18998   tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18999 
19000 #ifdef REMOVED
19001   /* Put in active list */
19002   tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19003   TDLIST_DEQUEUE_THIS (tdList);
19004   TDLIST_ENQUEUE_AT_TAIL (tdList, &(satDevData->satActiveIntIoLinkList));
19005   tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19006 
19007   satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
19008   TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19009 #endif
19010 
19011   /*
19012     typedef struct
19013     {
19014       tdList_t                    satIntIoLink;
19015       tiIORequest_t               satIntTiIORequest;
19016       void                        *satIntRequestBody;
19017       tiScsiInitiatorRequest_t   satIntTiScsiXchg;
19018       tiMem_t                     satIntDmaMem;
19019       tiMem_t                     satIntReqBodyMem;
19020       bit32                       satIntFlag;
19021     } satInternalIo_t;
19022   */
19023 
19024   /*
19025    * Allocate mem for Request Body
19026    */
19027   satIntIo->satIntReqBodyMem.totalLength = sizeof(tdIORequestBody_t);
19028 
19029   memAllocStatus = ostiAllocMemory( tiRoot,
19030                                     &satIntIo->satIntReqBodyMem.osHandle,
19031                                     (void **)&satIntIo->satIntRequestBody,
19032                                     &satIntIo->satIntReqBodyMem.physAddrUpper,
19033                                     &satIntIo->satIntReqBodyMem.physAddrLower,
19034                                     8,
19035                                     satIntIo->satIntReqBodyMem.totalLength,
19036                                     agTRUE );
19037 
19038   if (memAllocStatus != tiSuccess)
19039   {
19040     TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for Req Body.\n"));
19041     /*
19042      * Return satIntIo to the free list
19043      */
19044     tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19045     TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19046     TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19047     tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19048 
19049     return agNULL;
19050   }
19051 
19052   /*
19053    *   Allocate DMA memory if required
19054    */
19055   if (dmaAllocLength != 0)
19056   {
19057     satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
19058 
19059     memAllocStatus = ostiAllocMemory( tiRoot,
19060                                       &satIntIo->satIntDmaMem.osHandle,
19061                                       (void **)&satIntIo->satIntDmaMem.virtPtr,
19062                                       &satIntIo->satIntDmaMem.physAddrUpper,
19063                                       &satIntIo->satIntDmaMem.physAddrLower,
19064                                       8,
19065                                       satIntIo->satIntDmaMem.totalLength,
19066                                       agFALSE);
19067     TI_DBG6(("satAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
19068     TI_DBG6(("satAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
19069 
19070     if (memAllocStatus != tiSuccess)
19071     {
19072       TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for DMA mem.\n"));
19073       /*
19074        * Return satIntIo to the free list
19075        */
19076       tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19077       TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19078       TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19079       tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19080 
19081       /*
19082        * Free mem allocated for Req body
19083        */
19084       ostiFreeMemory( tiRoot,
19085                       satIntIo->satIntReqBodyMem.osHandle,
19086                       satIntIo->satIntReqBodyMem.totalLength);
19087 
19088       return agNULL;
19089     }
19090   }
19091 
19092   /*
19093     typedef struct
19094     {
19095       tdList_t                    satIntIoLink;
19096       tiIORequest_t               satIntTiIORequest;
19097       void                        *satIntRequestBody;
19098       tiScsiInitiatorRequest_t   satIntTiScsiXchg;
19099       tiMem_t                     satIntDmaMem;
19100       tiMem_t                     satIntReqBodyMem;
19101       bit32                       satIntFlag;
19102     } satInternalIo_t;
19103   */
19104 
19105   /*
19106    * Initialize satIntTiIORequest field
19107    */
19108   satIntIo->satIntTiIORequest.osData = agNULL;  /* Not used for internal SAT I/O */
19109   satIntIo->satIntTiIORequest.tdData = satIntIo->satIntRequestBody;
19110 
19111   /*
19112    * saves the original tiIOrequest
19113    */
19114   satIntIo->satOrgTiIORequest = tiIORequest;
19115   /*
19116     typedef struct tiIniScsiCmnd
19117     {
19118       tiLUN_t     lun;
19119       bit32       expDataLength;
19120       bit32       taskAttribute;
19121       bit32       crn;
19122       bit8        cdb[16];
19123     } tiIniScsiCmnd_t;
19124 
19125     typedef struct tiScsiInitiatorExchange
19126     {
19127       void                *sglVirtualAddr;
19128       tiIniScsiCmnd_t     scsiCmnd;
19129       tiSgl_t             agSgl1;
19130       tiSgl_t             agSgl2;
19131       tiDataDirection_t   dataDirection;
19132     } tiScsiInitiatorRequest_t;
19133 
19134   */
19135 
19136   /*
19137    * Initialize satIntTiScsiXchg. Since the internal SAT request is NOT
19138    * originated from SCSI request, only the following fields are initialized:
19139    *  - sglVirtualAddr if DMA transfer is involved
19140    *  - agSgl1 if DMA transfer is involved
19141    *  - expDataLength in scsiCmnd since this field is read by sataLLIOStart()
19142    */
19143   if (dmaAllocLength != 0)
19144   {
19145     satIntIo->satIntTiScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
19146 
19147     OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntTiScsiXchg.agSgl1.len, 0,
19148                      satIntIo->satIntDmaMem.totalLength);
19149     satIntIo->satIntTiScsiXchg.agSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
19150     satIntIo->satIntTiScsiXchg.agSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
19151     satIntIo->satIntTiScsiXchg.agSgl1.type  = tiSgl;
19152 
19153     satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
19154   }
19155   else
19156   {
19157     satIntIo->satIntTiScsiXchg.sglVirtualAddr = agNULL;
19158 
19159     satIntIo->satIntTiScsiXchg.agSgl1.len   = 0;
19160     satIntIo->satIntTiScsiXchg.agSgl1.lower = 0;
19161     satIntIo->satIntTiScsiXchg.agSgl1.upper = 0;
19162     satIntIo->satIntTiScsiXchg.agSgl1.type  = tiSgl;
19163 
19164     satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19165   }
19166 
19167   TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
19168 
19169   TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
19170 
19171   TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
19172 
19173   TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
19174     TI_DBG5(("satAllocIntIoResource: return satIntIo %p\n", satIntIo));
19175   return  satIntIo;
19176 
19177 }
19178 
19179 /*****************************************************************************/
19180 /*! \brief  Free resource for SAT intervally generated I/O.
19181  *
19182  *  Free resource for SAT intervally generated I/O that was previously
19183  *  allocated in satAllocIntIoResource().
19184  *
19185  *  \param   tiRoot:      Pointer to TISA driver/port instance.
19186  *  \param   satDevData:  Pointer to SAT specific device data.
19187  *  \param   satIntIo:    Pointer to context for SAT internal I/O that was
19188  *                        previously allocated in satAllocIntIoResource().
19189  *
19190  *  \return  None
19191  */
19192 /*****************************************************************************/
19193 GLOBAL void  satFreeIntIoResource(
19194                     tiRoot_t              *tiRoot,
19195                     satDeviceData_t       *satDevData,
19196                     satInternalIo_t       *satIntIo)
19197 {
19198   TI_DBG6(("satFreeIntIoResource: start\n"));
19199 
19200   if (satIntIo == agNULL)
19201   {
19202     TI_DBG6(("satFreeIntIoResource: allowed call\n"));
19203     return;
19204   }
19205 
19206   /* sets the original tiIOrequest to agNULL for internally generated ATA cmnd */
19207   satIntIo->satOrgTiIORequest = agNULL;
19208 
19209   /*
19210    * Free DMA memory if previosly alocated
19211    */
19212   if (satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength != 0)
19213   {
19214     TI_DBG1(("satFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
19215     TI_DBG6(("satFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
19216 
19217     ostiFreeMemory( tiRoot,
19218                     satIntIo->satIntDmaMem.osHandle,
19219                     satIntIo->satIntDmaMem.totalLength);
19220     satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19221   }
19222 
19223   if (satIntIo->satIntReqBodyMem.totalLength != 0)
19224   {
19225     TI_DBG1(("satFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
19226     /*
19227      * Free mem allocated for Req body
19228      */
19229     ostiFreeMemory( tiRoot,
19230                     satIntIo->satIntReqBodyMem.osHandle,
19231                     satIntIo->satIntReqBodyMem.totalLength);
19232 
19233     satIntIo->satIntReqBodyMem.totalLength = 0;
19234   }
19235 
19236   TI_DBG6(("satFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19237   /*
19238    * Return satIntIo to the free list
19239    */
19240   tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19241   TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
19242   TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
19243   tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19244 
19245 }
19246 
19247 
19248 /*****************************************************************************/
19249 /*! \brief SAT implementation for SCSI INQUIRY.
19250  *
19251  *  SAT implementation for SCSI INQUIRY.
19252  *  This function sends ATA Identify Device data command for SCSI INQUIRY
19253  *
19254  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
19255  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
19256  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
19257  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
19258  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19259  *
19260  *  \return If command is started successfully
19261  *    - \e tiSuccess:     I/O request successfully initiated.
19262  *    - \e tiBusy:        No resources available, try again later.
19263  *    - \e tiIONoDevice:  Invalid device handle.
19264  *    - \e tiError:       Other errors.
19265  */
19266 /*****************************************************************************/
19267 GLOBAL bit32  satSendIDDev(
19268                            tiRoot_t                  *tiRoot,
19269                            tiIORequest_t             *tiIORequest,
19270                            tiDeviceHandle_t          *tiDeviceHandle,
19271                            tiScsiInitiatorRequest_t *tiScsiRequest,
19272                            satIOContext_t            *satIOContext)
19273 
19274 {
19275   bit32                     status;
19276   bit32                     agRequestType;
19277   satDeviceData_t           *pSatDevData;
19278   agsaFisRegHostToDevice_t  *fis;
19279 #ifdef  TD_DEBUG_ENABLE
19280   satInternalIo_t           *satIntIoContext;
19281   tdsaDeviceData_t          *oneDeviceData;
19282   tdIORequestBody_t         *tdIORequestBody;
19283 #endif
19284 
19285   pSatDevData   = satIOContext->pSatDevData;
19286   fis           = satIOContext->pFis;
19287 
19288   TI_DBG5(("satSendIDDev: start\n"));
19289 #ifdef  TD_DEBUG_ENABLE
19290   oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
19291 #endif
19292   TI_DBG5(("satSendIDDev: did %d\n", oneDeviceData->id));
19293 
19294 
19295 #ifdef  TD_DEBUG_ENABLE
19296   satIntIoContext = satIOContext->satIntIoContext;
19297   tdIORequestBody = satIntIoContext->satIntRequestBody;
19298 #endif
19299 
19300   TI_DBG5(("satSendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
19301 
19302   fis->h.fisType        = 0x27;                   /* Reg host to device */
19303   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19304   if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
19305       fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
19306   else
19307       fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
19308   fis->h.features       = 0;                      /* FIS reserve */
19309   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
19310   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19311   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19312   fis->d.device         = 0;                      /* FIS LBA mode  */
19313   fis->d.lbaLowExp      = 0;
19314   fis->d.lbaMidExp      = 0;
19315   fis->d.lbaHighExp     = 0;
19316   fis->d.featuresExp    = 0;
19317   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
19318   fis->d.sectorCountExp = 0;
19319   fis->d.reserved4      = 0;
19320   fis->d.control        = 0;                      /* FIS HOB bit clear */
19321   fis->d.reserved5      = 0;
19322 
19323   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19324 
19325   /* Initialize CB for SATA completion.
19326    */
19327   satIOContext->satCompleteCB = &satInquiryCB;
19328 
19329   /*
19330    * Prepare SGL and send FIS to LL layer.
19331    */
19332   satIOContext->reqType = agRequestType;       /* Save it */
19333 
19334 #ifdef TD_INTERNAL_DEBUG
19335   tdhexdump("satSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19336 #ifdef  TD_DEBUG_ENABLE
19337   tdhexdump("satSendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19338 #endif
19339 #endif
19340 
19341   status = sataLLIOStart( tiRoot,
19342                           tiIORequest,
19343                           tiDeviceHandle,
19344                           tiScsiRequest,
19345                           satIOContext);
19346 
19347   TI_DBG6(("satSendIDDev: end status %d\n", status));
19348   return status;
19349 }
19350 
19351 
19352 /*****************************************************************************/
19353 /*! \brief SAT implementation for SCSI INQUIRY.
19354  *
19355  *  SAT implementation for SCSI INQUIRY.
19356  *  This function prepares TD layer internal resource to send ATA
19357  *  Identify Device data command for SCSI INQUIRY
19358  *
19359  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
19360  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
19361  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
19362  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
19363  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19364  *
19365  *  \return If command is started successfully
19366  *    - \e tiSuccess:     I/O request successfully initiated.
19367  *    - \e tiBusy:        No resources available, try again later.
19368  *    - \e tiIONoDevice:  Invalid device handle.
19369  *    - \e tiError:       Other errors.
19370  */
19371 /*****************************************************************************/
19372 /* prerequsite: tdsaDeviceData and agdevhandle must exist; in other words, LL discovered the device
19373    already */
19374 /*
19375   convert OS generated IO to TD generated IO due to difference in sgl
19376 */
19377 GLOBAL bit32  satStartIDDev(
19378                                tiRoot_t                  *tiRoot,
19379                                tiIORequest_t             *tiIORequest,
19380                                tiDeviceHandle_t          *tiDeviceHandle,
19381                                tiScsiInitiatorRequest_t *tiScsiRequest,
19382                                satIOContext_t            *satIOContext
19383                             )
19384 {
19385   satInternalIo_t           *satIntIo = agNULL;
19386   satDeviceData_t           *satDevData = agNULL;
19387   tdIORequestBody_t         *tdIORequestBody;
19388   satIOContext_t            *satNewIOContext;
19389   bit32                     status;
19390 
19391   TI_DBG6(("satStartIDDev: start\n"));
19392 
19393   satDevData = satIOContext->pSatDevData;
19394 
19395   TI_DBG6(("satStartIDDev: before alloc\n"));
19396 
19397   /* allocate identify device command */
19398   satIntIo = satAllocIntIoResource( tiRoot,
19399                                     tiIORequest,
19400                                     satDevData,
19401                                     sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
19402                                     satIntIo);
19403 
19404   TI_DBG6(("satStartIDDev: before after\n"));
19405 
19406   if (satIntIo == agNULL)
19407   {
19408     TI_DBG1(("satStartIDDev: can't alloacate\n"));
19409 
19410 #if 0
19411     ostiInitiatorIOCompleted (
19412                               tiRoot,
19413                               tiIORequest,
19414                               tiIOFailed,
19415                               tiDetailOtherError,
19416                               agNULL,
19417                               satIOContext->interruptContext
19418                               );
19419 #endif
19420 
19421     return tiError;
19422   }
19423 
19424   /* fill in fields */
19425   /* real ttttttthe one worked and the same; 5/21/07/ */
19426   satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
19427   tdIORequestBody = satIntIo->satIntRequestBody;
19428   satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
19429 
19430   satNewIOContext->pSatDevData   = satDevData;
19431   satNewIOContext->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
19432   satNewIOContext->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
19433   satNewIOContext->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
19434   satNewIOContext->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
19435   satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
19436   satNewIOContext->interruptContext = tiInterruptContext;
19437   satNewIOContext->satIntIoContext  = satIntIo;
19438 
19439   satNewIOContext->ptiDeviceHandle = agNULL;
19440   satNewIOContext->satOrgIOContext = satIOContext; /* changed */
19441 
19442   /* this is valid only for TD layer generated (not triggered by OS at all) IO */
19443   satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
19444 
19445 
19446   TI_DBG6(("satStartIDDev: OS satIOContext %p \n", satIOContext));
19447   TI_DBG6(("satStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
19448   TI_DBG6(("satStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
19449   TI_DBG6(("satStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
19450 
19451 
19452 
19453   TI_DBG1(("satStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
19454 
19455   status = satSendIDDev( tiRoot,
19456                          &satIntIo->satIntTiIORequest, /* New tiIORequest */
19457                          tiDeviceHandle,
19458                          satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
19459                          satNewIOContext);
19460 
19461   if (status != tiSuccess)
19462   {
19463     TI_DBG1(("satStartIDDev: failed in sending\n"));
19464 
19465     satFreeIntIoResource( tiRoot,
19466                           satDevData,
19467                           satIntIo);
19468 
19469 #if 0
19470     ostiInitiatorIOCompleted (
19471                               tiRoot,
19472                               tiIORequest,
19473                               tiIOFailed,
19474                               tiDetailOtherError,
19475                               agNULL,
19476                               satIOContext->interruptContext
19477                               );
19478 #endif
19479 
19480     return tiError;
19481   }
19482 
19483 
19484   TI_DBG6(("satStartIDDev: end\n"));
19485 
19486   return status;
19487 
19488 
19489 }
19490 
19491 /*****************************************************************************/
19492 /*! \brief satComputeCDB10LBA.
19493  *
19494  *  This fuctions computes LBA of CDB10.
19495  *
19496  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19497  *
19498  *  \return
19499  *    - \e LBA
19500  */
19501 /*****************************************************************************/
19502 bit32 satComputeCDB10LBA(satIOContext_t            *satIOContext)
19503 {
19504   tiIniScsiCmnd_t           *scsiCmnd;
19505   tiScsiInitiatorRequest_t *tiScsiRequest;
19506   bit32                     lba = 0;
19507 
19508   TI_DBG5(("satComputeCDB10LBA: start\n"));
19509   tiScsiRequest = satIOContext->tiScsiXchg;
19510   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19511 
19512   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19513     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19514 
19515   return lba;
19516 }
19517 
19518 /*****************************************************************************/
19519 /*! \brief satComputeCDB10TL.
19520  *
19521  *  This fuctions computes transfer length of CDB10.
19522  *
19523  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19524  *
19525  *  \return
19526  *    - \e TL
19527  */
19528 /*****************************************************************************/
19529 bit32 satComputeCDB10TL(satIOContext_t            *satIOContext)
19530 {
19531 
19532   tiIniScsiCmnd_t           *scsiCmnd;
19533   tiScsiInitiatorRequest_t *tiScsiRequest;
19534   bit32                     tl = 0;
19535 
19536   TI_DBG5(("satComputeCDB10TL: start\n"));
19537   tiScsiRequest = satIOContext->tiScsiXchg;
19538   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19539 
19540   tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
19541   return tl;
19542 }
19543 
19544 /*****************************************************************************/
19545 /*! \brief satComputeCDB12LBA.
19546  *
19547  *  This fuctions computes LBA of CDB12.
19548  *
19549  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19550  *
19551  *  \return
19552  *    - \e LBA
19553  */
19554 /*****************************************************************************/
19555 bit32 satComputeCDB12LBA(satIOContext_t            *satIOContext)
19556 {
19557   tiIniScsiCmnd_t           *scsiCmnd;
19558   tiScsiInitiatorRequest_t *tiScsiRequest;
19559   bit32                     lba = 0;
19560 
19561   TI_DBG5(("satComputeCDB10LBA: start\n"));
19562   tiScsiRequest = satIOContext->tiScsiXchg;
19563   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19564 
19565   lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19566     + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19567 
19568   return lba;
19569 }
19570 
19571 /*****************************************************************************/
19572 /*! \brief satComputeCDB12TL.
19573  *
19574  *  This fuctions computes transfer length of CDB12.
19575  *
19576  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19577  *
19578  *  \return
19579  *    - \e TL
19580  */
19581 /*****************************************************************************/
19582 bit32 satComputeCDB12TL(satIOContext_t            *satIOContext)
19583 {
19584 
19585   tiIniScsiCmnd_t           *scsiCmnd;
19586   tiScsiInitiatorRequest_t *tiScsiRequest;
19587   bit32                     tl = 0;
19588 
19589   TI_DBG5(("satComputeCDB10TL: start\n"));
19590   tiScsiRequest = satIOContext->tiScsiXchg;
19591   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19592 
19593   tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19594     + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19595   return tl;
19596 }
19597 
19598 
19599 /*****************************************************************************/
19600 /*! \brief satComputeCDB16LBA.
19601  *
19602  *  This fuctions computes LBA of CDB16.
19603  *
19604  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19605  *
19606  *  \return
19607  *    - \e LBA
19608  */
19609 /*****************************************************************************/
19610 /*
19611   CBD16 has bit64 LBA
19612   But it has to be less than (2^28 - 1)
19613   Therefore, use last four bytes to compute LBA is OK
19614 */
19615 bit32 satComputeCDB16LBA(satIOContext_t            *satIOContext)
19616 {
19617   tiIniScsiCmnd_t           *scsiCmnd;
19618   tiScsiInitiatorRequest_t *tiScsiRequest;
19619   bit32                     lba = 0;
19620 
19621   TI_DBG5(("satComputeCDB10LBA: start\n"));
19622   tiScsiRequest = satIOContext->tiScsiXchg;
19623   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19624 
19625   lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19626     + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19627 
19628   return lba;
19629 }
19630 
19631 /*****************************************************************************/
19632 /*! \brief satComputeCDB16TL.
19633  *
19634  *  This fuctions computes transfer length of CDB16.
19635  *
19636  *  \param   satIOContext_t:   Pointer to the SAT IO Context
19637  *
19638  *  \return
19639  *    - \e TL
19640  */
19641 /*****************************************************************************/
19642 bit32 satComputeCDB16TL(satIOContext_t            *satIOContext)
19643 {
19644 
19645   tiIniScsiCmnd_t           *scsiCmnd;
19646   tiScsiInitiatorRequest_t *tiScsiRequest;
19647   bit32                     tl = 0;
19648 
19649   TI_DBG5(("satComputeCDB10TL: start\n"));
19650   tiScsiRequest = satIOContext->tiScsiXchg;
19651   scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19652 
19653   tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
19654     + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
19655   return tl;
19656 }
19657 
19658 /*****************************************************************************/
19659 /*! \brief satComputeLoopNum.
19660  *
19661  *  This fuctions computes the number of interation needed for a transfer
19662  *  length with a specific number.
19663  *
19664  *  \param   a:   a numerator
19665  *  \param   b:   a denominator
19666  *
19667  *  \return
19668  *    - \e number of interation
19669  */
19670 /*****************************************************************************/
19671 /*
19672   (tl, denom)
19673   tl can be upto bit32 because CDB16 has bit32 tl
19674   Therefore, fine
19675   either (tl, 0xFF) or (tl, 0xFFFF)
19676 */
19677 bit32 satComputeLoopNum(bit32 a, bit32 b)
19678 {
19679 
19680   bit32 quo = 0, rem = 0;
19681   bit32 LoopNum = 0;
19682 
19683   TI_DBG5(("satComputeLoopNum: start\n"));
19684 
19685   quo = a/b;
19686 
19687   if (quo == 0)
19688   {
19689     LoopNum = 1;
19690   }
19691   else
19692   {
19693     rem = a % b;
19694     if (rem == 0)
19695     {
19696       LoopNum = quo;
19697     }
19698     else
19699     {
19700       LoopNum = quo + 1;
19701     }
19702   }
19703 
19704   return LoopNum;
19705 }
19706 
19707 /*****************************************************************************/
19708 /*! \brief satAddNComparebit64.
19709  *
19710  *
19711  *
19712  *
19713  *  \param   a:   lba
19714  *  \param   b:   tl
19715  *
19716  *  \return
19717  *    - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19718  *    - \e FALSE otherwise
19719  *  \note: a and b must be in the same length
19720  */
19721 /*****************************************************************************/
19722 /*
19723   input: bit8 a[8], bit8 b[8] (lba, tl) must be in same length
19724   if (lba + tl > SAT_TR_LBA_LIMIT)
19725   then returns true
19726   else returns false
19727   (LBA,TL)
19728 */
19729 bit32 satAddNComparebit64(bit8 *a, bit8 *b)
19730 {
19731   bit16 ans[8];       // 0 MSB, 8 LSB
19732   bit8  final_ans[9]; // 0 MSB, 9 LSB
19733   bit8  max[9];
19734   int i;
19735 
19736   TI_DBG5(("satAddNComparebit64: start\n"));
19737 
19738   osti_memset(ans, 0, sizeof(ans));
19739   osti_memset(final_ans, 0, sizeof(final_ans));
19740   osti_memset(max, 0, sizeof(max));
19741 
19742   max[0] = 0x1; //max = 0x1 0000 0000 0000 0000
19743 
19744   // adding from LSB to MSB
19745   for(i=7;i>=0;i--)
19746   {
19747     ans[i] = (bit16)(a[i] + b[i]);
19748     if (i != 7)
19749     {
19750       ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19751     }
19752   }
19753 
19754   /*
19755     filling in the final answer
19756    */
19757   final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19758   final_ans[1] = (bit8)(ans[0] & 0xFF);
19759 
19760   for(i=2;i<=8;i++)
19761   {
19762     final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19763   }
19764 
19765   //compare final_ans to max
19766   for(i=0;i<=8;i++)
19767   {
19768     if (final_ans[i] > max[i])
19769     {
19770       TI_DBG5(("satAddNComparebit64: yes at %d\n", i));
19771       return agTRUE;
19772     }
19773     else if (final_ans[i] < max[i])
19774     {
19775       TI_DBG5(("satAddNComparebit64: no at %d\n", i));
19776       return agFALSE;
19777     }
19778     else
19779     {
19780       continue;
19781     }
19782   }
19783 
19784 
19785   return agFALSE;
19786 }
19787 
19788 /*****************************************************************************/
19789 /*! \brief satAddNComparebit32.
19790  *
19791  *
19792  *
19793  *
19794  *  \param   a:   lba
19795  *  \param   b:   tl
19796  *
19797  *  \return
19798  *    - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19799  *    - \e FALSE otherwise
19800  *  \note: a and b must be in the same length
19801  */
19802 /*****************************************************************************/
19803 /*
19804   input: bit8 a[4], bit8 b[4] (lba, tl) must be in same length
19805   if (lba + tl > SAT_TR_LBA_LIMIT)
19806   then returns true
19807   else returns false
19808   (LBA,TL)
19809 */
19810 bit32 satAddNComparebit32(bit8 *a, bit8 *b)
19811 {
19812   bit16 ans[4];       // 0 MSB, 4 LSB
19813   bit8  final_ans[5]; // 0 MSB, 5 LSB
19814   bit8   max[4];
19815   int i;
19816 
19817   TI_DBG5(("satAddNComparebit32: start\n"));
19818 
19819   osti_memset(ans, 0, sizeof(ans));
19820   osti_memset(final_ans, 0, sizeof(final_ans));
19821   osti_memset(max, 0, sizeof(max));
19822 
19823   max[0] = 0x10; // max =0x1000 0000
19824 
19825   // adding from LSB to MSB
19826   for(i=3;i>=0;i--)
19827   {
19828     ans[i] = (bit16)(a[i] + b[i]);
19829     if (i != 3)
19830     {
19831       ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19832     }
19833   }
19834 
19835 
19836   /*
19837     filling in the final answer
19838    */
19839   final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19840   final_ans[1] = (bit8)(ans[0] & 0xFF);
19841 
19842   for(i=2;i<=4;i++)
19843   {
19844     final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19845   }
19846 
19847   //compare final_ans to max
19848   if (final_ans[0] != 0)
19849   {
19850     TI_DBG5(("satAddNComparebit32: yes bigger and out of range\n"));
19851     return agTRUE;
19852   }
19853   for(i=1;i<=4;i++)
19854   {
19855     if (final_ans[i] > max[i-1])
19856     {
19857       TI_DBG5(("satAddNComparebit32: yes at %d\n", i));
19858       return agTRUE;
19859     }
19860     else if (final_ans[i] < max[i-1])
19861     {
19862       TI_DBG5(("satAddNComparebit32: no at %d\n", i));
19863       return agFALSE;
19864     }
19865     else
19866     {
19867       continue;
19868     }
19869   }
19870 
19871 
19872   return agFALSE;;
19873 }
19874 
19875 /*****************************************************************************/
19876 /*! \brief satCompareLBALimitbit.
19877  *
19878  *
19879  *
19880  *
19881  *  \param   lba:   lba
19882  *
19883  *  \return
19884  *    - \e TRUE if (lba > SAT_TR_LBA_LIMIT - 1)
19885  *    - \e FALSE otherwise
19886  *  \note: a and b must be in the same length
19887  */
19888 /*****************************************************************************/
19889 
19890 /*
19891   lba
19892 */
19893 /*
19894   input: bit8 lba[8]
19895   if (lba > SAT_TR_LBA_LIMIT - 1)
19896   then returns true
19897   else returns false
19898   (LBA,TL)
19899 */
19900 bit32 satCompareLBALimitbit(bit8 *lba)
19901 {
19902   bit32 i;
19903   bit8 limit[8];
19904 
19905   /* limit is 0xF FF FF = 2^28 - 1 */
19906   limit[0] = 0x0;   /* MSB */
19907   limit[1] = 0x0;
19908   limit[2] = 0x0;
19909   limit[3] = 0x0;
19910   limit[4] = 0xF;
19911   limit[5] = 0xFF;
19912   limit[6] = 0xFF;
19913   limit[7] = 0xFF; /* LSB */
19914 
19915   //compare lba to limit
19916   for(i=0;i<8;i++)
19917   {
19918     if (lba[i] > limit[i])
19919     {
19920       TI_DBG5(("satCompareLBALimitbit64: yes at %d\n", i));
19921       return agTRUE;
19922     }
19923     else if (lba[i] < limit[i])
19924     {
19925       TI_DBG5(("satCompareLBALimitbit64: no at %d\n", i));
19926       return agFALSE;
19927     }
19928     else
19929     {
19930       continue;
19931     }
19932   }
19933 
19934 
19935   return agFALSE;
19936 
19937 }
19938 /*****************************************************************************
19939 *! \brief
19940 *  Purpose: bitwise set
19941 *
19942 *  Parameters:
19943 *   data        - input output buffer
19944 *   index       - bit to set
19945 *
19946 *  Return:
19947 *   none
19948 *
19949 *****************************************************************************/
19950 GLOBAL void
19951 satBitSet(bit8 *data, bit32 index)
19952 {
19953   data[index/8] |= (1 << (index%8));
19954 }
19955 
19956 /*****************************************************************************
19957 *! \brief
19958 *  Purpose: bitwise clear
19959 *
19960 *  Parameters:
19961 *   data        - input output buffer
19962 *   index       - bit to clear
19963 *
19964 *  Return:
19965 *   none
19966 *
19967 *****************************************************************************/
19968 GLOBAL void
19969 satBitClear(bit8 *data, bit32 index)
19970 {
19971   data[index/8] &= ~(1 << (index%8));
19972 }
19973 
19974 /*****************************************************************************
19975 *! \brief
19976 *  Purpose: bitwise test
19977 *
19978 *  Parameters:
19979 *   data        - input output buffer
19980 *   index       - bit to test
19981 *
19982 *  Return:
19983 *   0 - not set
19984 *   1 - set
19985 *
19986 *****************************************************************************/
19987 GLOBAL agBOOLEAN
19988 satBitTest(bit8 *data, bit32 index)
19989 {
19990   return ( (BOOLEAN)((data[index/8] & (1 << (index%8)) ) ? 1: 0));
19991 }
19992 
19993 
19994 /******************************************************************************/
19995 /*! \brief allocate an available SATA tag
19996  *
19997  *  allocate an available SATA tag
19998  *
19999  *  \param tiRoot           Pointer to TISA initiator driver/port instance.
20000  *  \param pSatDevData
20001  *  \param pTag
20002  *
20003  *  \return -Success or fail-
20004  */
20005 /*******************************************************************************/
20006 GLOBAL bit32 satTagAlloc(
20007                            tiRoot_t          *tiRoot,
20008                            satDeviceData_t   *pSatDevData,
20009                            bit8              *pTag
20010                            )
20011 {
20012   bit32             retCode = agFALSE;
20013   bit32             i;
20014 
20015   tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20016   for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
20017   {
20018     if ( 0 == satBitTest((bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
20019     {
20020       satBitSet((bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20021       *pTag = (bit8) i;
20022       retCode = agTRUE;
20023       break;
20024     }
20025   }
20026   tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20027   return retCode;
20028 }
20029 
20030 /******************************************************************************/
20031 /*! \brief release an SATA tag
20032  *
20033  *  release an available SATA tag
20034  *
20035  *  \param tiRoot           Pointer to TISA initiator driver/port instance.
20036  *  \param pSatDevData
20037  *  \param Tag
20038  *
20039  *  \return -the tag-
20040  */
20041 /*******************************************************************************/
20042 GLOBAL bit32 satTagRelease(
20043                               tiRoot_t          *tiRoot,
20044                               satDeviceData_t   *pSatDevData,
20045                               bit8              tag
20046                               )
20047 {
20048   bit32             retCode = agFALSE;
20049 
20050   tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20051   if ( tag < pSatDevData->satNCQMaxIO )
20052   {
20053     satBitClear( (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
20054     retCode = agTRUE;
20055   }
20056   tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20057   return retCode;
20058 }
20059 
20060 /*****************************************************************************
20061  *! \brief  satSubTM
20062  *
20063  *   This routine is called to initiate a TM request to SATL.
20064  *   This routine is independent of HW/LL API.
20065  *
20066  *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
20067  *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20068  *  \param  task:             SAM-3 task management request.
20069  *  \param  lun:              Pointer to LUN.
20070  *  \param  taskTag:          Pointer to the associated task where the TM
20071  *                            command is to be applied.
20072  *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
20073  *  \param  NotifyOS          flag determines whether notify OS layer or not
20074  *
20075  *  \return:
20076  *
20077  *  \e tiSuccess:     I/O request successfully initiated.
20078  *  \e tiBusy:        No resources available, try again later.
20079  *  \e tiIONoDevice:  Invalid device handle.
20080  *  \e tiError:       Other errors that prevent the I/O request to be started.
20081  *
20082  *  \note:
20083  *        This funcion is triggered bottom up. Not yet in use.
20084  *****************************************************************************/
20085 /* called for bottom up */
20086 osGLOBAL bit32 satSubTM(
20087                         tiRoot_t          *tiRoot,
20088                         tiDeviceHandle_t  *tiDeviceHandle,
20089                         bit32             task,
20090                         tiLUN_t           *lun,
20091                         tiIORequest_t     *taskTag,
20092                         tiIORequest_t     *currentTaskTag,
20093                         bit32              NotifyOS
20094                         )
20095 {
20096   void                        *osMemHandle;
20097   tdIORequestBody_t           *TMtdIORequestBody;
20098   bit32                       PhysUpper32;
20099   bit32                       PhysLower32;
20100   bit32                       memAllocStatus;
20101   agsaIORequest_t             *agIORequest = agNULL;
20102 
20103   TI_DBG6(("satSubTM: start\n"));
20104 
20105   /* allocation tdIORequestBody and pass it to satTM() */
20106   memAllocStatus = ostiAllocMemory(
20107                                    tiRoot,
20108                                    &osMemHandle,
20109                                    (void **)&TMtdIORequestBody,
20110                                    &PhysUpper32,
20111                                    &PhysLower32,
20112                                    8,
20113                                    sizeof(tdIORequestBody_t),
20114                                    agTRUE
20115                                    );
20116 
20117   if (memAllocStatus != tiSuccess)
20118   {
20119     TI_DBG1(("satSubTM: ostiAllocMemory failed... \n"));
20120     return tiError;
20121   }
20122 
20123   if (TMtdIORequestBody == agNULL)
20124   {
20125     TI_DBG1(("satSubTM: ostiAllocMemory returned NULL TMIORequestBody\n"));
20126     return tiError;
20127    }
20128 
20129   /* setup task management structure */
20130   TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
20131   TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
20132   TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
20133 
20134   /* initialize tiDevhandle */
20135   TMtdIORequestBody->tiDevHandle = tiDeviceHandle;
20136 
20137   /* initialize tiIORequest */
20138   TMtdIORequestBody->tiIORequest = agNULL;
20139 
20140   /* initialize agIORequest */
20141   agIORequest = &(TMtdIORequestBody->agIORequest);
20142   agIORequest->osData = (void *) TMtdIORequestBody;
20143   agIORequest->sdkData = agNULL; /* SA takes care of this */
20144   satTM(tiRoot,
20145         tiDeviceHandle,
20146         task, /* TD_INTERNAL_TM_RESET */
20147         agNULL,
20148         agNULL,
20149         agNULL,
20150         TMtdIORequestBody,
20151         agFALSE);
20152 
20153   return tiSuccess;
20154 }
20155 
20156 
20157 /*****************************************************************************/
20158 /*! \brief SAT implementation for satStartResetDevice.
20159  *
20160  *  SAT implementation for sending SRT and send FIS request to LL layer.
20161  *
20162  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20163  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20164  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20165  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20166  *  \param   satIOContext_t:   Pointer to the SAT IO Context
20167  *
20168  *  \return If command is started successfully
20169  *    - \e tiSuccess:     I/O request successfully initiated.
20170  *    - \e tiBusy:        No resources available, try again later.
20171  *    - \e tiIONoDevice:  Invalid device handle.
20172  *    - \e tiError:       Other errors.
20173  *  \note : triggerred by OS layer or bottom up
20174  */
20175 /*****************************************************************************/
20176 /* OS triggerred or bottom up */
20177 GLOBAL bit32
20178 satStartResetDevice(
20179                             tiRoot_t                  *tiRoot,
20180                             tiIORequest_t             *tiIORequest, /* currentTaskTag */
20181                             tiDeviceHandle_t          *tiDeviceHandle,
20182                             tiScsiInitiatorRequest_t *tiScsiRequest, /* should be NULL */
20183                             satIOContext_t            *satIOContext
20184                             )
20185 {
20186   satInternalIo_t           *satIntIo = agNULL;
20187   satDeviceData_t           *satDevData = agNULL;
20188   satIOContext_t            *satNewIOContext;
20189   bit32                     status;
20190   tiIORequest_t             *currentTaskTag = agNULL;
20191 
20192   TI_DBG1(("satStartResetDevice: start\n"));
20193 
20194   currentTaskTag = tiIORequest;
20195 
20196   satDevData = satIOContext->pSatDevData;
20197 
20198   TI_DBG6(("satStartResetDevice: before alloc\n"));
20199 
20200   /* allocate any fis for seting SRT bit in device control */
20201   satIntIo = satAllocIntIoResource( tiRoot,
20202                                     tiIORequest,
20203                                     satDevData,
20204                                     0,
20205                                     satIntIo);
20206 
20207   TI_DBG6(("satStartResetDevice: before after\n"));
20208 
20209   if (satIntIo == agNULL)
20210   {
20211     TI_DBG1(("satStartResetDevice: can't alloacate\n"));
20212     if (satIOContext->NotifyOS)
20213     {
20214       ostiInitiatorEvent( tiRoot,
20215                           NULL,
20216                           NULL,
20217                           tiIntrEventTypeTaskManagement,
20218                           tiTMFailed,
20219                           currentTaskTag );
20220     }
20221     return tiError;
20222   }
20223 
20224   satNewIOContext = satPrepareNewIO(satIntIo,
20225                                     tiIORequest,
20226                                     satDevData,
20227                                     agNULL,
20228                                     satIOContext);
20229 
20230   TI_DBG6(("satStartResetDevice: OS satIOContext %p \n", satIOContext));
20231   TI_DBG6(("satStartResetDevice: TD satNewIOContext %p \n", satNewIOContext));
20232   TI_DBG6(("satStartResetDevice: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
20233   TI_DBG6(("satStartResetDevice: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
20234 
20235 
20236 
20237   TI_DBG6(("satStartResetDevice: satNewIOContext %p \n", satNewIOContext));
20238 
20239   if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
20240   {
20241     status = satDeviceReset(tiRoot,
20242                           &satIntIo->satIntTiIORequest, /* New tiIORequest */
20243                           tiDeviceHandle,
20244                           satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20245                           satNewIOContext);
20246   }
20247   else
20248   {
20249     status = satResetDevice(tiRoot,
20250                           &satIntIo->satIntTiIORequest, /* New tiIORequest */
20251                           tiDeviceHandle,
20252                           satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20253                           satNewIOContext);
20254   }
20255 
20256   if (status != tiSuccess)
20257   {
20258     TI_DBG1(("satStartResetDevice: failed in sending\n"));
20259 
20260     satFreeIntIoResource( tiRoot,
20261                           satDevData,
20262                           satIntIo);
20263     if (satIOContext->NotifyOS)
20264     {
20265       ostiInitiatorEvent( tiRoot,
20266                           NULL,
20267                           NULL,
20268                           tiIntrEventTypeTaskManagement,
20269                           tiTMFailed,
20270                           currentTaskTag );
20271     }
20272 
20273     return tiError;
20274   }
20275 
20276 
20277   TI_DBG6(("satStartResetDevice: end\n"));
20278 
20279   return status;
20280 }
20281 
20282 /*****************************************************************************/
20283 /*! \brief SAT implementation for satResetDevice.
20284  *
20285  *  SAT implementation for building SRT FIS and sends the request to LL layer.
20286  *
20287  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20288  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20289  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20290  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20291  *  \param   satIOContext_t:   Pointer to the SAT IO Context
20292  *
20293  *  \return If command is started successfully
20294  *    - \e tiSuccess:     I/O request successfully initiated.
20295  *    - \e tiBusy:        No resources available, try again later.
20296  *    - \e tiIONoDevice:  Invalid device handle.
20297  *    - \e tiError:       Other errors.
20298  */
20299 /*****************************************************************************/
20300 
20301 /*
20302   create any fis and set SRST bit in device control
20303 */
20304 GLOBAL bit32
20305 satResetDevice(
20306                             tiRoot_t                  *tiRoot,
20307                             tiIORequest_t             *tiIORequest,
20308                             tiDeviceHandle_t          *tiDeviceHandle,
20309                             tiScsiInitiatorRequest_t *tiScsiRequest,
20310                             satIOContext_t            *satIOContext
20311                             )
20312 {
20313   bit32                     status;
20314   bit32                     agRequestType;
20315   agsaFisRegHostToDevice_t  *fis;
20316 #ifdef  TD_DEBUG_ENABLE
20317   tdIORequestBody_t         *tdIORequestBody;
20318   satInternalIo_t           *satIntIoContext;
20319 #endif
20320 
20321   fis           = satIOContext->pFis;
20322 
20323   TI_DBG2(("satResetDevice: start\n"));
20324 
20325 #ifdef  TD_DEBUG_ENABLE
20326   satIntIoContext = satIOContext->satIntIoContext;
20327   tdIORequestBody = satIntIoContext->satIntRequestBody;
20328 #endif
20329   TI_DBG5(("satResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20330   /* any fis should work */
20331   fis->h.fisType        = 0x27;                   /* Reg host to device */
20332   fis->h.c_pmPort       = 0;                      /* C Bit is not set */
20333   fis->h.command        = 0;                      /* any command */
20334   fis->h.features       = 0;                      /* FIS reserve */
20335   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
20336   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
20337   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
20338   fis->d.device         = 0;                      /* FIS LBA mode  */
20339   fis->d.lbaLowExp      = 0;
20340   fis->d.lbaMidExp      = 0;
20341   fis->d.lbaHighExp     = 0;
20342   fis->d.featuresExp    = 0;
20343   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
20344   fis->d.sectorCountExp = 0;
20345   fis->d.reserved4      = 0;
20346   fis->d.control        = 0x4;                    /* SRST bit is set  */
20347   fis->d.reserved5      = 0;
20348 
20349   agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
20350 
20351   satIOContext->satCompleteCB = &satResetDeviceCB;
20352 
20353   /*
20354    * Prepare SGL and send FIS to LL layer.
20355    */
20356   satIOContext->reqType = agRequestType;       /* Save it */
20357 
20358 #ifdef TD_INTERNAL_DEBUG
20359   tdhexdump("satResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20360 #ifdef  TD_DEBUG_ENABLE
20361   tdhexdump("satResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20362 #endif
20363 #endif
20364 
20365   status = sataLLIOStart( tiRoot,
20366                           tiIORequest,
20367                           tiDeviceHandle,
20368                           tiScsiRequest,
20369                           satIOContext);
20370 
20371   TI_DBG6(("satResetDevice: end status %d\n", status));
20372   return status;
20373 }
20374 
20375 /*****************************************************************************
20376 *! \brief  satResetDeviceCB
20377 *
20378 *   This routine is a callback function called from ossaSATACompleted().
20379 *   This CB routine deals with SRT completion. This function send DSRT
20380 *
20381 *  \param   agRoot:      Handles for this instance of SAS/SATA hardware
20382 *  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
20383 *  \param   agIOStatus:  Status of completed I/O.
20384 *  \param   agFirstDword:Pointer to the four bytes of FIS.
20385 *  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20386 *                        length.
20387 *  \param   agParam:     Additional info based on status.
20388 *  \param   ioContext:   Pointer to satIOContext_t.
20389 *
20390 *  \return: none
20391 *
20392 *****************************************************************************/
20393 GLOBAL void satResetDeviceCB(
20394                    agsaRoot_t        *agRoot,
20395                    agsaIORequest_t   *agIORequest,
20396                    bit32             agIOStatus,
20397                    agsaFisHeader_t   *agFirstDword,
20398                    bit32             agIOInfoLen,
20399                    agsaFrameHandle_t agFrameHandle,
20400                    void              *ioContext
20401                    )
20402 {
20403   /* callback for satResetDevice */
20404   tdsaRootOsData_t   *osData = (tdsaRootOsData_t *)agRoot->osData;
20405   tiRoot_t           *tiRoot = (tiRoot_t *)osData->tiRoot;
20406   tdsaRoot_t         *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
20407   tdsaContext_t      *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20408   tdIORequestBody_t  *tdIORequestBody;
20409   tdIORequestBody_t  *tdOrgIORequestBody;
20410   satIOContext_t     *satIOContext;
20411   satIOContext_t     *satOrgIOContext;
20412   satIOContext_t     *satNewIOContext;
20413   satInternalIo_t    *satIntIo;
20414   satInternalIo_t    *satNewIntIo = agNULL;
20415   satDeviceData_t    *satDevData;
20416   tiIORequest_t      *tiOrgIORequest;
20417 #ifdef  TD_DEBUG_ENABLE
20418   bit32                     ataStatus = 0;
20419   bit32                     ataError;
20420   agsaFisPioSetupHeader_t  *satPIOSetupHeader = agNULL;
20421 #endif
20422   bit32                     status;
20423 
20424   TI_DBG1(("satResetDeviceCB: start\n"));
20425   TI_DBG6(("satResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20426 
20427   tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
20428   satIOContext           = (satIOContext_t *) ioContext;
20429   satIntIo               = satIOContext->satIntIoContext;
20430   satDevData             = satIOContext->pSatDevData;
20431   if (satIntIo == agNULL)
20432   {
20433     TI_DBG6(("satResetDeviceCB: External, OS generated\n"));
20434     satOrgIOContext      = satIOContext;
20435     tiOrgIORequest       = tdIORequestBody->tiIORequest;
20436   }
20437   else
20438   {
20439     TI_DBG6(("satResetDeviceCB: Internal, TD generated\n"));
20440     satOrgIOContext        = satIOContext->satOrgIOContext;
20441     if (satOrgIOContext == agNULL)
20442     {
20443       TI_DBG6(("satResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20444       return;
20445     }
20446     else
20447     {
20448       TI_DBG6(("satResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20449     }
20450     tdOrgIORequestBody    = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20451     tiOrgIORequest        = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20452   }
20453 
20454   tdIORequestBody->ioCompleted = agTRUE;
20455   tdIORequestBody->ioStarted = agFALSE;
20456 
20457   if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20458   {
20459     TI_DBG1(("satResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20460     if (satOrgIOContext->NotifyOS == agTRUE)
20461     {
20462       ostiInitiatorEvent( tiRoot,
20463                           NULL,
20464                           NULL,
20465                           tiIntrEventTypeTaskManagement,
20466                           tiTMFailed,
20467                           tiOrgIORequest );
20468     }
20469 
20470     satDevData->satTmTaskTag = agNULL;
20471 
20472     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20473 
20474     satFreeIntIoResource( tiRoot,
20475                           satDevData,
20476                           satIntIo);
20477     return;
20478   }
20479 
20480   if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20481       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20482       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20483       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20484       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20485       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20486       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20487       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20488       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20489       )
20490   {
20491     TI_DBG1(("satResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20492 
20493     if (satOrgIOContext->NotifyOS == agTRUE)
20494     {
20495       ostiInitiatorEvent( tiRoot,
20496                           NULL,
20497                           NULL,
20498                           tiIntrEventTypeTaskManagement,
20499                           tiTMFailed,
20500                           tiOrgIORequest );
20501     }
20502 
20503     satDevData->satTmTaskTag = agNULL;
20504 
20505     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20506 
20507     satFreeIntIoResource( tiRoot,
20508                          satDevData,
20509                          satIntIo);
20510     return;
20511   }
20512 
20513  if (agIOStatus != OSSA_IO_SUCCESS)
20514   {
20515 #ifdef  TD_DEBUG_ENABLE
20516     /* only agsaFisPioSetup_t is expected */
20517     satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20518     ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
20519     ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
20520 #endif
20521     TI_DBG1(("satResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20522 
20523      if (satOrgIOContext->NotifyOS == agTRUE)
20524      {
20525       ostiInitiatorEvent( tiRoot,
20526                           NULL,
20527                           NULL,
20528                           tiIntrEventTypeTaskManagement,
20529                           tiTMFailed,
20530                           tiOrgIORequest );
20531      }
20532 
20533     satDevData->satTmTaskTag = agNULL;
20534 
20535     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20536 
20537     satFreeIntIoResource( tiRoot,
20538                           satDevData,
20539                           satIntIo);
20540     return;
20541   }
20542 
20543   /* success */
20544 
20545   satNewIntIo = satAllocIntIoResource( tiRoot,
20546                                        tiOrgIORequest,
20547                                        satDevData,
20548                                        0,
20549                                        satNewIntIo);
20550   if (satNewIntIo == agNULL)
20551   {
20552     satDevData->satTmTaskTag = agNULL;
20553 
20554     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20555 
20556     /* memory allocation failure */
20557     satFreeIntIoResource( tiRoot,
20558                           satDevData,
20559                           satNewIntIo);
20560 
20561     if (satOrgIOContext->NotifyOS == agTRUE)
20562     {
20563       ostiInitiatorEvent( tiRoot,
20564                           NULL,
20565                           NULL,
20566                           tiIntrEventTypeTaskManagement,
20567                           tiTMFailed,
20568                           tiOrgIORequest );
20569     }
20570 
20571 
20572       TI_DBG1(("satResetDeviceCB: momory allocation fails\n"));
20573       return;
20574     } /* end of memory allocation failure */
20575 
20576     /*
20577      * Need to initialize all the fields within satIOContext
20578      */
20579 
20580     satNewIOContext = satPrepareNewIO(
20581                                       satNewIntIo,
20582                                       tiOrgIORequest,
20583                                       satDevData,
20584                                       agNULL,
20585                                       satOrgIOContext
20586                                       );
20587 
20588 
20589 
20590 
20591     /* send AGSA_SATA_PROTOCOL_SRST_DEASSERT */
20592     status = satDeResetDevice(tiRoot,
20593                               tiOrgIORequest,
20594                               satOrgIOContext->ptiDeviceHandle,
20595                               agNULL,
20596                               satNewIOContext
20597                               );
20598 
20599     if (status != tiSuccess)
20600     {
20601       if (satOrgIOContext->NotifyOS == agTRUE)
20602       {
20603         ostiInitiatorEvent( tiRoot,
20604                             NULL,
20605                             NULL,
20606                             tiIntrEventTypeTaskManagement,
20607                             tiTMFailed,
20608                             tiOrgIORequest );
20609       }
20610 
20611       /* sending AGSA_SATA_PROTOCOL_SRST_DEASSERT fails */
20612 
20613       satDevData->satTmTaskTag = agNULL;
20614 
20615       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20616 
20617       satFreeIntIoResource( tiRoot,
20618                           satDevData,
20619                           satNewIntIo);
20620       return;
20621 
20622     }
20623 
20624   satDevData->satTmTaskTag = agNULL;
20625 
20626   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20627 
20628   satFreeIntIoResource( tiRoot,
20629                         satDevData,
20630                         satIntIo);
20631   TI_DBG5(("satResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20632   TI_DBG6(("satResetDeviceCB: end\n"));
20633   return;
20634 
20635 }
20636 
20637 
20638 /*****************************************************************************/
20639 /*! \brief SAT implementation for satDeResetDevice.
20640  *
20641  *  SAT implementation for building DSRT FIS and sends the request to LL layer.
20642  *
20643  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20644  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20645  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20646  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20647  *  \param   satIOContext_t:   Pointer to the SAT IO Context
20648  *
20649  *  \return If command is started successfully
20650  *    - \e tiSuccess:     I/O request successfully initiated.
20651  *    - \e tiBusy:        No resources available, try again later.
20652  *    - \e tiIONoDevice:  Invalid device handle.
20653  *    - \e tiError:       Other errors.
20654  */
20655 /*****************************************************************************/
20656 GLOBAL bit32  satDeResetDevice(
20657                             tiRoot_t                  *tiRoot,
20658                             tiIORequest_t             *tiIORequest,
20659                             tiDeviceHandle_t          *tiDeviceHandle,
20660                             tiScsiInitiatorRequest_t *tiScsiRequest,
20661                             satIOContext_t            *satIOContext
20662                             )
20663 {
20664   bit32                     status;
20665   bit32                     agRequestType;
20666   agsaFisRegHostToDevice_t  *fis;
20667 #ifdef  TD_DEBUG_ENABLE
20668   tdIORequestBody_t         *tdIORequestBody;
20669   satInternalIo_t           *satIntIoContext;
20670 #endif
20671   fis           = satIOContext->pFis;
20672 
20673   TI_DBG6(("satDeResetDevice: start\n"));
20674 
20675 #ifdef  TD_DEBUG_ENABLE
20676   satIntIoContext = satIOContext->satIntIoContext;
20677   tdIORequestBody = satIntIoContext->satIntRequestBody;
20678   TI_DBG5(("satDeResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20679 #endif
20680   /* any fis should work */
20681   fis->h.fisType        = 0x27;                   /* Reg host to device */
20682   fis->h.c_pmPort       = 0;                      /* C Bit is not set */
20683   fis->h.command        = 0;                      /* any command */
20684   fis->h.features       = 0;                      /* FIS reserve */
20685   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
20686   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
20687   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
20688   fis->d.device         = 0;                      /* FIS LBA mode  */
20689   fis->d.lbaLowExp      = 0;
20690   fis->d.lbaMidExp      = 0;
20691   fis->d.lbaHighExp     = 0;
20692   fis->d.featuresExp    = 0;
20693   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
20694   fis->d.sectorCountExp = 0;
20695   fis->d.reserved4      = 0;
20696   fis->d.control        = 0;                    /* SRST bit is not set  */
20697   fis->d.reserved5      = 0;
20698 
20699   agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT;
20700 
20701   satIOContext->satCompleteCB = &satDeResetDeviceCB;
20702 
20703   /*
20704    * Prepare SGL and send FIS to LL layer.
20705    */
20706   satIOContext->reqType = agRequestType;       /* Save it */
20707 
20708 #ifdef TD_INTERNAL_DEBUG
20709   tdhexdump("satDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20710 #ifdef  TD_DEBUG_ENABLE
20711   tdhexdump("satDeResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20712 #endif
20713 #endif
20714 
20715   status = sataLLIOStart( tiRoot,
20716                           tiIORequest,
20717                           tiDeviceHandle,
20718                           tiScsiRequest,
20719                           satIOContext);
20720 
20721   TI_DBG6(("satDeResetDevice: end status %d\n", status));
20722   return status;
20723 
20724 }
20725 
20726 /*****************************************************************************
20727 *! \brief  satDeResetDeviceCB
20728 *
20729 *   This routine is a callback function called from ossaSATACompleted().
20730 *   This CB routine deals with DSRT completion.
20731 *
20732 *  \param   agRoot:      Handles for this instance of SAS/SATA hardware
20733 *  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
20734 *  \param   agIOStatus:  Status of completed I/O.
20735 *  \param   agFirstDword:Pointer to the four bytes of FIS.
20736 *  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20737 *                        length.
20738 *  \param   agParam:     Additional info based on status.
20739 *  \param   ioContext:   Pointer to satIOContext_t.
20740 *
20741 *  \return: none
20742 *
20743 *****************************************************************************/
20744 GLOBAL void satDeResetDeviceCB(
20745                    agsaRoot_t        *agRoot,
20746                    agsaIORequest_t   *agIORequest,
20747                    bit32             agIOStatus,
20748                    agsaFisHeader_t   *agFirstDword,
20749                    bit32             agIOInfoLen,
20750                    agsaFrameHandle_t agFrameHandle,
20751                    void              *ioContext
20752                    )
20753 {
20754   /* callback for satDeResetDevice */
20755   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
20756   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
20757   tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
20758   tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20759   tdIORequestBody_t       *tdIORequestBody;
20760   tdIORequestBody_t       *tdOrgIORequestBody = agNULL;
20761   satIOContext_t          *satIOContext;
20762   satIOContext_t          *satOrgIOContext;
20763   satInternalIo_t         *satIntIo;
20764   satDeviceData_t         *satDevData;
20765   tiIORequest_t           *tiOrgIORequest;
20766 #ifdef  TD_DEBUG_ENABLE
20767   bit32                    ataStatus = 0;
20768   bit32                    ataError;
20769   agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
20770 #endif
20771   bit32                     report = agFALSE;
20772   bit32                     AbortTM = agFALSE;
20773 
20774   TI_DBG1(("satDeResetDeviceCB: start\n"));
20775   TI_DBG6(("satDeResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20776   tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
20777   satIOContext           = (satIOContext_t *) ioContext;
20778   satIntIo               = satIOContext->satIntIoContext;
20779   satDevData             = satIOContext->pSatDevData;
20780   if (satIntIo == agNULL)
20781   {
20782     TI_DBG6(("satDeResetDeviceCB: External, OS generated\n"));
20783     satOrgIOContext      = satIOContext;
20784     tiOrgIORequest       = tdIORequestBody->tiIORequest;
20785   }
20786   else
20787   {
20788     TI_DBG6(("satDeResetDeviceCB: Internal, TD generated\n"));
20789     satOrgIOContext        = satIOContext->satOrgIOContext;
20790     if (satOrgIOContext == agNULL)
20791     {
20792       TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20793       return;
20794     }
20795     else
20796     {
20797       TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20798     }
20799     tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20800     tiOrgIORequest         = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20801   }
20802 
20803   tdIORequestBody->ioCompleted = agTRUE;
20804   tdIORequestBody->ioStarted = agFALSE;
20805 
20806   if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20807   {
20808     TI_DBG1(("satDeResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20809     if (satOrgIOContext->NotifyOS == agTRUE)
20810     {
20811       ostiInitiatorEvent( tiRoot,
20812                           NULL,
20813                           NULL,
20814                           tiIntrEventTypeTaskManagement,
20815                           tiTMFailed,
20816                           tiOrgIORequest );
20817     }
20818 
20819     satDevData->satTmTaskTag = agNULL;
20820     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20821 
20822     satFreeIntIoResource( tiRoot,
20823                           satDevData,
20824                           satIntIo);
20825     return;
20826   }
20827 
20828   if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20829       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20830       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20831       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20832       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20833       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20834       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20835       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20836       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20837       )
20838   {
20839     TI_DBG1(("satDeResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20840 
20841     if (satOrgIOContext->NotifyOS == agTRUE)
20842     {
20843       ostiInitiatorEvent( tiRoot,
20844                           NULL,
20845                           NULL,
20846                           tiIntrEventTypeTaskManagement,
20847                           tiTMFailed,
20848                           tiOrgIORequest );
20849     }
20850 
20851     satDevData->satTmTaskTag = agNULL;
20852 
20853     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20854 
20855     satFreeIntIoResource( tiRoot,
20856                          satDevData,
20857                          satIntIo);
20858     return;
20859   }
20860 
20861  if (agIOStatus != OSSA_IO_SUCCESS)
20862   {
20863 #ifdef  TD_DEBUG_ENABLE
20864     /* only agsaFisPioSetup_t is expected */
20865     satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20866     ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
20867     ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
20868 #endif
20869     TI_DBG1(("satDeResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20870 
20871      if (satOrgIOContext->NotifyOS == agTRUE)
20872      {
20873       ostiInitiatorEvent( tiRoot,
20874                           NULL,
20875                           NULL,
20876                           tiIntrEventTypeTaskManagement,
20877                           tiTMFailed,
20878                           tiOrgIORequest );
20879      }
20880 
20881     satDevData->satTmTaskTag = agNULL;
20882 
20883     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20884 
20885     satFreeIntIoResource( tiRoot,
20886                           satDevData,
20887                           satIntIo);
20888     return;
20889   }
20890 
20891   /* success */
20892   TI_DBG1(("satDeResetDeviceCB: success \n"));
20893   TI_DBG1(("satDeResetDeviceCB: TMF %d\n", satOrgIOContext->TMF));
20894 
20895   if (satOrgIOContext->TMF == AG_ABORT_TASK)
20896   {
20897     AbortTM = agTRUE;
20898   }
20899 
20900   if (satOrgIOContext->NotifyOS == agTRUE)
20901   {
20902     report = agTRUE;
20903   }
20904 
20905   if (AbortTM == agTRUE)
20906   {
20907     TI_DBG1(("satDeResetDeviceCB: calling satAbort\n"));
20908     satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
20909   }
20910   satDevData->satTmTaskTag = agNULL;
20911 
20912   satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
20913 
20914   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20915 
20916   TI_DBG1(("satDeResetDeviceCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
20917   TI_DBG1(("satDeResetDeviceCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
20918 
20919   satFreeIntIoResource( tiRoot,
20920                         satDevData,
20921                         satIntIo);
20922 
20923   /* clean up TD layer's IORequestBody */
20924   if (tdOrgIORequestBody != agNULL)
20925   {
20926     ostiFreeMemory(
20927                    tiRoot,
20928                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
20929                    sizeof(tdIORequestBody_t)
20930                    );
20931   }
20932   else
20933   {
20934     TI_DBG1(("satDeResetDeviceCB: tdOrgIORequestBody is NULL, wrong\n"));
20935   }
20936 
20937 
20938   if (report)
20939   {
20940     ostiInitiatorEvent( tiRoot,
20941                         NULL,
20942                         NULL,
20943                         tiIntrEventTypeTaskManagement,
20944                         tiTMOK,
20945                         tiOrgIORequest );
20946   }
20947 
20948 
20949   TI_DBG5(("satDeResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20950   TI_DBG6(("satDeResetDeviceCB: end\n"));
20951   return;
20952 
20953 }
20954 
20955 /*****************************************************************************/
20956 /*! \brief SAT implementation for satStartCheckPowerMode.
20957  *
20958  *  SAT implementation for abort task management for non-ncq sata disk.
20959  *  This function sends CHECK POWER MODE
20960  *
20961  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20962  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20963  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20964  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20965  *  \param   satIOContext_t:   Pointer to the SAT IO Context
20966  *
20967  *  \return If command is started successfully
20968  *    - \e tiSuccess:     I/O request successfully initiated.
20969  *    - \e tiBusy:        No resources available, try again later.
20970  *    - \e tiIONoDevice:  Invalid device handle.
20971  *    - \e tiError:       Other errors.
20972  */
20973 /*****************************************************************************/
20974 GLOBAL bit32  satStartCheckPowerMode(
20975                             tiRoot_t                  *tiRoot,
20976                             tiIORequest_t             *tiIORequest,
20977                             tiDeviceHandle_t          *tiDeviceHandle,
20978                             tiScsiInitiatorRequest_t  *tiScsiRequest, /* NULL */
20979                             satIOContext_t            *satIOContext
20980                             )
20981 {
20982   satInternalIo_t           *satIntIo = agNULL;
20983   satDeviceData_t           *satDevData = agNULL;
20984   satIOContext_t            *satNewIOContext;
20985   bit32                     status;
20986   tiIORequest_t             *currentTaskTag = agNULL;
20987 
20988   TI_DBG6(("satStartCheckPowerMode: start\n"));
20989 
20990   currentTaskTag = tiIORequest;
20991 
20992   satDevData = satIOContext->pSatDevData;
20993 
20994   TI_DBG6(("satStartCheckPowerMode: before alloc\n"));
20995 
20996   /* allocate any fis for seting SRT bit in device control */
20997   satIntIo = satAllocIntIoResource( tiRoot,
20998                                     tiIORequest,
20999                                     satDevData,
21000                                     0,
21001                                     satIntIo);
21002 
21003   TI_DBG6(("satStartCheckPowerMode: before after\n"));
21004 
21005   if (satIntIo == agNULL)
21006   {
21007     TI_DBG1(("satStartCheckPowerMode: can't alloacate\n"));
21008     if (satIOContext->NotifyOS)
21009     {
21010       ostiInitiatorEvent( tiRoot,
21011                           NULL,
21012                           NULL,
21013                           tiIntrEventTypeTaskManagement,
21014                           tiTMFailed,
21015                           currentTaskTag );
21016     }
21017     return tiError;
21018   }
21019 
21020   satNewIOContext = satPrepareNewIO(satIntIo,
21021                                     tiIORequest,
21022                                     satDevData,
21023                                     agNULL,
21024                                     satIOContext);
21025 
21026   TI_DBG6(("satStartCheckPowerMode: OS satIOContext %p \n", satIOContext));
21027   TI_DBG6(("satStartCheckPowerMode: TD satNewIOContext %p \n", satNewIOContext));
21028   TI_DBG6(("satStartCheckPowerMode: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21029   TI_DBG6(("satStartCheckPowerMode: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21030 
21031 
21032 
21033   TI_DBG1(("satStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
21034 
21035   status = satCheckPowerMode(tiRoot,
21036                              &satIntIo->satIntTiIORequest, /* New tiIORequest */
21037                              tiDeviceHandle,
21038                              satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21039                              satNewIOContext);
21040 
21041   if (status != tiSuccess)
21042   {
21043     TI_DBG1(("satStartCheckPowerMode: failed in sending\n"));
21044 
21045     satFreeIntIoResource( tiRoot,
21046                           satDevData,
21047                           satIntIo);
21048     if (satIOContext->NotifyOS)
21049     {
21050       ostiInitiatorEvent( tiRoot,
21051                           NULL,
21052                           NULL,
21053                           tiIntrEventTypeTaskManagement,
21054                           tiTMFailed,
21055                           currentTaskTag );
21056     }
21057 
21058     return tiError;
21059   }
21060 
21061 
21062   TI_DBG6(("satStartCheckPowerMode: end\n"));
21063 
21064   return status;
21065 }
21066 
21067 /*****************************************************************************/
21068 /*! \brief SAT implementation for satCheckPowerMode.
21069  *
21070  *  This function creates CHECK POWER MODE fis and sends the request to LL layer
21071  *
21072  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
21073  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
21074  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
21075  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
21076  *  \param   satIOContext_t:   Pointer to the SAT IO Context
21077  *
21078  *  \return If command is started successfully
21079  *    - \e tiSuccess:     I/O request successfully initiated.
21080  *    - \e tiBusy:        No resources available, try again later.
21081  *    - \e tiIONoDevice:  Invalid device handle.
21082  *    - \e tiError:       Other errors.
21083  */
21084 /*****************************************************************************/
21085 GLOBAL bit32  satCheckPowerMode(
21086                             tiRoot_t                  *tiRoot,
21087                             tiIORequest_t             *tiIORequest,
21088                             tiDeviceHandle_t          *tiDeviceHandle,
21089                             tiScsiInitiatorRequest_t *tiScsiRequest,
21090                             satIOContext_t            *satIOContext
21091                             )
21092 {
21093   /*
21094     sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands
21095     internally generated - no directly corresponding scsi
21096   */
21097   bit32                     status;
21098   bit32                     agRequestType;
21099   agsaFisRegHostToDevice_t  *fis;
21100 
21101   fis           = satIOContext->pFis;
21102   TI_DBG5(("satCheckPowerMode: start\n"));
21103   /*
21104    * Send the ATA CHECK POWER MODE command.
21105    */
21106   fis->h.fisType        = 0x27;                   /* Reg host to device */
21107   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
21108   fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
21109   fis->h.features       = 0;
21110   fis->d.lbaLow         = 0;
21111   fis->d.lbaMid         = 0;
21112   fis->d.lbaHigh        = 0;
21113   fis->d.device         = 0;
21114   fis->d.lbaLowExp      = 0;
21115   fis->d.lbaMidExp      = 0;
21116   fis->d.lbaHighExp     = 0;
21117   fis->d.featuresExp    = 0;
21118   fis->d.sectorCount    = 0;
21119   fis->d.sectorCountExp = 0;
21120   fis->d.reserved4      = 0;
21121   fis->d.control        = 0;                      /* FIS HOB bit clear */
21122   fis->d.reserved5      = 0;
21123 
21124   agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
21125 
21126   /* Initialize CB for SATA completion.
21127    */
21128   satIOContext->satCompleteCB = &satCheckPowerModeCB;
21129 
21130   /*
21131    * Prepare SGL and send FIS to LL layer.
21132    */
21133   satIOContext->reqType = agRequestType;       /* Save it */
21134 
21135   status = sataLLIOStart( tiRoot,
21136                           tiIORequest,
21137                           tiDeviceHandle,
21138                           tiScsiRequest,
21139                           satIOContext);
21140 
21141   TI_DBG5(("satCheckPowerMode: return\n"));
21142 
21143   return status;
21144 }
21145 
21146 /*****************************************************************************
21147 *! \brief  satCheckPowerModeCB
21148 *
21149 *   This routine is a callback function called from ossaSATACompleted().
21150 *   This CB routine deals with CHECK POWER MODE completion as abort task
21151 *   management.
21152 *
21153 *  \param   agRoot:      Handles for this instance of SAS/SATA hardware
21154 *  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
21155 *  \param   agIOStatus:  Status of completed I/O.
21156 *  \param   agFirstDword:Pointer to the four bytes of FIS.
21157 *  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21158 *                        length.
21159 *  \param   agParam:     Additional info based on status.
21160 *  \param   ioContext:   Pointer to satIOContext_t.
21161 *
21162 *  \return: none
21163 *
21164 *****************************************************************************/
21165 GLOBAL void satCheckPowerModeCB(
21166                    agsaRoot_t        *agRoot,
21167                    agsaIORequest_t   *agIORequest,
21168                    bit32             agIOStatus,
21169                    agsaFisHeader_t   *agFirstDword,
21170                    bit32             agIOInfoLen,
21171                    agsaFrameHandle_t agFrameHandle,
21172                    void              *ioContext
21173                    )
21174 {
21175   /* callback for satDeResetDevice */
21176   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
21177   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
21178   tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
21179   tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21180   tdIORequestBody_t       *tdIORequestBody;
21181   tdIORequestBody_t       *tdOrgIORequestBody = agNULL;
21182   satIOContext_t          *satIOContext;
21183   satIOContext_t          *satOrgIOContext;
21184   satInternalIo_t         *satIntIo;
21185   satDeviceData_t         *satDevData;
21186 
21187   tiIORequest_t             *tiOrgIORequest;
21188 #ifdef  TD_DEBUG_ENABLE
21189   bit32                     ataStatus = 0;
21190   bit32                     ataError;
21191   agsaFisPioSetupHeader_t   *satPIOSetupHeader = agNULL;
21192 #endif
21193   bit32                     report = agFALSE;
21194   bit32                     AbortTM = agFALSE;
21195 
21196 
21197   TI_DBG1(("satCheckPowerModeCB: start\n"));
21198 
21199   TI_DBG1(("satCheckPowerModeCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21200 
21201   tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
21202   satIOContext           = (satIOContext_t *) ioContext;
21203   satIntIo               = satIOContext->satIntIoContext;
21204   satDevData             = satIOContext->pSatDevData;
21205   if (satIntIo == agNULL)
21206   {
21207     TI_DBG6(("satCheckPowerModeCB: External, OS generated\n"));
21208     satOrgIOContext      = satIOContext;
21209     tiOrgIORequest       = tdIORequestBody->tiIORequest;
21210   }
21211   else
21212   {
21213     TI_DBG6(("satCheckPowerModeCB: Internal, TD generated\n"));
21214     satOrgIOContext        = satIOContext->satOrgIOContext;
21215     if (satOrgIOContext == agNULL)
21216     {
21217       TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NULL, wrong\n"));
21218       return;
21219     }
21220     else
21221     {
21222       TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NOT NULL\n"));
21223     }
21224     tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21225     tiOrgIORequest         = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
21226   }
21227 
21228 
21229   tdIORequestBody->ioCompleted = agTRUE;
21230   tdIORequestBody->ioStarted = agFALSE;
21231 
21232   if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21233   {
21234     TI_DBG1(("satCheckPowerModeCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21235 
21236     if (satOrgIOContext->NotifyOS == agTRUE)
21237     {
21238       ostiInitiatorEvent( tiRoot,
21239                           NULL,
21240                           NULL,
21241                           tiIntrEventTypeTaskManagement,
21242                           tiTMFailed,
21243                           tiOrgIORequest );
21244     }
21245 
21246     satDevData->satTmTaskTag = agNULL;
21247 
21248     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21249 
21250     satFreeIntIoResource( tiRoot,
21251                           satDevData,
21252                           satIntIo);
21253     return;
21254   }
21255 
21256   if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21257       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21258       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21259       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21260       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21261       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21262       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21263       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21264       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21265       )
21266   {
21267     TI_DBG1(("satCheckPowerModeCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21268 
21269     if (satOrgIOContext->NotifyOS == agTRUE)
21270     {
21271       ostiInitiatorEvent( tiRoot,
21272                           NULL,
21273                           NULL,
21274                           tiIntrEventTypeTaskManagement,
21275                           tiTMFailed,
21276                           tiOrgIORequest );
21277     }
21278 
21279     satDevData->satTmTaskTag = agNULL;
21280 
21281     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21282 
21283     satFreeIntIoResource( tiRoot,
21284                          satDevData,
21285                          satIntIo);
21286     return;
21287   }
21288 
21289  if (agIOStatus != OSSA_IO_SUCCESS)
21290   {
21291 #ifdef  TD_DEBUG_ENABLE
21292     /* only agsaFisPioSetup_t is expected */
21293     satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
21294     ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
21295     ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
21296 #endif
21297     TI_DBG1(("satCheckPowerModeCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
21298 
21299      if (satOrgIOContext->NotifyOS == agTRUE)
21300      {
21301       ostiInitiatorEvent( tiRoot,
21302                           NULL,
21303                           NULL,
21304                           tiIntrEventTypeTaskManagement,
21305                           tiTMFailed,
21306                           tiOrgIORequest );
21307      }
21308 
21309     satDevData->satTmTaskTag = agNULL;
21310 
21311     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21312 
21313     satFreeIntIoResource( tiRoot,
21314                           satDevData,
21315                           satIntIo);
21316     return;
21317   }
21318 
21319   /* success */
21320   TI_DBG1(("satCheckPowerModeCB: success\n"));
21321   TI_DBG1(("satCheckPowerModeCB: TMF %d\n", satOrgIOContext->TMF));
21322 
21323   if (satOrgIOContext->TMF == AG_ABORT_TASK)
21324   {
21325     AbortTM = agTRUE;
21326   }
21327 
21328   if (satOrgIOContext->NotifyOS == agTRUE)
21329   {
21330     report = agTRUE;
21331   }
21332   if (AbortTM == agTRUE)
21333   {
21334     TI_DBG1(("satCheckPowerModeCB: calling satAbort\n"));
21335     satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
21336   }
21337   satDevData->satTmTaskTag = agNULL;
21338 
21339   satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
21340 
21341   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21342 
21343   TI_DBG1(("satCheckPowerModeCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
21344   TI_DBG1(("satCheckPowerModeCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
21345 
21346   satFreeIntIoResource( tiRoot,
21347                         satDevData,
21348                         satIntIo);
21349 
21350   /* clean up TD layer's IORequestBody */
21351   if (tdOrgIORequestBody != agNULL)
21352   {
21353     ostiFreeMemory(
21354                    tiRoot,
21355                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21356                    sizeof(tdIORequestBody_t)
21357                    );
21358   }
21359   else
21360   {
21361     TI_DBG1(("satCheckPowerModeCB: tdOrgIORequestBody is NULL, wrong\n"));
21362   }
21363   if (report)
21364   {
21365     ostiInitiatorEvent( tiRoot,
21366                         NULL,
21367                         NULL,
21368                         tiIntrEventTypeTaskManagement,
21369                         tiTMOK,
21370                         tiOrgIORequest );
21371   }
21372 
21373   TI_DBG5(("satCheckPowerModeCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
21374   TI_DBG2(("satCheckPowerModeCB: end\n"));
21375   return;
21376 
21377 }
21378 
21379 /*****************************************************************************/
21380 /*! \brief SAT implementation for satAddSATAStartIDDev.
21381  *
21382  *  This function sends identify device data to find out the uniqueness
21383  *  of device.
21384  *
21385  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
21386  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
21387  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
21388  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
21389  *  \param   satIOContext_t:   Pointer to the SAT IO Context
21390  *
21391  *  \return If command is started successfully
21392  *    - \e tiSuccess:     I/O request successfully initiated.
21393  *    - \e tiBusy:        No resources available, try again later.
21394  *    - \e tiIONoDevice:  Invalid device handle.
21395  *    - \e tiError:       Other errors.
21396  */
21397 /*****************************************************************************/
21398 GLOBAL bit32  satAddSATAStartIDDev(
21399                                tiRoot_t                  *tiRoot,
21400                                tiIORequest_t             *tiIORequest,
21401                                tiDeviceHandle_t          *tiDeviceHandle,
21402                                tiScsiInitiatorRequest_t  *tiScsiRequest, // NULL
21403                                satIOContext_t            *satIOContext
21404                             )
21405 {
21406   satInternalIo_t           *satIntIo = agNULL;
21407   satDeviceData_t           *satDevData = agNULL;
21408   tdIORequestBody_t         *tdIORequestBody;
21409   satIOContext_t            *satNewIOContext;
21410   bit32                     status;
21411 
21412   TI_DBG2(("satAddSATAStartIDDev: start\n"));
21413 
21414   satDevData = satIOContext->pSatDevData;
21415 
21416   TI_DBG2(("satAddSATAStartIDDev: before alloc\n"));
21417 
21418   /* allocate identify device command */
21419   satIntIo = satAllocIntIoResource( tiRoot,
21420                                     tiIORequest,
21421                                     satDevData,
21422                                     sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
21423                                     satIntIo);
21424 
21425   TI_DBG2(("satAddSATAStartIDDev: after alloc\n"));
21426 
21427   if (satIntIo == agNULL)
21428   {
21429     TI_DBG1(("satAddSATAStartIDDev: can't alloacate\n"));
21430 
21431     return tiError;
21432   }
21433 
21434   /* fill in fields */
21435   /* real ttttttthe one worked and the same; 5/21/07/ */
21436   satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
21437   tdIORequestBody = satIntIo->satIntRequestBody;
21438   satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
21439 
21440   satNewIOContext->pSatDevData   = satDevData;
21441   satNewIOContext->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
21442   satNewIOContext->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
21443   satNewIOContext->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
21444   satNewIOContext->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
21445   satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
21446   satNewIOContext->interruptContext = tiInterruptContext;
21447   satNewIOContext->satIntIoContext  = satIntIo;
21448 
21449   satNewIOContext->ptiDeviceHandle = agNULL;
21450   satNewIOContext->satOrgIOContext = satIOContext; /* changed */
21451 
21452   /* this is valid only for TD layer generated (not triggered by OS at all) IO */
21453   satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
21454 
21455 
21456   TI_DBG6(("satAddSATAStartIDDev: OS satIOContext %p \n", satIOContext));
21457   TI_DBG6(("satAddSATAStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
21458   TI_DBG6(("satAddSATAStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21459   TI_DBG6(("satAddSATAStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21460 
21461 
21462 
21463   TI_DBG2(("satAddSATAStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
21464 
21465   status = satAddSATASendIDDev( tiRoot,
21466                                 &satIntIo->satIntTiIORequest, /* New tiIORequest */
21467                                 tiDeviceHandle,
21468                                 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21469                                 satNewIOContext);
21470 
21471   if (status != tiSuccess)
21472   {
21473     TI_DBG1(("satAddSATAStartIDDev: failed in sending\n"));
21474 
21475     satFreeIntIoResource( tiRoot,
21476                           satDevData,
21477                           satIntIo);
21478 
21479     return tiError;
21480   }
21481 
21482 
21483   TI_DBG6(("satAddSATAStartIDDev: end\n"));
21484 
21485   return status;
21486 
21487 
21488 }
21489 
21490 /*****************************************************************************/
21491 /*! \brief SAT implementation for satAddSATASendIDDev.
21492  *
21493  *  This function creates identify device data fis and send it to LL
21494  *
21495  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
21496  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
21497  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
21498  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
21499  *  \param   satIOContext_t:   Pointer to the SAT IO Context
21500  *
21501  *  \return If command is started successfully
21502  *    - \e tiSuccess:     I/O request successfully initiated.
21503  *    - \e tiBusy:        No resources available, try again later.
21504  *    - \e tiIONoDevice:  Invalid device handle.
21505  *    - \e tiError:       Other errors.
21506  */
21507 /*****************************************************************************/
21508 GLOBAL bit32  satAddSATASendIDDev(
21509                            tiRoot_t                  *tiRoot,
21510                            tiIORequest_t             *tiIORequest,
21511                            tiDeviceHandle_t          *tiDeviceHandle,
21512                            tiScsiInitiatorRequest_t  *tiScsiRequest,
21513                            satIOContext_t            *satIOContext)
21514 {
21515   bit32                     status;
21516   bit32                     agRequestType;
21517   satDeviceData_t           *pSatDevData;
21518   agsaFisRegHostToDevice_t  *fis;
21519 #ifdef  TD_DEBUG_ENABLE
21520   tdIORequestBody_t         *tdIORequestBody;
21521   satInternalIo_t           *satIntIoContext;
21522 #endif
21523 
21524   pSatDevData   = satIOContext->pSatDevData;
21525   fis           = satIOContext->pFis;
21526   TI_DBG2(("satAddSATASendIDDev: start\n"));
21527 #ifdef  TD_DEBUG_ENABLE
21528   satIntIoContext = satIOContext->satIntIoContext;
21529   tdIORequestBody = satIntIoContext->satIntRequestBody;
21530 #endif
21531   TI_DBG5(("satAddSATASendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
21532 
21533   fis->h.fisType        = 0x27;                   /* Reg host to device */
21534   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
21535   if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
21536       fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
21537   else
21538       fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
21539   fis->h.features       = 0;                      /* FIS reserve */
21540   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
21541   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
21542   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
21543   fis->d.device         = 0;                      /* FIS LBA mode  */
21544   fis->d.lbaLowExp      = 0;
21545   fis->d.lbaMidExp      = 0;
21546   fis->d.lbaHighExp     = 0;
21547   fis->d.featuresExp    = 0;
21548   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
21549   fis->d.sectorCountExp = 0;
21550   fis->d.reserved4      = 0;
21551   fis->d.control        = 0;                      /* FIS HOB bit clear */
21552   fis->d.reserved5      = 0;
21553 
21554   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
21555 
21556   /* Initialize CB for SATA completion.
21557    */
21558   satIOContext->satCompleteCB = &satAddSATAIDDevCB;
21559 
21560   /*
21561    * Prepare SGL and send FIS to LL layer.
21562    */
21563   satIOContext->reqType = agRequestType;       /* Save it */
21564 
21565 #ifdef TD_INTERNAL_DEBUG
21566   tdhexdump("satAddSATASendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
21567 #ifdef  TD_DEBUG_ENABLE
21568   tdhexdump("satAddSATASendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
21569 #endif
21570 #endif
21571 
21572   status = sataLLIOStart( tiRoot,
21573                           tiIORequest,
21574                           tiDeviceHandle,
21575                           tiScsiRequest,
21576                           satIOContext);
21577 
21578   TI_DBG2(("satAddSATASendIDDev: end status %d\n", status));
21579   return status;
21580 }
21581 
21582 /*****************************************************************************
21583 *! \brief  satAddSATAIDDevCB
21584 *
21585 *   This routine is a callback function for satAddSATASendIDDev()
21586 *   Using Identify Device Data, this function finds whether devicedata is
21587 *   new or old. If new, add it to the devicelist.
21588 *
21589 *  \param   agRoot:      Handles for this instance of SAS/SATA hardware
21590 *  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
21591 *  \param   agIOStatus:  Status of completed I/O.
21592 *  \param   agFirstDword:Pointer to the four bytes of FIS.
21593 *  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21594 *                        length.
21595 *  \param   agParam:     Additional info based on status.
21596 *  \param   ioContext:   Pointer to satIOContext_t.
21597 *
21598 *  \return: none
21599 *
21600 *****************************************************************************/
21601 void satAddSATAIDDevCB(
21602                    agsaRoot_t        *agRoot,
21603                    agsaIORequest_t   *agIORequest,
21604                    bit32             agIOStatus,
21605                    agsaFisHeader_t   *agFirstDword,
21606                    bit32             agIOInfoLen,
21607                    void              *agParam,
21608                    void              *ioContext
21609                    )
21610 {
21611 
21612   /*
21613     In the process of Inquiry
21614     Process SAT_IDENTIFY_DEVICE
21615   */
21616   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
21617   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
21618   tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
21619   tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21620   tdIORequestBody_t       *tdIORequestBody;
21621   tdIORequestBody_t       *tdOrgIORequestBody;
21622   satIOContext_t          *satIOContext;
21623   satIOContext_t          *satOrgIOContext;
21624   satIOContext_t          *satNewIOContext;
21625   satInternalIo_t         *satIntIo;
21626   satInternalIo_t         *satNewIntIo = agNULL;
21627   satDeviceData_t         *satDevData;
21628   tiIORequest_t           *tiOrgIORequest = agNULL;
21629   agsaSATAIdentifyData_t    *pSATAIdData;
21630   bit16                     *tmpptr, tmpptr_tmp;
21631   bit32                     x;
21632   tdsaDeviceData_t          *NewOneDeviceData = agNULL;
21633   tdsaDeviceData_t          *oneDeviceData = agNULL;
21634   tdList_t                  *DeviceListList;
21635   int                       new_device = agTRUE;
21636   bit8                      PhyID;
21637   void                      *sglVirtualAddr;
21638   bit32                     retry_status;
21639   agsaContext_t             *agContext;
21640   tdsaPortContext_t         *onePortContext;
21641   bit32                     status = 0;
21642 
21643   TI_DBG2(("satAddSATAIDDevCB: start\n"));
21644   TI_DBG6(("satAddSATAIDDevCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21645   tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
21646   satIOContext           = (satIOContext_t *) ioContext;
21647   satIntIo               = satIOContext->satIntIoContext;
21648   satDevData             = satIOContext->pSatDevData;
21649 
21650   NewOneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
21651   TI_DBG2(("satAddSATAIDDevCB: NewOneDeviceData %p did %d\n", NewOneDeviceData, NewOneDeviceData->id));
21652   PhyID = NewOneDeviceData->phyID;
21653   TI_DBG2(("satAddSATAIDDevCB: phyID %d\n", PhyID));
21654   agContext = &(NewOneDeviceData->agDeviceResetContext);
21655   agContext->osData = agNULL;
21656   if (satIntIo == agNULL)
21657   {
21658     TI_DBG1(("satAddSATAIDDevCB: External, OS generated\n"));
21659     TI_DBG1(("satAddSATAIDDevCB: Not possible case\n"));
21660     satOrgIOContext      = satIOContext;
21661     tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21662     tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21663 
21664     /* put onedevicedata back to free list */
21665     osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21666     TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21667     TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21668 
21669     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21670 
21671     satFreeIntIoResource( tiRoot,
21672                           satDevData,
21673                           satIntIo);
21674     /* clean up TD layer's IORequestBody */
21675     ostiFreeMemory(
21676                    tiRoot,
21677                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21678                    sizeof(tdIORequestBody_t)
21679                    );
21680 
21681     /* notifying link up */
21682     ostiPortEvent (
21683                    tiRoot,
21684                    tiPortLinkUp,
21685                    tiSuccess,
21686                    (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
21687                    );
21688 #ifdef INITIATOR_DRIVER
21689     /* triggers discovery */
21690     ostiPortEvent(
21691                   tiRoot,
21692                   tiPortDiscoveryReady,
21693                   tiSuccess,
21694                   (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
21695                   );
21696 #endif
21697     return;
21698   }
21699   else
21700   {
21701     TI_DBG1(("satAddSATAIDDevCB: Internal, TD generated\n"));
21702     satOrgIOContext        = satIOContext->satOrgIOContext;
21703     if (satOrgIOContext == agNULL)
21704     {
21705       TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NULL\n"));
21706       return;
21707     }
21708     else
21709     {
21710       TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NOT NULL\n"));
21711       tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21712       sglVirtualAddr         = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
21713     }
21714   }
21715   tiOrgIORequest           = tdIORequestBody->tiIORequest;
21716 
21717   tdIORequestBody->ioCompleted = agTRUE;
21718   tdIORequestBody->ioStarted = agFALSE;
21719   TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21720   /* protect against double completion for old port */
21721   if (satOrgIOContext->pid != tdsaAllShared->Ports[PhyID].portContext->id)
21722   {
21723     TI_DBG2(("satAddSATAIDDevCB: incorrect pid\n"));
21724     TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21725     TI_DBG2(("satAddSATAIDDevCB: tiPortalContext pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
21726     tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21727     /* put onedevicedata back to free list */
21728     osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21729     TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21730     TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21731     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21732 
21733     satFreeIntIoResource( tiRoot,
21734                           satDevData,
21735                           satIntIo);
21736     /* clean up TD layer's IORequestBody */
21737     ostiFreeMemory(
21738                    tiRoot,
21739                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21740                    sizeof(tdIORequestBody_t)
21741                    );
21742     /* no notification to OS layer */
21743     return;
21744   }
21745   /* completion after portcontext is invalidated */
21746   onePortContext = NewOneDeviceData->tdPortContext;
21747   if (onePortContext != agNULL)
21748   {
21749     if (onePortContext->valid == agFALSE)
21750     {
21751       TI_DBG1(("satAddSATAIDDevCB: portcontext is invalid\n"));
21752       TI_DBG1(("satAddSATAIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
21753       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21754 
21755       satFreeIntIoResource( tiRoot,
21756                             satDevData,
21757                             satIntIo);
21758       /* clean up TD layer's IORequestBody */
21759       ostiFreeMemory(
21760                      tiRoot,
21761                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21762                      sizeof(tdIORequestBody_t)
21763                      );
21764       /* no notification to OS layer */
21765       return;
21766     }
21767   }
21768   else
21769   {
21770     TI_DBG1(("satAddSATAIDDevCB: onePortContext is NULL!!!\n"));
21771     return;
21772   }
21773   if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21774   {
21775     TI_DBG1(("satAddSATAIDDevCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21776     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21777     {
21778       satDevData->satPendingNONNCQIO--;
21779       satDevData->satPendingIO--;
21780       retry_status = sataLLIOStart(tiRoot,
21781                                    &satIntIo->satIntTiIORequest,
21782                                    &(NewOneDeviceData->tiDeviceHandle),
21783                                    satIOContext->tiScsiXchg,
21784                                    satIOContext);
21785       if (retry_status != tiSuccess)
21786       {
21787         /* simply give up */
21788         satDevData->ID_Retries = 0;
21789         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21790         return;
21791       }
21792       satDevData->ID_Retries++;
21793       tdIORequestBody->ioCompleted = agFALSE;
21794       tdIORequestBody->ioStarted = agTRUE;
21795       return;
21796     }
21797     else
21798     {
21799       if (tdsaAllShared->ResetInDiscovery == 0)
21800       {
21801         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21802       }
21803       else /* ResetInDiscovery in on */
21804       {
21805         /* RESET only one after ID retries */
21806         if (satDevData->NumOfIDRetries <= 0)
21807         {
21808           satDevData->NumOfIDRetries++;
21809           satDevData->ID_Retries = 0;
21810           satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21811           /* send link reset */
21812           saLocalPhyControl(agRoot,
21813                             agContext,
21814                             tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21815                             PhyID,
21816                             AGSA_PHY_HARD_RESET,
21817                             agNULL);
21818         }
21819         else
21820         {
21821           satDevData->ID_Retries = 0;
21822           satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21823         }
21824       }
21825       return;
21826     }
21827   }
21828   if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21829       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21830       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21831       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21832       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21833       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21834       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21835       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21836       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21837       )
21838   {
21839     TI_DBG1(("satAddSATAIDDevCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21840     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21841     {
21842       satDevData->satPendingNONNCQIO--;
21843       satDevData->satPendingIO--;
21844       retry_status = sataLLIOStart(tiRoot,
21845                                    &satIntIo->satIntTiIORequest,
21846                                    &(NewOneDeviceData->tiDeviceHandle),
21847                                    satIOContext->tiScsiXchg,
21848                                    satIOContext);
21849       if (retry_status != tiSuccess)
21850       {
21851         /* simply give up */
21852         satDevData->ID_Retries = 0;
21853         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21854         return;
21855       }
21856       satDevData->ID_Retries++;
21857       tdIORequestBody->ioCompleted = agFALSE;
21858       tdIORequestBody->ioStarted = agTRUE;
21859       return;
21860     }
21861     else
21862     {
21863       if (tdsaAllShared->ResetInDiscovery == 0)
21864       {
21865         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21866       }
21867       else /* ResetInDiscovery in on */
21868       {
21869         /* RESET only one after ID retries */
21870         if (satDevData->NumOfIDRetries <= 0)
21871         {
21872           satDevData->NumOfIDRetries++;
21873           satDevData->ID_Retries = 0;
21874           satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21875           /* send link reset */
21876           saLocalPhyControl(agRoot,
21877                             agContext,
21878                             tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21879                             PhyID,
21880                             AGSA_PHY_HARD_RESET,
21881                             agNULL);
21882         }
21883         else
21884         {
21885           satDevData->ID_Retries = 0;
21886           satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21887         }
21888       }
21889       return;
21890     }
21891   }
21892 
21893   if ( agIOStatus != OSSA_IO_SUCCESS ||
21894       (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
21895     )
21896   {
21897     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21898     {
21899       satIOContext->pSatDevData->satPendingNONNCQIO--;
21900       satIOContext->pSatDevData->satPendingIO--;
21901       retry_status = sataLLIOStart(tiRoot,
21902                                    &satIntIo->satIntTiIORequest,
21903                                    &(NewOneDeviceData->tiDeviceHandle),
21904                                    satIOContext->tiScsiXchg,
21905                                    satIOContext);
21906       if (retry_status != tiSuccess)
21907       {
21908         /* simply give up */
21909         satDevData->ID_Retries = 0;
21910         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21911         return;
21912       }
21913       satDevData->ID_Retries++;
21914       tdIORequestBody->ioCompleted = agFALSE;
21915       tdIORequestBody->ioStarted = agTRUE;
21916       return;
21917     }
21918     else
21919     {
21920       if (tdsaAllShared->ResetInDiscovery == 0)
21921       {
21922         satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21923       }
21924       else /* ResetInDiscovery in on */
21925       {
21926         /* RESET only one after ID retries */
21927         if (satDevData->NumOfIDRetries <= 0)
21928         {
21929           satDevData->NumOfIDRetries++;
21930           satDevData->ID_Retries = 0;
21931           satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21932           /* send link reset */
21933           saLocalPhyControl(agRoot,
21934                             agContext,
21935                             tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21936                             PhyID,
21937                             AGSA_PHY_HARD_RESET,
21938                             agNULL);
21939         }
21940         else
21941         {
21942           satDevData->ID_Retries = 0;
21943           satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21944         }
21945       }
21946       return;
21947     }
21948   }
21949 
21950   /* success */
21951   TI_DBG2(("satAddSATAIDDevCB: Success\n"));
21952   /* Convert to host endian */
21953   tmpptr = (bit16*)sglVirtualAddr;
21954   //tdhexdump("satAddSATAIDDevCB before", (bit8 *)sglVirtualAddr, sizeof(agsaSATAIdentifyData_t));
21955   for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
21956   {
21957    OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
21958    *tmpptr = tmpptr_tmp;
21959    tmpptr++;
21960     /*Print tmpptr_tmp here for debugging purpose*/
21961   }
21962 
21963   pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
21964   //tdhexdump("satAddSATAIDDevCB after", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
21965 
21966   TI_DBG5(("satAddSATAIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
21967   TI_DBG5(("satAddSATAIDDevCB: TD satIOContext %p \n", satIOContext));
21968   TI_DBG5(("satAddSATAIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
21969   TI_DBG5(("satAddSATAIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21970 
21971 
21972   /* compare idenitfy device data to the exiting list */
21973   DeviceListList = tdsaAllShared->MainDeviceList.flink;
21974   while (DeviceListList != &(tdsaAllShared->MainDeviceList))
21975   {
21976     oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
21977     TI_DBG1(("satAddSATAIDDevCB: LOOP oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
21978     //tdhexdump("satAddSATAIDDevCB LOOP", (bit8 *)&oneDeviceData->satDevData.satIdentifyData, sizeof(agsaSATAIdentifyData_t));
21979 
21980     /* what is unique ID for sata device -> response of identify devicedata; not really
21981        Let's compare serial number, firmware version, model number
21982     */
21983     if ( oneDeviceData->DeviceType == TD_SATA_DEVICE &&
21984          (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.serialNumber,
21985                        pSATAIdData->serialNumber,
21986                        20) == 0) &&
21987          (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.firmwareVersion,
21988                        pSATAIdData->firmwareVersion,
21989                        8) == 0) &&
21990          (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.modelNumber,
21991                        pSATAIdData->modelNumber,
21992                        40) == 0)
21993        )
21994     {
21995       TI_DBG2(("satAddSATAIDDevCB: did %d\n", oneDeviceData->id));
21996       new_device = agFALSE;
21997       break;
21998     }
21999     DeviceListList = DeviceListList->flink;
22000   }
22001 
22002   if (new_device == agFALSE)
22003   {
22004     TI_DBG2(("satAddSATAIDDevCB: old device data\n"));
22005     oneDeviceData->valid = agTRUE;
22006     oneDeviceData->valid2 = agTRUE;
22007     /* save data field from new device data */
22008     oneDeviceData->agRoot = agRoot;
22009     oneDeviceData->agDevHandle = NewOneDeviceData->agDevHandle;
22010     oneDeviceData->agDevHandle->osData = oneDeviceData; /* TD layer */
22011     oneDeviceData->tdPortContext = NewOneDeviceData->tdPortContext;
22012     oneDeviceData->phyID = NewOneDeviceData->phyID;
22013 
22014     /*
22015       one SATA directly attached device per phy;
22016       Therefore, deregister then register
22017     */
22018     saDeregisterDeviceHandle(agRoot, agNULL, NewOneDeviceData->agDevHandle, 0);
22019 
22020     if (oneDeviceData->registered == agFALSE)
22021     {
22022       TI_DBG2(("satAddSATAIDDevCB: re-registering old device data\n"));
22023       /* already has old information; just register it again */
22024       saRegisterNewDevice( /* satAddSATAIDDevCB */
22025                           agRoot,
22026                           &oneDeviceData->agContext,
22027                           tdsaRotateQnumber(tiRoot, oneDeviceData),
22028                           &oneDeviceData->agDeviceInfo,
22029                           oneDeviceData->tdPortContext->agPortContext,
22030                           0
22031                           );
22032     }
22033 
22034 //    tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
22035     /* put onedevicedata back to free list */
22036     osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22037     TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
22038     TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22039     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22040 
22041     satFreeIntIoResource( tiRoot,
22042                           satDevData,
22043                           satIntIo);
22044 
22045     if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22046     {
22047       /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22048       satNewIntIo = satAllocIntIoResource( tiRoot,
22049                                        tiOrgIORequest,
22050                                        satDevData,
22051                                        0,
22052                                        satNewIntIo);
22053 
22054       if (satNewIntIo == agNULL)
22055       {
22056         TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22057           /* clean up TD layer's IORequestBody */
22058         ostiFreeMemory(
22059                      tiRoot,
22060                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22061                      sizeof(tdIORequestBody_t)
22062                      );
22063         return;
22064       } /* end memory allocation */
22065 
22066       satNewIOContext = satPrepareNewIO(satNewIntIo,
22067                                         tiOrgIORequest,
22068                                         satDevData,
22069                                         agNULL,
22070                                         satOrgIOContext
22071                                         );
22072       /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22073       status = satSetFeatures(tiRoot,
22074                      &satNewIntIo->satIntTiIORequest,
22075                      satNewIOContext->ptiDeviceHandle,
22076                      &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22077                      satNewIOContext,
22078                      agFALSE);
22079       if (status != tiSuccess)
22080       {
22081            satFreeIntIoResource( tiRoot,
22082                         satDevData,
22083                         satIntIo);
22084            /* clean up TD layer's IORequestBody */
22085            ostiFreeMemory(
22086                      tiRoot,
22087                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22088                      sizeof(tdIORequestBody_t)
22089                      );
22090       }
22091     }
22092     else
22093     {
22094       /* clean up TD layer's IORequestBody */
22095       ostiFreeMemory(
22096                    tiRoot,
22097                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22098                    sizeof(tdIORequestBody_t)
22099                    );
22100       TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22101       /* notifying link up */
22102       ostiPortEvent(
22103                    tiRoot,
22104                    tiPortLinkUp,
22105                    tiSuccess,
22106                    (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22107                    );
22108 
22109 
22110     #ifdef INITIATOR_DRIVER
22111         /* triggers discovery */
22112         ostiPortEvent(
22113                   tiRoot,
22114                   tiPortDiscoveryReady,
22115                   tiSuccess,
22116                   (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22117                   );
22118     #endif
22119     }
22120     return;
22121   }
22122 
22123   TI_DBG2(("satAddSATAIDDevCB: new device data\n"));
22124   /* copy ID Dev data to satDevData */
22125   satDevData->satIdentifyData = *pSATAIdData;
22126 
22127 
22128   satDevData->IDDeviceValid = agTRUE;
22129 #ifdef TD_INTERNAL_DEBUG
22130   tdhexdump("satAddSATAIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
22131   tdhexdump("satAddSATAIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
22132 #endif
22133 
22134   /* set satDevData fields from IndentifyData */
22135   satSetDevInfo(satDevData,pSATAIdData);
22136   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22137 
22138   satFreeIntIoResource( tiRoot,
22139                         satDevData,
22140                         satIntIo);
22141 
22142   if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22143   {
22144       /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22145       satNewIntIo = satAllocIntIoResource( tiRoot,
22146                                        tiOrgIORequest,
22147                                        satDevData,
22148                                        0,
22149                                        satNewIntIo);
22150 
22151       if (satNewIntIo == agNULL)
22152       {
22153         TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22154           /* clean up TD layer's IORequestBody */
22155         ostiFreeMemory(
22156                      tiRoot,
22157                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22158                      sizeof(tdIORequestBody_t)
22159                      );
22160         return;
22161       } /* end memory allocation */
22162 
22163       satNewIOContext = satPrepareNewIO(satNewIntIo,
22164                                         tiOrgIORequest,
22165                                         satDevData,
22166                                         agNULL,
22167                                         satOrgIOContext
22168                                         );
22169       /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22170       status = satSetFeatures(tiRoot,
22171                      &satNewIntIo->satIntTiIORequest,
22172                      satNewIOContext->ptiDeviceHandle,
22173                      &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22174                      satNewIOContext,
22175                      agFALSE);
22176       if (status != tiSuccess)
22177       {
22178            satFreeIntIoResource( tiRoot,
22179                         satDevData,
22180                         satIntIo);
22181            /* clean up TD layer's IORequestBody */
22182            ostiFreeMemory(
22183                      tiRoot,
22184                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22185                      sizeof(tdIORequestBody_t)
22186                      );
22187       }
22188 
22189   }
22190   else
22191   {
22192        /* clean up TD layer's IORequestBody */
22193       ostiFreeMemory(
22194                      tiRoot,
22195                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22196                      sizeof(tdIORequestBody_t)
22197                      );
22198 
22199       TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22200       /* notifying link up */
22201       ostiPortEvent (
22202                      tiRoot,
22203                      tiPortLinkUp,
22204                      tiSuccess,
22205                      (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22206                      );
22207     #ifdef INITIATOR_DRIVER
22208       /* triggers discovery */
22209       ostiPortEvent(
22210                     tiRoot,
22211                     tiPortDiscoveryReady,
22212                     tiSuccess,
22213                     (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22214                     );
22215     #endif
22216   }
22217 
22218  TI_DBG2(("satAddSATAIDDevCB: end\n"));
22219  return;
22220 
22221 }
22222 
22223 /*****************************************************************************
22224 *! \brief  satAddSATAIDDevCBReset
22225 *
22226 *   This routine cleans up IOs for failed Identify device data
22227 *
22228 *  \param   agRoot:           Handles for this instance of SAS/SATA hardware
22229 *  \param   oneDeviceData:    Pointer to the device data.
22230 *  \param   ioContext:        Pointer to satIOContext_t.
22231 *  \param   tdIORequestBody:  Pointer to the request body
22232 *  \param   flag:             Decrement pending io or not
22233 *
22234 *  \return: none
22235 *
22236 *****************************************************************************/
22237 void satAddSATAIDDevCBReset(
22238                    agsaRoot_t        *agRoot,
22239                    tdsaDeviceData_t  *oneDeviceData,
22240                    satIOContext_t    *satIOContext,
22241                    tdIORequestBody_t *tdIORequestBody
22242                    )
22243 {
22244   tdsaRootOsData_t   *osData = (tdsaRootOsData_t *)agRoot->osData;
22245   tiRoot_t           *tiRoot = (tiRoot_t *)osData->tiRoot;
22246   tdsaRoot_t         *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
22247   tdsaContext_t      *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22248   satInternalIo_t    *satIntIo;
22249   satDeviceData_t    *satDevData;
22250 
22251   TI_DBG2(("satAddSATAIDDevCBReset: start\n"));
22252   satIntIo           = satIOContext->satIntIoContext;
22253   satDevData         = satIOContext->pSatDevData;
22254   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22255 
22256   satFreeIntIoResource( tiRoot,
22257                         satDevData,
22258                         satIntIo);
22259   /* clean up TD layer's IORequestBody */
22260   ostiFreeMemory(
22261                  tiRoot,
22262                  tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22263                  sizeof(tdIORequestBody_t)
22264                 );
22265   return;
22266 }
22267 
22268 
22269 /*****************************************************************************
22270 *! \brief  satAddSATAIDDevCBCleanup
22271 *
22272 *   This routine cleans up IOs for failed Identify device data
22273 *
22274 *  \param   agRoot:           Handles for this instance of SAS/SATA hardware
22275 *  \param   oneDeviceData:    Pointer to the device data.
22276 *  \param   ioContext:        Pointer to satIOContext_t.
22277 *  \param   tdIORequestBody:  Pointer to the request body
22278 *
22279 *  \return: none
22280 *
22281 *****************************************************************************/
22282 void satAddSATAIDDevCBCleanup(
22283                    agsaRoot_t        *agRoot,
22284                    tdsaDeviceData_t  *oneDeviceData,
22285                    satIOContext_t    *satIOContext,
22286                    tdIORequestBody_t *tdIORequestBody
22287                    )
22288 {
22289   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
22290   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
22291   tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
22292   tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22293   satInternalIo_t         *satIntIo;
22294   satDeviceData_t         *satDevData;
22295   bit8                    PhyID;
22296 
22297   TI_DBG2(("satAddSATAIDDevCBCleanup: start\n"));
22298   satIntIo               = satIOContext->satIntIoContext;
22299   satDevData             = satIOContext->pSatDevData;
22300   PhyID                  = oneDeviceData->phyID;
22301   tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
22302   /* put onedevicedata back to free list */
22303   osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22304   TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
22305   TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22306 
22307   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22308 
22309 
22310   satFreeIntIoResource( tiRoot,
22311                         satDevData,
22312                         satIntIo);
22313 
22314   /* clean up TD layer's IORequestBody */
22315   ostiFreeMemory(
22316                  tiRoot,
22317                  tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22318                  sizeof(tdIORequestBody_t)
22319                 );
22320 
22321   /* notifying link up */
22322   ostiPortEvent (
22323                  tiRoot,
22324                  tiPortLinkUp,
22325                  tiSuccess,
22326                  (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22327                 );
22328 #ifdef INITIATOR_DRIVER
22329   /* triggers discovery */
22330   ostiPortEvent(
22331                 tiRoot,
22332                 tiPortDiscoveryReady,
22333                 tiSuccess,
22334                 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22335                 );
22336 #endif
22337 
22338   return;
22339 }
22340 
22341 /*****************************************************************************/
22342 /*! \brief SAT implementation for tdsaDiscoveryStartIDDev.
22343  *
22344  *  This function sends identify device data to SATA device in discovery
22345  *
22346  *
22347  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
22348  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
22349  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
22350  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
22351  *  \param   oneDeviceData :   Pointer to the device data.
22352  *
22353  *  \return If command is started successfully
22354  *    - \e tiSuccess:     I/O request successfully initiated.
22355  *    - \e tiBusy:        No resources available, try again later.
22356  *    - \e tiIONoDevice:  Invalid device handle.
22357  *    - \e tiError:       Other errors.
22358  */
22359 /*****************************************************************************/
22360 GLOBAL bit32
22361 tdsaDiscoveryStartIDDev(tiRoot_t                  *tiRoot,
22362                         tiIORequest_t             *tiIORequest, /* agNULL */
22363                         tiDeviceHandle_t          *tiDeviceHandle,
22364                         tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */
22365                         tdsaDeviceData_t          *oneDeviceData
22366                         )
22367 {
22368   void                        *osMemHandle;
22369   tdIORequestBody_t           *tdIORequestBody;
22370   bit32                       PhysUpper32;
22371   bit32                       PhysLower32;
22372   bit32                       memAllocStatus;
22373   agsaIORequest_t             *agIORequest = agNULL; /* identify device data itself */
22374   satIOContext_t              *satIOContext = agNULL;
22375   bit32                       status;
22376 
22377   /* allocate tdiorequestbody and call tdsaDiscoveryIntStartIDDev
22378   tdsaDiscoveryIntStartIDDev(tiRoot, agNULL, tiDeviceHandle, satIOContext);
22379 
22380   */
22381 
22382   TI_DBG3(("tdsaDiscoveryStartIDDev: start\n"));
22383   TI_DBG3(("tdsaDiscoveryStartIDDev: did %d\n", oneDeviceData->id));
22384 
22385   /* allocation tdIORequestBody and pass it to satTM() */
22386   memAllocStatus = ostiAllocMemory(
22387                                    tiRoot,
22388                                    &osMemHandle,
22389                                    (void **)&tdIORequestBody,
22390                                    &PhysUpper32,
22391                                    &PhysLower32,
22392                                    8,
22393                                    sizeof(tdIORequestBody_t),
22394                                    agTRUE
22395                                    );
22396 
22397   if (memAllocStatus != tiSuccess)
22398   {
22399     TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory failed... loc 1\n"));
22400     return tiError;
22401   }
22402   if (tdIORequestBody == agNULL)
22403   {
22404     TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory returned NULL tdIORequestBody loc 2\n"));
22405     return tiError;
22406   }
22407 
22408   /* setup identify device data IO structure */
22409   tdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
22410   tdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
22411   tdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
22412 
22413   /* initialize tiDevhandle */
22414   tdIORequestBody->tiDevHandle = &(oneDeviceData->tiDeviceHandle);
22415   tdIORequestBody->tiDevHandle->tdData = oneDeviceData;
22416 
22417   /* initialize tiIORequest */
22418   tdIORequestBody->tiIORequest = agNULL;
22419 
22420   /* initialize agIORequest */
22421   agIORequest = &(tdIORequestBody->agIORequest);
22422   agIORequest->osData = (void *) tdIORequestBody;
22423   agIORequest->sdkData = agNULL; /* SA takes care of this */
22424 
22425   /* set up satIOContext */
22426   satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22427   satIOContext->pSatDevData   = &(oneDeviceData->satDevData);
22428   satIOContext->pFis          =
22429     &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22430 
22431   satIOContext->tiRequestBody = tdIORequestBody;
22432   satIOContext->ptiDeviceHandle = &(oneDeviceData->tiDeviceHandle);
22433   satIOContext->tiScsiXchg = agNULL;
22434   satIOContext->satIntIoContext  = agNULL;
22435   satIOContext->satOrgIOContext  = agNULL;
22436   /* followings are used only for internal IO */
22437   satIOContext->currentLBA = 0;
22438   satIOContext->OrgTL = 0;
22439   satIOContext->satToBeAbortedIOContext = agNULL;
22440   satIOContext->NotifyOS = agFALSE;
22441 
22442   /* saving port ID just in case of full discovery to full discovery transition */
22443   satIOContext->pid = oneDeviceData->tdPortContext->id;
22444   osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0x0, sizeof(agsaSATAIdentifyData_t));
22445   status = tdsaDiscoveryIntStartIDDev(tiRoot,
22446                                       tiIORequest, /* agNULL */
22447                                       tiDeviceHandle, /* &(oneDeviceData->tiDeviceHandle)*/
22448                                       agNULL,
22449                                       satIOContext
22450                                       );
22451   if (status != tiSuccess)
22452   {
22453     TI_DBG1(("tdsaDiscoveryStartIDDev: failed in sending %d\n", status));
22454     ostiFreeMemory(tiRoot, osMemHandle, sizeof(tdIORequestBody_t));
22455   }
22456   return status;
22457 }
22458 
22459 /*****************************************************************************/
22460 /*! \brief SAT implementation for tdsaDiscoveryIntStartIDDev.
22461  *
22462  *  This function sends identify device data to SATA device.
22463  *
22464  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
22465  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
22466  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
22467  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
22468  *  \param   satIOContext_t:   Pointer to the SAT IO Context
22469  *
22470  *  \return If command is started successfully
22471  *    - \e tiSuccess:     I/O request successfully initiated.
22472  *    - \e tiBusy:        No resources available, try again later.
22473  *    - \e tiIONoDevice:  Invalid device handle.
22474  *    - \e tiError:       Other errors.
22475  */
22476 /*****************************************************************************/
22477 GLOBAL bit32
22478 tdsaDiscoveryIntStartIDDev(tiRoot_t                  *tiRoot,
22479                            tiIORequest_t             *tiIORequest, /* agNULL */
22480                            tiDeviceHandle_t          *tiDeviceHandle,
22481                            tiScsiInitiatorRequest_t  *tiScsiRequest, /* agNULL */
22482                            satIOContext_t            *satIOContext
22483                            )
22484 {
22485   satInternalIo_t           *satIntIo = agNULL;
22486   satDeviceData_t           *satDevData = agNULL;
22487   tdIORequestBody_t         *tdIORequestBody;
22488   satIOContext_t            *satNewIOContext;
22489   bit32                     status;
22490 
22491   TI_DBG3(("tdsaDiscoveryIntStartIDDev: start\n"));
22492 
22493   satDevData = satIOContext->pSatDevData;
22494 
22495   /* allocate identify device command */
22496   satIntIo = satAllocIntIoResource( tiRoot,
22497                                     tiIORequest,
22498                                     satDevData,
22499                                     sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
22500                                     satIntIo);
22501 
22502   if (satIntIo == agNULL)
22503   {
22504     TI_DBG2(("tdsaDiscoveryIntStartIDDev: can't alloacate\n"));
22505 
22506     return tiError;
22507   }
22508 
22509   /* fill in fields */
22510   /* real ttttttthe one worked and the same; 5/21/07/ */
22511   satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
22512   tdIORequestBody = satIntIo->satIntRequestBody;
22513   satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22514 
22515   satNewIOContext->pSatDevData   = satDevData;
22516   satNewIOContext->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22517   satNewIOContext->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
22518   satNewIOContext->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
22519   satNewIOContext->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
22520   satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
22521   satNewIOContext->interruptContext = tiInterruptContext;
22522   satNewIOContext->satIntIoContext  = satIntIo;
22523 
22524   satNewIOContext->ptiDeviceHandle = agNULL;
22525   satNewIOContext->satOrgIOContext = satIOContext; /* changed */
22526 
22527   /* this is valid only for TD layer generated (not triggered by OS at all) IO */
22528   satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
22529 
22530 
22531   TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS satIOContext %p \n", satIOContext));
22532   TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
22533   TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
22534   TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
22535 
22536 
22537 
22538   TI_DBG3(("tdsaDiscoveryIntStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
22539 
22540   status = tdsaDiscoverySendIDDev(tiRoot,
22541                                   &satIntIo->satIntTiIORequest, /* New tiIORequest */
22542                                   tiDeviceHandle,
22543                                   satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
22544                                   satNewIOContext);
22545 
22546   if (status != tiSuccess)
22547   {
22548     TI_DBG1(("tdsaDiscoveryIntStartIDDev: failed in sending %d\n", status));
22549 
22550     satFreeIntIoResource( tiRoot,
22551                           satDevData,
22552                           satIntIo);
22553 
22554     return tiError;
22555   }
22556 
22557 
22558   TI_DBG6(("tdsaDiscoveryIntStartIDDev: end\n"));
22559 
22560   return status;
22561 }
22562 
22563 
22564 /*****************************************************************************/
22565 /*! \brief SAT implementation for tdsaDiscoverySendIDDev.
22566  *
22567  *  This function prepares identify device data FIS and sends it to SATA device.
22568  *
22569  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
22570  *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
22571  *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
22572  *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
22573  *  \param   satIOContext_t:   Pointer to the SAT IO Context
22574  *
22575  *  \return If command is started successfully
22576  *    - \e tiSuccess:     I/O request successfully initiated.
22577  *    - \e tiBusy:        No resources available, try again later.
22578  *    - \e tiIONoDevice:  Invalid device handle.
22579  *    - \e tiError:       Other errors.
22580  */
22581 /*****************************************************************************/
22582 GLOBAL bit32
22583 tdsaDiscoverySendIDDev(tiRoot_t                  *tiRoot,
22584                        tiIORequest_t             *tiIORequest,
22585                        tiDeviceHandle_t          *tiDeviceHandle,
22586                        tiScsiInitiatorRequest_t  *tiScsiRequest,
22587                        satIOContext_t            *satIOContext
22588                        )
22589 {
22590   bit32                     status;
22591   bit32                     agRequestType;
22592   satDeviceData_t           *pSatDevData;
22593   agsaFisRegHostToDevice_t  *fis;
22594 #ifdef  TD_DEBUG_ENABLE
22595   tdIORequestBody_t         *tdIORequestBody;
22596   satInternalIo_t           *satIntIoContext;
22597 #endif
22598 
22599   pSatDevData   = satIOContext->pSatDevData;
22600   fis           = satIOContext->pFis;
22601   TI_DBG3(("tdsaDiscoverySendIDDev: start\n"));
22602 #ifdef  TD_DEBUG_ENABLE
22603   satIntIoContext = satIOContext->satIntIoContext;
22604   tdIORequestBody = satIntIoContext->satIntRequestBody;
22605 #endif
22606   TI_DBG5(("tdsaDiscoverySendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
22607 
22608   fis->h.fisType        = 0x27;                   /* Reg host to device */
22609   fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
22610   if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
22611       fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0xA1 */
22612   else
22613       fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
22614   fis->h.features       = 0;                      /* FIS reserve */
22615   fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
22616   fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
22617   fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
22618   fis->d.device         = 0;                      /* FIS LBA mode  */
22619   fis->d.lbaLowExp      = 0;
22620   fis->d.lbaMidExp      = 0;
22621   fis->d.lbaHighExp     = 0;
22622   fis->d.featuresExp    = 0;
22623   fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
22624   fis->d.sectorCountExp = 0;
22625   fis->d.reserved4      = 0;
22626   fis->d.control        = 0;                      /* FIS HOB bit clear */
22627   fis->d.reserved5      = 0;
22628 
22629   agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
22630 
22631   /* Initialize CB for SATA completion.
22632    */
22633   satIOContext->satCompleteCB = &tdsaDiscoveryStartIDDevCB;
22634 
22635   /*
22636    * Prepare SGL and send FIS to LL layer.
22637    */
22638   satIOContext->reqType = agRequestType;       /* Save it */
22639 
22640 #ifdef TD_INTERNAL_DEBUG
22641   tdhexdump("tdsaDiscoverySendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
22642 #ifdef  TD_DEBUG_ENABLE
22643   tdhexdump("tdsaDiscoverySendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
22644 #endif
22645 #endif
22646   status = sataLLIOStart( tiRoot,
22647                           tiIORequest,
22648                           tiDeviceHandle,
22649                           tiScsiRequest,
22650                           satIOContext);
22651   TI_DBG3(("tdsaDiscoverySendIDDev: end status %d\n", status));
22652   return status;
22653 }
22654 
22655 
22656 /*****************************************************************************
22657 *! \brief  tdsaDiscoveryStartIDDevCB
22658 *
22659 *   This routine is a callback function for tdsaDiscoverySendIDDev()
22660 *   Using Identify Device Data, this function finds whether devicedata is
22661 *   new or old. If new, add it to the devicelist. This is done as a part
22662 *   of discovery.
22663 *
22664 *  \param   agRoot:      Handles for this instance of SAS/SATA hardware
22665 *  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
22666 *  \param   agIOStatus:  Status of completed I/O.
22667 *  \param   agFirstDword:Pointer to the four bytes of FIS.
22668 *  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
22669 *                        length.
22670 *  \param   agParam:     Additional info based on status.
22671 *  \param   ioContext:   Pointer to satIOContext_t.
22672 *
22673 *  \return: none
22674 *
22675 *****************************************************************************/
22676 void tdsaDiscoveryStartIDDevCB(
22677                                agsaRoot_t        *agRoot,
22678                                agsaIORequest_t   *agIORequest,
22679                                 bit32             agIOStatus,
22680                                 agsaFisHeader_t   *agFirstDword,
22681                                 bit32             agIOInfoLen,
22682                                 void              *agParam,
22683                                 void              *ioContext
22684                                 )
22685 {
22686  /*
22687     In the process of SAT_IDENTIFY_DEVICE during discovery
22688   */
22689   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
22690   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
22691   tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
22692   tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22693   tdIORequestBody_t       *tdIORequestBody;
22694   tdIORequestBody_t       *tdOrgIORequestBody;
22695   satIOContext_t          *satIOContext;
22696   satIOContext_t          *satOrgIOContext;
22697   satIOContext_t          *satNewIOContext;
22698   satInternalIo_t         *satIntIo;
22699   satInternalIo_t         *satNewIntIo = agNULL;
22700   satDeviceData_t         *satDevData;
22701   tiIORequest_t           *tiOrgIORequest = agNULL;
22702 
22703 #ifdef  TD_DEBUG_ENABLE
22704   bit32                     ataStatus = 0;
22705   bit32                     ataError;
22706   agsaFisPioSetupHeader_t   *satPIOSetupHeader = agNULL;
22707 #endif
22708   agsaSATAIdentifyData_t    *pSATAIdData;
22709   bit16                     *tmpptr, tmpptr_tmp;
22710   bit32                     x;
22711   tdsaDeviceData_t          *oneDeviceData = agNULL;
22712   void                      *sglVirtualAddr;
22713   tdsaPortContext_t         *onePortContext = agNULL;
22714   tiPortalContext_t         *tiPortalContext = agNULL;
22715   bit32                     retry_status;
22716 
22717   TI_DBG3(("tdsaDiscoveryStartIDDevCB: start\n"));
22718 
22719   tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
22720   satIOContext           = (satIOContext_t *) ioContext;
22721   satIntIo               = satIOContext->satIntIoContext;
22722   satDevData             = satIOContext->pSatDevData;
22723   oneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
22724   TI_DBG3(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22725   onePortContext = oneDeviceData->tdPortContext;
22726   if (onePortContext == agNULL)
22727   {
22728       TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL\n"));
22729       return;
22730   }
22731   tiPortalContext= onePortContext->tiPortalContext;
22732 
22733   satDevData->IDDeviceValid = agFALSE;
22734 
22735   if (satIntIo == agNULL)
22736   {
22737     TI_DBG1(("tdsaDiscoveryStartIDDevCB: External, OS generated\n"));
22738     TI_DBG1(("tdsaDiscoveryStartIDDevCB: Not possible case\n"));
22739     satOrgIOContext      = satIOContext;
22740     tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22741 
22742     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22743 
22744     satFreeIntIoResource( tiRoot,
22745                           satDevData,
22746                           satIntIo);
22747 
22748     /* clean up TD layer's IORequestBody */
22749     ostiFreeMemory(
22750                    tiRoot,
22751                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22752                    sizeof(tdIORequestBody_t)
22753                    );
22754     return;
22755   }
22756   else
22757   {
22758     TI_DBG3(("tdsaDiscoveryStartIDDevCB: Internal, TD generated\n"));
22759     satOrgIOContext        = satIOContext->satOrgIOContext;
22760     if (satOrgIOContext == agNULL)
22761     {
22762       TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NULL\n"));
22763       return;
22764     }
22765     else
22766     {
22767       TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NOT NULL\n"));
22768       tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22769       sglVirtualAddr         = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
22770     }
22771   }
22772 
22773   tiOrgIORequest           = tdIORequestBody->tiIORequest;
22774   tdIORequestBody->ioCompleted = agTRUE;
22775   tdIORequestBody->ioStarted = agFALSE;
22776 
22777   TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22778 
22779   /* protect against double completion for old port */
22780   if (satOrgIOContext->pid != oneDeviceData->tdPortContext->id)
22781   {
22782     TI_DBG3(("tdsaDiscoveryStartIDDevCB: incorrect pid\n"));
22783     TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22784     TI_DBG3(("tdsaDiscoveryStartIDDevCB: tiPortalContext pid %d\n", oneDeviceData->tdPortContext->id));
22785 
22786     satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22787 
22788     satFreeIntIoResource( tiRoot,
22789                           satDevData,
22790                           satIntIo);
22791 
22792     /* clean up TD layer's IORequestBody */
22793     ostiFreeMemory(
22794                    tiRoot,
22795                    tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22796                    sizeof(tdIORequestBody_t)
22797                    );
22798 
22799     return;
22800   }
22801 
22802   /* completion after portcontext is invalidated */
22803   if (onePortContext != agNULL)
22804   {
22805     if (onePortContext->valid == agFALSE)
22806     {
22807       TI_DBG1(("tdsaDiscoveryStartIDDevCB: portcontext is invalid\n"));
22808       TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
22809       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22810 
22811       satFreeIntIoResource( tiRoot,
22812                             satDevData,
22813                             satIntIo);
22814 
22815       /* clean up TD layer's IORequestBody */
22816       ostiFreeMemory(
22817                      tiRoot,
22818                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22819                      sizeof(tdIORequestBody_t)
22820                      );
22821 
22822       /* no notification to OS layer */
22823       return;
22824     }
22825   }
22826 
22827   if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
22828   {
22829     TI_DBG1(("tdsaDiscoveryStartIDDevCB: agFirstDword is NULL when error, status %d\n", agIOStatus));
22830     TI_DBG1(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22831 
22832     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22833     {
22834       satIOContext->pSatDevData->satPendingNONNCQIO--;
22835       satIOContext->pSatDevData->satPendingIO--;
22836       retry_status = sataLLIOStart(tiRoot,
22837                                    &satIntIo->satIntTiIORequest,
22838            &(oneDeviceData->tiDeviceHandle),
22839            satIOContext->tiScsiXchg,
22840            satIOContext);
22841       if (retry_status != tiSuccess)
22842       {
22843         /* simply give up */
22844         satDevData->ID_Retries = 0;
22845         satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22846 
22847         satFreeIntIoResource( tiRoot,
22848                               satDevData,
22849                               satIntIo);
22850 
22851         /* clean up TD layer's IORequestBody */
22852         ostiFreeMemory(
22853                        tiRoot,
22854                        tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22855                        sizeof(tdIORequestBody_t)
22856                        );
22857         return;
22858       }
22859       satDevData->ID_Retries++;
22860       tdIORequestBody->ioCompleted = agFALSE;
22861       tdIORequestBody->ioStarted = agTRUE;
22862       return;
22863     }
22864     else
22865     {
22866       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22867       satFreeIntIoResource( tiRoot,
22868                             satDevData,
22869                             satIntIo);
22870 
22871       /* clean up TD layer's IORequestBody */
22872       ostiFreeMemory(
22873                      tiRoot,
22874                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22875                      sizeof(tdIORequestBody_t)
22876                      );
22877       if (tdsaAllShared->ResetInDiscovery != 0)
22878       {
22879         /* ResetInDiscovery in on */
22880         if (satDevData->NumOfIDRetries <= 0)
22881         {
22882           satDevData->NumOfIDRetries++;
22883           satDevData->ID_Retries = 0;
22884           /* send link reset */
22885           tdsaPhyControlSend(tiRoot,
22886                              oneDeviceData,
22887                              SMP_PHY_CONTROL_HARD_RESET,
22888                              agNULL,
22889                              tdsaRotateQnumber(tiRoot, oneDeviceData)
22890                             );
22891         }
22892       }
22893       return;
22894     }
22895   }
22896 
22897   if (agIOStatus == OSSA_IO_ABORTED ||
22898       agIOStatus == OSSA_IO_UNDERFLOW ||
22899       agIOStatus == OSSA_IO_XFER_ERROR_BREAK ||
22900       agIOStatus == OSSA_IO_XFER_ERROR_PHY_NOT_READY ||
22901       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
22902       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
22903       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
22904       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
22905       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
22906       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY ||
22907       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
22908       agIOStatus == OSSA_IO_XFER_ERROR_NAK_RECEIVED ||
22909       agIOStatus == OSSA_IO_XFER_ERROR_DMA ||
22910       agIOStatus == OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT ||
22911       agIOStatus == OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE ||
22912       agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT ||
22913       agIOStatus == OSSA_IO_NO_DEVICE ||
22914       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
22915       agIOStatus == OSSA_IO_PORT_IN_RESET ||
22916       agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
22917       agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
22918       agIOStatus == OSSA_IO_DS_IN_ERROR
22919       )
22920   {
22921     TI_DBG1(("tdsaDiscoveryStartIDDevCB: OSSA_IO_OPEN_CNX_ERROR 0x%x\n", agIOStatus));
22922     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22923     {
22924       satIOContext->pSatDevData->satPendingNONNCQIO--;
22925       satIOContext->pSatDevData->satPendingIO--;
22926       retry_status = sataLLIOStart(tiRoot,
22927                                    &satIntIo->satIntTiIORequest,
22928            &(oneDeviceData->tiDeviceHandle),
22929            satIOContext->tiScsiXchg,
22930            satIOContext);
22931       if (retry_status != tiSuccess)
22932       {
22933         /* simply give up */
22934         satDevData->ID_Retries = 0;
22935         satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22936 
22937         satFreeIntIoResource( tiRoot,
22938                               satDevData,
22939                               satIntIo);
22940 
22941         /* clean up TD layer's IORequestBody */
22942         ostiFreeMemory(
22943                        tiRoot,
22944                        tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22945                        sizeof(tdIORequestBody_t)
22946                        );
22947         return;
22948       }
22949       satDevData->ID_Retries++;
22950       tdIORequestBody->ioCompleted = agFALSE;
22951       tdIORequestBody->ioStarted = agTRUE;
22952       return;
22953     }
22954     else
22955     {
22956       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22957       satFreeIntIoResource( tiRoot,
22958                             satDevData,
22959                             satIntIo);
22960 
22961       /* clean up TD layer's IORequestBody */
22962       ostiFreeMemory(
22963                      tiRoot,
22964                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22965                      sizeof(tdIORequestBody_t)
22966                      );
22967       if (tdsaAllShared->ResetInDiscovery != 0)
22968       {
22969         /* ResetInDiscovery in on */
22970         if (satDevData->NumOfIDRetries <= 0)
22971         {
22972           satDevData->NumOfIDRetries++;
22973           satDevData->ID_Retries = 0;
22974           /* send link reset */
22975           tdsaPhyControlSend(tiRoot,
22976                              oneDeviceData,
22977                              SMP_PHY_CONTROL_HARD_RESET,
22978                              agNULL,
22979                              tdsaRotateQnumber(tiRoot, oneDeviceData)
22980                             );
22981         }
22982       }
22983       return;
22984     }
22985   }
22986 
22987   if ( agIOStatus != OSSA_IO_SUCCESS ||
22988        (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
22989      )
22990   {
22991 #ifdef  TD_DEBUG_ENABLE
22992     /* only agsaFisPioSetup_t is expected */
22993     satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
22994     ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
22995     ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
22996 #endif
22997     TI_DBG1(("tdsaDiscoveryStartIDDevCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
22998 
22999     if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
23000     {
23001       satIOContext->pSatDevData->satPendingNONNCQIO--;
23002       satIOContext->pSatDevData->satPendingIO--;
23003       retry_status = sataLLIOStart(tiRoot,
23004                                    &satIntIo->satIntTiIORequest,
23005            &(oneDeviceData->tiDeviceHandle),
23006            satIOContext->tiScsiXchg,
23007            satIOContext);
23008       if (retry_status != tiSuccess)
23009       {
23010         /* simply give up */
23011         satDevData->ID_Retries = 0;
23012         satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23013 
23014         satFreeIntIoResource( tiRoot,
23015                               satDevData,
23016                               satIntIo);
23017 
23018         /* clean up TD layer's IORequestBody */
23019         ostiFreeMemory(
23020                        tiRoot,
23021                        tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23022                        sizeof(tdIORequestBody_t)
23023                        );
23024         return;
23025       }
23026       satDevData->ID_Retries++;
23027       tdIORequestBody->ioCompleted = agFALSE;
23028       tdIORequestBody->ioStarted = agTRUE;
23029       return;
23030     }
23031     else
23032     {
23033       satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23034       satFreeIntIoResource( tiRoot,
23035                             satDevData,
23036                             satIntIo);
23037 
23038       /* clean up TD layer's IORequestBody */
23039       ostiFreeMemory(
23040                      tiRoot,
23041                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23042                      sizeof(tdIORequestBody_t)
23043                      );
23044       if (tdsaAllShared->ResetInDiscovery != 0)
23045       {
23046         /* ResetInDiscovery in on */
23047         if (satDevData->NumOfIDRetries <= 0)
23048         {
23049           satDevData->NumOfIDRetries++;
23050           satDevData->ID_Retries = 0;
23051           /* send link reset */
23052           tdsaPhyControlSend(tiRoot,
23053                              oneDeviceData,
23054                              SMP_PHY_CONTROL_HARD_RESET,
23055                              agNULL,
23056                              tdsaRotateQnumber(tiRoot, oneDeviceData)
23057                             );
23058         }
23059       }
23060       return;
23061     }
23062   }
23063 
23064 
23065   /* success */
23066   TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success\n"));
23067   TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success did %d\n", oneDeviceData->id));
23068 
23069   /* Convert to host endian */
23070   tmpptr = (bit16*)sglVirtualAddr;
23071   for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
23072   {
23073     OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
23074     *tmpptr = tmpptr_tmp;
23075     tmpptr++;
23076   }
23077 
23078   pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
23079   //tdhexdump("satAddSATAIDDevCB before", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23080 
23081   TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
23082   TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD satIOContext %p \n", satIOContext));
23083   TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
23084   TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
23085 
23086 
23087    /* copy ID Dev data to satDevData */
23088   satDevData->satIdentifyData = *pSATAIdData;
23089   satDevData->IDDeviceValid = agTRUE;
23090 
23091 #ifdef TD_INTERNAL_DEBUG
23092   tdhexdump("tdsaDiscoveryStartIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23093   tdhexdump("tdsaDiscoveryStartIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
23094 #endif
23095 
23096   /* set satDevData fields from IndentifyData */
23097   satSetDevInfo(satDevData,pSATAIdData);
23098   satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23099 
23100   satFreeIntIoResource( tiRoot,
23101                         satDevData,
23102                         satIntIo);
23103 
23104   if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
23105   {
23106       /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
23107       satNewIntIo = satAllocIntIoResource( tiRoot,
23108                                        tiOrgIORequest,
23109                                        satDevData,
23110                                        0,
23111                                        satNewIntIo);
23112 
23113       if (satNewIntIo == agNULL)
23114       {
23115         TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
23116           /* clean up TD layer's IORequestBody */
23117         ostiFreeMemory(
23118                      tiRoot,
23119                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23120                      sizeof(tdIORequestBody_t)
23121                      );
23122         return;
23123       } /* end memory allocation */
23124 
23125       satNewIOContext = satPrepareNewIO(satNewIntIo,
23126                                         tiOrgIORequest,
23127                                         satDevData,
23128                                         agNULL,
23129                                         satOrgIOContext
23130                                         );
23131       /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
23132       retry_status = satSetFeatures(tiRoot,
23133                                  &satNewIntIo->satIntTiIORequest,
23134                                  satNewIOContext->ptiDeviceHandle,
23135                                  &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
23136                                  satNewIOContext,
23137                                  agFALSE);
23138       if (retry_status != tiSuccess)
23139       {
23140           satFreeIntIoResource(tiRoot, satDevData, satIntIo);
23141           /* clean up TD layer's IORequestBody */
23142           ostiFreeMemory(
23143                  tiRoot,
23144                  tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23145                  sizeof(tdIORequestBody_t)
23146                  );
23147       }
23148   }
23149   else
23150   {
23151       /* clean up TD layer's IORequestBody */
23152       ostiFreeMemory(
23153                      tiRoot,
23154                      tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23155                      sizeof(tdIORequestBody_t)
23156                      );
23157       if (onePortContext != agNULL)
23158       {
23159         if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED)
23160         {
23161           TI_DBG1(("tdsaDiscoveryStartIDDevCB: ID completed after discovery is done; tiDeviceArrival\n"));
23162           /* in case registration is finished after discovery is finished */
23163           ostiInitiatorEvent(
23164                              tiRoot,
23165                              tiPortalContext,
23166                              agNULL,
23167                              tiIntrEventTypeDeviceChange,
23168                              tiDeviceArrival,
23169                              agNULL
23170                              );
23171         }
23172       }
23173       else
23174       {
23175         TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL, wrong\n"));
23176       }
23177   }
23178   TI_DBG3(("tdsaDiscoveryStartIDDevCB: end\n"));
23179   return;
23180 }
23181 /*****************************************************************************
23182 *! \brief  satAbort
23183 *
23184 *   This routine does local abort for outstanding FIS.
23185 *
23186 *  \param   agRoot:         Handles for this instance of SAS/SATA hardware
23187 *  \param   satIOContext:   Pointer to satIOContext_t.
23188 *
23189 *  \return: none
23190 *
23191 *****************************************************************************/
23192 GLOBAL void satAbort(agsaRoot_t        *agRoot,
23193                      satIOContext_t    *satIOContext)
23194 {
23195   tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
23196   tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
23197   tdIORequestBody_t       *tdIORequestBody; /* io to be aborted */
23198   tdIORequestBody_t       *tdAbortIORequestBody; /* abort io itself */
23199   agsaIORequest_t         *agToBeAbortedIORequest; /* io to be aborted */
23200   agsaIORequest_t         *agAbortIORequest;  /* abort io itself */
23201   bit32                   PhysUpper32;
23202   bit32                   PhysLower32;
23203   bit32                   memAllocStatus;
23204   void                    *osMemHandle;
23205 
23206   TI_DBG1(("satAbort: start\n"));
23207 
23208   if (satIOContext == agNULL)
23209   {
23210     TI_DBG1(("satAbort: satIOContext is NULL, wrong\n"));
23211     return;
23212   }
23213   tdIORequestBody = (tdIORequestBody_t *)satIOContext->tiRequestBody;
23214   agToBeAbortedIORequest = (agsaIORequest_t *)&(tdIORequestBody->agIORequest);
23215   /* allocating agIORequest for abort itself */
23216   memAllocStatus = ostiAllocMemory(
23217                                    tiRoot,
23218                                    &osMemHandle,
23219                                    (void **)&tdAbortIORequestBody,
23220                                    &PhysUpper32,
23221                                    &PhysLower32,
23222                                    8,
23223                                    sizeof(tdIORequestBody_t),
23224                                    agTRUE
23225                                    );
23226 
23227   if (memAllocStatus != tiSuccess)
23228   {
23229     /* let os process IO */
23230     TI_DBG1(("satAbort: ostiAllocMemory failed...\n"));
23231     return;
23232   }
23233 
23234   if (tdAbortIORequestBody == agNULL)
23235   {
23236     /* let os process IO */
23237     TI_DBG1(("satAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
23238     return;
23239   }
23240   /* setup task management structure */
23241   tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
23242   tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
23243 
23244   /* initialize agIORequest */
23245   agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
23246   agAbortIORequest->osData = (void *) tdAbortIORequestBody;
23247   agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
23248 
23249 
23250   /*
23251    * Issue abort
23252    */
23253   saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, agNULL );
23254 
23255 
23256   TI_DBG1(("satAbort: end\n"));
23257   return;
23258 }
23259 
23260 /*****************************************************************************
23261  *! \brief  satSATADeviceReset
23262  *
23263  *   This routine is called to reset all phys of port which a device belongs to
23264  *
23265  *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
23266  *  \param   oneDeviceData:    Pointer to the device data.
23267  *  \param   flag:             reset flag
23268  *
23269  *  \return:
23270  *
23271  *  none
23272  *
23273  *****************************************************************************/
23274 osGLOBAL void
23275 satSATADeviceReset(                                                                                                  tiRoot_t            *tiRoot,
23276                 tdsaDeviceData_t    *oneDeviceData,
23277                 bit32               flag)
23278 {
23279   agsaRoot_t              *agRoot;
23280   tdsaPortContext_t       *onePortContext;
23281   bit32                   i;
23282 
23283   TI_DBG1(("satSATADeviceReset: start\n"));
23284   agRoot         = oneDeviceData->agRoot;
23285   onePortContext = oneDeviceData->tdPortContext;
23286 
23287   if (agRoot == agNULL)
23288   {
23289     TI_DBG1(("satSATADeviceReset: Error!!! agRoot is NULL\n"));
23290     return;
23291   }
23292   if (onePortContext == agNULL)
23293   {
23294     TI_DBG1(("satSATADeviceReset: Error!!! onePortContext is NULL\n"));
23295     return;
23296   }
23297 
23298    for(i=0;i<TD_MAX_NUM_PHYS;i++)
23299   {
23300     if (onePortContext->PhyIDList[i] == agTRUE)
23301     {
23302       saLocalPhyControl(agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, flag, agNULL);
23303     }
23304   }
23305 
23306   return;
23307 }
23308 
23309 #endif  /* #ifdef SATA_ENABLE */
23310