]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - sys/dev/pms/RefTisa/tisa/sassata/sata/host/sat.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / sys / dev / pms / RefTisa / tisa / sassata / sata / host / sat.c
1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved. 
3 *
4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided 
5 *that the following conditions are met: 
6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7 *following disclaimer. 
8 *2. Redistributions in binary form must reproduce the above copyright notice, 
9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10 *with the distribution. 
11 *
12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 
13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20
21 ********************************************************************************/
22 /*****************************************************************************/
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 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 */