sat.c revision 285809
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 *****************************************************************************/
103GLOBAL 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
561ext:
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/*****************************************************************************/
580void 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
658void 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/*****************************************************************************/
738GLOBAL 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/*****************************************************************************/
852GLOBAL 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/*****************************************************************************/
937GLOBAL 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/*****************************************************************************/
1041GLOBAL 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/*****************************************************************************/
1118GLOBAL 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/*****************************************************************************/
1196GLOBAL 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 */
1655GLOBAL 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/*****************************************************************************/
1925GLOBAL 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/*****************************************************************************/
2356GLOBAL 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/*****************************************************************************/
2804GLOBAL 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/*****************************************************************************/
3134GLOBAL 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/*****************************************************************************/
3566GLOBAL 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/*****************************************************************************/
3988GLOBAL 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/*****************************************************************************/
4419GLOBAL 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/*****************************************************************************/
4696GLOBAL 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/*****************************************************************************/
5023GLOBAL 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/*****************************************************************************/
5209GLOBAL 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/*****************************************************************************/
5291GLOBAL 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/*****************************************************************************/
5408GLOBAL 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/*****************************************************************************/
5663GLOBAL 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/*****************************************************************************/
5755GLOBAL 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/*****************************************************************************/
5868GLOBAL 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/*****************************************************************************/
6111GLOBAL 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/*****************************************************************************/
6360GLOBAL 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/*****************************************************************************/
6919GLOBAL 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/*****************************************************************************/
7774GLOBAL 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
8041GLOBAL 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/*****************************************************************************/
8200GLOBAL 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/*****************************************************************************/
8482GLOBAL 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/*****************************************************************************/
8771GLOBAL 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/*****************************************************************************/
8992GLOBAL 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/*****************************************************************************/
9591GLOBAL 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/*****************************************************************************/
9702GLOBAL 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/*****************************************************************************/
9810GLOBAL 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/*****************************************************************************/
10150GLOBAL 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/*****************************************************************************/
10230GLOBAL 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/*****************************************************************************/
10341GLOBAL 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/*****************************************************************************/
10785GLOBAL 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/*****************************************************************************/
10880GLOBAL 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/*****************************************************************************/
10975GLOBAL 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/*****************************************************************************/
11070GLOBAL 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/*****************************************************************************/
11118GLOBAL 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/*****************************************************************************/
11241GLOBAL 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/*****************************************************************************/
11318GLOBAL 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/*****************************************************************************/
11390GLOBAL 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/*****************************************************************************/
11466GLOBAL 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/*****************************************************************************/
11595GLOBAL 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/*****************************************************************************/
12021GLOBAL 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/*****************************************************************************/
12503GLOBAL 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/*****************************************************************************/
12637GLOBAL 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/*****************************************************************************/
13155GLOBAL 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/*****************************************************************************/
13300GLOBAL 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/*****************************************************************************/
13447GLOBAL 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
13863GLOBAL 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/*****************************************************************************/
14215GLOBAL 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/*****************************************************************************/
14309GLOBAL 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
14715GLOBAL 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
14786GLOBAL 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  */
15050GLOBAL 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
15217GLOBAL 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/*****************************************************************************/
15377GLOBAL 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/*****************************************************************************/
15811GLOBAL 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*/
16012GLOBAL 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*/
16248GLOBAL 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/*****************************************************************************/
16447GLOBAL 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 */
16631GLOBAL 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 */
16769GLOBAL 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/*****************************************************************************/
16998GLOBAL 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 *****************************************************************************/
17056GLOBAL 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 */
17170osGLOBAL 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 *****************************************************************************/
17306osGLOBAL 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 *****************************************************************************/
17394osGLOBAL 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
17450osGLOBAL 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 *****************************************************************************/
17527osGLOBAL 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 *****************************************************************************/
17698osGLOBAL 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 *****************************************************************************/
17835osGLOBAL 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/*****************************************************************************/
18139GLOBAL 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/*****************************************************************************/
18329GLOBAL 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/*****************************************************************************/
18365GLOBAL 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/*****************************************************************************/
18520GLOBAL 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/*****************************************************************************/
18642GLOBAL 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/*****************************************************************************/
18703GLOBAL 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/*****************************************************************************/
18779GLOBAL 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/*****************************************************************************/
18955GLOBAL 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/*****************************************************************************/
19193GLOBAL 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/*****************************************************************************/
19267GLOBAL 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*/
19377GLOBAL 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/*****************************************************************************/
19502bit32 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/*****************************************************************************/
19529bit32 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/*****************************************************************************/
19555bit32 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/*****************************************************************************/
19582bit32 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*/
19615bit32 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/*****************************************************************************/
19642bit32 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*/
19677bit32 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*/
19729bit32 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*/
19810bit32 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*/
19900bit32 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*****************************************************************************/
19950GLOBAL void
19951satBitSet(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*****************************************************************************/
19968GLOBAL void
19969satBitClear(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*****************************************************************************/
19987GLOBAL agBOOLEAN
19988satBitTest(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/*******************************************************************************/
20006GLOBAL 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/*******************************************************************************/
20042GLOBAL 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 */
20086osGLOBAL 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 */
20177GLOBAL bit32
20178satStartResetDevice(
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*/
20304GLOBAL bit32
20305satResetDevice(
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*****************************************************************************/
20393GLOBAL 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/*****************************************************************************/
20656GLOBAL 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*****************************************************************************/
20744GLOBAL 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/*****************************************************************************/
20974GLOBAL 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/*****************************************************************************/
21085GLOBAL 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*****************************************************************************/
21165GLOBAL 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/*****************************************************************************/
21398GLOBAL 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/*****************************************************************************/
21508GLOBAL 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*****************************************************************************/
21601void 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*****************************************************************************/
22237void 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*****************************************************************************/
22282void 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/*****************************************************************************/
22360GLOBAL bit32
22361tdsaDiscoveryStartIDDev(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/*****************************************************************************/
22477GLOBAL bit32
22478tdsaDiscoveryIntStartIDDev(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/*****************************************************************************/
22582GLOBAL bit32
22583tdsaDiscoverySendIDDev(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*****************************************************************************/
22676void 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*****************************************************************************/
23192GLOBAL 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 *****************************************************************************/
23274osGLOBAL void
23275satSATADeviceReset(                                                                                                  tiRoot_t            *tiRoot,
23276                tdsaDeviceData_t    *oneDeviceData,
23277                bit32               flag)
23278{
23279  agsaRoot_t              *agRoot;
23280  tdsaPortContext_t       *onePortContext;
23281  bit32                   i;
23282
23283  TI_DBG1(("satSATADeviceReset: start\n"));
23284  agRoot         = oneDeviceData->agRoot;
23285  onePortContext = oneDeviceData->tdPortContext;
23286
23287  if (agRoot == agNULL)
23288  {
23289    TI_DBG1(("satSATADeviceReset: Error!!! agRoot is NULL\n"));
23290    return;
23291  }
23292  if (onePortContext == agNULL)
23293  {
23294    TI_DBG1(("satSATADeviceReset: Error!!! onePortContext is NULL\n"));
23295    return;
23296  }
23297
23298   for(i=0;i<TD_MAX_NUM_PHYS;i++)
23299  {
23300    if (onePortContext->PhyIDList[i] == agTRUE)
23301    {
23302      saLocalPhyControl(agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, flag, agNULL);
23303    }
23304  }
23305
23306  return;
23307}
23308
23309#endif  /* #ifdef SATA_ENABLE */
23310