1/*******************************************************************************
2*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3*
4*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5*that the following conditions are met:
6*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7*following disclaimer.
8*2. Redistributions in binary form must reproduce the above copyright notice,
9*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10*with the distribution.
11*
12*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20
21********************************************************************************/
22/*****************************************************************************/
23/** \file
24 *
25 * The file implementing SCSI/ATA Translation (SAT).
26 * The routines in this file are independent from HW LL API.
27 *
28 */
29/*****************************************************************************/
30#include <sys/cdefs.h>
31#include <dev/pms/config.h>
32
33#include <dev/pms/freebsd/driver/common/osenv.h>
34#include <dev/pms/freebsd/driver/common/ostypes.h>
35#include <dev/pms/freebsd/driver/common/osdebug.h>
36
37#ifdef SATA_ENABLE
38
39#include <dev/pms/RefTisa/sallsdk/api/sa.h>
40#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
41#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
42
43#include <dev/pms/RefTisa/tisa/api/titypes.h>
44#include <dev/pms/RefTisa/tisa/api/ostiapi.h>
45#include <dev/pms/RefTisa/tisa/api/tiapi.h>
46#include <dev/pms/RefTisa/tisa/api/tiglobal.h>
47
48#ifdef FDS_SM
49#include <dev/pms/RefTisa/sat/api/sm.h>
50#include <dev/pms/RefTisa/sat/api/smapi.h>
51#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
52#endif
53
54#ifdef FDS_DM
55#include <dev/pms/RefTisa/discovery/api/dm.h>
56#include <dev/pms/RefTisa/discovery/api/dmapi.h>
57#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
58#endif
59
60#include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
61#include <dev/pms/freebsd/driver/common/osstring.h>
62#include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
63
64#ifdef INITIATOR_DRIVER
65#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
66#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
67#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
68#endif
69
70#ifdef TARGET_DRIVER
71#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
72#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
73#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
74#endif
75
76#include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
77#include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
78
79#include <dev/pms/RefTisa/tisa/sassata/sata/host/sat.h>
80#include <dev/pms/RefTisa/tisa/sassata/sata/host/satproto.h>
81
82/*****************************************************************************
83 *! \brief  satIOStart
84 *
85 *   This routine is called to initiate a new SCSI request to SATL.
86 *
87 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
88 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
89 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
90 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
91 *  \param   satIOContext_t:   Pointer to the SAT IO Context
92 *
93 *  \return:
94 *
95 *  \e tiSuccess:     I/O request successfully initiated.
96 *  \e tiBusy:        No resources available, try again later.
97 *  \e tiIONoDevice:  Invalid device handle.
98 *  \e tiError:       Other errors that prevent the I/O request to be started.
99 *
100 *
101 *****************************************************************************/
102GLOBAL bit32  satIOStart(
103                   tiRoot_t                  *tiRoot,
104                   tiIORequest_t             *tiIORequest,
105                   tiDeviceHandle_t          *tiDeviceHandle,
106                   tiScsiInitiatorRequest_t  *tiScsiRequest,
107                   satIOContext_t            *satIOContext
108                  )
109{
110
111  bit32             retVal = tiSuccess;
112  satDeviceData_t   *pSatDevData;
113  scsiRspSense_t    *pSense;
114  tiIniScsiCmnd_t   *scsiCmnd;
115  tiLUN_t           *pLun;
116  satInternalIo_t   *pSatIntIo;
117#ifdef  TD_DEBUG_ENABLE
118  tdsaDeviceData_t  *oneDeviceData;
119#endif
120
121  pSense        = satIOContext->pSense;
122  pSatDevData   = satIOContext->pSatDevData;
123  scsiCmnd      = &tiScsiRequest->scsiCmnd;
124  pLun          = &scsiCmnd->lun;
125
126  /*
127   * Reject all other LUN other than LUN 0.
128   */
129  if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
130         pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) &&
131        (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)
132     )
133  {
134    TI_DBG1(("satIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
135                 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
136    satSetSensePayload( pSense,
137                        SCSI_SNSKEY_ILLEGAL_REQUEST,
138                        0,
139                        SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
140                        satIOContext);
141
142    ostiInitiatorIOCompleted( tiRoot,
143                              tiIORequest,
144                              tiIOSuccess,
145                              SCSI_STAT_CHECK_CONDITION,
146                              satIOContext->pTiSenseData,
147                              satIOContext->interruptContext );
148    retVal = tiSuccess;
149    goto ext;
150  }
151
152  TI_DBG6(("satIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
153
154  /* this may happen after tiCOMReset until OS sends inquiry */
155  if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
156  {
157#ifdef  TD_DEBUG_ENABLE
158    oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
159#endif
160    TI_DBG1(("satIOStart: invalid identify device data did %d\n", oneDeviceData->id));
161    retVal = tiIONoDevice;
162    goto ext;
163  }
164  /*
165   * Check if we need to return BUSY, i.e. recovery in progress
166   */
167  if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
168  {
169#ifdef  TD_DEBUG_ENABLE
170    oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
171#endif
172    TI_DBG1(("satIOStart: IN RECOVERY STATE cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
173                 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
174    TI_DBG1(("satIOStart: IN RECOVERY STATE did %d\n", oneDeviceData->id));
175
176    TI_DBG1(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
177    TI_DBG1(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
178    retVal = tiError;
179    goto ext;
180//    return tiBusy;
181  }
182
183  if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
184  {
185     if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
186     {
187        return satReportLun(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
188     }
189     else
190     {
191        return satPacket(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
192     }
193  }
194  else /* pSatDevData->satDeviceType != SATA_ATAPI_DEVICE */
195  {
196     /* Parse CDB */
197     switch(scsiCmnd->cdb[0])
198     {
199       case SCSIOPC_READ_6:
200         retVal = satRead6( tiRoot,
201                            tiIORequest,
202                            tiDeviceHandle,
203                            tiScsiRequest,
204                            satIOContext);
205         break;
206
207       case SCSIOPC_READ_10:
208         retVal = satRead10( tiRoot,
209                             tiIORequest,
210                             tiDeviceHandle,
211                             tiScsiRequest,
212                             satIOContext);
213         break;
214
215       case SCSIOPC_READ_12:
216         TI_DBG5(("satIOStart: SCSIOPC_READ_12\n"));
217         retVal = satRead12( tiRoot,
218                             tiIORequest,
219                             tiDeviceHandle,
220                             tiScsiRequest,
221                             satIOContext);
222         break;
223
224       case SCSIOPC_READ_16:
225         retVal = satRead16( tiRoot,
226                             tiIORequest,
227                             tiDeviceHandle,
228                             tiScsiRequest,
229                             satIOContext);
230         break;
231
232       case SCSIOPC_WRITE_6:
233         retVal = satWrite6( tiRoot,
234                             tiIORequest,
235                             tiDeviceHandle,
236                             tiScsiRequest,
237                             satIOContext);
238         break;
239
240       case SCSIOPC_WRITE_10:
241         retVal = satWrite10( tiRoot,
242                              tiIORequest,
243                              tiDeviceHandle,
244                              tiScsiRequest,
245                              satIOContext);
246         break;
247
248       case SCSIOPC_WRITE_12:
249         TI_DBG5(("satIOStart: SCSIOPC_WRITE_12 \n"));
250         retVal = satWrite12( tiRoot,
251                              tiIORequest,
252                              tiDeviceHandle,
253                              tiScsiRequest,
254                              satIOContext);
255
256         break;
257
258       case SCSIOPC_WRITE_16:
259         TI_DBG5(("satIOStart: SCSIOPC_WRITE_16\n"));
260         retVal = satWrite16( tiRoot,
261                              tiIORequest,
262                              tiDeviceHandle,
263                              tiScsiRequest,
264                              satIOContext);
265
266         break;
267
268       case SCSIOPC_VERIFY_10:
269         retVal = satVerify10( tiRoot,
270                               tiIORequest,
271                               tiDeviceHandle,
272                               tiScsiRequest,
273                               satIOContext);
274         break;
275
276       case SCSIOPC_VERIFY_12:
277         TI_DBG5(("satIOStart: SCSIOPC_VERIFY_12\n"));
278         retVal = satVerify12( tiRoot,
279                               tiIORequest,
280                               tiDeviceHandle,
281                               tiScsiRequest,
282                               satIOContext);
283         break;
284
285       case SCSIOPC_VERIFY_16:
286         TI_DBG5(("satIOStart: SCSIOPC_VERIFY_16\n"));
287         retVal = satVerify16( tiRoot,
288                               tiIORequest,
289                               tiDeviceHandle,
290                               tiScsiRequest,
291                               satIOContext);
292         break;
293
294       case SCSIOPC_TEST_UNIT_READY:
295         retVal = satTestUnitReady( tiRoot,
296                                    tiIORequest,
297                                    tiDeviceHandle,
298                                    tiScsiRequest,
299                                    satIOContext);
300         break;
301
302       case SCSIOPC_INQUIRY:
303         retVal = satInquiry( tiRoot,
304                              tiIORequest,
305                              tiDeviceHandle,
306                              tiScsiRequest,
307                              satIOContext);
308         break;
309
310       case SCSIOPC_REQUEST_SENSE:
311         retVal = satRequestSense( tiRoot,
312                                   tiIORequest,
313                                   tiDeviceHandle,
314                                   tiScsiRequest,
315                                   satIOContext);
316         break;
317
318       case SCSIOPC_MODE_SENSE_6:
319         retVal = satModeSense6( tiRoot,
320                                 tiIORequest,
321                                 tiDeviceHandle,
322                                 tiScsiRequest,
323                                 satIOContext);
324         break;
325
326       case SCSIOPC_MODE_SENSE_10:
327         retVal = satModeSense10( tiRoot,
328                                 tiIORequest,
329                                 tiDeviceHandle,
330                                 tiScsiRequest,
331                                 satIOContext);
332         break;
333
334
335       case SCSIOPC_READ_CAPACITY_10:
336         retVal = satReadCapacity10( tiRoot,
337                                     tiIORequest,
338                                     tiDeviceHandle,
339                                     tiScsiRequest,
340                                     satIOContext);
341         break;
342
343       case SCSIOPC_READ_CAPACITY_16:
344         retVal = satReadCapacity16( tiRoot,
345                                     tiIORequest,
346                                     tiDeviceHandle,
347                                     tiScsiRequest,
348                                     satIOContext);
349         break;
350
351       case SCSIOPC_REPORT_LUN:
352         retVal = satReportLun( tiRoot,
353                                tiIORequest,
354                                tiDeviceHandle,
355                                tiScsiRequest,
356                                satIOContext);
357         break;
358
359       case SCSIOPC_FORMAT_UNIT:
360         TI_DBG5(("satIOStart: SCSIOPC_FORMAT_UNIT\n"));
361         retVal = satFormatUnit( tiRoot,
362                                 tiIORequest,
363                                 tiDeviceHandle,
364                                 tiScsiRequest,
365                                 satIOContext);
366         break;
367       case SCSIOPC_SEND_DIAGNOSTIC: /* Table 28, p40 */
368         TI_DBG5(("satIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
369         retVal = satSendDiagnostic( tiRoot,
370                                     tiIORequest,
371                                     tiDeviceHandle,
372                                     tiScsiRequest,
373                                     satIOContext);
374         break;
375
376       case SCSIOPC_START_STOP_UNIT:
377         TI_DBG5(("satIOStart: SCSIOPC_START_STOP_UNIT\n"));
378         retVal = satStartStopUnit( tiRoot,
379                                    tiIORequest,
380                                    tiDeviceHandle,
381                                    tiScsiRequest,
382                                    satIOContext);
383         break;
384
385       case SCSIOPC_WRITE_SAME_10: /*  sector and LBA; SAT p64 case 3 accessing payload and very
386                                      inefficient now */
387         TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_10\n"));
388         retVal = satWriteSame10( tiRoot,
389                                  tiIORequest,
390                                  tiDeviceHandle,
391                                  tiScsiRequest,
392                                  satIOContext);
393         break;
394
395       case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */
396         TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_16\n"));
397         retVal = satWriteSame16( tiRoot,
398                                  tiIORequest,
399                                  tiDeviceHandle,
400                                  tiScsiRequest,
401                                  satIOContext);
402         break;
403
404       case SCSIOPC_LOG_SENSE: /* SCT and log parameter(informational exceptions) */
405         TI_DBG5(("satIOStart: SCSIOPC_LOG_SENSE\n"));
406         retVal = satLogSense( tiRoot,
407                               tiIORequest,
408                               tiDeviceHandle,
409                               tiScsiRequest,
410                               satIOContext);
411         break;
412
413       case SCSIOPC_MODE_SELECT_6: /*mode layout and AlloLen check */
414         TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_6\n"));
415         retVal = satModeSelect6( tiRoot,
416                                  tiIORequest,
417                                  tiDeviceHandle,
418                                  tiScsiRequest,
419                                  satIOContext);
420         break;
421
422       case SCSIOPC_MODE_SELECT_10: /* mode layout and AlloLen check and sharing CB with  satModeSelect6*/
423         TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_10\n"));
424         retVal = satModeSelect10( tiRoot,
425                                   tiIORequest,
426                                   tiDeviceHandle,
427                                   tiScsiRequest,
428                                   satIOContext);
429         break;
430
431       case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with
432                                           satSynchronizeCache16 */
433         TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
434         retVal = satSynchronizeCache10( tiRoot,
435                                         tiIORequest,
436                                         tiDeviceHandle,
437                                         tiScsiRequest,
438                                         satIOContext);
439         break;
440
441       case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with
442                                            satSynchronizeCache16 */
443
444         TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
445         retVal = satSynchronizeCache16( tiRoot,
446                                         tiIORequest,
447                                         tiDeviceHandle,
448                                         tiScsiRequest,
449                                         satIOContext);
450         break;
451
452       case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */
453         TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
454         retVal = satWriteAndVerify10( tiRoot,
455                                       tiIORequest,
456                                       tiDeviceHandle,
457                                       tiScsiRequest,
458                                       satIOContext);
459         break;
460
461       case SCSIOPC_WRITE_AND_VERIFY_12:
462         TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
463         retVal = satWriteAndVerify12( tiRoot,
464                                       tiIORequest,
465                                       tiDeviceHandle,
466                                       tiScsiRequest,
467                                       satIOContext);
468         break;
469
470       case SCSIOPC_WRITE_AND_VERIFY_16:
471         TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
472         retVal = satWriteAndVerify16( tiRoot,
473                                       tiIORequest,
474                                       tiDeviceHandle,
475                                       tiScsiRequest,
476                                       satIOContext);
477
478         break;
479
480       case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
481         TI_DBG5(("satIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
482         retVal = satReadMediaSerialNumber( tiRoot,
483                                            tiIORequest,
484                                            tiDeviceHandle,
485                                            tiScsiRequest,
486                                            satIOContext);
487
488         break;
489
490       case SCSIOPC_READ_BUFFER:
491         TI_DBG5(("satIOStart: SCSIOPC_READ_BUFFER\n"));
492         retVal = satReadBuffer( tiRoot,
493                                 tiIORequest,
494                                 tiDeviceHandle,
495                                 tiScsiRequest,
496                                 satIOContext);
497
498         break;
499
500       case SCSIOPC_WRITE_BUFFER:
501         TI_DBG5(("satIOStart: SCSIOPC_WRITE_BUFFER\n"));
502         retVal = satWriteBuffer( tiRoot,
503                                 tiIORequest,
504                                 tiDeviceHandle,
505                                 tiScsiRequest,
506                                 satIOContext);
507
508         break;
509
510       case SCSIOPC_REASSIGN_BLOCKS:
511         TI_DBG5(("satIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
512         retVal = satReassignBlocks( tiRoot,
513                                 tiIORequest,
514                                 tiDeviceHandle,
515                                 tiScsiRequest,
516                                 satIOContext);
517
518         break;
519
520       default:
521         /* Not implemented SCSI cmd, set up error response */
522         TI_DBG1(("satIOStart: unsupported SCSI cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
523                    scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
524
525         satSetSensePayload( pSense,
526                             SCSI_SNSKEY_ILLEGAL_REQUEST,
527                             0,
528                             SCSI_SNSCODE_INVALID_COMMAND,
529                             satIOContext);
530
531         ostiInitiatorIOCompleted( tiRoot,
532                                   tiIORequest,
533                                   tiIOSuccess,
534                                   SCSI_STAT_CHECK_CONDITION,
535                                   satIOContext->pTiSenseData,
536                                   satIOContext->interruptContext );
537         retVal = tiSuccess;
538
539         break;
540
541     }  /* end switch  */
542  }
543  if (retVal == tiBusy)
544  {
545#ifdef  TD_DEBUG_ENABLE
546    oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
547#endif
548    TI_DBG1(("satIOStart: BUSY did %d\n", oneDeviceData->id));
549    TI_DBG3(("satIOStart: LL is busy or target queue is full\n"));
550    TI_DBG3(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
551    TI_DBG3(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
552    pSatIntIo               = satIOContext->satIntIoContext;
553
554    /* interal structure free */
555    satFreeIntIoResource( tiRoot,
556                          pSatDevData,
557                          pSatIntIo);
558  }
559
560ext:
561  return retVal;
562}
563
564
565/*****************************************************************************/
566/*! \brief Setup up the SCSI Sense response.
567 *
568 *  This function is used to setup up the Sense Data payload for
569 *     CHECK CONDITION status.
570 *
571 *  \param pSense:      Pointer to the scsiRspSense_t sense data structure.
572 *  \param SnsKey:      SCSI Sense Key.
573 *  \param SnsInfo:     SCSI Sense Info.
574 *  \param SnsCode:     SCSI Sense Code.
575 *
576 *  \return: None
577 */
578/*****************************************************************************/
579void satSetSensePayload( scsiRspSense_t   *pSense,
580                         bit8             SnsKey,
581                         bit32            SnsInfo,
582                         bit16            SnsCode,
583                         satIOContext_t   *satIOContext
584                         )
585{
586  /* for fixed format sense data, SPC-4, p37 */
587  bit32      i;
588  bit32      senseLength;
589
590  TI_DBG5(("satSetSensePayload: start\n"));
591
592  senseLength  = sizeof(scsiRspSense_t);
593
594  /* zero out the data area */
595  for (i=0;i< senseLength;i++)
596  {
597    ((bit8*)pSense)[i] = 0;
598  }
599
600  /*
601   * SCSI Sense Data part of response data
602   */
603  pSense->snsRespCode  = 0x70;    /*  0xC0 == vendor specific */
604                                      /*  0x70 == standard current error */
605  pSense->senseKey     = SnsKey;
606  /*
607   * Put sense info in scsi order format
608   */
609  pSense->info[0]      = (bit8)((SnsInfo >> 24) & 0xff);
610  pSense->info[1]      = (bit8)((SnsInfo >> 16) & 0xff);
611  pSense->info[2]      = (bit8)((SnsInfo >> 8) & 0xff);
612  pSense->info[3]      = (bit8)((SnsInfo) & 0xff);
613  pSense->addSenseLen  = 11;          /* fixed size of sense data = 18 */
614  pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
615  pSense->senseQual    = (bit8)(SnsCode & 0xFF);
616  /*
617   * Set pointer in scsi status
618   */
619  switch(SnsKey)
620  {
621    /*
622     * set illegal request sense key specific error in cdb, no bit pointer
623     */
624    case SCSI_SNSKEY_ILLEGAL_REQUEST:
625      pSense->skeySpecific[0] = 0xC8;
626      break;
627
628    default:
629      break;
630  }
631  /* setting sense data length */
632  if (satIOContext != agNULL)
633  {
634    satIOContext->pTiSenseData->senseLen = 18;
635  }
636  else
637  {
638    TI_DBG1(("satSetSensePayload: satIOContext is NULL\n"));
639  }
640}
641
642/*****************************************************************************/
643/*! \brief Setup up the SCSI Sense response.
644 *
645 *  This function is used to setup up the Sense Data payload for
646 *     CHECK CONDITION status.
647 *
648 *  \param pSense:      Pointer to the scsiRspSense_t sense data structure.
649 *  \param SnsKey:      SCSI Sense Key.
650 *  \param SnsInfo:     SCSI Sense Info.
651 *  \param SnsCode:     SCSI Sense Code.
652 *
653 *  \return: None
654 */
655/*****************************************************************************/
656
657void satSetDeferredSensePayload( scsiRspSense_t  *pSense,
658                                 bit8             SnsKey,
659                                 bit32            SnsInfo,
660                                 bit16            SnsCode,
661                                 satIOContext_t   *satIOContext
662                                 )
663{
664  /* for fixed format sense data, SPC-4, p37 */
665  bit32      i;
666  bit32      senseLength;
667
668  senseLength  = sizeof(scsiRspSense_t);
669
670  /* zero out the data area */
671  for (i=0;i< senseLength;i++)
672  {
673    ((bit8*)pSense)[i] = 0;
674  }
675
676  /*
677   * SCSI Sense Data part of response data
678   */
679  pSense->snsRespCode  = 0x71;        /*  0xC0 == vendor specific */
680                                      /*  0x70 == standard current error */
681  pSense->senseKey     = SnsKey;
682  /*
683   * Put sense info in scsi order format
684   */
685  pSense->info[0]      = (bit8)((SnsInfo >> 24) & 0xff);
686  pSense->info[1]      = (bit8)((SnsInfo >> 16) & 0xff);
687  pSense->info[2]      = (bit8)((SnsInfo >> 8) & 0xff);
688  pSense->info[3]      = (bit8)((SnsInfo) & 0xff);
689  pSense->addSenseLen  = 11;          /* fixed size of sense data = 18 */
690  pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
691  pSense->senseQual    = (bit8)(SnsCode & 0xFF);
692  /*
693   * Set pointer in scsi status
694   */
695  switch(SnsKey)
696  {
697    /*
698     * set illegal request sense key specific error in cdb, no bit pointer
699     */
700    case SCSI_SNSKEY_ILLEGAL_REQUEST:
701      pSense->skeySpecific[0] = 0xC8;
702      break;
703
704    default:
705      break;
706  }
707
708  /* setting sense data length */
709  if (satIOContext != agNULL)
710  {
711    satIOContext->pTiSenseData->senseLen = 18;
712  }
713  else
714  {
715    TI_DBG1(("satSetDeferredSensePayload: satIOContext is NULL\n"));
716  }
717
718}
719/*****************************************************************************/
720/*! \brief SAT implementation for ATAPI Packet Command.
721 *
722 *  SAT implementation for ATAPI Packet and send FIS request to LL layer.
723 *
724 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
725 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
726 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
727 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
728 *  \param   satIOContext_t:   Pointer to the SAT IO Context
729 *
730 *  \return If command is started successfully
731 *    - \e tiSuccess:     I/O request successfully initiated.
732 *    - \e tiBusy:        No resources available, try again later.
733 *    - \e tiIONoDevice:  Invalid device handle.
734 *    - \e tiError:       Other errors.
735 */
736/*****************************************************************************/
737GLOBAL bit32  satPacket(
738                   tiRoot_t                  *tiRoot,
739                   tiIORequest_t             *tiIORequest,
740                   tiDeviceHandle_t          *tiDeviceHandle,
741                   tiScsiInitiatorRequest_t  *tiScsiRequest,
742                   satIOContext_t            *satIOContext)
743{
744  bit32                     status;
745  bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
746  satDeviceData_t           *pSatDevData;
747  tiIniScsiCmnd_t           *scsiCmnd;
748  agsaFisRegHostToDevice_t  *fis;
749
750  pSatDevData   = satIOContext->pSatDevData;
751  scsiCmnd      = &tiScsiRequest->scsiCmnd;
752  fis           = satIOContext->pFis;
753
754  TI_DBG3(("satPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
755           scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
756           scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
757           scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
758
759  fis->h.fisType        = 0x27;                   /* Reg host to device */
760  fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
761  fis->h.command        = SAT_PACKET;             /* 0xA0 */
762  if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
763  {
764     fis->h.features    = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
765  }
766  else
767  {
768     fis->h.features    = 0;                      /* FIS reserve */
769  }
770  /* Byte count low and byte count high */
771  if ( scsiCmnd->expDataLength > 0xFFFF )
772  {
773     fis->d.lbaMid = 0xFF;                               /* FIS LBA (7 :0 ) */
774     fis->d.lbaHigh = 0xFF;                              /* FIS LBA (15:8 ) */
775  }
776  else
777  {
778     fis->d.lbaMid = (bit8)scsiCmnd->expDataLength;       /* FIS LBA (7 :0 ) */
779     fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (15:8 ) */
780  }
781
782  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
783  fis->d.device         = 0;                      /* FIS LBA (27:24) and FIS LBA mode  */
784  fis->d.lbaLowExp      = 0;
785  fis->d.lbaMidExp      = 0;
786  fis->d.lbaHighExp     = 0;
787  fis->d.featuresExp    = 0;
788  fis->d.sectorCount    = 0;                       /* FIS sector count (7:0) */
789  fis->d.sectorCountExp = 0;
790  fis->d.reserved4      = 0;
791  fis->d.control        = 0;                      /* FIS HOB bit clear */
792  fis->d.reserved5      = 0;
793
794  satIOContext->ATACmd = SAT_PACKET;
795
796  if (tiScsiRequest->dataDirection == tiDirectionIn)
797  {
798      agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
799  }
800  else
801  {
802      agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
803  }
804
805  if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
806  {
807     /*DMA transfer mode*/
808     fis->h.features |= 0x01;
809  }
810  else
811  {
812     /*PIO transfer mode*/
813     fis->h.features |= 0x0;
814  }
815
816  satIOContext->satCompleteCB = &satPacketCB;
817
818  /*
819   * Prepare SGL and send FIS to LL layer.
820   */
821  satIOContext->reqType = agRequestType;       /* Save it */
822
823  status = sataLLIOStart( tiRoot,
824                          tiIORequest,
825                          tiDeviceHandle,
826                          tiScsiRequest,
827                          satIOContext);
828
829  TI_DBG5(("satPacket: return\n"));
830  return (status);
831}
832
833/*****************************************************************************/
834/*! \brief SAT implementation for satSetFeatures.
835 *
836 *  This function creates SetFeatures fis and sends the request to LL layer
837 *
838 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
839 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
840 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
841 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
842 *  \param   satIOContext_t:   Pointer to the SAT IO Context
843 *
844 *  \return If command is started successfully
845 *    - \e tiSuccess:     I/O request successfully initiated.
846 *    - \e tiBusy:        No resources available, try again later.
847 *    - \e tiIONoDevice:  Invalid device handle.
848 *    - \e tiError:       Other errors.
849 */
850/*****************************************************************************/
851GLOBAL bit32  satSetFeatures(
852                            tiRoot_t                  *tiRoot,
853                            tiIORequest_t             *tiIORequest,
854                            tiDeviceHandle_t          *tiDeviceHandle,
855                            tiScsiInitiatorRequest_t  *tiScsiRequest,
856                            satIOContext_t            *satIOContext,
857                            bit8                      bIsDMAMode
858                            )
859{
860  bit32                     status;
861  bit32                     agRequestType;
862  agsaFisRegHostToDevice_t  *fis;
863
864  fis           = satIOContext->pFis;
865  TI_DBG3(("satSetFeatures: start\n"));
866
867  /*
868   * Send the Set Features command.
869   */
870  fis->h.fisType        = 0x27;                   /* Reg host to device */
871  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
872  fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
873  fis->h.features       = 0x03;                   /* set transfer mode */
874  fis->d.lbaLow         = 0;
875  fis->d.lbaMid         = 0;
876  fis->d.lbaHigh        = 0;
877  fis->d.device         = 0;
878  fis->d.lbaLowExp      = 0;
879  fis->d.lbaMidExp      = 0;
880  fis->d.lbaHighExp     = 0;
881  fis->d.featuresExp    = 0;
882  fis->d.sectorCountExp = 0;
883  fis->d.reserved4      = 0;
884  fis->d.control        = 0;                      /* FIS HOB bit clear */
885  fis->d.reserved5      = 0;
886
887  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
888
889  /* Initialize CB for SATA completion.
890   */
891  if (bIsDMAMode)
892  {
893      fis->d.sectorCount = 0x45;
894      /*satIOContext->satCompleteCB = &satSetFeaturesDMACB;*/
895  }
896  else
897  {
898      fis->d.sectorCount = 0x0C;
899      /*satIOContext->satCompleteCB = &satSetFeaturesPIOCB;*/
900  }
901  satIOContext->satCompleteCB = &satSetFeaturesCB;
902
903  /*
904   * Prepare SGL and send FIS to LL layer.
905   */
906  satIOContext->reqType = agRequestType;       /* Save it */
907
908  status = sataLLIOStart( tiRoot,
909                          tiIORequest,
910                          tiDeviceHandle,
911                          tiScsiRequest,
912                          satIOContext);
913
914  TI_DBG5(("satSetFeatures: return\n"));
915
916  return status;
917}
918/*****************************************************************************/
919/*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device.
920 *
921 *  SAT implementation for SCSI REQUEST SENSE.
922 *
923 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
924 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
925 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
926 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
927 *  \param   satIOContext_t:   Pointer to the SAT IO Context
928 *
929 *  \return If command is started successfully
930 *    - \e tiSuccess:     I/O request successfully initiated.
931 *    - \e tiBusy:        No resources available, try again later.
932 *    - \e tiIONoDevice:  Invalid device handle.
933 *    - \e tiError:       Other errors.
934 */
935/*****************************************************************************/
936GLOBAL bit32  satRequestSenseForATAPI(
937                   tiRoot_t                  *tiRoot,
938                   tiIORequest_t             *tiIORequest,
939                   tiDeviceHandle_t          *tiDeviceHandle,
940                   tiScsiInitiatorRequest_t  *tiScsiRequest,
941                   satIOContext_t            *satIOContext)
942{
943  bit32                     status;
944  bit32                     agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
945  satDeviceData_t           *pSatDevData;
946  tiIniScsiCmnd_t           *scsiCmnd;
947  agsaFisRegHostToDevice_t  *fis;
948
949  pSatDevData   = satIOContext->pSatDevData;
950  scsiCmnd      = &tiScsiRequest->scsiCmnd;
951  fis           = satIOContext->pFis;
952
953  scsiCmnd->cdb[0]   = SCSIOPC_REQUEST_SENSE;
954  scsiCmnd->cdb[1]   = 0;
955  scsiCmnd->cdb[2]   = 0;
956  scsiCmnd->cdb[3]   = 0;
957  scsiCmnd->cdb[4]   = SENSE_DATA_LENGTH;
958  scsiCmnd->cdb[5]   = 0;
959  TI_DBG3(("satRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
960           scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
961           scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
962           scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
963
964  fis->h.fisType        = 0x27;                   /* Reg host to device */
965  fis->h.c_pmPort       = 0x80;                   /* C Bit is set 1*/
966  fis->h.command        = SAT_PACKET;             /* 0xA0 */
967  if (pSatDevData->satDMADIRSupport)              /* DMADIR enabled*/
968  {
969     fis->h.features    = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
970  }
971  else
972  {
973     fis->h.features    = 0;                         /* FIS reserve */
974  }
975
976  fis->d.lbaLow         = 0;                         /* FIS LBA (7 :0 ) */
977  fis->d.lbaMid         = 0;                         /* FIS LBA (15:8 ) */
978  fis->d.lbaHigh        = 0x20;                      /* FIS LBA (23:16) */
979  fis->d.device         = 0;                         /* FIS LBA (27:24) and FIS LBA mode  */
980  fis->d.lbaLowExp      = 0;
981  fis->d.lbaMidExp      = 0;
982  fis->d.lbaHighExp     = 0;
983  fis->d.featuresExp    = 0;
984  fis->d.sectorCount    = 0;                          /* FIS sector count (7:0) */
985  fis->d.sectorCountExp = 0;
986  fis->d.reserved4      = 0;
987  fis->d.control        = 0;                         /* FIS HOB bit clear */
988  fis->d.reserved5      = (bit32)(scsiCmnd->cdb[0]|(scsiCmnd->cdb[1]<<8)|(scsiCmnd->cdb[2]<<16)|(scsiCmnd->cdb[3]<<24));
989
990  satIOContext->ATACmd = SAT_PACKET;
991
992  agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
993
994  //if (pSatDevData->sat48BitSupport == agTRUE)
995  {
996    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
997    {
998       fis->h.features |= 0x01;
999    }
1000    else
1001    {
1002       fis->h.features |= 0x0;
1003    }
1004  }
1005
1006  satIOContext->satCompleteCB = &satRequestSenseForATAPICB;
1007
1008  /*
1009   * Prepare SGL and send FIS to LL layer.
1010   */
1011  satIOContext->reqType = agRequestType;       /* Save it */
1012
1013  status = sataLLIOStart( tiRoot,
1014                          tiIORequest,
1015                          tiDeviceHandle,
1016                          tiScsiRequest,
1017                          satIOContext);
1018
1019  TI_DBG5(("satRequestSenseForATAPI: return\n"));
1020  return (status);
1021}
1022/*****************************************************************************/
1023/*! \brief SAT implementation for satDeviceReset.
1024 *
1025 *  This function creates DEVICE RESET fis and sends the request to LL layer
1026 *
1027 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1028 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1029 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1030 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1031 *  \param   satIOContext_t:   Pointer to the SAT IO Context
1032 *
1033 *  \return If command is started successfully
1034 *    - \e tiSuccess:     I/O request successfully initiated.
1035 *    - \e tiBusy:        No resources available, try again later.
1036 *    - \e tiIONoDevice:  Invalid device handle.
1037 *    - \e tiError:       Other errors.
1038 */
1039/*****************************************************************************/
1040GLOBAL bit32 satDeviceReset(
1041                            tiRoot_t                  *tiRoot,
1042                            tiIORequest_t             *tiIORequest,
1043                            tiDeviceHandle_t          *tiDeviceHandle,
1044                            tiScsiInitiatorRequest_t  *tiScsiRequest,
1045                            satIOContext_t            *satIOContext
1046                            )
1047{
1048  bit32                     status;
1049  bit32                     agRequestType;
1050  agsaFisRegHostToDevice_t  *fis;
1051
1052  fis           = satIOContext->pFis;
1053
1054  TI_DBG3(("satDeviceReset: start\n"));
1055
1056  /*
1057   * Send the  Execute Device Diagnostic command.
1058   */
1059  fis->h.fisType        = 0x27;                   /* Reg host to device */
1060  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1061  fis->h.command        = SAT_DEVICE_RESET;   /* 0x90 */
1062  fis->h.features       = 0;
1063  fis->d.lbaLow         = 0;
1064  fis->d.lbaMid         = 0;
1065  fis->d.lbaHigh        = 0;
1066  fis->d.device         = 0;
1067  fis->d.lbaLowExp      = 0;
1068  fis->d.lbaMidExp      = 0;
1069  fis->d.lbaHighExp     = 0;
1070  fis->d.featuresExp    = 0;
1071  fis->d.sectorCount    = 0;
1072  fis->d.sectorCountExp = 0;
1073  fis->d.reserved4      = 0;
1074  fis->d.control        = 0;                      /* FIS HOB bit clear */
1075  fis->d.reserved5      = 0;
1076
1077  agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
1078
1079  /* Initialize CB for SATA completion.
1080   */
1081  satIOContext->satCompleteCB = &satDeviceResetCB;
1082
1083  /*
1084   * Prepare SGL and send FIS to LL layer.
1085   */
1086  satIOContext->reqType = agRequestType;       /* Save it */
1087
1088  status = sataLLIOStart( tiRoot,
1089                          tiIORequest,
1090                          tiDeviceHandle,
1091                          tiScsiRequest,
1092                          satIOContext);
1093
1094  TI_DBG3(("satDeviceReset: return\n"));
1095
1096  return status;
1097}
1098
1099/*****************************************************************************/
1100/*! \brief SAT implementation for saExecuteDeviceDiagnostic.
1101 *
1102 *  This function creates Execute Device Diagnostic fis and sends the request to LL layer
1103 *
1104 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1105 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1106 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1107 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1108 *  \param   satIOContext_t:   Pointer to the SAT IO Context
1109 *
1110 *  \return If command is started successfully
1111 *    - \e tiSuccess:     I/O request successfully initiated.
1112 *    - \e tiBusy:        No resources available, try again later.
1113 *    - \e tiIONoDevice:  Invalid device handle.
1114 *    - \e tiError:       Other errors.
1115 */
1116/*****************************************************************************/
1117GLOBAL bit32  satExecuteDeviceDiagnostic(
1118                            tiRoot_t                  *tiRoot,
1119                            tiIORequest_t             *tiIORequest,
1120                            tiDeviceHandle_t          *tiDeviceHandle,
1121                            tiScsiInitiatorRequest_t  *tiScsiRequest,
1122                            satIOContext_t            *satIOContext
1123                            )
1124{
1125  bit32                     status;
1126  bit32                     agRequestType;
1127  agsaFisRegHostToDevice_t  *fis;
1128
1129  fis           = satIOContext->pFis;
1130
1131  TI_DBG3(("satExecuteDeviceDiagnostic: start\n"));
1132
1133  /*
1134   * Send the  Execute Device Diagnostic command.
1135   */
1136  fis->h.fisType        = 0x27;                   /* Reg host to device */
1137  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1138  fis->h.command        = SAT_EXECUTE_DEVICE_DIAGNOSTIC;   /* 0x90 */
1139  fis->h.features       = 0;
1140  fis->d.lbaLow         = 0;
1141  fis->d.lbaMid         = 0;
1142  fis->d.lbaHigh        = 0;
1143  fis->d.device         = 0;
1144  fis->d.lbaLowExp      = 0;
1145  fis->d.lbaMidExp      = 0;
1146  fis->d.lbaHighExp     = 0;
1147  fis->d.featuresExp    = 0;
1148  fis->d.sectorCount    = 0;
1149  fis->d.sectorCountExp = 0;
1150  fis->d.reserved4      = 0;
1151  fis->d.control        = 0;                      /* FIS HOB bit clear */
1152  fis->d.reserved5      = 0;
1153
1154  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
1155
1156  /* Initialize CB for SATA completion.
1157   */
1158  satIOContext->satCompleteCB = &satExecuteDeviceDiagnosticCB;
1159
1160  /*
1161   * Prepare SGL and send FIS to LL layer.
1162   */
1163  satIOContext->reqType = agRequestType;       /* Save it */
1164
1165  status = sataLLIOStart( tiRoot,
1166                          tiIORequest,
1167                          tiDeviceHandle,
1168                          tiScsiRequest,
1169                          satIOContext);
1170
1171  TI_DBG5(("satExecuteDeviceDiagnostic: return\n"));
1172
1173  return status;
1174}
1175
1176
1177/*****************************************************************************/
1178/*! \brief SAT implementation for SCSI READ10.
1179 *
1180 *  SAT implementation for SCSI READ10 and send FIS request to LL layer.
1181 *
1182 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1183 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1184 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1185 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1186 *  \param   satIOContext_t:   Pointer to the SAT IO Context
1187 *
1188 *  \return If command is started successfully
1189 *    - \e tiSuccess:     I/O request successfully initiated.
1190 *    - \e tiBusy:        No resources available, try again later.
1191 *    - \e tiIONoDevice:  Invalid device handle.
1192 *    - \e tiError:       Other errors.
1193 */
1194/*****************************************************************************/
1195GLOBAL bit32  satRead10(
1196                   tiRoot_t                  *tiRoot,
1197                   tiIORequest_t             *tiIORequest,
1198                   tiDeviceHandle_t          *tiDeviceHandle,
1199                   tiScsiInitiatorRequest_t *tiScsiRequest,
1200                   satIOContext_t            *satIOContext)
1201{
1202
1203  bit32                     status;
1204  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1205  satDeviceData_t           *pSatDevData;
1206  scsiRspSense_t            *pSense;
1207  tiIniScsiCmnd_t           *scsiCmnd;
1208  agsaFisRegHostToDevice_t  *fis;
1209  bit32                     lba = 0;
1210  bit32                     tl = 0;
1211  bit32                     LoopNum = 1;
1212  bit8                      LBA[4];
1213  bit8                      TL[4];
1214  bit32                     rangeChk = agFALSE; /* lba and tl range check */
1215
1216  pSense        = satIOContext->pSense;
1217  pSatDevData   = satIOContext->pSatDevData;
1218  scsiCmnd      = &tiScsiRequest->scsiCmnd;
1219  fis           = satIOContext->pFis;
1220
1221  TI_DBG5(("satRead10: start\n"));
1222  TI_DBG5(("satRead10: pSatDevData=%p\n", pSatDevData));
1223  //  tdhexdump("satRead10", (bit8 *)scsiCmnd->cdb, 10);
1224
1225  /* checking FUA_NV */
1226  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1227  {
1228    satSetSensePayload( pSense,
1229                        SCSI_SNSKEY_ILLEGAL_REQUEST,
1230                        0,
1231                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1232                        satIOContext);
1233
1234    ostiInitiatorIOCompleted( tiRoot,
1235                              tiIORequest,
1236                              tiIOSuccess,
1237                              SCSI_STAT_CHECK_CONDITION,
1238                              satIOContext->pTiSenseData,
1239                              satIOContext->interruptContext );
1240
1241    TI_DBG1(("satRead10: return FUA_NV\n"));
1242    return tiSuccess;
1243
1244  }
1245
1246  /* checking CONTROL */
1247  /* NACA == 1 or LINK == 1*/
1248  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
1249  {
1250    satSetSensePayload( pSense,
1251                        SCSI_SNSKEY_ILLEGAL_REQUEST,
1252                        0,
1253                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1254                        satIOContext);
1255
1256    ostiInitiatorIOCompleted( tiRoot,
1257                              tiIORequest,
1258                              tiIOSuccess,
1259                              SCSI_STAT_CHECK_CONDITION,
1260                              satIOContext->pTiSenseData,
1261                              satIOContext->interruptContext );
1262
1263    TI_DBG1(("satRead10: return control\n"));
1264    return tiSuccess;
1265  }
1266
1267  osti_memset(LBA, 0, sizeof(LBA));
1268  osti_memset(TL, 0, sizeof(TL));
1269
1270  /* do not use memcpy due to indexing in LBA and TL */
1271  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
1272  LBA[1] = scsiCmnd->cdb[3];
1273  LBA[2] = scsiCmnd->cdb[4];
1274  LBA[3] = scsiCmnd->cdb[5];  /* LSB */
1275
1276  TL[0] = 0;
1277  TL[1] = 0;
1278  TL[2] = scsiCmnd->cdb[7];   /* MSB */
1279  TL[3] = scsiCmnd->cdb[8];   /* LSB */
1280
1281  rangeChk = satAddNComparebit32(LBA, TL);
1282
1283  /* cbd10; computing LBA and transfer length */
1284  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
1285    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
1286  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
1287
1288
1289  TI_DBG5(("satRead10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
1290  TI_DBG5(("satRead10: lba 0x%x functioned lba 0x%x\n", lba, satComputeCDB10LBA(satIOContext)));
1291  TI_DBG5(("satRead10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
1292
1293  /* Table 34, 9.1, p 46 */
1294  /*
1295    note: As of 2/10/2006, no support for DMA QUEUED
1296   */
1297
1298  /*
1299    Table 34, 9.1, p 46, b
1300    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
1301    return check condition
1302  */
1303
1304  if (pSatDevData->satNCQ != agTRUE &&
1305      pSatDevData->sat48BitSupport != agTRUE
1306      )
1307  {
1308    if (lba > SAT_TR_LBA_LIMIT - 1)
1309    {
1310      TI_DBG1(("satRead10: return LBA out of range, not EXT\n"));
1311      satSetSensePayload( pSense,
1312                          SCSI_SNSKEY_ILLEGAL_REQUEST,
1313                          0,
1314                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1315                          satIOContext);
1316
1317      ostiInitiatorIOCompleted( tiRoot,
1318                                tiIORequest,
1319                                tiIOSuccess,
1320                                SCSI_STAT_CHECK_CONDITION,
1321                                satIOContext->pTiSenseData,
1322                                satIOContext->interruptContext );
1323
1324    return tiSuccess;
1325    }
1326
1327
1328    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
1329    {
1330      TI_DBG1(("satRead10: return LBA+TL out of range, not EXT\n"));
1331      satSetSensePayload( pSense,
1332                          SCSI_SNSKEY_ILLEGAL_REQUEST,
1333                          0,
1334                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1335                          satIOContext);
1336
1337      ostiInitiatorIOCompleted( tiRoot,
1338                                tiIORequest,
1339                                tiIOSuccess,
1340                                SCSI_STAT_CHECK_CONDITION,
1341                                satIOContext->pTiSenseData,
1342                                satIOContext->interruptContext );
1343
1344    return tiSuccess;
1345    }
1346  }
1347
1348  /* case 1 and 2 */
1349  if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
1350  {
1351    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1352    {
1353      /* case 2 */
1354      /* READ DMA*/
1355      /* in case that we can't fit the transfer length,
1356         we need to make it fit by sending multiple ATA cmnds */
1357      TI_DBG5(("satRead10: case 2\n"));
1358
1359
1360      fis->h.fisType        = 0x27;                   /* Reg host to device */
1361      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1362      fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
1363      fis->h.features       = 0;                      /* FIS reserve */
1364      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1365      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1366      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1367      fis->d.device         =
1368        (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
1369      fis->d.lbaLowExp      = 0;
1370      fis->d.lbaMidExp      = 0;
1371      fis->d.lbaHighExp     = 0;
1372      fis->d.featuresExp    = 0;
1373      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1374      fis->d.sectorCountExp = 0;
1375      fis->d.reserved4      = 0;
1376      fis->d.control        = 0;                      /* FIS HOB bit clear */
1377      fis->d.reserved5      = 0;
1378
1379
1380      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1381      satIOContext->ATACmd = SAT_READ_DMA;
1382    }
1383    else
1384    {
1385      /* case 1 */
1386      /* READ MULTIPLE or READ SECTOR(S) */
1387      /* READ SECTORS for easier implemetation */
1388      /* in case that we can't fit the transfer length,
1389         we need to make it fit by sending multiple ATA cmnds */
1390      TI_DBG5(("satRead10: case 1\n"));
1391
1392      fis->h.fisType        = 0x27;                   /* Reg host to device */
1393      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1394      fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
1395      fis->h.features       = 0;                      /* FIS reserve */
1396      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1397      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1398      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1399      fis->d.device         =
1400        (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
1401      fis->d.lbaLowExp      = 0;
1402      fis->d.lbaMidExp      = 0;
1403      fis->d.lbaHighExp     = 0;
1404      fis->d.featuresExp    = 0;
1405      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1406      fis->d.sectorCountExp = 0;
1407      fis->d.reserved4      = 0;
1408      fis->d.control        = 0;                      /* FIS HOB bit clear */
1409      fis->d.reserved5      = 0;
1410
1411
1412      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1413      satIOContext->ATACmd = SAT_READ_SECTORS;
1414    }
1415  }
1416
1417   /* case 3 and 4 */
1418  if (pSatDevData->sat48BitSupport == agTRUE)
1419  {
1420    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1421    {
1422      /* case 3 */
1423      /* READ DMA EXT */
1424      TI_DBG5(("satRead10: case 3\n"));
1425      fis->h.fisType        = 0x27;                   /* Reg host to device */
1426
1427      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1428      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
1429      fis->h.features       = 0;                      /* FIS reserve */
1430      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1431      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1432      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1433      fis->d.device         = 0x40;                   /* FIS LBA mode set */
1434      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
1435      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1436      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1437      fis->d.featuresExp    = 0;                      /* FIS reserve */
1438      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1439      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
1440      fis->d.reserved4      = 0;
1441      fis->d.control        = 0;                      /* FIS HOB bit clear */
1442      fis->d.reserved5      = 0;
1443
1444      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1445      satIOContext->ATACmd = SAT_READ_DMA_EXT;
1446
1447    }
1448    else
1449    {
1450      /* case 4 */
1451      /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
1452      /* READ SECTORS EXT for easier implemetation */
1453      TI_DBG5(("satRead10: case 4\n"));
1454      fis->h.fisType        = 0x27;                   /* Reg host to device */
1455      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1456
1457      /* Check FUA bit */
1458      if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1459      {
1460
1461        /* for now, no support for FUA */
1462        satSetSensePayload( pSense,
1463                            SCSI_SNSKEY_ILLEGAL_REQUEST,
1464                            0,
1465                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1466                            satIOContext);
1467
1468        ostiInitiatorIOCompleted( tiRoot,
1469                                  tiIORequest,
1470                                  tiIOSuccess,
1471                                  SCSI_STAT_CHECK_CONDITION,
1472                                  satIOContext->pTiSenseData,
1473                                  satIOContext->interruptContext );
1474        return tiSuccess;
1475      }
1476
1477      fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
1478
1479      fis->h.features       = 0;                      /* FIS reserve */
1480      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1481      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1482      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1483      fis->d.device         = 0x40;                   /* FIS LBA mode set */
1484      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
1485      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1486      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1487      fis->d.featuresExp    = 0;                      /* FIS reserve */
1488      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1489      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
1490      fis->d.reserved4      = 0;
1491      fis->d.control        = 0;                      /* FIS HOB bit clear */
1492      fis->d.reserved5      = 0;
1493
1494      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1495      satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
1496    }
1497  }
1498
1499  /* case 5 */
1500  if (pSatDevData->satNCQ == agTRUE)
1501  {
1502    /* READ FPDMA QUEUED */
1503    if (pSatDevData->sat48BitSupport != agTRUE)
1504    {
1505      TI_DBG5(("satRead10: case 5 !!! error NCQ but 28 bit address support \n"));
1506      satSetSensePayload( pSense,
1507                          SCSI_SNSKEY_ILLEGAL_REQUEST,
1508                          0,
1509                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1510                          satIOContext);
1511
1512      ostiInitiatorIOCompleted( tiRoot,
1513                                tiIORequest,
1514                                tiIOSuccess,
1515                                SCSI_STAT_CHECK_CONDITION,
1516                                satIOContext->pTiSenseData,
1517                                satIOContext->interruptContext );
1518      return tiSuccess;
1519    }
1520
1521    TI_DBG6(("satRead10: case 5\n"));
1522
1523    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
1524
1525    fis->h.fisType        = 0x27;                   /* Reg host to device */
1526    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1527    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
1528    fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
1529    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
1530    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
1531    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
1532
1533    /* Check FUA bit */
1534    if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1535      fis->d.device       = 0xC0;                   /* FIS FUA set */
1536    else
1537      fis->d.device       = 0x40;                   /* FIS FUA clear */
1538
1539    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
1540    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1541    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1542    fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
1543    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
1544    fis->d.sectorCountExp = 0;
1545    fis->d.reserved4      = 0;
1546    fis->d.control        = 0;                      /* FIS HOB bit clear */
1547    fis->d.reserved5      = 0;
1548
1549    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1550    satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
1551  }
1552
1553
1554  //  tdhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
1555
1556  /* saves the current LBA and orginal TL */
1557  satIOContext->currentLBA = lba;
1558  satIOContext->OrgTL = tl;
1559
1560 /*
1561    computing number of loop and remainder for tl
1562    0xFF in case not ext
1563    0xFFFF in case EXT
1564  */
1565  if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1566  {
1567    LoopNum = satComputeLoopNum(tl, 0xFF);
1568  }
1569  else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1570  {
1571    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1572    LoopNum = satComputeLoopNum(tl, 0xFFFF);
1573  }
1574  else
1575  {
1576    /* SAT_READ_FPDMA_QUEUED */
1577    LoopNum = satComputeLoopNum(tl, 0xFFFF);
1578  }
1579
1580  satIOContext->LoopNum = LoopNum;
1581
1582  /* Initialize CB for SATA completion.
1583   */
1584  if (LoopNum == 1)
1585  {
1586    TI_DBG5(("satRead10: NON CHAINED data\n"));
1587    satIOContext->satCompleteCB = &satNonChainedDataIOCB;
1588  }
1589  else
1590  {
1591    TI_DBG1(("satRead10: CHAINED data\n"));
1592    /* re-setting tl */
1593    if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1594    {
1595       fis->d.sectorCount    = 0xFF;
1596    }
1597    else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1598    {
1599      /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1600      fis->d.sectorCount    = 0xFF;
1601      fis->d.sectorCountExp = 0xFF;
1602    }
1603    else
1604    {
1605      /* SAT_READ_FPDMA_QUEUED */
1606      fis->h.features       = 0xFF;
1607      fis->d.featuresExp    = 0xFF;
1608    }
1609
1610    /* chained data */
1611    satIOContext->satCompleteCB = &satChainedDataIOCB;
1612
1613  }
1614
1615  /*
1616   * Prepare SGL and send FIS to LL layer.
1617   */
1618  satIOContext->reqType = agRequestType;       /* Save it */
1619
1620  status = sataLLIOStart( tiRoot,
1621                          tiIORequest,
1622                          tiDeviceHandle,
1623                          tiScsiRequest,
1624                          satIOContext);
1625
1626  TI_DBG5(("satRead10: return\n"));
1627  return (status);
1628
1629}
1630
1631
1632/*****************************************************************************/
1633/*! \brief SAT implementation for SCSI satRead_1.
1634 *
1635 *  SAT implementation for SCSI satRead_1
1636 *  Sub function of satRead10
1637 *
1638 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1639 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1640 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1641 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1642 *  \param   satIOContext_t:   Pointer to the SAT IO Context
1643 *
1644 *  \return If command is started successfully
1645 *    - \e tiSuccess:     I/O request successfully initiated.
1646 *    - \e tiBusy:        No resources available, try again later.
1647 *    - \e tiIONoDevice:  Invalid device handle.
1648 *    - \e tiError:       Other errors.
1649 */
1650/*****************************************************************************/
1651/*
1652 * as a part of loop for read10
1653 */
1654GLOBAL bit32  satRead_1(
1655                          tiRoot_t                  *tiRoot,
1656                          tiIORequest_t             *tiIORequest,
1657                          tiDeviceHandle_t          *tiDeviceHandle,
1658                          tiScsiInitiatorRequest_t *tiScsiRequest,
1659                          satIOContext_t            *satIOContext)
1660{
1661  /*
1662    Assumption: error check on lba and tl has been done in satRead*()
1663    lba = lba + tl;
1664  */
1665  bit32                     status;
1666  satIOContext_t            *satOrgIOContext = agNULL;
1667  tiIniScsiCmnd_t           *scsiCmnd;
1668  agsaFisRegHostToDevice_t  *fis;
1669  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1670  bit32                     lba = 0;
1671  bit32                     DenomTL = 0xFF;
1672  bit32                     Remainder = 0;
1673  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
1674
1675  TI_DBG2(("satRead_1: start\n"));
1676
1677  fis             = satIOContext->pFis;
1678  satOrgIOContext = satIOContext->satOrgIOContext;
1679  scsiCmnd        = satOrgIOContext->pScsiCmnd;
1680
1681  osti_memset(LBA,0, sizeof(LBA));
1682
1683  switch (satOrgIOContext->ATACmd)
1684  {
1685  case SAT_READ_DMA:
1686    DenomTL = 0xFF;
1687    break;
1688  case SAT_READ_SECTORS:
1689    DenomTL = 0xFF;
1690    break;
1691  case SAT_READ_DMA_EXT:
1692    DenomTL = 0xFFFF;
1693    break;
1694  case SAT_READ_SECTORS_EXT:
1695    DenomTL = 0xFFFF;
1696    break;
1697  case SAT_READ_FPDMA_QUEUED:
1698    DenomTL = 0xFFFF;
1699    break;
1700  default:
1701    TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1702    return tiError;
1703    break;
1704  }
1705
1706  Remainder = satOrgIOContext->OrgTL % DenomTL;
1707  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
1708  lba = satOrgIOContext->currentLBA;
1709
1710  LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3));
1711  LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
1712  LBA[2] = (bit8)((lba & 0xF0) >> 8);
1713  LBA[3] = (bit8)(lba & 0xF);
1714
1715
1716  switch (satOrgIOContext->ATACmd)
1717  {
1718  case SAT_READ_DMA:
1719    fis->h.fisType        = 0x27;                   /* Reg host to device */
1720    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1721    fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
1722    fis->h.features       = 0;                      /* FIS reserve */
1723    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1724    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1725    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1726    fis->d.device         =
1727      (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
1728    fis->d.lbaLowExp      = 0;
1729    fis->d.lbaMidExp      = 0;
1730    fis->d.lbaHighExp     = 0;
1731    fis->d.featuresExp    = 0;
1732
1733    if (satOrgIOContext->LoopNum == 1)
1734    {
1735      /* last loop */
1736      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
1737    }
1738    else
1739    {
1740      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
1741    }
1742
1743    fis->d.sectorCountExp = 0;
1744    fis->d.reserved4      = 0;
1745    fis->d.control        = 0;                      /* FIS HOB bit clear */
1746    fis->d.reserved5      = 0;
1747
1748    agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1749
1750    break;
1751  case SAT_READ_SECTORS:
1752    fis->h.fisType        = 0x27;                   /* Reg host to device */
1753    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1754    fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
1755    fis->h.features       = 0;                      /* FIS reserve */
1756    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1757    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1758    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1759    fis->d.device         =
1760      (bit8)((0x4 << 4) | (LBA[0] & 0xF));                  /* FIS LBA (27:24) and FIS LBA mode  */
1761    fis->d.lbaLowExp      = 0;
1762    fis->d.lbaMidExp      = 0;
1763    fis->d.lbaHighExp     = 0;
1764    fis->d.featuresExp    = 0;
1765    if (satOrgIOContext->LoopNum == 1)
1766    {
1767      /* last loop */
1768      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
1769    }
1770    else
1771    {
1772      fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
1773    }
1774    fis->d.sectorCountExp = 0;
1775    fis->d.reserved4      = 0;
1776    fis->d.control        = 0;                      /* FIS HOB bit clear */
1777    fis->d.reserved5      = 0;
1778
1779    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1780
1781    break;
1782  case SAT_READ_DMA_EXT:
1783    fis->h.fisType        = 0x27;                   /* Reg host to device */
1784    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1785    fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
1786    fis->h.features       = 0;                      /* FIS reserve */
1787    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1788    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1789    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1790    fis->d.device         = 0x40;                   /* FIS LBA mode set */
1791    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
1792    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1793    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1794    fis->d.featuresExp    = 0;                      /* FIS reserve */
1795    if (satOrgIOContext->LoopNum == 1)
1796    {
1797      /* last loop */
1798      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
1799      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
1800
1801    }
1802    else
1803    {
1804      fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
1805      fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
1806    }
1807    fis->d.reserved4      = 0;
1808    fis->d.control        = 0;                      /* FIS HOB bit clear */
1809    fis->d.reserved5      = 0;
1810
1811    agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1812
1813    break;
1814  case SAT_READ_SECTORS_EXT:
1815    fis->h.fisType        = 0x27;                   /* Reg host to device */
1816    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1817    fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
1818    fis->h.features       = 0;                      /* FIS reserve */
1819    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1820    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1821    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1822    fis->d.device         = 0x40;                   /* FIS LBA mode set */
1823    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
1824    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1825    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1826    fis->d.featuresExp    = 0;                      /* FIS reserve */
1827    if (satOrgIOContext->LoopNum == 1)
1828    {
1829      /* last loop */
1830      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
1831      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);  /* FIS sector count (15:8) */
1832    }
1833    else
1834    {
1835      fis->d.sectorCount    = 0xFF;       /* FIS sector count (7:0) */
1836      fis->d.sectorCountExp = 0xFF;       /* FIS sector count (15:8) */
1837    }
1838    fis->d.reserved4      = 0;
1839    fis->d.control        = 0;                      /* FIS HOB bit clear */
1840    fis->d.reserved5      = 0;
1841
1842    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1843    break;
1844  case SAT_READ_FPDMA_QUEUED:
1845    fis->h.fisType        = 0x27;                   /* Reg host to device */
1846    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
1847    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
1848    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
1849    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
1850    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
1851
1852    /* Check FUA bit */
1853    if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1854      fis->d.device       = 0xC0;                   /* FIS FUA set */
1855    else
1856      fis->d.device       = 0x40;                   /* FIS FUA clear */
1857
1858    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
1859    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
1860    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
1861    if (satOrgIOContext->LoopNum == 1)
1862    {
1863      /* last loop */
1864      fis->h.features       = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
1865      fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
1866    }
1867    else
1868    {
1869      fis->h.features       = 0xFF;       /* FIS sector count (7:0) */
1870      fis->d.featuresExp    = 0xFF;       /* FIS sector count (15:8) */
1871    }
1872    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
1873    fis->d.sectorCountExp = 0;
1874    fis->d.reserved4      = 0;
1875    fis->d.control        = 0;                      /* FIS HOB bit clear */
1876    fis->d.reserved5      = 0;
1877
1878    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1879    break;
1880  default:
1881    TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1882    return tiError;
1883    break;
1884  }
1885
1886  /* Initialize CB for SATA completion.
1887   */
1888  /* chained data */
1889  satIOContext->satCompleteCB = &satChainedDataIOCB;
1890
1891
1892  /*
1893   * Prepare SGL and send FIS to LL layer.
1894   */
1895  satIOContext->reqType = agRequestType;       /* Save it */
1896
1897  status = sataLLIOStart( tiRoot,
1898                          tiIORequest,
1899                          tiDeviceHandle,
1900                          tiScsiRequest,
1901                          satIOContext);
1902
1903  TI_DBG5(("satRead_1: return\n"));
1904  return (status);
1905}
1906/*****************************************************************************/
1907/*! \brief SAT implementation for SCSI READ12.
1908 *
1909 *  SAT implementation for SCSI READ12 and send FIS request to LL layer.
1910 *
1911 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
1912 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
1913 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
1914 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
1915 *  \param   satIOContext_t:   Pointer to the SAT IO Context
1916 *
1917 *  \return If command is started successfully
1918 *    - \e tiSuccess:     I/O request successfully initiated.
1919 *    - \e tiBusy:        No resources available, try again later.
1920 *    - \e tiIONoDevice:  Invalid device handle.
1921 *    - \e tiError:       Other errors.
1922 */
1923/*****************************************************************************/
1924GLOBAL bit32  satRead12(
1925                   tiRoot_t                  *tiRoot,
1926                   tiIORequest_t             *tiIORequest,
1927                   tiDeviceHandle_t          *tiDeviceHandle,
1928                   tiScsiInitiatorRequest_t *tiScsiRequest,
1929                   satIOContext_t            *satIOContext)
1930{
1931  bit32                     status;
1932  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1933  satDeviceData_t           *pSatDevData;
1934  scsiRspSense_t            *pSense;
1935  tiIniScsiCmnd_t           *scsiCmnd;
1936  agsaFisRegHostToDevice_t  *fis;
1937  bit32                     lba = 0;
1938  bit32                     tl = 0;
1939  bit32                     LoopNum = 1;
1940  bit8                      LBA[4];
1941  bit8                      TL[4];
1942  bit32                     rangeChk = agFALSE; /* lba and tl range check */
1943
1944  pSense        = satIOContext->pSense;
1945  pSatDevData   = satIOContext->pSatDevData;
1946  scsiCmnd      = &tiScsiRequest->scsiCmnd;
1947  fis           = satIOContext->pFis;
1948
1949  TI_DBG5(("satRead12: start\n"));
1950
1951  /* checking FUA_NV */
1952  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1953  {
1954    satSetSensePayload( pSense,
1955                        SCSI_SNSKEY_ILLEGAL_REQUEST,
1956                        0,
1957                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1958                        satIOContext);
1959
1960    ostiInitiatorIOCompleted( tiRoot,
1961                              tiIORequest,
1962                              tiIOSuccess,
1963                              SCSI_STAT_CHECK_CONDITION,
1964                              satIOContext->pTiSenseData,
1965                              satIOContext->interruptContext );
1966
1967    TI_DBG1(("satRead12: return FUA_NV\n"));
1968    return tiSuccess;
1969
1970  }
1971
1972  /* checking CONTROL */
1973  /* NACA == 1 or LINK == 1*/
1974  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
1975  {
1976    satSetSensePayload( pSense,
1977                        SCSI_SNSKEY_ILLEGAL_REQUEST,
1978                        0,
1979                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1980                        satIOContext);
1981
1982    ostiInitiatorIOCompleted( tiRoot,
1983                              tiIORequest,
1984                              tiIOSuccess,
1985                              SCSI_STAT_CHECK_CONDITION,
1986                              satIOContext->pTiSenseData,
1987                              satIOContext->interruptContext );
1988
1989    TI_DBG2(("satRead12: return control\n"));
1990    return tiSuccess;
1991  }
1992
1993  osti_memset(LBA, 0, sizeof(LBA));
1994  osti_memset(TL, 0, sizeof(TL));
1995
1996  /* do not use memcpy due to indexing in LBA and TL */
1997  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
1998  LBA[1] = scsiCmnd->cdb[3];
1999  LBA[2] = scsiCmnd->cdb[4];
2000  LBA[3] = scsiCmnd->cdb[5];  /* LSB */
2001
2002  TL[0] = scsiCmnd->cdb[6];   /* MSB */
2003  TL[1] = scsiCmnd->cdb[7];
2004  TL[2] = scsiCmnd->cdb[8];
2005  TL[3] = scsiCmnd->cdb[9];   /* LSB */
2006
2007  rangeChk = satAddNComparebit32(LBA, TL);
2008
2009  lba = satComputeCDB12LBA(satIOContext);
2010  tl = satComputeCDB12TL(satIOContext);
2011
2012  /* Table 34, 9.1, p 46 */
2013  /*
2014    note: As of 2/10/2006, no support for DMA QUEUED
2015   */
2016
2017  /*
2018    Table 34, 9.1, p 46, b
2019    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2020    return check condition
2021  */
2022  if (pSatDevData->satNCQ != agTRUE &&
2023      pSatDevData->sat48BitSupport != agTRUE
2024      )
2025  {
2026    if (lba > SAT_TR_LBA_LIMIT - 1)
2027    {
2028      TI_DBG1(("satRead12: return LBA out of range, not EXT\n"));
2029      satSetSensePayload( pSense,
2030                          SCSI_SNSKEY_ILLEGAL_REQUEST,
2031                          0,
2032                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2033                          satIOContext);
2034
2035      ostiInitiatorIOCompleted( tiRoot,
2036                                tiIORequest,
2037                                tiIOSuccess,
2038                                SCSI_STAT_CHECK_CONDITION,
2039                                satIOContext->pTiSenseData,
2040                                satIOContext->interruptContext );
2041
2042    return tiSuccess;
2043    }
2044    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
2045    {
2046      TI_DBG1(("satRead12: return LBA+TL out of range, not EXT\n"));
2047      satSetSensePayload( pSense,
2048                          SCSI_SNSKEY_ILLEGAL_REQUEST,
2049                          0,
2050                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2051                          satIOContext);
2052
2053      ostiInitiatorIOCompleted( tiRoot,
2054                                tiIORequest,
2055                                tiIOSuccess,
2056                                SCSI_STAT_CHECK_CONDITION,
2057                                satIOContext->pTiSenseData,
2058                                satIOContext->interruptContext );
2059
2060    return tiSuccess;
2061    }
2062  }
2063
2064  /* case 1 and 2 */
2065  if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
2066  {
2067    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2068    {
2069      /* case 2 */
2070      /* READ DMA*/
2071      /* in case that we can't fit the transfer length,
2072         we need to make it fit by sending multiple ATA cmnds */
2073      TI_DBG5(("satRead12: case 2\n"));
2074
2075
2076      fis->h.fisType        = 0x27;                   /* Reg host to device */
2077      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2078      fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
2079      fis->h.features       = 0;                      /* FIS reserve */
2080      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2081      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2082      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2083      fis->d.device         =
2084        (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2085      fis->d.lbaLowExp      = 0;
2086      fis->d.lbaMidExp      = 0;
2087      fis->d.lbaHighExp     = 0;
2088      fis->d.featuresExp    = 0;
2089      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2090      fis->d.sectorCountExp = 0;
2091      fis->d.reserved4      = 0;
2092      fis->d.control        = 0;                      /* FIS HOB bit clear */
2093      fis->d.reserved5      = 0;
2094
2095
2096      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2097      satIOContext->ATACmd = SAT_READ_DMA;
2098    }
2099    else
2100    {
2101      /* case 1 */
2102      /* READ MULTIPLE or READ SECTOR(S) */
2103      /* READ SECTORS for easier implemetation */
2104      /* can't fit the transfer length but need to make it fit by sending multiple*/
2105      TI_DBG5(("satRead12: case 1\n"));
2106
2107      fis->h.fisType        = 0x27;                   /* Reg host to device */
2108      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2109      fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
2110      fis->h.features       = 0;                      /* FIS reserve */
2111      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2112      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2113      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2114      fis->d.device         =
2115        (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2116      fis->d.lbaLowExp      = 0;
2117      fis->d.lbaMidExp      = 0;
2118      fis->d.lbaHighExp     = 0;
2119      fis->d.featuresExp    = 0;
2120      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2121      fis->d.sectorCountExp = 0;
2122      fis->d.reserved4      = 0;
2123      fis->d.control        = 0;                      /* FIS HOB bit clear */
2124      fis->d.reserved5      = 0;
2125
2126
2127      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2128      satIOContext->ATACmd = SAT_READ_SECTORS;
2129    }
2130  }
2131
2132  /* case 3 and 4 */
2133  if (pSatDevData->sat48BitSupport == agTRUE)
2134  {
2135    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2136    {
2137      /* case 3 */
2138      /* READ DMA EXT */
2139      TI_DBG5(("satRead12: case 3\n"));
2140      fis->h.fisType        = 0x27;                   /* Reg host to device */
2141
2142      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2143      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
2144      fis->h.features       = 0;                      /* FIS reserve */
2145      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2146      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2147      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2148      fis->d.device         = 0x40;                   /* FIS LBA mode set */
2149      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
2150      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2151      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2152      fis->d.featuresExp    = 0;                      /* FIS reserve */
2153      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2154      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
2155      fis->d.reserved4      = 0;
2156      fis->d.control        = 0;                      /* FIS HOB bit clear */
2157      fis->d.reserved5      = 0;
2158
2159      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2160      satIOContext->ATACmd = SAT_READ_DMA_EXT;
2161
2162    }
2163    else
2164    {
2165      /* case 4 */
2166      /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2167      /* READ SECTORS EXT for easier implemetation */
2168      TI_DBG5(("satRead12: case 4\n"));
2169      fis->h.fisType        = 0x27;                   /* Reg host to device */
2170      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2171
2172      /* Check FUA bit */
2173      if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2174      {
2175        /* for now, no support for FUA */
2176        satSetSensePayload( pSense,
2177                            SCSI_SNSKEY_ILLEGAL_REQUEST,
2178                            0,
2179                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2180                            satIOContext);
2181
2182        ostiInitiatorIOCompleted( tiRoot,
2183                                  tiIORequest,
2184                                  tiIOSuccess,
2185                                  SCSI_STAT_CHECK_CONDITION,
2186                                  satIOContext->pTiSenseData,
2187                                  satIOContext->interruptContext );
2188        return tiSuccess;
2189      }
2190
2191      fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
2192
2193      fis->h.features       = 0;                      /* FIS reserve */
2194      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2195      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2196      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2197      fis->d.device         = 0x40;                   /* FIS LBA mode set */
2198      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
2199      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2200      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2201      fis->d.featuresExp    = 0;                      /* FIS reserve */
2202      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2203      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
2204      fis->d.reserved4      = 0;
2205      fis->d.control        = 0;                      /* FIS HOB bit clear */
2206      fis->d.reserved5      = 0;
2207
2208      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2209      satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2210    }
2211  }
2212
2213  /* case 5 */
2214  if (pSatDevData->satNCQ == agTRUE)
2215  {
2216    /* READ FPDMA QUEUED */
2217    if (pSatDevData->sat48BitSupport != agTRUE)
2218    {
2219      TI_DBG5(("satRead12: case 5 !!! error NCQ but 28 bit address support \n"));
2220      satSetSensePayload( pSense,
2221                          SCSI_SNSKEY_ILLEGAL_REQUEST,
2222                          0,
2223                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2224                          satIOContext);
2225
2226      ostiInitiatorIOCompleted( tiRoot,
2227                                tiIORequest,
2228                                tiIOSuccess,
2229                                SCSI_STAT_CHECK_CONDITION,
2230                                satIOContext->pTiSenseData,
2231                                satIOContext->interruptContext );
2232      return tiSuccess;
2233    }
2234
2235    TI_DBG6(("satRead12: case 5\n"));
2236
2237    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2238
2239    fis->h.fisType        = 0x27;                   /* Reg host to device */
2240    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2241    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
2242    fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
2243    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
2244    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
2245    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
2246
2247    /* Check FUA bit */
2248    if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2249      fis->d.device       = 0xC0;                   /* FIS FUA set */
2250    else
2251      fis->d.device       = 0x40;                   /* FIS FUA clear */
2252
2253    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
2254    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2255    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2256    fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
2257    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
2258    fis->d.sectorCountExp = 0;
2259    fis->d.reserved4      = 0;
2260    fis->d.control        = 0;                      /* FIS HOB bit clear */
2261    fis->d.reserved5      = 0;
2262
2263    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2264    satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2265  }
2266
2267  /* saves the current LBA and orginal TL */
2268  satIOContext->currentLBA = lba;
2269  satIOContext->OrgTL = tl;
2270
2271  /*
2272    computing number of loop and remainder for tl
2273    0xFF in case not ext
2274    0xFFFF in case EXT
2275  */
2276  if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2277  {
2278    LoopNum = satComputeLoopNum(tl, 0xFF);
2279  }
2280  else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2281  {
2282    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2283    LoopNum = satComputeLoopNum(tl, 0xFFFF);
2284  }
2285  else
2286  {
2287    /* SAT_READ_FPDMA_QUEUEDK */
2288    LoopNum = satComputeLoopNum(tl, 0xFFFF);
2289  }
2290
2291  satIOContext->LoopNum = LoopNum;
2292
2293  if (LoopNum == 1)
2294  {
2295    TI_DBG5(("satRead12: NON CHAINED data\n"));
2296    satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2297  }
2298  else
2299  {
2300    TI_DBG1(("satRead12: CHAINED data\n"));
2301    /* re-setting tl */
2302    if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2303    {
2304       fis->d.sectorCount    = 0xFF;
2305    }
2306    else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2307    {
2308      /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2309      fis->d.sectorCount    = 0xFF;
2310      fis->d.sectorCountExp = 0xFF;
2311    }
2312    else
2313    {
2314      /* SAT_READ_FPDMA_QUEUED */
2315      fis->h.features       = 0xFF;
2316      fis->d.featuresExp    = 0xFF;
2317    }
2318
2319    /* chained data */
2320    satIOContext->satCompleteCB = &satChainedDataIOCB;
2321  }
2322
2323  /*
2324   * Prepare SGL and send FIS to LL layer.
2325   */
2326  satIOContext->reqType = agRequestType;       /* Save it */
2327
2328  status = sataLLIOStart( tiRoot,
2329                          tiIORequest,
2330                          tiDeviceHandle,
2331                          tiScsiRequest,
2332                          satIOContext);
2333
2334  TI_DBG5(("satRead12: return\n"));
2335  return (status);
2336}
2337/*****************************************************************************/
2338/*! \brief SAT implementation for SCSI READ16.
2339 *
2340 *  SAT implementation for SCSI READ16 and send FIS request to LL layer.
2341 *
2342 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
2343 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
2344 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
2345 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
2346 *  \param   satIOContext_t:   Pointer to the SAT IO Context
2347 *
2348 *  \return If command is started successfully
2349 *    - \e tiSuccess:     I/O request successfully initiated.
2350 *    - \e tiBusy:        No resources available, try again later.
2351 *    - \e tiIONoDevice:  Invalid device handle.
2352 *    - \e tiError:       Other errors.
2353 */
2354/*****************************************************************************/
2355GLOBAL bit32  satRead16(
2356                   tiRoot_t                  *tiRoot,
2357                   tiIORequest_t             *tiIORequest,
2358                   tiDeviceHandle_t          *tiDeviceHandle,
2359                   tiScsiInitiatorRequest_t *tiScsiRequest,
2360                   satIOContext_t            *satIOContext)
2361{
2362  bit32                     status;
2363  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2364  satDeviceData_t           *pSatDevData;
2365  scsiRspSense_t            *pSense;
2366  tiIniScsiCmnd_t           *scsiCmnd;
2367  agsaFisRegHostToDevice_t  *fis;
2368  bit32                     lba = 0;
2369  bit32                     tl = 0;
2370  bit32                     LoopNum = 1;
2371  bit8                      LBA[8];
2372  bit8                      TL[8];
2373  bit32                     rangeChk = agFALSE; /* lba and tl range check */
2374  bit32                     limitChk = agFALSE; /* lba and tl range check */
2375
2376  pSense        = satIOContext->pSense;
2377  pSatDevData   = satIOContext->pSatDevData;
2378  scsiCmnd      = &tiScsiRequest->scsiCmnd;
2379  fis           = satIOContext->pFis;
2380
2381  TI_DBG5(("satRead16: start\n"));
2382
2383  /* checking FUA_NV */
2384  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
2385  {
2386    satSetSensePayload( pSense,
2387                        SCSI_SNSKEY_ILLEGAL_REQUEST,
2388                        0,
2389                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2390                        satIOContext);
2391
2392    ostiInitiatorIOCompleted( tiRoot,
2393                              tiIORequest,
2394                              tiIOSuccess,
2395                              SCSI_STAT_CHECK_CONDITION,
2396                              satIOContext->pTiSenseData,
2397                              satIOContext->interruptContext );
2398
2399    TI_DBG1(("satRead16: return FUA_NV\n"));
2400    return tiSuccess;
2401
2402  }
2403
2404  /* checking CONTROL */
2405  /* NACA == 1 or LINK == 1*/
2406  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
2407  {
2408    satSetSensePayload( pSense,
2409                        SCSI_SNSKEY_ILLEGAL_REQUEST,
2410                        0,
2411                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2412                        satIOContext);
2413
2414    ostiInitiatorIOCompleted( tiRoot,
2415                              tiIORequest,
2416                              tiIOSuccess,
2417                              SCSI_STAT_CHECK_CONDITION,
2418                              satIOContext->pTiSenseData,
2419                              satIOContext->interruptContext );
2420
2421    TI_DBG1(("satRead16: return control\n"));
2422    return tiSuccess;
2423  }
2424
2425
2426  osti_memset(LBA, 0, sizeof(LBA));
2427  osti_memset(TL, 0, sizeof(TL));
2428
2429
2430  /* do not use memcpy due to indexing in LBA and TL */
2431  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
2432  LBA[1] = scsiCmnd->cdb[3];
2433  LBA[2] = scsiCmnd->cdb[4];
2434  LBA[3] = scsiCmnd->cdb[5];
2435  LBA[4] = scsiCmnd->cdb[6];
2436  LBA[5] = scsiCmnd->cdb[7];
2437  LBA[6] = scsiCmnd->cdb[8];
2438  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
2439
2440  TL[0] = 0;
2441  TL[1] = 0;
2442  TL[2] = 0;
2443  TL[3] = 0;
2444  TL[4] = scsiCmnd->cdb[10];   /* MSB */
2445  TL[5] = scsiCmnd->cdb[11];
2446  TL[6] = scsiCmnd->cdb[12];
2447  TL[7] = scsiCmnd->cdb[13];   /* LSB */
2448
2449 rangeChk = satAddNComparebit64(LBA, TL);
2450
2451 limitChk = satCompareLBALimitbit(LBA);
2452
2453 lba = satComputeCDB16LBA(satIOContext);
2454 tl = satComputeCDB16TL(satIOContext);
2455
2456
2457  /* Table 34, 9.1, p 46 */
2458  /*
2459    note: As of 2/10/2006, no support for DMA QUEUED
2460   */
2461
2462  /*
2463    Table 34, 9.1, p 46, b
2464    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2465    return check condition
2466  */
2467  if (pSatDevData->satNCQ != agTRUE &&
2468      pSatDevData->sat48BitSupport != agTRUE
2469      )
2470  {
2471    if (limitChk)
2472    {
2473      TI_DBG1(("satRead16: return LBA out of range, not EXT\n"));
2474      satSetSensePayload( pSense,
2475                          SCSI_SNSKEY_ILLEGAL_REQUEST,
2476                          0,
2477                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2478                          satIOContext);
2479
2480      ostiInitiatorIOCompleted( tiRoot,
2481                                tiIORequest,
2482                                tiIOSuccess,
2483                                SCSI_STAT_CHECK_CONDITION,
2484                                satIOContext->pTiSenseData,
2485                                satIOContext->interruptContext );
2486
2487    return tiSuccess;
2488    }
2489    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
2490    {
2491      TI_DBG1(("satRead16: return LBA+TL out of range, not EXT\n"));
2492      satSetSensePayload( pSense,
2493                          SCSI_SNSKEY_ILLEGAL_REQUEST,
2494                          0,
2495                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2496                          satIOContext);
2497
2498      ostiInitiatorIOCompleted( tiRoot,
2499                                tiIORequest,
2500                                tiIOSuccess,
2501                                SCSI_STAT_CHECK_CONDITION,
2502                                satIOContext->pTiSenseData,
2503                                satIOContext->interruptContext );
2504
2505    return tiSuccess;
2506    }
2507  }
2508
2509  /* case 1 and 2 */
2510  if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
2511  {
2512    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2513    {
2514      /* case 2 */
2515      /* READ DMA*/
2516      /* in case that we can't fit the transfer length,
2517         we need to make it fit by sending multiple ATA cmnds */
2518      TI_DBG5(("satRead16: case 2\n"));
2519
2520
2521      fis->h.fisType        = 0x27;                   /* Reg host to device */
2522      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2523      fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
2524      fis->h.features       = 0;                      /* FIS reserve */
2525      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2526      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2527      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2528      fis->d.device         =
2529        (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2530      fis->d.lbaLowExp      = 0;
2531      fis->d.lbaMidExp      = 0;
2532      fis->d.lbaHighExp     = 0;
2533      fis->d.featuresExp    = 0;
2534      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2535      fis->d.sectorCountExp = 0;
2536      fis->d.reserved4      = 0;
2537      fis->d.control        = 0;                      /* FIS HOB bit clear */
2538      fis->d.reserved5      = 0;
2539
2540
2541      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2542      satIOContext->ATACmd = SAT_READ_DMA;
2543    }
2544    else
2545    {
2546      /* case 1 */
2547      /* READ MULTIPLE or READ SECTOR(S) */
2548      /* READ SECTORS for easier implemetation */
2549      /* can't fit the transfer length but need to make it fit by sending multiple*/
2550      TI_DBG5(("satRead16: case 1\n"));
2551
2552      fis->h.fisType        = 0x27;                   /* Reg host to device */
2553      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2554      fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
2555      fis->h.features       = 0;                      /* FIS reserve */
2556      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2557      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2558      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2559      fis->d.device         =
2560        (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));        /* FIS LBA (27:24) and FIS LBA mode  */
2561      fis->d.lbaLowExp      = 0;
2562      fis->d.lbaMidExp      = 0;
2563      fis->d.lbaHighExp     = 0;
2564      fis->d.featuresExp    = 0;
2565      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2566      fis->d.sectorCountExp = 0;
2567      fis->d.reserved4      = 0;
2568      fis->d.control        = 0;                      /* FIS HOB bit clear */
2569      fis->d.reserved5      = 0;
2570
2571
2572      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2573      satIOContext->ATACmd = SAT_READ_SECTORS;
2574    }
2575  }
2576
2577  /* case 3 and 4 */
2578  if (pSatDevData->sat48BitSupport == agTRUE)
2579  {
2580    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2581    {
2582      /* case 3 */
2583      /* READ DMA EXT */
2584      TI_DBG5(("satRead16: case 3\n"));
2585      fis->h.fisType        = 0x27;                   /* Reg host to device */
2586
2587      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2588      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
2589      fis->h.features       = 0;                      /* FIS reserve */
2590      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2591      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2592      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2593      fis->d.device         = 0x40;                   /* FIS LBA mode set */
2594      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
2595      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
2596      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
2597      fis->d.featuresExp    = 0;                      /* FIS reserve */
2598      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2599      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
2600      fis->d.reserved4      = 0;
2601      fis->d.control        = 0;                      /* FIS HOB bit clear */
2602      fis->d.reserved5      = 0;
2603
2604      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2605      satIOContext->ATACmd = SAT_READ_DMA_EXT;
2606
2607    }
2608    else
2609    {
2610      /* case 4 */
2611      /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2612      /* READ SECTORS EXT for easier implemetation */
2613      TI_DBG5(("satRead16: case 4\n"));
2614      fis->h.fisType        = 0x27;                   /* Reg host to device */
2615      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2616
2617      /* Check FUA bit */
2618      if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2619      {
2620
2621        /* for now, no support for FUA */
2622        satSetSensePayload( pSense,
2623                            SCSI_SNSKEY_ILLEGAL_REQUEST,
2624                            0,
2625                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2626                            satIOContext);
2627
2628        ostiInitiatorIOCompleted( tiRoot,
2629                                  tiIORequest,
2630                                  tiIOSuccess,
2631                                  SCSI_STAT_CHECK_CONDITION,
2632                                  satIOContext->pTiSenseData,
2633                                  satIOContext->interruptContext );
2634        return tiSuccess;
2635      }
2636
2637      fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
2638
2639      fis->h.features       = 0;                      /* FIS reserve */
2640      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2641      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2642      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2643      fis->d.device         = 0x40;                   /* FIS LBA mode set */
2644      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
2645      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
2646      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
2647      fis->d.featuresExp    = 0;                      /* FIS reserve */
2648      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2649      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
2650      fis->d.reserved4      = 0;
2651      fis->d.control        = 0;                      /* FIS HOB bit clear */
2652      fis->d.reserved5      = 0;
2653
2654      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2655      satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2656    }
2657  }
2658
2659
2660  /* case 5 */
2661  if (pSatDevData->satNCQ == agTRUE)
2662  {
2663    /* READ FPDMA QUEUED */
2664    if (pSatDevData->sat48BitSupport != agTRUE)
2665    {
2666      TI_DBG5(("satRead16: case 5 !!! error NCQ but 28 bit address support \n"));
2667      satSetSensePayload( pSense,
2668                          SCSI_SNSKEY_ILLEGAL_REQUEST,
2669                          0,
2670                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2671                          satIOContext);
2672
2673      ostiInitiatorIOCompleted( tiRoot,
2674                                tiIORequest,
2675                                tiIOSuccess,
2676                                SCSI_STAT_CHECK_CONDITION,
2677                                satIOContext->pTiSenseData,
2678                                satIOContext->interruptContext );
2679      return tiSuccess;
2680    }
2681
2682    TI_DBG6(("satRead16: case 5\n"));
2683
2684    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2685
2686    fis->h.fisType        = 0x27;                   /* Reg host to device */
2687    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2688    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
2689    fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
2690    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
2691    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
2692    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
2693
2694    /* Check FUA bit */
2695    if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2696      fis->d.device       = 0xC0;                   /* FIS FUA set */
2697    else
2698      fis->d.device       = 0x40;                   /* FIS FUA clear */
2699
2700    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
2701    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
2702    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
2703    fis->d.featuresExp    = scsiCmnd->cdb[12];      /* FIS sector count (15:8) */
2704    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
2705    fis->d.sectorCountExp = 0;
2706    fis->d.reserved4      = 0;
2707    fis->d.control        = 0;                      /* FIS HOB bit clear */
2708    fis->d.reserved5      = 0;
2709
2710    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2711    satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2712  }
2713
2714  /* saves the current LBA and orginal TL */
2715  satIOContext->currentLBA = lba;
2716  satIOContext->OrgTL = tl;
2717
2718  /*
2719    computing number of loop and remainder for tl
2720    0xFF in case not ext
2721    0xFFFF in case EXT
2722  */
2723  if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2724  {
2725    LoopNum = satComputeLoopNum(tl, 0xFF);
2726  }
2727  else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2728  {
2729    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2730    LoopNum = satComputeLoopNum(tl, 0xFFFF);
2731  }
2732  else
2733  {
2734    /* SAT_READ_FPDMA_QUEUEDK */
2735    LoopNum = satComputeLoopNum(tl, 0xFFFF);
2736  }
2737  satIOContext->LoopNum = LoopNum;
2738
2739  if (LoopNum == 1)
2740  {
2741    TI_DBG5(("satRead16: NON CHAINED data\n"));
2742    satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2743  }
2744  else
2745  {
2746    TI_DBG1(("satRead16: CHAINED data\n"));
2747    /* re-setting tl */
2748    if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2749    {
2750       fis->d.sectorCount    = 0xFF;
2751    }
2752    else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2753    {
2754      /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2755      fis->d.sectorCount    = 0xFF;
2756      fis->d.sectorCountExp = 0xFF;
2757    }
2758    else
2759    {
2760      /* SAT_READ_FPDMA_QUEUED */
2761      fis->h.features       = 0xFF;
2762      fis->d.featuresExp    = 0xFF;
2763    }
2764
2765    /* chained data */
2766    satIOContext->satCompleteCB = &satChainedDataIOCB;
2767  }
2768
2769  /*
2770   * Prepare SGL and send FIS to LL layer.
2771   */
2772  satIOContext->reqType = agRequestType;       /* Save it */
2773
2774  status = sataLLIOStart( tiRoot,
2775                          tiIORequest,
2776                          tiDeviceHandle,
2777                          tiScsiRequest,
2778                          satIOContext);
2779
2780  TI_DBG5(("satRead16: return\n"));
2781  return (status);
2782
2783}
2784
2785/*****************************************************************************/
2786/*! \brief SAT implementation for SCSI READ6.
2787 *
2788 *  SAT implementation for SCSI READ6 and send FIS request to LL layer.
2789 *
2790 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
2791 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
2792 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
2793 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
2794 *  \param   satIOContext_t:   Pointer to the SAT IO Context
2795 *
2796 *  \return If command is started successfully
2797 *    - \e tiSuccess:     I/O request successfully initiated.
2798 *    - \e tiBusy:        No resources available, try again later.
2799 *    - \e tiIONoDevice:  Invalid device handle.
2800 *    - \e tiError:       Other errors.
2801 */
2802/*****************************************************************************/
2803GLOBAL bit32  satRead6(
2804                   tiRoot_t                  *tiRoot,
2805                   tiIORequest_t             *tiIORequest,
2806                   tiDeviceHandle_t          *tiDeviceHandle,
2807                   tiScsiInitiatorRequest_t *tiScsiRequest,
2808                   satIOContext_t            *satIOContext)
2809{
2810
2811  bit32                     status;
2812  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2813  satDeviceData_t           *pSatDevData;
2814  scsiRspSense_t            *pSense;
2815  tiIniScsiCmnd_t           *scsiCmnd;
2816  agsaFisRegHostToDevice_t  *fis;
2817  bit32                     lba = 0;
2818  bit16                     tl = 0;
2819
2820  pSense        = satIOContext->pSense;
2821  pSatDevData   = satIOContext->pSatDevData;
2822  scsiCmnd      = &tiScsiRequest->scsiCmnd;
2823  fis           = satIOContext->pFis;
2824
2825
2826   TI_DBG5(("satRead6: start\n"));
2827
2828  /* no FUA checking since read6 */
2829
2830
2831  /* checking CONTROL */
2832  /* NACA == 1 or LINK == 1*/
2833  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
2834  {
2835    satSetSensePayload( pSense,
2836                        SCSI_SNSKEY_ILLEGAL_REQUEST,
2837                        0,
2838                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2839                        satIOContext);
2840
2841    ostiInitiatorIOCompleted( tiRoot,
2842                              tiIORequest,
2843                              tiIOSuccess,
2844                              SCSI_STAT_CHECK_CONDITION,
2845                              satIOContext->pTiSenseData,
2846                              satIOContext->interruptContext );
2847
2848    TI_DBG2(("satRead6: return control\n"));
2849    return tiSuccess;
2850  }
2851
2852  /* cbd6; computing LBA and transfer length */
2853  lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
2854    + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
2855  tl = scsiCmnd->cdb[4];
2856
2857
2858  /* Table 34, 9.1, p 46 */
2859  /*
2860    note: As of 2/10/2006, no support for DMA QUEUED
2861   */
2862
2863  /*
2864    Table 34, 9.1, p 46, b
2865    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2866    return check condition
2867  */
2868  if (pSatDevData->satNCQ != agTRUE &&
2869      pSatDevData->sat48BitSupport != agTRUE
2870      )
2871  {
2872    if (lba > SAT_TR_LBA_LIMIT - 1)
2873    {
2874      satSetSensePayload( pSense,
2875                          SCSI_SNSKEY_ILLEGAL_REQUEST,
2876                          0,
2877                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2878                          satIOContext);
2879
2880      ostiInitiatorIOCompleted( tiRoot,
2881                                tiIORequest,
2882                                tiIOSuccess,
2883                                SCSI_STAT_CHECK_CONDITION,
2884                                satIOContext->pTiSenseData,
2885                                satIOContext->interruptContext );
2886
2887    TI_DBG1(("satRead6: return LBA out of range\n"));
2888    return tiSuccess;
2889    }
2890  }
2891
2892  /* case 1 and 2 */
2893  if (lba + tl <= SAT_TR_LBA_LIMIT)
2894  {
2895    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2896    {
2897      /* case 2 */
2898      /* READ DMA*/
2899      TI_DBG5(("satRead6: case 2\n"));
2900
2901
2902      fis->h.fisType        = 0x27;                   /* Reg host to device */
2903      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2904      fis->h.command        = SAT_READ_DMA;           /* 0xC8 */
2905      fis->h.features       = 0;                      /* FIS reserve */
2906      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
2907      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
2908      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
2909      fis->d.device         = 0x40;                   /* FIS LBA mode  */
2910      fis->d.lbaLowExp      = 0;
2911      fis->d.lbaMidExp      = 0;
2912      fis->d.lbaHighExp     = 0;
2913      fis->d.featuresExp    = 0;
2914      if (tl == 0)
2915      {
2916        /* temporary fix */
2917        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
2918      }
2919      else
2920      {
2921        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
2922      }
2923      fis->d.sectorCountExp = 0;
2924      fis->d.reserved4      = 0;
2925      fis->d.control        = 0;                      /* FIS HOB bit clear */
2926      fis->d.reserved5      = 0;
2927
2928      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2929    }
2930    else
2931    {
2932      /* case 1 */
2933      /* READ SECTORS for easier implemetation */
2934      TI_DBG5(("satRead6: case 1\n"));
2935
2936      fis->h.fisType        = 0x27;                   /* Reg host to device */
2937      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2938      fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
2939      fis->h.features       = 0;                      /* FIS reserve */
2940      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
2941      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
2942      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
2943      fis->d.device         = 0x40;                   /* FIS LBA mode  */
2944      fis->d.lbaLowExp      = 0;
2945      fis->d.lbaMidExp      = 0;
2946      fis->d.lbaHighExp     = 0;
2947      fis->d.featuresExp    = 0;
2948      if (tl == 0)
2949      {
2950        /* temporary fix */
2951        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
2952      }
2953      else
2954      {
2955        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
2956      }
2957      fis->d.sectorCountExp = 0;
2958      fis->d.reserved4      = 0;
2959      fis->d.control        = 0;                      /* FIS HOB bit clear */
2960      fis->d.reserved5      = 0;
2961
2962      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2963
2964    }
2965  }
2966
2967  /* case 3 and 4 */
2968  if (pSatDevData->sat48BitSupport == agTRUE)
2969  {
2970    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2971    {
2972      /* case 3 */
2973      /* READ DMA EXT only */
2974      TI_DBG5(("satRead6: case 3\n"));
2975      fis->h.fisType        = 0x27;                   /* Reg host to device */
2976      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
2977      fis->h.command        = SAT_READ_DMA_EXT;       /* 0x25 */
2978      fis->h.features       = 0;                      /* FIS reserve */
2979      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
2980      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
2981      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
2982      fis->d.device         = 0x40;                   /* FIS LBA mode set */
2983      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
2984      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
2985      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
2986      fis->d.featuresExp    = 0;                      /* FIS reserve */
2987      if (tl == 0)
2988      {
2989        /* sector count is 256, 0x100*/
2990        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
2991        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
2992      }
2993      else
2994      {
2995        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
2996        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
2997      }
2998      fis->d.reserved4      = 0;
2999      fis->d.control        = 0;                      /* FIS HOB bit clear */
3000      fis->d.reserved5      = 0;
3001
3002      agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
3003    }
3004    else
3005    {
3006      /* case 4 */
3007      /* READ SECTORS EXT for easier implemetation */
3008      TI_DBG5(("satRead6: case 4\n"));
3009
3010      fis->h.fisType        = 0x27;                   /* Reg host to device */
3011      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3012      fis->h.command        = SAT_READ_SECTORS_EXT;   /* 0x24 */
3013      fis->h.features       = 0;                      /* FIS reserve */
3014      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
3015      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
3016      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
3017      fis->d.device         = 0x40;                   /* FIS LBA mode set */
3018      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
3019      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3020      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3021      fis->d.featuresExp    = 0;                      /* FIS reserve */
3022      if (tl == 0)
3023      {
3024        /* sector count is 256, 0x100*/
3025        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
3026        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
3027      }
3028      else
3029      {
3030        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
3031        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
3032      }
3033      fis->d.reserved4      = 0;
3034      fis->d.control        = 0;                      /* FIS HOB bit clear */
3035      fis->d.reserved5      = 0;
3036
3037      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
3038    }
3039  }
3040
3041  /* case 5 */
3042  if (pSatDevData->satNCQ == agTRUE)
3043  {
3044    /* READ FPDMA QUEUED */
3045    if (pSatDevData->sat48BitSupport != agTRUE)
3046    {
3047      /* sanity check */
3048      TI_DBG5(("satRead6: case 5 !!! error NCQ but 28 bit address support \n"));
3049      satSetSensePayload( pSense,
3050                          SCSI_SNSKEY_ILLEGAL_REQUEST,
3051                          0,
3052                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3053                          satIOContext);
3054
3055      ostiInitiatorIOCompleted( tiRoot,
3056                                tiIORequest,
3057                                tiIOSuccess,
3058                                SCSI_STAT_CHECK_CONDITION,
3059                                satIOContext->pTiSenseData,
3060                                satIOContext->interruptContext );
3061      return tiSuccess;
3062    }
3063    TI_DBG5(("satRead6: case 5\n"));
3064
3065    /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
3066
3067    fis->h.fisType        = 0x27;                   /* Reg host to device */
3068    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3069    fis->h.command        = SAT_READ_FPDMA_QUEUED;  /* 0x60 */
3070    fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
3071    fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
3072    fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
3073    fis->d.device         = 0x40;                   /* FIS FUA clear */
3074    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
3075    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3076    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3077    if (tl == 0)
3078    {
3079      /* sector count is 256, 0x100*/
3080      fis->h.features       = 0;                         /* FIS sector count (7:0) */
3081      fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
3082    }
3083    else
3084    {
3085      fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
3086      fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
3087    }
3088    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
3089    fis->d.sectorCountExp = 0;
3090    fis->d.reserved4      = 0;
3091    fis->d.control        = 0;                      /* FIS HOB bit clear */
3092    fis->d.reserved5      = 0;
3093
3094    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
3095  }
3096
3097   /* Initialize CB for SATA completion.
3098   */
3099  satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3100
3101  /*
3102   * Prepare SGL and send FIS to LL layer.
3103   */
3104  satIOContext->reqType = agRequestType;       /* Save it */
3105
3106  status = sataLLIOStart( tiRoot,
3107                          tiIORequest,
3108                          tiDeviceHandle,
3109                          tiScsiRequest,
3110                          satIOContext);
3111  return (status);
3112
3113}
3114
3115/*****************************************************************************/
3116/*! \brief SAT implementation for SCSI WRITE16.
3117 *
3118 *  SAT implementation for SCSI WRITE16 and send FIS request to LL layer.
3119 *
3120 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
3121 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
3122 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
3123 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
3124 *  \param   satIOContext_t:   Pointer to the SAT IO Context
3125 *
3126 *  \return If command is started successfully
3127 *    - \e tiSuccess:     I/O request successfully initiated.
3128 *    - \e tiBusy:        No resources available, try again later.
3129 *    - \e tiIONoDevice:  Invalid device handle.
3130 *    - \e tiError:       Other errors.
3131 */
3132/*****************************************************************************/
3133GLOBAL bit32  satWrite16(
3134                   tiRoot_t                  *tiRoot,
3135                   tiIORequest_t             *tiIORequest,
3136                   tiDeviceHandle_t          *tiDeviceHandle,
3137                   tiScsiInitiatorRequest_t *tiScsiRequest,
3138                   satIOContext_t            *satIOContext)
3139{
3140  bit32                     status;
3141  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3142  satDeviceData_t           *pSatDevData;
3143  scsiRspSense_t            *pSense;
3144  tiIniScsiCmnd_t           *scsiCmnd;
3145  agsaFisRegHostToDevice_t  *fis;
3146  bit32                     lba = 0;
3147  bit32                     tl = 0;
3148  bit32                     LoopNum = 1;
3149  bit8                      LBA[8];
3150  bit8                      TL[8];
3151  bit32                     rangeChk = agFALSE; /* lba and tl range check */
3152  bit32                     limitChk = agFALSE; /* lba and tl range check */
3153
3154  pSense        = satIOContext->pSense;
3155  pSatDevData   = satIOContext->pSatDevData;
3156  scsiCmnd      = &tiScsiRequest->scsiCmnd;
3157  fis           = satIOContext->pFis;
3158
3159  TI_DBG5(("satWrite16: start\n"));
3160
3161  /* checking FUA_NV */
3162  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3163  {
3164    satSetSensePayload( pSense,
3165                        SCSI_SNSKEY_ILLEGAL_REQUEST,
3166                        0,
3167                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3168                        satIOContext);
3169
3170    ostiInitiatorIOCompleted( tiRoot,
3171                              tiIORequest,
3172                              tiIOSuccess,
3173                              SCSI_STAT_CHECK_CONDITION,
3174                              satIOContext->pTiSenseData,
3175                              satIOContext->interruptContext );
3176
3177    TI_DBG1(("satWrite16: return FUA_NV\n"));
3178    return tiSuccess;
3179
3180  }
3181
3182  /* checking CONTROL */
3183  /* NACA == 1 or LINK == 1*/
3184  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
3185  {
3186    satSetSensePayload( pSense,
3187                        SCSI_SNSKEY_ILLEGAL_REQUEST,
3188                        0,
3189                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3190                        satIOContext);
3191
3192    ostiInitiatorIOCompleted( tiRoot,
3193                              tiIORequest,
3194                              tiIOSuccess,
3195                              SCSI_STAT_CHECK_CONDITION,
3196                              satIOContext->pTiSenseData,
3197                              satIOContext->interruptContext );
3198
3199    TI_DBG1(("satWrite16: return control\n"));
3200    return tiSuccess;
3201  }
3202
3203
3204  osti_memset(LBA, 0, sizeof(LBA));
3205  osti_memset(TL, 0, sizeof(TL));
3206
3207
3208  /* do not use memcpy due to indexing in LBA and TL */
3209  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
3210  LBA[1] = scsiCmnd->cdb[3];
3211  LBA[2] = scsiCmnd->cdb[4];
3212  LBA[3] = scsiCmnd->cdb[5];
3213  LBA[4] = scsiCmnd->cdb[6];
3214  LBA[5] = scsiCmnd->cdb[7];
3215  LBA[6] = scsiCmnd->cdb[8];
3216  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
3217
3218  TL[0] = 0;
3219  TL[1] = 0;
3220  TL[2] = 0;
3221  TL[3] = 0;
3222  TL[4] = scsiCmnd->cdb[10];   /* MSB */
3223  TL[5] = scsiCmnd->cdb[11];
3224  TL[6] = scsiCmnd->cdb[12];
3225  TL[7] = scsiCmnd->cdb[13];   /* LSB */
3226
3227  rangeChk = satAddNComparebit64(LBA, TL);
3228
3229  limitChk = satCompareLBALimitbit(LBA);
3230
3231  lba = satComputeCDB16LBA(satIOContext);
3232  tl = satComputeCDB16TL(satIOContext);
3233
3234
3235
3236  /* Table 34, 9.1, p 46 */
3237  /*
3238    note: As of 2/10/2006, no support for DMA QUEUED
3239  */
3240
3241  /*
3242    Table 34, 9.1, p 46, b
3243    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3244    return check condition
3245  */
3246  if (pSatDevData->satNCQ != agTRUE &&
3247     pSatDevData->sat48BitSupport != agTRUE
3248     )
3249  {
3250    if (limitChk)
3251    {
3252      TI_DBG1(("satWrite16: return LBA out of range, not EXT\n"));
3253      satSetSensePayload( pSense,
3254                          SCSI_SNSKEY_ILLEGAL_REQUEST,
3255                          0,
3256                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3257                          satIOContext);
3258
3259      ostiInitiatorIOCompleted( tiRoot,
3260                                tiIORequest,
3261                                tiIOSuccess,
3262                                SCSI_STAT_CHECK_CONDITION,
3263                                satIOContext->pTiSenseData,
3264                                satIOContext->interruptContext );
3265
3266    return tiSuccess;
3267    }
3268    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
3269    {
3270      TI_DBG1(("satWrite16: return LBA+TL out of range, not EXT\n"));
3271      satSetSensePayload( pSense,
3272                          SCSI_SNSKEY_ILLEGAL_REQUEST,
3273                          0,
3274                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3275                          satIOContext);
3276
3277      ostiInitiatorIOCompleted( tiRoot,
3278                                tiIORequest,
3279                                tiIOSuccess,
3280                                SCSI_STAT_CHECK_CONDITION,
3281                                satIOContext->pTiSenseData,
3282                                satIOContext->interruptContext );
3283
3284    return tiSuccess;
3285    }
3286  }
3287
3288  /* case 1 and 2 */
3289  if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
3290  {
3291    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3292    {
3293      /* case 2 */
3294      /* WRITE DMA*/
3295      /* In case that we can't fit the transfer length, we loop */
3296      TI_DBG5(("satWrite16: case 2\n"));
3297      fis->h.fisType        = 0x27;                   /* Reg host to device */
3298      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3299      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
3300      fis->h.features       = 0;                      /* FIS reserve */
3301      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3302      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3303      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3304
3305      /* FIS LBA mode set LBA (27:24) */
3306      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3307
3308      fis->d.lbaLowExp      = 0;
3309      fis->d.lbaMidExp      = 0;
3310      fis->d.lbaHighExp     = 0;
3311      fis->d.featuresExp    = 0;
3312      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3313      fis->d.sectorCountExp = 0;
3314      fis->d.reserved4      = 0;
3315      fis->d.control        = 0;                      /* FIS HOB bit clear */
3316      fis->d.reserved5      = 0;
3317
3318      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3319      satIOContext->ATACmd = SAT_WRITE_DMA;
3320    }
3321    else
3322    {
3323      /* case 1 */
3324      /* WRITE MULTIPLE or WRITE SECTOR(S) */
3325      /* WRITE SECTORS for easier implemetation */
3326      /* In case that we can't fit the transfer length, we loop */
3327      TI_DBG5(("satWrite16: case 1\n"));
3328      fis->h.fisType        = 0x27;                   /* Reg host to device */
3329      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3330      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
3331      fis->h.features       = 0;                      /* FIS reserve */
3332      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3333      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3334      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3335
3336      /* FIS LBA mode set LBA (27:24) */
3337      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3338
3339      fis->d.lbaLowExp      = 0;
3340      fis->d.lbaMidExp      = 0;
3341      fis->d.lbaHighExp     = 0;
3342      fis->d.featuresExp    = 0;
3343      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3344      fis->d.sectorCountExp = 0;
3345      fis->d.reserved4      = 0;
3346      fis->d.control        = 0;                      /* FIS HOB bit clear */
3347      fis->d.reserved5      = 0;
3348
3349      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3350      satIOContext->ATACmd = SAT_WRITE_SECTORS;
3351    }
3352  }
3353
3354  /* case 3 and 4 */
3355  if (pSatDevData->sat48BitSupport == agTRUE)
3356  {
3357    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3358    {
3359      /* case 3 */
3360      /* WRITE DMA EXT or WRITE DMA FUA EXT */
3361      TI_DBG5(("satWrite16: case 3\n"));
3362      fis->h.fisType        = 0x27;                   /* Reg host to device */
3363      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3364
3365      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3366      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
3367
3368      fis->h.features       = 0;                      /* FIS reserve */
3369      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3370      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3371      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3372      fis->d.device         = 0x40;                   /* FIS LBA mode set */
3373      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
3374      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
3375      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
3376      fis->d.featuresExp    = 0;                      /* FIS reserve */
3377      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3378      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
3379      fis->d.reserved4      = 0;
3380      fis->d.control        = 0;                      /* FIS HOB bit clear */
3381      fis->d.reserved5      = 0;
3382
3383      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3384      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3385    }
3386    else
3387    {
3388      /* case 4 */
3389      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3390      /* WRITE SECTORS EXT for easier implemetation */
3391      TI_DBG5(("satWrite16: case 4\n"));
3392      fis->h.fisType        = 0x27;                   /* Reg host to device */
3393      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3394      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
3395
3396      fis->h.features       = 0;                      /* FIS reserve */
3397      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3398      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3399      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3400      fis->d.device         = 0x40;                   /* FIS LBA mode set */
3401      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
3402      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
3403      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
3404      fis->d.featuresExp    = 0;                      /* FIS reserve */
3405      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3406      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
3407      fis->d.reserved4      = 0;
3408      fis->d.control        = 0;                      /* FIS HOB bit clear */
3409      fis->d.reserved5      = 0;
3410
3411      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3412      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3413    }
3414  }
3415
3416  /* case 5 */
3417  if (pSatDevData->satNCQ == agTRUE)
3418  {
3419    /* WRITE FPDMA QUEUED */
3420    if (pSatDevData->sat48BitSupport != agTRUE)
3421    {
3422      TI_DBG5(("satWrite16: case 5 !!! error NCQ but 28 bit address support \n"));
3423      satSetSensePayload( pSense,
3424                          SCSI_SNSKEY_ILLEGAL_REQUEST,
3425                          0,
3426                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3427                          satIOContext);
3428
3429      ostiInitiatorIOCompleted( tiRoot,
3430                                tiIORequest,
3431                                tiIOSuccess,
3432                                SCSI_STAT_CHECK_CONDITION,
3433                                satIOContext->pTiSenseData,
3434                                satIOContext->interruptContext );
3435      return tiSuccess;
3436    }
3437    TI_DBG6(("satWrite16: case 5\n"));
3438
3439    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3440
3441    fis->h.fisType        = 0x27;                   /* Reg host to device */
3442    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3443    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3444    fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
3445    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
3446    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
3447    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
3448
3449    /* Check FUA bit */
3450    if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
3451      fis->d.device       = 0xC0;                   /* FIS FUA set */
3452    else
3453      fis->d.device       = 0x40;                   /* FIS FUA clear */
3454
3455    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
3456    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
3457    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
3458    fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
3459    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
3460    fis->d.sectorCountExp = 0;
3461    fis->d.reserved4      = 0;
3462    fis->d.control        = 0;                      /* FIS HOB bit clear */
3463    fis->d.reserved5      = 0;
3464
3465    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3466    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3467  }
3468
3469  satIOContext->currentLBA = lba;
3470  satIOContext->OrgTL = tl;
3471
3472  /*
3473    computing number of loop and remainder for tl
3474    0xFF in case not ext
3475    0xFFFF in case EXT
3476  */
3477  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3478  {
3479    LoopNum = satComputeLoopNum(tl, 0xFF);
3480  }
3481  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3482           fis->h.command == SAT_WRITE_DMA_EXT     ||
3483           fis->h.command == SAT_WRITE_DMA_FUA_EXT
3484           )
3485  {
3486    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3487    LoopNum = satComputeLoopNum(tl, 0xFFFF);
3488  }
3489  else
3490  {
3491    /* SAT_WRITE_FPDMA_QUEUEDK */
3492    LoopNum = satComputeLoopNum(tl, 0xFFFF);
3493  }
3494
3495  satIOContext->LoopNum = LoopNum;
3496
3497
3498  if (LoopNum == 1)
3499  {
3500    TI_DBG5(("satWrite16: NON CHAINED data\n"));
3501    /* Initialize CB for SATA completion.
3502     */
3503    satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3504  }
3505  else
3506  {
3507    TI_DBG1(("satWrite16: CHAINED data\n"));
3508    /* re-setting tl */
3509    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3510    {
3511       fis->d.sectorCount    = 0xFF;
3512    }
3513    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3514             fis->h.command == SAT_WRITE_DMA_EXT ||
3515             fis->h.command == SAT_WRITE_DMA_FUA_EXT
3516             )
3517    {
3518      fis->d.sectorCount    = 0xFF;
3519      fis->d.sectorCountExp = 0xFF;
3520    }
3521    else
3522    {
3523      /* SAT_WRITE_FPDMA_QUEUED */
3524      fis->h.features       = 0xFF;
3525      fis->d.featuresExp    = 0xFF;
3526    }
3527
3528    /* Initialize CB for SATA completion.
3529     */
3530    satIOContext->satCompleteCB = &satChainedDataIOCB;
3531  }
3532
3533
3534  /*
3535   * Prepare SGL and send FIS to LL layer.
3536   */
3537  satIOContext->reqType = agRequestType;       /* Save it */
3538
3539  status = sataLLIOStart( tiRoot,
3540                          tiIORequest,
3541                          tiDeviceHandle,
3542                          tiScsiRequest,
3543                          satIOContext);
3544  return (status);
3545}
3546
3547/*****************************************************************************/
3548/*! \brief SAT implementation for SCSI WRITE12.
3549 *
3550 *  SAT implementation for SCSI WRITE12 and send FIS request to LL layer.
3551 *
3552 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
3553 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
3554 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
3555 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
3556 *  \param   satIOContext_t:   Pointer to the SAT IO Context
3557 *
3558 *  \return If command is started successfully
3559 *    - \e tiSuccess:     I/O request successfully initiated.
3560 *    - \e tiBusy:        No resources available, try again later.
3561 *    - \e tiIONoDevice:  Invalid device handle.
3562 *    - \e tiError:       Other errors.
3563 */
3564/*****************************************************************************/
3565GLOBAL bit32  satWrite12(
3566                   tiRoot_t                  *tiRoot,
3567                   tiIORequest_t             *tiIORequest,
3568                   tiDeviceHandle_t          *tiDeviceHandle,
3569                   tiScsiInitiatorRequest_t *tiScsiRequest,
3570                   satIOContext_t            *satIOContext)
3571{
3572  bit32                     status;
3573  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3574  satDeviceData_t           *pSatDevData;
3575  scsiRspSense_t            *pSense;
3576  tiIniScsiCmnd_t           *scsiCmnd;
3577  agsaFisRegHostToDevice_t  *fis;
3578  bit32                     lba = 0;
3579  bit32                     tl = 0;
3580  bit32                     LoopNum = 1;
3581  bit8                      LBA[4];
3582  bit8                      TL[4];
3583  bit32                     rangeChk = agFALSE; /* lba and tl range check */
3584
3585  pSense        = satIOContext->pSense;
3586  pSatDevData   = satIOContext->pSatDevData;
3587  scsiCmnd      = &tiScsiRequest->scsiCmnd;
3588  fis           = satIOContext->pFis;
3589
3590  TI_DBG5(("satWrite12: start\n"));
3591
3592  /* checking FUA_NV */
3593  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3594  {
3595    satSetSensePayload( pSense,
3596                        SCSI_SNSKEY_ILLEGAL_REQUEST,
3597                        0,
3598                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3599                        satIOContext);
3600
3601    ostiInitiatorIOCompleted( tiRoot,
3602                              tiIORequest,
3603                              tiIOSuccess,
3604                              SCSI_STAT_CHECK_CONDITION,
3605                              satIOContext->pTiSenseData,
3606                              satIOContext->interruptContext );
3607
3608    TI_DBG1(("satWrite12: return FUA_NV\n"));
3609    return tiSuccess;
3610
3611  }
3612
3613
3614  /* checking CONTROL */
3615  /* NACA == 1 or LINK == 1*/
3616  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
3617  {
3618    satSetSensePayload( pSense,
3619                        SCSI_SNSKEY_ILLEGAL_REQUEST,
3620                        0,
3621                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3622                        satIOContext);
3623
3624    ostiInitiatorIOCompleted( tiRoot,
3625                              tiIORequest,
3626                              tiIOSuccess,
3627                              SCSI_STAT_CHECK_CONDITION,
3628                              satIOContext->pTiSenseData,
3629                              satIOContext->interruptContext );
3630
3631    TI_DBG1(("satWrite12: return control\n"));
3632    return tiSuccess;
3633  }
3634
3635
3636  osti_memset(LBA, 0, sizeof(LBA));
3637  osti_memset(TL, 0, sizeof(TL));
3638
3639  /* do not use memcpy due to indexing in LBA and TL */
3640  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
3641  LBA[1] = scsiCmnd->cdb[3];
3642  LBA[2] = scsiCmnd->cdb[4];
3643  LBA[3] = scsiCmnd->cdb[5];  /* LSB */
3644
3645  TL[0] = scsiCmnd->cdb[6];   /* MSB */
3646  TL[1] = scsiCmnd->cdb[7];
3647  TL[2] = scsiCmnd->cdb[8];
3648  TL[3] = scsiCmnd->cdb[9];   /* LSB */
3649
3650  rangeChk = satAddNComparebit32(LBA, TL);
3651
3652  lba = satComputeCDB12LBA(satIOContext);
3653  tl = satComputeCDB12TL(satIOContext);
3654
3655
3656  /* Table 34, 9.1, p 46 */
3657  /*
3658    note: As of 2/10/2006, no support for DMA QUEUED
3659   */
3660
3661  /*
3662    Table 34, 9.1, p 46, b
3663    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3664    return check condition
3665  */
3666  if (pSatDevData->satNCQ != agTRUE &&
3667      pSatDevData->sat48BitSupport != agTRUE
3668      )
3669  {
3670    if (lba > SAT_TR_LBA_LIMIT - 1)
3671    {
3672      satSetSensePayload( pSense,
3673                          SCSI_SNSKEY_ILLEGAL_REQUEST,
3674                          0,
3675                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3676                          satIOContext);
3677
3678      ostiInitiatorIOCompleted( tiRoot,
3679                                tiIORequest,
3680                                tiIOSuccess,
3681                                SCSI_STAT_CHECK_CONDITION,
3682                                satIOContext->pTiSenseData,
3683                                satIOContext->interruptContext );
3684
3685    TI_DBG1(("satWrite12: return LBA out of range, not EXT\n"));
3686    return tiSuccess;
3687    }
3688
3689    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
3690    {
3691      TI_DBG1(("satWrite12: return LBA+TL out of range, not EXT\n"));
3692      satSetSensePayload( pSense,
3693                          SCSI_SNSKEY_ILLEGAL_REQUEST,
3694                          0,
3695                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3696                          satIOContext);
3697
3698      ostiInitiatorIOCompleted( tiRoot,
3699                                tiIORequest,
3700                                tiIOSuccess,
3701                                SCSI_STAT_CHECK_CONDITION,
3702                                satIOContext->pTiSenseData,
3703                                satIOContext->interruptContext );
3704
3705    return tiSuccess;
3706    }
3707  }
3708
3709
3710  /* case 1 and 2 */
3711  if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
3712  {
3713    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3714    {
3715      /* case 2 */
3716      /* WRITE DMA*/
3717      /* In case that we can't fit the transfer length, we loop */
3718      TI_DBG5(("satWrite12: case 2\n"));
3719      fis->h.fisType        = 0x27;                   /* Reg host to device */
3720      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3721      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
3722      fis->h.features       = 0;                      /* FIS reserve */
3723      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3724      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3725      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3726
3727      /* FIS LBA mode set LBA (27:24) */
3728      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3729
3730      fis->d.lbaLowExp      = 0;
3731      fis->d.lbaMidExp      = 0;
3732      fis->d.lbaHighExp     = 0;
3733      fis->d.featuresExp    = 0;
3734      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3735      fis->d.sectorCountExp = 0;
3736      fis->d.reserved4      = 0;
3737      fis->d.control        = 0;                      /* FIS HOB bit clear */
3738      fis->d.reserved5      = 0;
3739
3740      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3741      satIOContext->ATACmd = SAT_WRITE_DMA;
3742    }
3743    else
3744    {
3745      /* case 1 */
3746      /* WRITE MULTIPLE or WRITE SECTOR(S) */
3747      /* WRITE SECTORS for easier implemetation */
3748      /* In case that we can't fit the transfer length, we loop */
3749      TI_DBG5(("satWrite12: case 1\n"));
3750      fis->h.fisType        = 0x27;                   /* Reg host to device */
3751      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
3752      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
3753      fis->h.features       = 0;                      /* FIS reserve */
3754      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3755      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3756      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3757
3758      /* FIS LBA mode set LBA (27:24) */
3759      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3760
3761      fis->d.lbaLowExp      = 0;
3762      fis->d.lbaMidExp      = 0;
3763      fis->d.lbaHighExp     = 0;
3764      fis->d.featuresExp    = 0;
3765      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3766      fis->d.sectorCountExp = 0;
3767      fis->d.reserved4      = 0;
3768      fis->d.control        = 0;                      /* FIS HOB bit clear */
3769      fis->d.reserved5      = 0;
3770
3771      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3772      satIOContext->ATACmd = SAT_WRITE_SECTORS;
3773    }
3774  }
3775
3776  /* case 3 and 4 */
3777  if (pSatDevData->sat48BitSupport == agTRUE)
3778  {
3779    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3780    {
3781      /* case 3 */
3782      /* WRITE DMA EXT or WRITE DMA FUA EXT */
3783      TI_DBG5(("satWrite12: case 3\n"));
3784      fis->h.fisType        = 0x27;                   /* Reg host to device */
3785      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3786
3787      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3788      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
3789
3790      fis->h.features       = 0;                      /* FIS reserve */
3791      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3792      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3793      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3794      fis->d.device         = 0x40;                   /* FIS LBA mode set */
3795      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
3796      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3797      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3798      fis->d.featuresExp    = 0;                      /* FIS reserve */
3799      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3800      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
3801      fis->d.reserved4      = 0;
3802      fis->d.control        = 0;                      /* FIS HOB bit clear */
3803      fis->d.reserved5      = 0;
3804
3805      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3806      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3807    }
3808    else
3809    {
3810      /* case 4 */
3811      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3812      /* WRITE SECTORS EXT for easier implemetation */
3813      TI_DBG5(("satWrite12: case 4\n"));
3814      fis->h.fisType        = 0x27;                   /* Reg host to device */
3815      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3816      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
3817
3818      fis->h.features       = 0;                      /* FIS reserve */
3819      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3820      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3821      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3822      fis->d.device         = 0x40;                   /* FIS LBA mode set */
3823      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
3824      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3825      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3826      fis->d.featuresExp    = 0;                      /* FIS reserve */
3827      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3828      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
3829      fis->d.reserved4      = 0;
3830      fis->d.control        = 0;                      /* FIS HOB bit clear */
3831      fis->d.reserved5      = 0;
3832
3833      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3834      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3835    }
3836  }
3837
3838  /* case 5 */
3839  if (pSatDevData->satNCQ == agTRUE)
3840  {
3841    /* WRITE FPDMA QUEUED */
3842    if (pSatDevData->sat48BitSupport != agTRUE)
3843    {
3844      TI_DBG5(("satWrite12: case 5 !!! error NCQ but 28 bit address support \n"));
3845       satSetSensePayload( pSense,
3846                          SCSI_SNSKEY_ILLEGAL_REQUEST,
3847                          0,
3848                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3849                          satIOContext);
3850
3851      ostiInitiatorIOCompleted( tiRoot,
3852                                tiIORequest,
3853                                tiIOSuccess,
3854                                SCSI_STAT_CHECK_CONDITION,
3855                                satIOContext->pTiSenseData,
3856                                satIOContext->interruptContext );
3857      return tiSuccess;
3858    }
3859    TI_DBG6(("satWrite12: case 5\n"));
3860
3861    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3862
3863    fis->h.fisType        = 0x27;                   /* Reg host to device */
3864    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
3865    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3866    fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
3867    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
3868    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
3869    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
3870
3871    /* Check FUA bit */
3872    if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
3873      fis->d.device       = 0xC0;                   /* FIS FUA set */
3874    else
3875      fis->d.device       = 0x40;                   /* FIS FUA clear */
3876
3877    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
3878    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
3879    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
3880    fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
3881    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
3882    fis->d.sectorCountExp = 0;
3883    fis->d.reserved4      = 0;
3884    fis->d.control        = 0;                      /* FIS HOB bit clear */
3885    fis->d.reserved5      = 0;
3886
3887    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3888    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3889  }
3890
3891  satIOContext->currentLBA = lba;
3892  satIOContext->OrgTL = tl;
3893
3894  /*
3895    computing number of loop and remainder for tl
3896    0xFF in case not ext
3897    0xFFFF in case EXT
3898  */
3899  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3900  {
3901    LoopNum = satComputeLoopNum(tl, 0xFF);
3902  }
3903  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3904           fis->h.command == SAT_WRITE_DMA_EXT     ||
3905           fis->h.command == SAT_WRITE_DMA_FUA_EXT
3906           )
3907  {
3908    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3909    LoopNum = satComputeLoopNum(tl, 0xFFFF);
3910  }
3911  else
3912  {
3913    /* SAT_WRITE_FPDMA_QUEUEDK */
3914    LoopNum = satComputeLoopNum(tl, 0xFFFF);
3915  }
3916
3917  satIOContext->LoopNum = LoopNum;
3918
3919
3920  if (LoopNum == 1)
3921  {
3922    TI_DBG5(("satWrite12: NON CHAINED data\n"));
3923    /* Initialize CB for SATA completion.
3924     */
3925    satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3926  }
3927  else
3928  {
3929    TI_DBG1(("satWrite12: CHAINED data\n"));
3930    /* re-setting tl */
3931    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3932    {
3933       fis->d.sectorCount    = 0xFF;
3934    }
3935    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3936             fis->h.command == SAT_WRITE_DMA_EXT ||
3937             fis->h.command == SAT_WRITE_DMA_FUA_EXT
3938             )
3939    {
3940      fis->d.sectorCount    = 0xFF;
3941      fis->d.sectorCountExp = 0xFF;
3942    }
3943    else
3944    {
3945      /* SAT_WRITE_FPDMA_QUEUED */
3946      fis->h.features       = 0xFF;
3947      fis->d.featuresExp    = 0xFF;
3948    }
3949
3950    /* Initialize CB for SATA completion.
3951     */
3952    satIOContext->satCompleteCB = &satChainedDataIOCB;
3953  }
3954
3955
3956  /*
3957   * Prepare SGL and send FIS to LL layer.
3958   */
3959  satIOContext->reqType = agRequestType;       /* Save it */
3960
3961  status = sataLLIOStart( tiRoot,
3962                          tiIORequest,
3963                          tiDeviceHandle,
3964                          tiScsiRequest,
3965                          satIOContext);
3966  return (status);
3967}
3968
3969/*****************************************************************************/
3970/*! \brief SAT implementation for SCSI WRITE10.
3971 *
3972 *  SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
3973 *
3974 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
3975 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
3976 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
3977 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
3978 *  \param   satIOContext_t:   Pointer to the SAT IO Context
3979 *
3980 *  \return If command is started successfully
3981 *    - \e tiSuccess:     I/O request successfully initiated.
3982 *    - \e tiBusy:        No resources available, try again later.
3983 *    - \e tiIONoDevice:  Invalid device handle.
3984 *    - \e tiError:       Other errors.
3985 */
3986/*****************************************************************************/
3987GLOBAL bit32  satWrite10(
3988                   tiRoot_t                  *tiRoot,
3989                   tiIORequest_t             *tiIORequest,
3990                   tiDeviceHandle_t          *tiDeviceHandle,
3991                   tiScsiInitiatorRequest_t *tiScsiRequest,
3992                   satIOContext_t            *satIOContext)
3993{
3994
3995  bit32                     status;
3996  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3997  satDeviceData_t           *pSatDevData;
3998  scsiRspSense_t            *pSense;
3999  tiIniScsiCmnd_t           *scsiCmnd;
4000  agsaFisRegHostToDevice_t  *fis;
4001  bit32                     lba = 0;
4002  bit32                     tl = 0;
4003  bit32                     LoopNum = 1;
4004  bit8                      LBA[4];
4005  bit8                      TL[4];
4006  bit32                     rangeChk = agFALSE; /* lba and tl range check */
4007
4008  pSense        = satIOContext->pSense;
4009  pSatDevData   = satIOContext->pSatDevData;
4010  scsiCmnd      = &tiScsiRequest->scsiCmnd;
4011  fis           = satIOContext->pFis;
4012
4013  TI_DBG5(("satWrite10: start\n"));
4014
4015  /* checking FUA_NV */
4016  if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
4017  {
4018    satSetSensePayload( pSense,
4019                        SCSI_SNSKEY_ILLEGAL_REQUEST,
4020                        0,
4021                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4022                        satIOContext);
4023
4024    ostiInitiatorIOCompleted( tiRoot,
4025                              tiIORequest,
4026                              tiIOSuccess,
4027                              SCSI_STAT_CHECK_CONDITION,
4028                              satIOContext->pTiSenseData,
4029                              satIOContext->interruptContext );
4030
4031    TI_DBG1(("satWrite10: return FUA_NV\n"));
4032    return tiSuccess;
4033
4034  }
4035
4036  /* checking CONTROL */
4037  /* NACA == 1 or LINK == 1*/
4038  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
4039  {
4040    satSetSensePayload( pSense,
4041                        SCSI_SNSKEY_ILLEGAL_REQUEST,
4042                        0,
4043                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4044                        satIOContext);
4045
4046    ostiInitiatorIOCompleted( tiRoot,
4047                              tiIORequest,
4048                              tiIOSuccess,
4049                              SCSI_STAT_CHECK_CONDITION,
4050                              satIOContext->pTiSenseData,
4051                              satIOContext->interruptContext );
4052
4053    TI_DBG1(("satWrite10: return control\n"));
4054    return tiSuccess;
4055  }
4056
4057  osti_memset(LBA, 0, sizeof(LBA));
4058  osti_memset(TL, 0, sizeof(TL));
4059
4060  /* do not use memcpy due to indexing in LBA and TL */
4061  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
4062  LBA[1] = scsiCmnd->cdb[3];
4063  LBA[2] = scsiCmnd->cdb[4];
4064  LBA[3] = scsiCmnd->cdb[5];  /* LSB */
4065
4066  TL[0] = 0;
4067  TL[1] = 0;
4068  TL[2] = scsiCmnd->cdb[7];  /* MSB */
4069  TL[3] = scsiCmnd->cdb[8];  /* LSB */
4070
4071  rangeChk = satAddNComparebit32(LBA, TL);
4072
4073
4074  /* cbd10; computing LBA and transfer length */
4075  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
4076    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
4077  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
4078
4079  TI_DBG5(("satWrite10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
4080  TI_DBG5(("satWrite10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
4081
4082  /* Table 34, 9.1, p 46 */
4083  /*
4084    note: As of 2/10/2006, no support for DMA QUEUED
4085   */
4086
4087  /*
4088    Table 34, 9.1, p 46, b
4089    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4090    return check condition
4091  */
4092  if (pSatDevData->satNCQ != agTRUE &&
4093      pSatDevData->sat48BitSupport != agTRUE
4094      )
4095  {
4096    if (lba > SAT_TR_LBA_LIMIT - 1)
4097    {
4098      satSetSensePayload( pSense,
4099                          SCSI_SNSKEY_ILLEGAL_REQUEST,
4100                          0,
4101                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4102                          satIOContext);
4103
4104      ostiInitiatorIOCompleted( tiRoot,
4105                                tiIORequest,
4106                                tiIOSuccess,
4107                                SCSI_STAT_CHECK_CONDITION,
4108                                satIOContext->pTiSenseData,
4109                                satIOContext->interruptContext );
4110
4111      TI_DBG1(("satWrite10: return LBA out of range, not EXT\n"));
4112      TI_DBG1(("satWrite10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
4113             scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
4114      TI_DBG1(("satWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
4115      return tiSuccess;
4116    }
4117
4118    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
4119    {
4120      TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
4121      satSetSensePayload( pSense,
4122                          SCSI_SNSKEY_ILLEGAL_REQUEST,
4123                          0,
4124                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4125                          satIOContext);
4126
4127      ostiInitiatorIOCompleted( tiRoot,
4128                                tiIORequest,
4129                                tiIOSuccess,
4130                                SCSI_STAT_CHECK_CONDITION,
4131                                satIOContext->pTiSenseData,
4132                                satIOContext->interruptContext );
4133
4134      return tiSuccess;
4135    }
4136
4137  }
4138
4139
4140  /* case 1 and 2 */
4141  if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
4142  {
4143    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4144    {
4145      /* case 2 */
4146      /* WRITE DMA*/
4147      /* can't fit the transfer length */
4148      TI_DBG5(("satWrite10: case 2\n"));
4149      fis->h.fisType        = 0x27;                   /* Reg host to device */
4150      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4151      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
4152      fis->h.features       = 0;                      /* FIS reserve */
4153      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4154      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4155      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4156
4157      /* FIS LBA mode set LBA (27:24) */
4158      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4159
4160      fis->d.lbaLowExp      = 0;
4161      fis->d.lbaMidExp      = 0;
4162      fis->d.lbaHighExp     = 0;
4163      fis->d.featuresExp    = 0;
4164      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4165      fis->d.sectorCountExp = 0;
4166      fis->d.reserved4      = 0;
4167      fis->d.control        = 0;                      /* FIS HOB bit clear */
4168      fis->d.reserved5      = 0;
4169
4170      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4171      satIOContext->ATACmd = SAT_WRITE_DMA;
4172    }
4173    else
4174    {
4175      /* case 1 */
4176      /* WRITE MULTIPLE or WRITE SECTOR(S) */
4177      /* WRITE SECTORS for easier implemetation */
4178      /* can't fit the transfer length */
4179      TI_DBG5(("satWrite10: case 1\n"));
4180      fis->h.fisType        = 0x27;                   /* Reg host to device */
4181      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4182      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
4183      fis->h.features       = 0;                      /* FIS reserve */
4184      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4185      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4186      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4187
4188      /* FIS LBA mode set LBA (27:24) */
4189      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4190
4191      fis->d.lbaLowExp      = 0;
4192      fis->d.lbaMidExp      = 0;
4193      fis->d.lbaHighExp     = 0;
4194      fis->d.featuresExp    = 0;
4195      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4196      fis->d.sectorCountExp = 0;
4197      fis->d.reserved4      = 0;
4198      fis->d.control        = 0;                      /* FIS HOB bit clear */
4199      fis->d.reserved5      = 0;
4200
4201      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4202      satIOContext->ATACmd = SAT_WRITE_SECTORS;
4203    }
4204  }
4205  /* case 3 and 4 */
4206  if (pSatDevData->sat48BitSupport == agTRUE)
4207  {
4208    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4209    {
4210      /* case 3 */
4211      /* WRITE DMA EXT or WRITE DMA FUA EXT */
4212      TI_DBG5(("satWrite10: case 3\n"));
4213      fis->h.fisType        = 0x27;                   /* Reg host to device */
4214      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4215
4216      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
4217      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
4218      satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
4219
4220      fis->h.features       = 0;                      /* FIS reserve */
4221      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4222      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4223      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4224      fis->d.device         = 0x40;                   /* FIS LBA mode set */
4225      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4226      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4227      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4228      fis->d.featuresExp    = 0;                      /* FIS reserve */
4229      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4230      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4231      fis->d.reserved4      = 0;
4232      fis->d.control        = 0;                      /* FIS HOB bit clear */
4233      fis->d.reserved5      = 0;
4234
4235      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4236    }
4237    else
4238    {
4239      /* case 4 */
4240      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
4241      /* WRITE SECTORS EXT for easier implemetation */
4242      TI_DBG5(("satWrite10: case 4\n"));
4243      fis->h.fisType        = 0x27;                   /* Reg host to device */
4244      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4245      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
4246
4247      fis->h.features       = 0;                      /* FIS reserve */
4248      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4249      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4250      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4251      fis->d.device         = 0x40;                   /* FIS LBA mode set */
4252      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4253      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4254      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4255      fis->d.featuresExp    = 0;                      /* FIS reserve */
4256      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4257      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4258      fis->d.reserved4      = 0;
4259      fis->d.control        = 0;                      /* FIS HOB bit clear */
4260      fis->d.reserved5      = 0;
4261
4262      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4263      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
4264    }
4265  }
4266  /* case 5 */
4267  if (pSatDevData->satNCQ == agTRUE)
4268  {
4269    /* WRITE FPDMA QUEUED */
4270    if (pSatDevData->sat48BitSupport != agTRUE)
4271    {
4272      TI_DBG5(("satWrite10: case 5 !!! error NCQ but 28 bit address support \n"));
4273      satSetSensePayload( pSense,
4274                          SCSI_SNSKEY_ILLEGAL_REQUEST,
4275                          0,
4276                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4277                          satIOContext);
4278
4279      ostiInitiatorIOCompleted( tiRoot,
4280                                tiIORequest,
4281                                tiIOSuccess,
4282                                SCSI_STAT_CHECK_CONDITION,
4283                                satIOContext->pTiSenseData,
4284                                satIOContext->interruptContext );
4285      return tiSuccess;
4286    }
4287    TI_DBG6(("satWrite10: case 5\n"));
4288
4289    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4290
4291    fis->h.fisType        = 0x27;                   /* Reg host to device */
4292    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4293    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4294    fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
4295    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
4296    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
4297    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
4298
4299    /* Check FUA bit */
4300    if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4301      fis->d.device       = 0xC0;                   /* FIS FUA set */
4302    else
4303      fis->d.device       = 0x40;                   /* FIS FUA clear */
4304
4305    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
4306    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4307    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4308    fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
4309    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4310    fis->d.sectorCountExp = 0;
4311    fis->d.reserved4      = 0;
4312    fis->d.control        = 0;                      /* FIS HOB bit clear */
4313    fis->d.reserved5      = 0;
4314
4315    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4316    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
4317  }
4318
4319  //  tdhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
4320
4321  satIOContext->currentLBA = lba;
4322  satIOContext->OrgTL = tl;
4323
4324  /*
4325    computing number of loop and remainder for tl
4326    0xFF in case not ext
4327    0xFFFF in case EXT
4328  */
4329  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4330  {
4331    LoopNum = satComputeLoopNum(tl, 0xFF);
4332  }
4333  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4334           fis->h.command == SAT_WRITE_DMA_EXT     ||
4335           fis->h.command == SAT_WRITE_DMA_FUA_EXT
4336           )
4337  {
4338    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
4339    LoopNum = satComputeLoopNum(tl, 0xFFFF);
4340  }
4341  else
4342  {
4343    /* SAT_WRITE_FPDMA_QUEUEDK */
4344    LoopNum = satComputeLoopNum(tl, 0xFFFF);
4345  }
4346
4347  satIOContext->LoopNum = LoopNum;
4348
4349
4350  if (LoopNum == 1)
4351  {
4352    TI_DBG5(("satWrite10: NON CHAINED data\n"));
4353    /* Initialize CB for SATA completion.
4354     */
4355    satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4356  }
4357  else
4358  {
4359    TI_DBG1(("satWrite10: CHAINED data\n"));
4360    /* re-setting tl */
4361    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4362    {
4363       fis->d.sectorCount    = 0xFF;
4364    }
4365    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4366             fis->h.command == SAT_WRITE_DMA_EXT ||
4367             fis->h.command == SAT_WRITE_DMA_FUA_EXT
4368             )
4369    {
4370      fis->d.sectorCount    = 0xFF;
4371      fis->d.sectorCountExp = 0xFF;
4372    }
4373    else
4374    {
4375      /* SAT_WRITE_FPDMA_QUEUED */
4376      fis->h.features       = 0xFF;
4377      fis->d.featuresExp    = 0xFF;
4378    }
4379
4380    /* Initialize CB for SATA completion.
4381     */
4382    satIOContext->satCompleteCB = &satChainedDataIOCB;
4383  }
4384
4385
4386  /*
4387   * Prepare SGL and send FIS to LL layer.
4388   */
4389  satIOContext->reqType = agRequestType;       /* Save it */
4390
4391  status = sataLLIOStart( tiRoot,
4392                          tiIORequest,
4393                          tiDeviceHandle,
4394                          tiScsiRequest,
4395                          satIOContext);
4396  return (status);
4397}
4398
4399/*****************************************************************************/
4400/*! \brief SAT implementation for SCSI satWrite_1.
4401 *
4402 *  SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
4403 *  This is used when WRITE10 is divided into multiple ATA commands
4404 *
4405 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4406 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4407 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4408 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4409 *  \param   satIOContext_t:   Pointer to the SAT IO Context
4410 *
4411 *  \return If command is started successfully
4412 *    - \e tiSuccess:     I/O request successfully initiated.
4413 *    - \e tiBusy:        No resources available, try again later.
4414 *    - \e tiIONoDevice:  Invalid device handle.
4415 *    - \e tiError:       Other errors.
4416 */
4417/*****************************************************************************/
4418GLOBAL bit32  satWrite_1(
4419                   tiRoot_t                  *tiRoot,
4420                   tiIORequest_t             *tiIORequest,
4421                   tiDeviceHandle_t          *tiDeviceHandle,
4422                   tiScsiInitiatorRequest_t *tiScsiRequest,
4423                   satIOContext_t            *satIOContext)
4424{
4425  /*
4426    Assumption: error check on lba and tl has been done in satWrite*()
4427    lba = lba + tl;
4428  */
4429  bit32                     status;
4430  satIOContext_t            *satOrgIOContext = agNULL;
4431  tiIniScsiCmnd_t           *scsiCmnd;
4432  agsaFisRegHostToDevice_t  *fis;
4433  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4434  bit32                     lba = 0;
4435  bit32                     DenomTL = 0xFF;
4436  bit32                     Remainder = 0;
4437  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
4438
4439  TI_DBG2(("satWrite_1: start\n"));
4440
4441  fis             = satIOContext->pFis;
4442  satOrgIOContext = satIOContext->satOrgIOContext;
4443  scsiCmnd        = satOrgIOContext->pScsiCmnd;
4444
4445  osti_memset(LBA,0, sizeof(LBA));
4446
4447  switch (satOrgIOContext->ATACmd)
4448  {
4449  case SAT_WRITE_DMA:
4450    DenomTL = 0xFF;
4451    break;
4452  case SAT_WRITE_SECTORS:
4453    DenomTL = 0xFF;
4454    break;
4455  case SAT_WRITE_DMA_EXT:
4456    DenomTL = 0xFFFF;
4457    break;
4458  case SAT_WRITE_DMA_FUA_EXT:
4459    DenomTL = 0xFFFF;
4460    break;
4461  case SAT_WRITE_SECTORS_EXT:
4462    DenomTL = 0xFFFF;
4463    break;
4464  case SAT_WRITE_FPDMA_QUEUED:
4465    DenomTL = 0xFFFF;
4466    break;
4467  default:
4468    TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4469    return tiError;
4470    break;
4471  }
4472
4473  Remainder = satOrgIOContext->OrgTL % DenomTL;
4474  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
4475  lba = satOrgIOContext->currentLBA;
4476
4477  LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
4478  LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
4479  LBA[2] = (bit8)((lba & 0xF0) >> 8);
4480  LBA[3] = (bit8)(lba & 0xF);               /* LSB */
4481
4482  switch (satOrgIOContext->ATACmd)
4483  {
4484  case SAT_WRITE_DMA:
4485    fis->h.fisType        = 0x27;                   /* Reg host to device */
4486    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4487    fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
4488    fis->h.features       = 0;                      /* FIS reserve */
4489    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4490    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4491    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4492
4493    /* FIS LBA mode set LBA (27:24) */
4494    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4495
4496    fis->d.lbaLowExp      = 0;
4497    fis->d.lbaMidExp      = 0;
4498    fis->d.lbaHighExp     = 0;
4499    fis->d.featuresExp    = 0;
4500    if (satOrgIOContext->LoopNum == 1)
4501    {
4502      /* last loop */
4503      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
4504    }
4505    else
4506    {
4507      fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
4508    }
4509    fis->d.sectorCountExp = 0;
4510    fis->d.reserved4      = 0;
4511    fis->d.control        = 0;                      /* FIS HOB bit clear */
4512    fis->d.reserved5      = 0;
4513
4514    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4515
4516    break;
4517  case SAT_WRITE_SECTORS:
4518    fis->h.fisType        = 0x27;                   /* Reg host to device */
4519    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
4520    fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
4521    fis->h.features       = 0;                      /* FIS reserve */
4522    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4523    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4524    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4525
4526    /* FIS LBA mode set LBA (27:24) */
4527    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4528
4529    fis->d.lbaLowExp      = 0;
4530    fis->d.lbaMidExp      = 0;
4531    fis->d.lbaHighExp     = 0;
4532    fis->d.featuresExp    = 0;
4533    if (satOrgIOContext->LoopNum == 1)
4534    {
4535      /* last loop */
4536      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
4537    }
4538    else
4539    {
4540      fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
4541    }
4542    fis->d.sectorCountExp = 0;
4543    fis->d.reserved4      = 0;
4544    fis->d.control        = 0;                      /* FIS HOB bit clear */
4545    fis->d.reserved5      = 0;
4546
4547    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4548
4549    break;
4550  case SAT_WRITE_DMA_EXT:
4551    fis->h.fisType        = 0x27;                   /* Reg host to device */
4552    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4553    fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
4554    fis->h.features       = 0;                      /* FIS reserve */
4555    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4556    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4557    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4558    fis->d.device         = 0x40;                   /* FIS LBA mode set */
4559    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
4560    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4561    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4562    fis->d.featuresExp    = 0;                      /* FIS reserve */
4563    if (satOrgIOContext->LoopNum == 1)
4564    {
4565      /* last loop */
4566      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
4567      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
4568    }
4569    else
4570    {
4571      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
4572      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
4573    }
4574    fis->d.reserved4      = 0;
4575    fis->d.control        = 0;                       /* FIS HOB bit clear */
4576    fis->d.reserved5      = 0;
4577
4578    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4579
4580    break;
4581  case SAT_WRITE_SECTORS_EXT:
4582    fis->h.fisType        = 0x27;                   /* Reg host to device */
4583    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4584    fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
4585
4586    fis->h.features       = 0;                      /* FIS reserve */
4587    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4588    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4589    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4590    fis->d.device         = 0x40;                   /* FIS LBA mode set */
4591    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
4592    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4593    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4594    fis->d.featuresExp    = 0;                      /* FIS reserve */
4595    if (satOrgIOContext->LoopNum == 1)
4596    {
4597      /* last loop */
4598      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
4599      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
4600    }
4601    else
4602    {
4603      fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
4604      fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
4605    }
4606    fis->d.reserved4      = 0;
4607    fis->d.control        = 0;                      /* FIS HOB bit clear */
4608    fis->d.reserved5      = 0;
4609
4610    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4611
4612    break;
4613  case SAT_WRITE_FPDMA_QUEUED:
4614    fis->h.fisType        = 0x27;                   /* Reg host to device */
4615    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4616    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4617    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
4618    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
4619    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
4620
4621    /* Check FUA bit */
4622    if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4623      fis->d.device       = 0xC0;                   /* FIS FUA set */
4624    else
4625      fis->d.device       = 0x40;                   /* FIS FUA clear */
4626
4627    fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
4628    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4629    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4630    if (satOrgIOContext->LoopNum == 1)
4631    {
4632      /* last loop */
4633      fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
4634      fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
4635    }
4636    else
4637    {
4638      fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
4639      fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
4640    }
4641    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4642    fis->d.sectorCountExp = 0;
4643    fis->d.reserved4      = 0;
4644    fis->d.control        = 0;                      /* FIS HOB bit clear */
4645    fis->d.reserved5      = 0;
4646
4647    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4648    break;
4649
4650  default:
4651    TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4652    return tiError;
4653    break;
4654  }
4655
4656  /* Initialize CB for SATA completion.
4657   */
4658  /* chained data */
4659  satIOContext->satCompleteCB = &satChainedDataIOCB;
4660
4661
4662  /*
4663   * Prepare SGL and send FIS to LL layer.
4664   */
4665  satIOContext->reqType = agRequestType;       /* Save it */
4666
4667  status = sataLLIOStart( tiRoot,
4668                          tiIORequest,
4669                          tiDeviceHandle,
4670                          tiScsiRequest,
4671                          satIOContext);
4672
4673  TI_DBG5(("satWrite_1: return\n"));
4674  return (status);
4675}
4676
4677/*****************************************************************************/
4678/*! \brief SAT implementation for SCSI WRITE6.
4679 *
4680 *  SAT implementation for SCSI WRITE6 and send FIS request to LL layer.
4681 *
4682 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
4683 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
4684 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
4685 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
4686 *  \param   satIOContext_t:   Pointer to the SAT IO Context
4687 *
4688 *  \return If command is started successfully
4689 *    - \e tiSuccess:     I/O request successfully initiated.
4690 *    - \e tiBusy:        No resources available, try again later.
4691 *    - \e tiIONoDevice:  Invalid device handle.
4692 *    - \e tiError:       Other errors.
4693 */
4694/*****************************************************************************/
4695GLOBAL bit32  satWrite6(
4696                   tiRoot_t                  *tiRoot,
4697                   tiIORequest_t             *tiIORequest,
4698                   tiDeviceHandle_t          *tiDeviceHandle,
4699                   tiScsiInitiatorRequest_t *tiScsiRequest,
4700                   satIOContext_t            *satIOContext)
4701{
4702
4703  bit32                     status;
4704  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4705  satDeviceData_t           *pSatDevData;
4706  scsiRspSense_t            *pSense;
4707  tiIniScsiCmnd_t           *scsiCmnd;
4708  agsaFisRegHostToDevice_t  *fis;
4709  bit32                     lba = 0;
4710  bit16                     tl = 0;
4711
4712  pSense        = satIOContext->pSense;
4713  pSatDevData   = satIOContext->pSatDevData;
4714  scsiCmnd      = &tiScsiRequest->scsiCmnd;
4715  fis           = satIOContext->pFis;
4716
4717  TI_DBG5(("satWrite6: start\n"));
4718
4719  /* checking CONTROL */
4720  /* NACA == 1 or LINK == 1*/
4721  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
4722  {
4723    satSetSensePayload( pSense,
4724                        SCSI_SNSKEY_ILLEGAL_REQUEST,
4725                        0,
4726                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4727                        satIOContext);
4728
4729    ostiInitiatorIOCompleted( tiRoot,
4730                              tiIORequest,
4731                              tiIOSuccess,
4732                              SCSI_STAT_CHECK_CONDITION,
4733                              satIOContext->pTiSenseData,
4734                              satIOContext->interruptContext );
4735
4736    TI_DBG1(("satWrite6: return control\n"));
4737    return tiSuccess;
4738  }
4739
4740
4741  /* cbd6; computing LBA and transfer length */
4742  lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
4743    + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
4744  tl = scsiCmnd->cdb[4];
4745
4746
4747  /* Table 34, 9.1, p 46 */
4748  /*
4749    note: As of 2/10/2006, no support for DMA QUEUED
4750   */
4751
4752  /*
4753    Table 34, 9.1, p 46, b
4754    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4755    return check condition
4756  */
4757  if (pSatDevData->satNCQ != agTRUE &&
4758      pSatDevData->sat48BitSupport != agTRUE
4759      )
4760  {
4761    if (lba > SAT_TR_LBA_LIMIT - 1)
4762    {
4763      satSetSensePayload( pSense,
4764                          SCSI_SNSKEY_ILLEGAL_REQUEST,
4765                          0,
4766                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4767                          satIOContext);
4768
4769      ostiInitiatorIOCompleted( tiRoot,
4770                                tiIORequest,
4771                                tiIOSuccess,
4772                                SCSI_STAT_CHECK_CONDITION,
4773                                satIOContext->pTiSenseData,
4774                                satIOContext->interruptContext );
4775
4776    TI_DBG1(("satWrite6: return LBA out of range\n"));
4777    return tiSuccess;
4778    }
4779  }
4780
4781  /* case 1 and 2 */
4782  if (lba + tl <= SAT_TR_LBA_LIMIT)
4783  {
4784    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4785    {
4786      /* case 2 */
4787      /* WRITE DMA*/
4788      TI_DBG5(("satWrite6: case 2\n"));
4789
4790
4791      fis->h.fisType        = 0x27;                   /* Reg host to device */
4792      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4793      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
4794      fis->h.features       = 0;                      /* FIS reserve */
4795      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4796      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4797      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4798      fis->d.device         = 0x40;                   /* FIS LBA mode  */
4799      fis->d.lbaLowExp      = 0;
4800      fis->d.lbaMidExp      = 0;
4801      fis->d.lbaHighExp     = 0;
4802      fis->d.featuresExp    = 0;
4803      if (tl == 0)
4804      {
4805        /* temporary fix */
4806        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4807      }
4808      else
4809      {
4810        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4811      }
4812      fis->d.sectorCountExp = 0;
4813      fis->d.reserved4      = 0;
4814      fis->d.control        = 0;                      /* FIS HOB bit clear */
4815      fis->d.reserved5      = 0;
4816
4817      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4818    }
4819    else
4820    {
4821      /* case 1 */
4822      /* WRITE SECTORS for easier implemetation */
4823      TI_DBG5(("satWrite6: case 1\n"));
4824
4825      fis->h.fisType        = 0x27;                   /* Reg host to device */
4826      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4827      fis->h.command        = SAT_WRITE_SECTORS;          /* 0xCA */
4828      fis->h.features       = 0;                      /* FIS reserve */
4829      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4830      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4831      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4832      fis->d.device         = 0x40;                   /* FIS LBA mode  */
4833      fis->d.lbaLowExp      = 0;
4834      fis->d.lbaMidExp      = 0;
4835      fis->d.lbaHighExp     = 0;
4836      fis->d.featuresExp    = 0;
4837      if (tl == 0)
4838      {
4839        /* temporary fix */
4840        fis->d.sectorCount    = 0xff;                   /* FIS sector count (7:0) */
4841      }
4842      else
4843      {
4844        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4845      }
4846      fis->d.sectorCountExp = 0;
4847      fis->d.reserved4      = 0;
4848      fis->d.control        = 0;                      /* FIS HOB bit clear */
4849      fis->d.reserved5      = 0;
4850
4851      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4852
4853    }
4854  }
4855
4856  /* case 3 and 4 */
4857  if (pSatDevData->sat48BitSupport == agTRUE)
4858  {
4859    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4860    {
4861      /* case 3 */
4862      /* WRITE DMA EXT only */
4863      TI_DBG5(("satWrite6: case 3\n"));
4864      fis->h.fisType        = 0x27;                   /* Reg host to device */
4865      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4866      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
4867      fis->h.features       = 0;                      /* FIS reserve */
4868      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4869      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4870      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4871      fis->d.device         = 0x40;                   /* FIS LBA mode set */
4872      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4873      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4874      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4875      fis->d.featuresExp    = 0;                      /* FIS reserve */
4876      if (tl == 0)
4877      {
4878        /* sector count is 256, 0x100*/
4879        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4880        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4881      }
4882      else
4883      {
4884        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4885        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4886      }
4887      fis->d.reserved4      = 0;
4888      fis->d.control        = 0;                      /* FIS HOB bit clear */
4889      fis->d.reserved5      = 0;
4890
4891      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4892    }
4893    else
4894    {
4895      /* case 4 */
4896      /* WRITE SECTORS EXT for easier implemetation */
4897      TI_DBG5(("satWrite6: case 4\n"));
4898
4899      fis->h.fisType        = 0x27;                   /* Reg host to device */
4900      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4901      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
4902      fis->h.features       = 0;                      /* FIS reserve */
4903      fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4904      fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4905      fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4906      fis->d.device         = 0x40;                   /* FIS LBA mode set */
4907      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4908      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4909      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4910      fis->d.featuresExp    = 0;                      /* FIS reserve */
4911      if (tl == 0)
4912      {
4913        /* sector count is 256, 0x100*/
4914        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
4915        fis->d.sectorCountExp = 0x01;                      /* FIS sector count (15:8) */
4916      }
4917      else
4918      {
4919        fis->d.sectorCount    = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4920        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
4921      }
4922      fis->d.reserved4      = 0;
4923      fis->d.control        = 0;                      /* FIS HOB bit clear */
4924      fis->d.reserved5      = 0;
4925
4926      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4927    }
4928  }
4929
4930   /* case 5 */
4931  if (pSatDevData->satNCQ == agTRUE)
4932  {
4933    /* WRITE FPDMA QUEUED */
4934    if (pSatDevData->sat48BitSupport != agTRUE)
4935    {
4936      /* sanity check */
4937      TI_DBG5(("satWrite6: case 5 !!! error NCQ but 28 bit address support \n"));
4938       satSetSensePayload( pSense,
4939                          SCSI_SNSKEY_ILLEGAL_REQUEST,
4940                          0,
4941                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4942                          satIOContext);
4943
4944      ostiInitiatorIOCompleted( tiRoot,
4945                                tiIORequest,
4946                                tiIOSuccess,
4947                                SCSI_STAT_CHECK_CONDITION,
4948                                satIOContext->pTiSenseData,
4949                                satIOContext->interruptContext );
4950      return tiSuccess;
4951    }
4952    TI_DBG5(("satWrite6: case 5\n"));
4953
4954    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4955
4956    fis->h.fisType        = 0x27;                   /* Reg host to device */
4957    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
4958    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4959    fis->d.lbaLow         = scsiCmnd->cdb[3];       /* FIS LBA (7 :0 ) */
4960    fis->d.lbaMid         = scsiCmnd->cdb[2];       /* FIS LBA (15:8 ) */
4961    fis->d.lbaHigh        = (bit8)((scsiCmnd->cdb[1]) & 0x1f);       /* FIS LBA (23:16) */
4962    fis->d.device         = 0x40;                   /* FIS FUA clear */
4963    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
4964    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
4965    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
4966    if (tl == 0)
4967    {
4968      /* sector count is 256, 0x100*/
4969      fis->h.features       = 0;                         /* FIS sector count (7:0) */
4970      fis->d.featuresExp    = 0x01;                      /* FIS sector count (15:8) */
4971    }
4972    else
4973    {
4974      fis->h.features       = scsiCmnd->cdb[4];       /* FIS sector count (7:0) */
4975      fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
4976    }
4977    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
4978    fis->d.sectorCountExp = 0;
4979    fis->d.reserved4      = 0;
4980    fis->d.control        = 0;                      /* FIS HOB bit clear */
4981    fis->d.reserved5      = 0;
4982
4983    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4984  }
4985
4986  /* Initialize CB for SATA completion.
4987   */
4988  satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4989
4990  /*
4991   * Prepare SGL and send FIS to LL layer.
4992   */
4993  satIOContext->reqType = agRequestType;       /* Save it */
4994
4995  status = sataLLIOStart( tiRoot,
4996                          tiIORequest,
4997                          tiDeviceHandle,
4998                          tiScsiRequest,
4999                          satIOContext);
5000  return (status);
5001}
5002
5003
5004/*****************************************************************************/
5005/*! \brief SAT implementation for SCSI TEST UNIT READY.
5006 *
5007 *  SAT implementation for SCSI TUR and send FIS request to LL layer.
5008 *
5009 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5010 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5011 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5012 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5013 *  \param   satIOContext_t:   Pointer to the SAT IO Context
5014 *
5015 *  \return If command is started successfully
5016 *    - \e tiSuccess:     I/O request successfully initiated.
5017 *    - \e tiBusy:        No resources available, try again later.
5018 *    - \e tiIONoDevice:  Invalid device handle.
5019 *    - \e tiError:       Other errors.
5020 */
5021/*****************************************************************************/
5022GLOBAL bit32  satTestUnitReady(
5023                   tiRoot_t                  *tiRoot,
5024                   tiIORequest_t             *tiIORequest,
5025                   tiDeviceHandle_t          *tiDeviceHandle,
5026                   tiScsiInitiatorRequest_t *tiScsiRequest,
5027                   satIOContext_t            *satIOContext)
5028{
5029
5030  bit32                     status;
5031  bit32                     agRequestType;
5032  satDeviceData_t           *pSatDevData;
5033  scsiRspSense_t            *pSense;
5034  tiIniScsiCmnd_t           *scsiCmnd;
5035  agsaFisRegHostToDevice_t  *fis;
5036
5037  pSense        = satIOContext->pSense;
5038  pSatDevData   = satIOContext->pSatDevData;
5039  scsiCmnd      = &tiScsiRequest->scsiCmnd;
5040  fis           = satIOContext->pFis;
5041
5042  TI_DBG6(("satTestUnitReady: entry tiDeviceHandle=%p tiIORequest=%p\n",
5043      tiDeviceHandle, tiIORequest));
5044
5045  /* checking CONTROL */
5046  /* NACA == 1 or LINK == 1*/
5047  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5048  {
5049    satSetSensePayload( pSense,
5050                        SCSI_SNSKEY_ILLEGAL_REQUEST,
5051                        0,
5052                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5053                        satIOContext);
5054
5055    ostiInitiatorIOCompleted( tiRoot,
5056                              tiIORequest,
5057                              tiIOSuccess,
5058                              SCSI_STAT_CHECK_CONDITION,
5059                              satIOContext->pTiSenseData,
5060                              satIOContext->interruptContext );
5061
5062    TI_DBG1(("satTestUnitReady: return control\n"));
5063    return tiSuccess;
5064  }
5065
5066  /* SAT revision 8, 8.11.2, p42*/
5067  if (pSatDevData->satStopState == agTRUE)
5068  {
5069    satSetSensePayload( pSense,
5070                        SCSI_SNSKEY_NOT_READY,
5071                        0,
5072                        SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
5073                        satIOContext);
5074
5075    ostiInitiatorIOCompleted( tiRoot,
5076                              tiIORequest,
5077                              tiIOSuccess,
5078                              SCSI_STAT_CHECK_CONDITION,
5079                              satIOContext->pTiSenseData,
5080                              satIOContext->interruptContext );
5081    TI_DBG1(("satTestUnitReady: stop state\n"));
5082    return tiSuccess;
5083  }
5084
5085  /*
5086   * Check if format is in progress
5087   */
5088
5089  if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
5090  {
5091    TI_DBG1(("satTestUnitReady() FORMAT_IN_PROGRESS  tiDeviceHandle=%p tiIORequest=%p\n",
5092         tiDeviceHandle, tiIORequest));
5093
5094    satSetSensePayload( pSense,
5095                        SCSI_SNSKEY_NOT_READY,
5096                        0,
5097                        SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
5098                        satIOContext);
5099
5100    ostiInitiatorIOCompleted( tiRoot,
5101                              tiIORequest,
5102                              tiIOSuccess,
5103                              SCSI_STAT_CHECK_CONDITION,
5104                              satIOContext->pTiSenseData,
5105                              satIOContext->interruptContext );
5106    TI_DBG1(("satTestUnitReady: format in progress\n"));
5107    return tiSuccess;
5108  }
5109
5110  /*
5111    check previously issued ATA command
5112  */
5113  if (pSatDevData->satPendingIO != 0)
5114  {
5115    if (pSatDevData->satDeviceFaultState == agTRUE)
5116    {
5117      satSetSensePayload( pSense,
5118                          SCSI_SNSKEY_HARDWARE_ERROR,
5119                          0,
5120                          SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
5121                          satIOContext);
5122
5123      ostiInitiatorIOCompleted( tiRoot,
5124                                tiIORequest,
5125                                tiIOSuccess,
5126                                SCSI_STAT_CHECK_CONDITION,
5127                                satIOContext->pTiSenseData,
5128                                satIOContext->interruptContext );
5129      TI_DBG1(("satTestUnitReady: previous command ended in error\n"));
5130      return tiSuccess;
5131    }
5132  }
5133  /*
5134    check removalbe media feature set
5135   */
5136  if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
5137  {
5138    TI_DBG5(("satTestUnitReady: sending get media status cmnd\n"));
5139    /* send GET MEDIA STATUS command */
5140    fis->h.fisType        = 0x27;                   /* Reg host to device */
5141    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5142    fis->h.command        = SAT_GET_MEDIA_STATUS;   /* 0xDA */
5143    fis->h.features       = 0;                      /* FIS features NA       */
5144    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
5145    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
5146    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
5147    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
5148    fis->d.lbaLowExp      = 0;
5149    fis->d.lbaMidExp      = 0;
5150    fis->d.lbaHighExp     = 0;
5151    fis->d.featuresExp    = 0;
5152    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
5153    fis->d.sectorCountExp = 0;
5154    fis->d.reserved4      = 0;
5155    fis->d.control        = 0;                      /* FIS HOB bit clear */
5156    fis->d.reserved5      = 0;
5157    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5158
5159    /* Initialize CB for SATA completion.
5160     */
5161    satIOContext->satCompleteCB = &satTestUnitReadyCB;
5162
5163    /*
5164     * Prepare SGL and send FIS to LL layer.
5165     */
5166    satIOContext->reqType = agRequestType;       /* Save it */
5167
5168    status = sataLLIOStart( tiRoot,
5169                            tiIORequest,
5170                            tiDeviceHandle,
5171                            tiScsiRequest,
5172                            satIOContext);
5173
5174    return (status);
5175  }
5176  /*
5177    number 6) in SAT p42
5178    send ATA CHECK POWER MODE
5179  */
5180   TI_DBG5(("satTestUnitReady: sending check power mode cmnd\n"));
5181   status = satTestUnitReady_1( tiRoot,
5182                               tiIORequest,
5183                               tiDeviceHandle,
5184                               tiScsiRequest,
5185                               satIOContext);
5186   return (status);
5187}
5188
5189
5190/*****************************************************************************/
5191/*! \brief SAT implementation for SCSI satTestUnitReady_1.
5192 *
5193 *  SAT implementation for SCSI satTestUnitReady_1.
5194 *
5195 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5196 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5197 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5198 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5199 *  \param   satIOContext_t:   Pointer to the SAT IO Context
5200 *
5201 *  \return If command is started successfully
5202 *    - \e tiSuccess:     I/O request successfully initiated.
5203 *    - \e tiBusy:        No resources available, try again later.
5204 *    - \e tiIONoDevice:  Invalid device handle.
5205 *    - \e tiError:       Other errors.
5206 */
5207/*****************************************************************************/
5208GLOBAL bit32  satTestUnitReady_1(
5209                         tiRoot_t                  *tiRoot,
5210                         tiIORequest_t             *tiIORequest,
5211                         tiDeviceHandle_t          *tiDeviceHandle,
5212                         tiScsiInitiatorRequest_t *tiScsiRequest,
5213                         satIOContext_t            *satIOContext)
5214{
5215  /*
5216    sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY
5217    internally generated - no directly corresponding scsi
5218    called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42
5219  */
5220  bit32                     status;
5221  bit32                     agRequestType;
5222  agsaFisRegHostToDevice_t  *fis;
5223
5224  fis           = satIOContext->pFis;
5225
5226  TI_DBG5(("satTestUnitReady_1: start\n"));
5227
5228  /*
5229   * Send the ATA CHECK POWER MODE command.
5230   */
5231  fis->h.fisType        = 0x27;                   /* Reg host to device */
5232  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5233  fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
5234  fis->h.features       = 0;
5235  fis->d.lbaLow         = 0;
5236  fis->d.lbaMid         = 0;
5237  fis->d.lbaHigh        = 0;
5238  fis->d.device         = 0;
5239  fis->d.lbaLowExp      = 0;
5240  fis->d.lbaMidExp      = 0;
5241  fis->d.lbaHighExp     = 0;
5242  fis->d.featuresExp    = 0;
5243  fis->d.sectorCount    = 0;
5244  fis->d.sectorCountExp = 0;
5245  fis->d.reserved4      = 0;
5246  fis->d.control        = 0;                      /* FIS HOB bit clear */
5247  fis->d.reserved5      = 0;
5248
5249  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5250
5251  /* Initialize CB for SATA completion.
5252   */
5253  satIOContext->satCompleteCB = &satTestUnitReadyCB;
5254
5255  /*
5256   * Prepare SGL and send FIS to LL layer.
5257   */
5258  satIOContext->reqType = agRequestType;       /* Save it */
5259
5260  status = sataLLIOStart( tiRoot,
5261                          tiIORequest,
5262                          tiDeviceHandle,
5263                          tiScsiRequest,
5264                          satIOContext);
5265
5266  TI_DBG5(("satTestUnitReady_1: return\n"));
5267
5268  return status;
5269}
5270
5271
5272/*****************************************************************************/
5273/*! \brief SAT implementation for SCSI satReportLun.
5274 *
5275 *  SAT implementation for SCSI satReportLun. Only LUN0 is reported.
5276 *
5277 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5278 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5279 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5280 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5281 *  \param   satIOContext_t:   Pointer to the SAT IO Context
5282 *
5283 *  \return If command is started successfully
5284 *    - \e tiSuccess:     I/O request successfully initiated.
5285 *    - \e tiBusy:        No resources available, try again later.
5286 *    - \e tiIONoDevice:  Invalid device handle.
5287 *    - \e tiError:       Other errors.
5288 */
5289/*****************************************************************************/
5290GLOBAL bit32  satReportLun(
5291                   tiRoot_t                  *tiRoot,
5292                   tiIORequest_t             *tiIORequest,
5293                   tiDeviceHandle_t          *tiDeviceHandle,
5294                   tiScsiInitiatorRequest_t *tiScsiRequest,
5295                   satIOContext_t            *satIOContext)
5296{
5297  scsiRspSense_t        *pSense;
5298  bit32                 allocationLen;
5299  bit32                 reportLunLen;
5300  scsiReportLun_t       *pReportLun;
5301  tiIniScsiCmnd_t       *scsiCmnd;
5302
5303  TI_DBG5(("satReportLun entry: tiDeviceHandle=%p tiIORequest=%p\n",
5304      tiDeviceHandle, tiIORequest));
5305
5306  pSense     = satIOContext->pSense;
5307  pReportLun = (scsiReportLun_t *) tiScsiRequest->sglVirtualAddr;
5308  scsiCmnd   = &tiScsiRequest->scsiCmnd;
5309
5310//  tdhexdump("satReportLun cdb", (bit8 *)scsiCmnd, 16);
5311
5312  /* Find the buffer size allocated by Initiator */
5313  allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
5314                  (((bit32)scsiCmnd->cdb[7]) << 16) |
5315                  (((bit32)scsiCmnd->cdb[8]) << 8 ) |
5316                  (((bit32)scsiCmnd->cdb[9])      );
5317
5318  reportLunLen  = 16;     /* 8 byte header and 8 bytes of LUN0 */
5319
5320  if (allocationLen < reportLunLen)
5321  {
5322    TI_DBG1(("satReportLun *** ERROR *** insufficient len=0x%x tiDeviceHandle=%p tiIORequest=%p\n",
5323        reportLunLen, tiDeviceHandle, tiIORequest));
5324
5325    satSetSensePayload( pSense,
5326                        SCSI_SNSKEY_ILLEGAL_REQUEST,
5327                        0,
5328                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5329                        satIOContext);
5330
5331    ostiInitiatorIOCompleted( tiRoot,
5332                              tiIORequest,
5333                              tiIOSuccess,
5334                              SCSI_STAT_CHECK_CONDITION,
5335                              satIOContext->pTiSenseData,
5336                              satIOContext->interruptContext );
5337    return tiSuccess;
5338
5339  }
5340
5341  /* Set length to one entry */
5342  pReportLun->len[0] = 0;
5343  pReportLun->len[1] = 0;
5344  pReportLun->len[2] = 0;
5345  pReportLun->len[3] = sizeof (tiLUN_t);
5346
5347  pReportLun->reserved = 0;
5348
5349  /* Set to LUN 0:
5350   * - address method to 0x00: Peripheral device addressing method,
5351   * - bus identifier to 0
5352   */
5353  pReportLun->lunList[0].lun[0] = 0;
5354  pReportLun->lunList[0].lun[1] = 0;
5355  pReportLun->lunList[0].lun[2] = 0;
5356  pReportLun->lunList[0].lun[3] = 0;
5357  pReportLun->lunList[0].lun[4] = 0;
5358  pReportLun->lunList[0].lun[5] = 0;
5359  pReportLun->lunList[0].lun[6] = 0;
5360  pReportLun->lunList[0].lun[7] = 0;
5361
5362  if (allocationLen > reportLunLen)
5363  {
5364    /* underrun */
5365    TI_DBG1(("satReportLun reporting underrun reportLunLen=0x%x allocationLen=0x%x \n", reportLunLen, allocationLen));
5366
5367    ostiInitiatorIOCompleted( tiRoot,
5368                              tiIORequest,
5369                              tiIOUnderRun,
5370                              allocationLen - reportLunLen,
5371                              agNULL,
5372                              satIOContext->interruptContext );
5373
5374
5375  }
5376  else
5377  {
5378    ostiInitiatorIOCompleted( tiRoot,
5379                              tiIORequest,
5380                              tiIOSuccess,
5381                              SCSI_STAT_GOOD,
5382                              agNULL,
5383                              satIOContext->interruptContext);
5384  }
5385  return tiSuccess;
5386}
5387
5388
5389/*****************************************************************************/
5390/*! \brief SAT implementation for SCSI REQUEST SENSE.
5391 *
5392 *  SAT implementation for SCSI REQUEST SENSE.
5393 *
5394 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5395 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5396 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5397 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5398 *  \param   satIOContext_t:   Pointer to the SAT IO Context
5399 *
5400 *  \return If command is started successfully
5401 *    - \e tiSuccess:     I/O request successfully initiated.
5402 *    - \e tiBusy:        No resources available, try again later.
5403 *    - \e tiIONoDevice:  Invalid device handle.
5404 *    - \e tiError:       Other errors.
5405 */
5406/*****************************************************************************/
5407GLOBAL bit32  satRequestSense(
5408                   tiRoot_t                  *tiRoot,
5409                   tiIORequest_t             *tiIORequest,
5410                   tiDeviceHandle_t          *tiDeviceHandle,
5411                   tiScsiInitiatorRequest_t *tiScsiRequest,
5412                   satIOContext_t            *satIOContext)
5413{
5414  /*
5415    SAT Rev 8 p38, Table25
5416    sending SMART RETURN STATUS
5417    Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB()
5418    Only fixed format sense data is support. In other words, we don't support DESC bit is set
5419    in Request Sense
5420   */
5421  bit32                     status;
5422  bit32                     agRequestType;
5423  scsiRspSense_t            *pSense;
5424  satDeviceData_t           *pSatDevData;
5425  tiIniScsiCmnd_t           *scsiCmnd;
5426  agsaFisRegHostToDevice_t  *fis;
5427  tdIORequestBody_t         *tdIORequestBody;
5428  satInternalIo_t           *satIntIo = agNULL;
5429  satIOContext_t            *satIOContext2;
5430
5431  TI_DBG4(("satRequestSense entry: tiDeviceHandle=%p tiIORequest=%p\n",
5432      tiDeviceHandle, tiIORequest));
5433
5434  pSense            = (scsiRspSense_t *) tiScsiRequest->sglVirtualAddr;
5435  pSatDevData       = satIOContext->pSatDevData;
5436  scsiCmnd          = &tiScsiRequest->scsiCmnd;
5437  fis               = satIOContext->pFis;
5438
5439  TI_DBG4(("satRequestSense: pSatDevData=%p\n", pSatDevData));
5440
5441  /* checking CONTROL */
5442  /* NACA == 1 or LINK == 1*/
5443  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5444  {
5445    satSetSensePayload( pSense,
5446                        SCSI_SNSKEY_ILLEGAL_REQUEST,
5447                        0,
5448                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5449                        satIOContext);
5450
5451    ostiInitiatorIOCompleted( tiRoot,
5452                              tiIORequest,
5453                              tiIOSuccess,
5454                              SCSI_STAT_CHECK_CONDITION,
5455                              satIOContext->pTiSenseData,
5456                              satIOContext->interruptContext );
5457
5458    TI_DBG1(("satRequestSense: return control\n"));
5459    return tiSuccess;
5460  }
5461
5462  /*
5463    Only fixed format sense data is support. In other words, we don't support DESC bit is set
5464    in Request Sense
5465   */
5466  if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
5467  {
5468    satSetSensePayload( pSense,
5469                        SCSI_SNSKEY_ILLEGAL_REQUEST,
5470                        0,
5471                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5472                        satIOContext);
5473
5474    ostiInitiatorIOCompleted( tiRoot,
5475                              tiIORequest,
5476                              tiIOSuccess,
5477                              SCSI_STAT_CHECK_CONDITION,
5478                              satIOContext->pTiSenseData,
5479                              satIOContext->interruptContext );
5480
5481    TI_DBG1(("satRequestSense: DESC bit is set, which we don't support\n"));
5482    return tiSuccess;
5483  }
5484
5485
5486  if (pSatDevData->satSMARTEnabled == agTRUE)
5487  {
5488    /* sends SMART RETURN STATUS */
5489    fis->h.fisType        = 0x27;                   /* Reg host to device */
5490    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5491
5492    fis->h.command        = SAT_SMART_RETURN_STATUS;    /* 0xB0 */
5493    fis->h.features       = 0xDA;                   /* FIS features */
5494    fis->d.featuresExp    = 0;                      /* FIS reserve */
5495    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
5496    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
5497    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
5498    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
5499    fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
5500    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
5501    fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
5502    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
5503    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
5504    fis->d.control        = 0;                      /* FIS HOB bit clear */
5505    fis->d.reserved4      = 0;
5506    fis->d.reserved5      = 0;
5507
5508    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5509    /* Initialize CB for SATA completion.
5510     */
5511    satIOContext->satCompleteCB = &satRequestSenseCB;
5512
5513    /*
5514     * Prepare SGL and send FIS to LL layer.
5515     */
5516    satIOContext->reqType = agRequestType;       /* Save it */
5517
5518    status = sataLLIOStart( tiRoot,
5519                            tiIORequest,
5520                            tiDeviceHandle,
5521                            tiScsiRequest,
5522                            satIOContext);
5523
5524    TI_DBG4(("satRequestSense: if return, status %d\n", status));
5525    return (status);
5526  }
5527  else
5528  {
5529    /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE
5530      then call satRequestSense2 */
5531
5532    TI_DBG4(("satRequestSense: before satIntIo %p\n", satIntIo));
5533    /* allocate iocontext */
5534    satIntIo = satAllocIntIoResource( tiRoot,
5535                                      tiIORequest, /* original request */
5536                                      pSatDevData,
5537                                      tiScsiRequest->scsiCmnd.expDataLength,
5538                                      satIntIo);
5539
5540    TI_DBG4(("satRequestSense: after satIntIo %p\n", satIntIo));
5541
5542    if (satIntIo == agNULL)
5543    {
5544      /* memory allocation failure */
5545      satFreeIntIoResource( tiRoot,
5546                            pSatDevData,
5547                            satIntIo);
5548
5549      /* failed during sending SMART RETURN STATUS */
5550      satSetSensePayload( pSense,
5551                          SCSI_SNSKEY_NO_SENSE,
5552                          0,
5553                          SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5554                          satIOContext);
5555
5556      ostiInitiatorIOCompleted( tiRoot,
5557                                tiIORequest,
5558                                tiIOSuccess,
5559                                SCSI_STAT_GOOD,
5560                                agNULL,
5561                                satIOContext->interruptContext );
5562
5563      TI_DBG4(("satRequestSense: else fail 1\n"));
5564      return tiSuccess;
5565    } /* end of memory allocation failure */
5566
5567
5568    /*
5569     * Need to initialize all the fields within satIOContext except
5570     * reqType and satCompleteCB which will be set depending on cmd.
5571     */
5572
5573    if (satIntIo == agNULL)
5574    {
5575      TI_DBG4(("satRequestSense: satIntIo is NULL\n"));
5576    }
5577    else
5578    {
5579      TI_DBG4(("satRequestSense: satIntIo is NOT NULL\n"));
5580    }
5581    /* use this --- tttttthe one the same */
5582
5583
5584    satIntIo->satOrgTiIORequest = tiIORequest;
5585    tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
5586    satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
5587
5588    satIOContext2->pSatDevData   = pSatDevData;
5589    satIOContext2->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
5590    satIOContext2->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
5591    satIOContext2->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
5592    satIOContext2->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
5593    satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
5594    satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
5595    satIOContext2->interruptContext = satIOContext->interruptContext;
5596    satIOContext2->satIntIoContext  = satIntIo;
5597    satIOContext2->ptiDeviceHandle = tiDeviceHandle;
5598    satIOContext2->satOrgIOContext = satIOContext;
5599
5600    TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
5601
5602    TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
5603
5604    TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
5605
5606    TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
5607
5608    status = satRequestSense_1( tiRoot,
5609                               &(satIntIo->satIntTiIORequest),
5610                               tiDeviceHandle,
5611                               &(satIntIo->satIntTiScsiXchg),
5612                               satIOContext2);
5613
5614    if (status != tiSuccess)
5615    {
5616      satFreeIntIoResource( tiRoot,
5617                            pSatDevData,
5618                            satIntIo);
5619
5620      /* failed during sending SMART RETURN STATUS */
5621      satSetSensePayload( pSense,
5622                          SCSI_SNSKEY_NO_SENSE,
5623                          0,
5624                          SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5625                          satIOContext);
5626
5627      ostiInitiatorIOCompleted( tiRoot,
5628                                tiIORequest,
5629                                tiIOSuccess,
5630                                SCSI_STAT_CHECK_CONDITION,
5631                                agNULL,
5632                                satIOContext->interruptContext );
5633
5634      TI_DBG1(("satRequestSense: else fail 2\n"));
5635      return tiSuccess;
5636    }
5637    TI_DBG4(("satRequestSense: else return success\n"));
5638    return tiSuccess;
5639  }
5640}
5641
5642
5643/*****************************************************************************/
5644/*! \brief SAT implementation for SCSI REQUEST SENSE.
5645 *
5646 *  SAT implementation for SCSI REQUEST SENSE.
5647 *  Sub function of satRequestSense
5648 *
5649 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5650 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5651 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5652 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5653 *  \param   satIOContext_t:   Pointer to the SAT IO Context
5654 *
5655 *  \return If command is started successfully
5656 *    - \e tiSuccess:     I/O request successfully initiated.
5657 *    - \e tiBusy:        No resources available, try again later.
5658 *    - \e tiIONoDevice:  Invalid device handle.
5659 *    - \e tiError:       Other errors.
5660 */
5661/*****************************************************************************/
5662GLOBAL bit32  satRequestSense_1(
5663                   tiRoot_t                  *tiRoot,
5664                   tiIORequest_t             *tiIORequest,
5665                   tiDeviceHandle_t          *tiDeviceHandle,
5666                   tiScsiInitiatorRequest_t *tiScsiRequest,
5667                   satIOContext_t            *satIOContext)
5668{
5669  /*
5670    sends SAT_CHECK_POWER_MODE
5671  */
5672  bit32                     status;
5673  bit32                     agRequestType;
5674  agsaFisRegHostToDevice_t  *fis;
5675
5676  TI_DBG4(("satRequestSense_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
5677      tiDeviceHandle, tiIORequest));
5678
5679  fis               = satIOContext->pFis;
5680  /*
5681   * Send the ATA CHECK POWER MODE command.
5682   */
5683  fis->h.fisType        = 0x27;                   /* Reg host to device */
5684  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
5685
5686  fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
5687  fis->h.features       = 0;
5688  fis->d.lbaLow         = 0;
5689  fis->d.lbaMid         = 0;
5690  fis->d.lbaHigh        = 0;
5691  fis->d.device         = 0;
5692  fis->d.lbaLowExp      = 0;
5693  fis->d.lbaMidExp      = 0;
5694  fis->d.lbaHighExp     = 0;
5695  fis->d.featuresExp    = 0;
5696  fis->d.sectorCount    = 0;
5697  fis->d.sectorCountExp = 0;
5698  fis->d.reserved4      = 0;
5699  fis->d.control        = 0;                      /* FIS HOB bit clear */
5700  fis->d.reserved5      = 0;
5701
5702  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5703
5704  /* Initialize CB for SATA completion.
5705   */
5706  satIOContext->satCompleteCB = &satRequestSenseCB;
5707
5708  /*
5709   * Prepare SGL and send FIS to LL layer.
5710   */
5711  satIOContext->reqType = agRequestType;       /* Save it */
5712
5713
5714  TI_DBG4(("satRequestSense_1: agSgl1.len %d\n", tiScsiRequest->agSgl1.len));
5715
5716  TI_DBG4(("satRequestSense_1: agSgl1.upper %d\n", tiScsiRequest->agSgl1.upper));
5717
5718  TI_DBG4(("satRequestSense_1: agSgl1.lower %d\n", tiScsiRequest->agSgl1.lower));
5719
5720  TI_DBG4(("satRequestSense_1: agSgl1.type %d\n", tiScsiRequest->agSgl1.type));
5721
5722  //  tdhexdump("satRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
5723
5724  status = sataLLIOStart( tiRoot,
5725                          tiIORequest,
5726                          tiDeviceHandle,
5727                          tiScsiRequest,
5728                          satIOContext);
5729
5730
5731
5732  return status;
5733}
5734
5735
5736/*****************************************************************************/
5737/*! \brief SAT implementation for SCSI INQUIRY.
5738 *
5739 *  SAT implementation for SCSI INQUIRY.
5740 *
5741 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5742 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5743 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5744 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5745 *  \param   satIOContext_t:   Pointer to the SAT IO Context
5746 *
5747 *  \return If command is started successfully
5748 *    - \e tiSuccess:     I/O request successfully initiated.
5749 *    - \e tiBusy:        No resources available, try again later.
5750 *    - \e tiIONoDevice:  Invalid device handle.
5751 *    - \e tiError:       Other errors.
5752 */
5753/*****************************************************************************/
5754GLOBAL bit32  satInquiry(
5755                   tiRoot_t                  *tiRoot,
5756                   tiIORequest_t             *tiIORequest,
5757                   tiDeviceHandle_t          *tiDeviceHandle,
5758                   tiScsiInitiatorRequest_t *tiScsiRequest,
5759                   satIOContext_t            *satIOContext)
5760{
5761  /*
5762    CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8
5763  */
5764  scsiRspSense_t            *pSense;
5765  tiIniScsiCmnd_t           *scsiCmnd;
5766  satDeviceData_t           *pSatDevData;
5767  bit32                     status;
5768
5769  TI_DBG5(("satInquiry: start\n"));
5770  TI_DBG5(("satInquiry entry: tiDeviceHandle=%p tiIORequest=%p\n",
5771      tiDeviceHandle, tiIORequest));
5772  pSense      = satIOContext->pSense;
5773  scsiCmnd    = &tiScsiRequest->scsiCmnd;
5774  pSatDevData = satIOContext->pSatDevData;
5775  TI_DBG5(("satInquiry: pSatDevData=%p\n", pSatDevData));
5776  //tdhexdump("satInquiry", (bit8 *)scsiCmnd->cdb, 6);
5777  /* checking CONTROL */
5778  /* NACA == 1 or LINK == 1*/
5779  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5780  {
5781    satSetSensePayload( pSense,
5782                        SCSI_SNSKEY_ILLEGAL_REQUEST,
5783                        0,
5784                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5785                        satIOContext);
5786    ostiInitiatorIOCompleted( tiRoot,
5787                              tiIORequest,
5788                              tiIOSuccess,
5789                              SCSI_STAT_CHECK_CONDITION,
5790                              satIOContext->pTiSenseData,
5791                              satIOContext->interruptContext );
5792    TI_DBG2(("satInquiry: return control\n"));
5793    return tiSuccess;
5794  }
5795
5796  /* checking EVPD and Allocation Length */
5797  /* SPC-4 spec 6.4 p141 */
5798  /* EVPD bit == 0 && PAGE CODE != 0 */
5799  if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
5800       (scsiCmnd->cdb[2] != 0)
5801       )
5802  {
5803    satSetSensePayload( pSense,
5804                        SCSI_SNSKEY_ILLEGAL_REQUEST,
5805                        0,
5806                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5807                        satIOContext);
5808    ostiInitiatorIOCompleted( tiRoot,
5809                              tiIORequest,
5810                              tiIOSuccess,
5811                              SCSI_STAT_CHECK_CONDITION,
5812                              satIOContext->pTiSenseData,
5813                              satIOContext->interruptContext );
5814    TI_DBG1(("satInquiry: return EVPD and PAGE CODE\n"));
5815    return tiSuccess;
5816  }
5817  TI_DBG6(("satInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4]));
5818
5819  /* convert OS IO to TD internal IO */
5820  if ( pSatDevData->IDDeviceValid == agFALSE)
5821  {
5822    status = satStartIDDev(
5823                         tiRoot,
5824                         tiIORequest,
5825                         tiDeviceHandle,
5826                         tiScsiRequest,
5827                         satIOContext
5828                         );
5829    TI_DBG6(("satInquiry: end status %d\n", status));
5830    return status;
5831  }
5832  else
5833  {
5834    TI_DBG6(("satInquiry: calling satInquiryIntCB\n"));
5835    satInquiryIntCB(
5836                    tiRoot,
5837                    tiIORequest,
5838                    tiDeviceHandle,
5839                    tiScsiRequest,
5840                    satIOContext
5841                    );
5842
5843    return tiSuccess;
5844  }
5845
5846}
5847
5848
5849/*****************************************************************************/
5850/*! \brief SAT implementation for SCSI satReadCapacity10.
5851 *
5852 *  SAT implementation for SCSI satReadCapacity10.
5853 *
5854 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
5855 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
5856 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
5857 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
5858 *  \param   satIOContext_t:   Pointer to the SAT IO Context
5859 *
5860 *  \return If command is started successfully
5861 *    - \e tiSuccess:     I/O request successfully initiated.
5862 *    - \e tiBusy:        No resources available, try again later.
5863 *    - \e tiIONoDevice:  Invalid device handle.
5864 *    - \e tiError:       Other errors.
5865 */
5866/*****************************************************************************/
5867GLOBAL bit32  satReadCapacity10(
5868                   tiRoot_t                  *tiRoot,
5869                   tiIORequest_t             *tiIORequest,
5870                   tiDeviceHandle_t          *tiDeviceHandle,
5871                   tiScsiInitiatorRequest_t *tiScsiRequest,
5872                   satIOContext_t            *satIOContext)
5873{
5874  scsiRspSense_t          *pSense;
5875  tiIniScsiCmnd_t         *scsiCmnd;
5876  bit8              *pVirtAddr;
5877  satDeviceData_t         *pSatDevData;
5878  agsaSATAIdentifyData_t  *pSATAIdData;
5879  bit32                   lastLba;
5880  bit32                   word117_118;
5881  bit32                   word117;
5882  bit32                   word118;
5883  TI_DBG5(("satReadCapacity10: start: tiDeviceHandle=%p tiIORequest=%p\n",
5884      tiDeviceHandle, tiIORequest));
5885
5886  pSense      = satIOContext->pSense;
5887  pVirtAddr   = (bit8 *) tiScsiRequest->sglVirtualAddr;
5888  scsiCmnd    = &tiScsiRequest->scsiCmnd;
5889  pSatDevData = satIOContext->pSatDevData;
5890  pSATAIdData = &pSatDevData->satIdentifyData;
5891
5892
5893  /* checking CONTROL */
5894  /* NACA == 1 or LINK == 1*/
5895  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
5896  {
5897    satSetSensePayload( pSense,
5898                        SCSI_SNSKEY_ILLEGAL_REQUEST,
5899                        0,
5900                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5901                        satIOContext);
5902
5903    ostiInitiatorIOCompleted( tiRoot,
5904                              tiIORequest,
5905                              tiIOSuccess,
5906                              SCSI_STAT_CHECK_CONDITION,
5907                              satIOContext->pTiSenseData,
5908                              satIOContext->interruptContext );
5909
5910    TI_DBG1(("satReadCapacity10: return control\n"));
5911    return tiSuccess;
5912  }
5913
5914
5915  /*
5916   * If Logical block address is not set to zero, return error
5917   */
5918  if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
5919  {
5920    TI_DBG1(("satReadCapacity10 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
5921        tiDeviceHandle, tiIORequest));
5922
5923    satSetSensePayload( pSense,
5924                        SCSI_SNSKEY_ILLEGAL_REQUEST,
5925                        0,
5926                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5927                        satIOContext);
5928
5929    ostiInitiatorIOCompleted( tiRoot,
5930                              tiIORequest,
5931                              tiIOSuccess,
5932                              SCSI_STAT_CHECK_CONDITION,
5933                              satIOContext->pTiSenseData,
5934                              satIOContext->interruptContext );
5935    return tiSuccess;
5936
5937  }
5938
5939  /*
5940   * If PMI bit is not zero, return error
5941   */
5942  if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
5943  {
5944    TI_DBG1(("satReadCapacity10 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
5945        tiDeviceHandle, tiIORequest));
5946
5947    satSetSensePayload( pSense,
5948                        SCSI_SNSKEY_ILLEGAL_REQUEST,
5949                        0,
5950                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5951                        satIOContext);
5952
5953    ostiInitiatorIOCompleted( tiRoot,
5954                              tiIORequest,
5955                              tiIOSuccess,
5956                              SCSI_STAT_CHECK_CONDITION,
5957                              satIOContext->pTiSenseData,
5958                              satIOContext->interruptContext );
5959    return tiSuccess;
5960
5961  }
5962
5963  /*
5964    filling in Read Capacity parameter data
5965    saved identify device has been already flipped
5966    See ATA spec p125 and p136 and SBC spec p54
5967  */
5968  /*
5969   * If 48-bit addressing is supported, set capacity information from Identify
5970   * Device Word 100-103.
5971   */
5972  if (pSatDevData->sat48BitSupport == agTRUE)
5973  {
5974    /*
5975     * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data:
5976     * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL
5977     * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL
5978     * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would
5979     * then issue a READ CAPACITY(16) command.
5980     */
5981    /* ATA Identify Device information word 100 - 103 */
5982    if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
5983    {
5984      pVirtAddr[0] = 0xFF;        /* MSB number of block */
5985      pVirtAddr[1] = 0xFF;
5986      pVirtAddr[2] = 0xFF;
5987      pVirtAddr[3] = 0xFF;        /* LSB number of block */
5988      TI_DBG1(("satReadCapacity10: returns 0xFFFFFFFF\n"));
5989    }
5990    else  /* Fit the Readcapacity10 4-bytes response length */
5991    {
5992      lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
5993                  (pSATAIdData->maxLBA0_15);
5994      lastLba = lastLba - 1;      /* LBA starts from zero */
5995
5996      /*
5997        for testing
5998      lastLba = lastLba - (512*10) - 1;
5999      */
6000
6001
6002      pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
6003      pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6004      pVirtAddr[2] = (bit8)((lastLba >> 8)  & 0xFF);
6005      pVirtAddr[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
6006
6007      TI_DBG3(("satReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
6008      TI_DBG3(("satReadCapacity10: LBA 0 is 0x%x %d\n", pVirtAddr[0], pVirtAddr[0]));
6009      TI_DBG3(("satReadCapacity10: LBA 1 is 0x%x %d\n", pVirtAddr[1], pVirtAddr[1]));
6010      TI_DBG3(("satReadCapacity10: LBA 2 is 0x%x %d\n", pVirtAddr[2], pVirtAddr[2]));
6011      TI_DBG3(("satReadCapacity10: LBA 3 is 0x%x %d\n", pVirtAddr[3], pVirtAddr[3]));
6012
6013    }
6014  }
6015
6016  /*
6017   * For 28-bit addressing, set capacity information from Identify
6018   * Device Word 60-61.
6019   */
6020  else
6021  {
6022    /* ATA Identify Device information word 60 - 61 */
6023    lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6024                (pSATAIdData->numOfUserAddressableSectorsLo);
6025    lastLba = lastLba - 1;      /* LBA starts from zero */
6026
6027    pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF);    /* MSB */
6028    pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6029    pVirtAddr[2] = (bit8)((lastLba >> 8)  & 0xFF);
6030    pVirtAddr[3] = (bit8)((lastLba )      & 0xFF);    /* LSB */
6031  }
6032  /* SAT Rev 8d */
6033  if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
6034  {
6035    TI_DBG5(("satReadCapacity10: Default Block Length is 512\n"));
6036    /*
6037     * Set the block size, fixed at 512 bytes.
6038     */
6039    pVirtAddr[4] = 0x00;        /* MSB block size in bytes */
6040    pVirtAddr[5] = 0x00;
6041    pVirtAddr[6] = 0x02;
6042    pVirtAddr[7] = 0x00;        /* LSB block size in bytes */
6043  }
6044  else
6045  {
6046    word118 = pSATAIdData->word112_126[6];
6047    word117 = pSATAIdData->word112_126[5];
6048
6049    word117_118 = (word118 << 16) + word117;
6050    word117_118 = word117_118 * 2;
6051    pVirtAddr[4] = (bit8)((word117_118 >> 24) & 0xFF);        /* MSB block size in bytes */
6052    pVirtAddr[5] = (bit8)((word117_118 >> 16) & 0xFF);
6053    pVirtAddr[6] = (bit8)((word117_118 >> 8) & 0xFF);
6054    pVirtAddr[7] = (bit8)(word117_118 & 0xFF);                /* LSB block size in bytes */
6055
6056    TI_DBG1(("satReadCapacity10: Nondefault word118 %d 0x%x \n", word118, word118));
6057    TI_DBG1(("satReadCapacity10: Nondefault word117 %d 0x%x \n", word117, word117));
6058    TI_DBG1(("satReadCapacity10: Nondefault Block Length is %d 0x%x \n",word117_118, word117_118));
6059
6060  }
6061
6062  /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6063  pSatDevData->satMaxLBA[0] = 0;            /* MSB */
6064  pSatDevData->satMaxLBA[1] = 0;
6065  pSatDevData->satMaxLBA[2] = 0;
6066  pSatDevData->satMaxLBA[3] = 0;
6067  pSatDevData->satMaxLBA[4] = pVirtAddr[0];
6068  pSatDevData->satMaxLBA[5] = pVirtAddr[1];
6069  pSatDevData->satMaxLBA[6] = pVirtAddr[2];
6070  pSatDevData->satMaxLBA[7] = pVirtAddr[3]; /* LSB */
6071
6072
6073  TI_DBG4(("satReadCapacity10 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
6074        pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6075        pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6076        tiDeviceHandle, tiIORequest));
6077
6078
6079  /*
6080   * Send the completion response now.
6081   */
6082  ostiInitiatorIOCompleted( tiRoot,
6083                            tiIORequest,
6084                            tiIOSuccess,
6085                            SCSI_STAT_GOOD,
6086                            agNULL,
6087                            satIOContext->interruptContext);
6088  return tiSuccess;
6089}
6090
6091
6092/*****************************************************************************/
6093/*! \brief SAT implementation for SCSI satReadCapacity16.
6094 *
6095 *  SAT implementation for SCSI satReadCapacity16.
6096 *
6097 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
6098 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
6099 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
6100 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
6101 *  \param   satIOContext_t:   Pointer to the SAT IO Context
6102 *
6103 *  \return If command is started successfully
6104 *    - \e tiSuccess:     I/O request successfully initiated.
6105 *    - \e tiBusy:        No resources available, try again later.
6106 *    - \e tiIONoDevice:  Invalid device handle.
6107 *    - \e tiError:       Other errors.
6108 */
6109/*****************************************************************************/
6110GLOBAL bit32  satReadCapacity16(
6111                   tiRoot_t                  *tiRoot,
6112                   tiIORequest_t             *tiIORequest,
6113                   tiDeviceHandle_t          *tiDeviceHandle,
6114                   tiScsiInitiatorRequest_t *tiScsiRequest,
6115                   satIOContext_t            *satIOContext)
6116{
6117
6118  scsiRspSense_t          *pSense;
6119  tiIniScsiCmnd_t         *scsiCmnd;
6120  bit8                    *pVirtAddr;
6121  satDeviceData_t         *pSatDevData;
6122  agsaSATAIdentifyData_t  *pSATAIdData;
6123  bit32                   lastLbaLo;
6124  bit32                   allocationLen;
6125  bit32                   readCapacityLen  = 32;
6126  bit32                   i = 0;
6127  TI_DBG5(("satReadCapacity16 start: tiDeviceHandle=%p tiIORequest=%p\n",
6128      tiDeviceHandle, tiIORequest));
6129
6130  pSense      = satIOContext->pSense;
6131  pVirtAddr   = (bit8 *) tiScsiRequest->sglVirtualAddr;
6132  scsiCmnd    = &tiScsiRequest->scsiCmnd;
6133  pSatDevData = satIOContext->pSatDevData;
6134  pSATAIdData = &pSatDevData->satIdentifyData;
6135
6136  /* Find the buffer size allocated by Initiator */
6137  allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
6138                  (((bit32)scsiCmnd->cdb[11]) << 16) |
6139                  (((bit32)scsiCmnd->cdb[12]) << 8 ) |
6140                  (((bit32)scsiCmnd->cdb[13])      );
6141
6142
6143  if (allocationLen < readCapacityLen)
6144  {
6145    TI_DBG1(("satReadCapacity16 *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x\n", allocationLen, readCapacityLen));
6146
6147    satSetSensePayload( pSense,
6148                        SCSI_SNSKEY_ILLEGAL_REQUEST,
6149                        0,
6150                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6151                        satIOContext);
6152
6153    ostiInitiatorIOCompleted( tiRoot,
6154                              tiIORequest,
6155                              tiIOSuccess,
6156                              SCSI_STAT_CHECK_CONDITION,
6157                              satIOContext->pTiSenseData,
6158                              satIOContext->interruptContext );
6159    return tiSuccess;
6160
6161  }
6162
6163  /* checking CONTROL */
6164  /* NACA == 1 or LINK == 1*/
6165  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
6166  {
6167    satSetSensePayload( pSense,
6168                        SCSI_SNSKEY_ILLEGAL_REQUEST,
6169                        0,
6170                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6171                        satIOContext);
6172
6173    ostiInitiatorIOCompleted( tiRoot,
6174                              tiIORequest,
6175                              tiIOSuccess,
6176                              SCSI_STAT_CHECK_CONDITION,
6177                              satIOContext->pTiSenseData,
6178                              satIOContext->interruptContext );
6179
6180    TI_DBG1(("satReadCapacity16: return control\n"));
6181    return tiSuccess;
6182  }
6183
6184  /*
6185   * If Logical blcok address is not set to zero, return error
6186   */
6187  if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) ||
6188      (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9])  )
6189  {
6190    TI_DBG1(("satReadCapacity16 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
6191        tiDeviceHandle, tiIORequest));
6192
6193    satSetSensePayload( pSense,
6194                        SCSI_SNSKEY_ILLEGAL_REQUEST,
6195                        0,
6196                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6197                        satIOContext);
6198
6199    ostiInitiatorIOCompleted( tiRoot,
6200                              tiIORequest,
6201                              tiIOSuccess,
6202                              SCSI_STAT_CHECK_CONDITION,
6203                              satIOContext->pTiSenseData,
6204                              satIOContext->interruptContext );
6205    return tiSuccess;
6206
6207  }
6208
6209  /*
6210   * If PMI bit is not zero, return error
6211   */
6212  if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
6213  {
6214    TI_DBG1(("satReadCapacity16 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
6215        tiDeviceHandle, tiIORequest));
6216
6217    satSetSensePayload( pSense,
6218                        SCSI_SNSKEY_ILLEGAL_REQUEST,
6219                        0,
6220                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6221                        satIOContext);
6222
6223    ostiInitiatorIOCompleted( tiRoot,
6224                              tiIORequest,
6225                              tiIOSuccess,
6226                              SCSI_STAT_CHECK_CONDITION,
6227                              satIOContext->pTiSenseData,
6228                              satIOContext->interruptContext );
6229    return tiSuccess;
6230
6231  }
6232
6233  /*
6234    filling in Read Capacity parameter data
6235  */
6236
6237  /*
6238   * If 48-bit addressing is supported, set capacity information from Identify
6239   * Device Word 100-103.
6240   */
6241  if (pSatDevData->sat48BitSupport == agTRUE)
6242  {
6243    pVirtAddr[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff);  /* MSB */
6244    pVirtAddr[1] = (bit8)((pSATAIdData->maxLBA48_63)        & 0xff);
6245    pVirtAddr[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
6246    pVirtAddr[3] = (bit8)((pSATAIdData->maxLBA32_47)        & 0xff);
6247
6248    lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
6249    lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
6250
6251    pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6252    pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6253    pVirtAddr[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
6254    pVirtAddr[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
6255
6256  }
6257
6258  /*
6259   * For 28-bit addressing, set capacity information from Identify
6260   * Device Word 60-61.
6261   */
6262  else
6263  {
6264    pVirtAddr[0] = 0;       /* MSB */
6265    pVirtAddr[1] = 0;
6266    pVirtAddr[2] = 0;
6267    pVirtAddr[3] = 0;
6268
6269    lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6270                  (pSATAIdData->numOfUserAddressableSectorsLo);
6271    lastLbaLo = lastLbaLo - 1;      /* LBA starts from zero */
6272
6273    pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6274    pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6275    pVirtAddr[6] = (bit8)((lastLbaLo >> 8)  & 0xFF);
6276    pVirtAddr[7] = (bit8)((lastLbaLo )      & 0xFF);    /* LSB */
6277
6278  }
6279
6280  /*
6281   * Set the block size, fixed at 512 bytes.
6282   */
6283  pVirtAddr[8]  = 0x00;        /* MSB block size in bytes */
6284  pVirtAddr[9]  = 0x00;
6285  pVirtAddr[10] = 0x02;
6286  pVirtAddr[11] = 0x00;        /* LSB block size in bytes */
6287
6288
6289  /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6290  pSatDevData->satMaxLBA[0] = pVirtAddr[0];            /* MSB */
6291  pSatDevData->satMaxLBA[1] = pVirtAddr[1];
6292  pSatDevData->satMaxLBA[2] = pVirtAddr[2];
6293  pSatDevData->satMaxLBA[3] = pVirtAddr[3];
6294  pSatDevData->satMaxLBA[4] = pVirtAddr[4];
6295  pSatDevData->satMaxLBA[5] = pVirtAddr[5];
6296  pSatDevData->satMaxLBA[6] = pVirtAddr[6];
6297  pSatDevData->satMaxLBA[7] = pVirtAddr[7];             /* LSB */
6298
6299  TI_DBG5(("satReadCapacity16 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
6300        pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6301        pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6302        pVirtAddr[8], pVirtAddr[9], pVirtAddr[10], pVirtAddr[11],
6303        tiDeviceHandle, tiIORequest));
6304
6305  for(i=12;i<=31;i++)
6306  {
6307    pVirtAddr[i] = 0x00;
6308  }
6309
6310  /*
6311   * Send the completion response now.
6312   */
6313  if (allocationLen > readCapacityLen)
6314  {
6315    /* underrun */
6316    TI_DBG1(("satReadCapacity16 reporting underrun readCapacityLen=0x%x allocationLen=0x%x \n", readCapacityLen, allocationLen));
6317
6318    ostiInitiatorIOCompleted( tiRoot,
6319                              tiIORequest,
6320                              tiIOUnderRun,
6321                              allocationLen - readCapacityLen,
6322                              agNULL,
6323                              satIOContext->interruptContext );
6324
6325
6326  }
6327  else
6328  {
6329    ostiInitiatorIOCompleted( tiRoot,
6330                              tiIORequest,
6331                              tiIOSuccess,
6332                              SCSI_STAT_GOOD,
6333                              agNULL,
6334                              satIOContext->interruptContext);
6335  }
6336  return tiSuccess;
6337
6338}
6339
6340
6341/*****************************************************************************/
6342/*! \brief SAT implementation for SCSI MODE SENSE (6).
6343 *
6344 *  SAT implementation for SCSI MODE SENSE (6).
6345 *
6346 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
6347 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
6348 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
6349 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
6350 *  \param   satIOContext_t:   Pointer to the SAT IO Context
6351 *
6352 *  \return If command is started successfully
6353 *    - \e tiSuccess:     I/O request successfully initiated.
6354 *    - \e tiBusy:        No resources available, try again later.
6355 *    - \e tiIONoDevice:  Invalid device handle.
6356 *    - \e tiError:       Other errors.
6357 */
6358/*****************************************************************************/
6359GLOBAL bit32  satModeSense6(
6360                   tiRoot_t                  *tiRoot,
6361                   tiIORequest_t             *tiIORequest,
6362                   tiDeviceHandle_t          *tiDeviceHandle,
6363                   tiScsiInitiatorRequest_t *tiScsiRequest,
6364                   satIOContext_t            *satIOContext)
6365{
6366
6367  scsiRspSense_t          *pSense;
6368  bit32                   requestLen;
6369  tiIniScsiCmnd_t         *scsiCmnd;
6370  bit32                   pageSupported;
6371  bit8                    page;
6372  bit8                    *pModeSense;    /* Mode Sense data buffer */
6373  satDeviceData_t         *pSatDevData;
6374  bit8                    PC;
6375  bit8                    AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN];
6376  bit8                    Control[MODE_SENSE6_CONTROL_PAGE_LEN];
6377  bit8                    RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN];
6378  bit8                    Caching[MODE_SENSE6_CACHING_LEN];
6379  bit8                    InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN];
6380  bit8                    lenRead = 0;
6381
6382
6383  TI_DBG5(("satModeSense6 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6384      tiDeviceHandle, tiIORequest));
6385
6386  pSense      = satIOContext->pSense;
6387  scsiCmnd    = &tiScsiRequest->scsiCmnd;
6388  pModeSense  = (bit8 *) tiScsiRequest->sglVirtualAddr;
6389  pSatDevData = satIOContext->pSatDevData;
6390
6391  //tdhexdump("satModeSense6", (bit8 *)scsiCmnd->cdb, 6);
6392  /* checking CONTROL */
6393  /* NACA == 1 or LINK == 1*/
6394  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
6395  {
6396    satSetSensePayload( pSense,
6397                        SCSI_SNSKEY_ILLEGAL_REQUEST,
6398                        0,
6399                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6400                        satIOContext);
6401
6402    ostiInitiatorIOCompleted( tiRoot,
6403                              tiIORequest,
6404                              tiIOSuccess,
6405                              SCSI_STAT_CHECK_CONDITION,
6406                              satIOContext->pTiSenseData,
6407                              satIOContext->interruptContext );
6408
6409    TI_DBG2(("satModeSense6: return control\n"));
6410    return tiSuccess;
6411  }
6412
6413  /* checking PC(Page Control)
6414     SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6415  */
6416  PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
6417  if (PC != 0)
6418  {
6419    satSetSensePayload( pSense,
6420                        SCSI_SNSKEY_ILLEGAL_REQUEST,
6421                        0,
6422                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6423                        satIOContext);
6424
6425    ostiInitiatorIOCompleted( tiRoot,
6426                              tiIORequest,
6427                              tiIOSuccess,
6428                              SCSI_STAT_CHECK_CONDITION,
6429                              satIOContext->pTiSenseData,
6430                              satIOContext->interruptContext );
6431
6432    TI_DBG1(("satModeSense6: return due to PC value pc 0x%x\n", PC >> 6));
6433    return tiSuccess;
6434  }
6435
6436  /* reading PAGE CODE */
6437  page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
6438
6439
6440  TI_DBG5(("satModeSense6: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
6441             page, tiDeviceHandle, tiIORequest));
6442
6443  requestLen = scsiCmnd->cdb[4];
6444
6445    /*
6446    Based on page code value, returns a corresponding mode page
6447    note: no support for subpage
6448  */
6449
6450  switch(page)
6451  {
6452    case MODESENSE_RETURN_ALL_PAGES:
6453    case MODESENSE_CONTROL_PAGE: /* control */
6454    case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6455    case MODESENSE_CACHING: /* caching */
6456    case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6457      pageSupported = agTRUE;
6458      break;
6459    case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
6460    default:
6461      pageSupported = agFALSE;
6462      break;
6463  }
6464
6465  if (pageSupported == agFALSE)
6466  {
6467
6468    TI_DBG1(("satModeSense6 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
6469        page, tiDeviceHandle, tiIORequest));
6470
6471    satSetSensePayload( pSense,
6472                        SCSI_SNSKEY_ILLEGAL_REQUEST,
6473                        0,
6474                        SCSI_SNSCODE_INVALID_COMMAND,
6475                        satIOContext);
6476
6477    ostiInitiatorIOCompleted( tiRoot,
6478                              tiIORequest,
6479                              tiIOSuccess,
6480                              SCSI_STAT_CHECK_CONDITION,
6481                              satIOContext->pTiSenseData,
6482                              satIOContext->interruptContext );
6483    return tiSuccess;
6484  }
6485
6486  switch(page)
6487  {
6488  case MODESENSE_RETURN_ALL_PAGES:
6489    lenRead = (bit8)MIN(requestLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
6490    break;
6491  case MODESENSE_CONTROL_PAGE: /* control */
6492    lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CONTROL_PAGE_LEN);
6493    break;
6494  case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6495    lenRead = (bit8)MIN(requestLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
6496    break;
6497  case MODESENSE_CACHING: /* caching */
6498    lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CACHING_LEN);
6499    break;
6500  case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6501    lenRead = (bit8)MIN(requestLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
6502    break;
6503  default:
6504    TI_DBG1(("satModeSense6: default error page %d\n", page));
6505    break;
6506  }
6507
6508  if (page == MODESENSE_RETURN_ALL_PAGES)
6509  {
6510    TI_DBG5(("satModeSense6: MODESENSE_RETURN_ALL_PAGES\n"));
6511    AllPages[0] = (bit8)(lenRead - 1);
6512    AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */
6513    AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6514    AllPages[3] = 0x08; /* block descriptor length */
6515
6516    /*
6517     * Fill-up direct-access device block-descriptor, SAT, Table 19
6518     */
6519
6520    /* density code */
6521    AllPages[4]  = 0x04; /* density-code : reserved for direct-access */
6522    /* number of blocks */
6523    AllPages[5]  = 0x00; /* unspecified */
6524    AllPages[6]  = 0x00; /* unspecified */
6525    AllPages[7]  = 0x00; /* unspecified */
6526    /* reserved */
6527    AllPages[8]  = 0x00; /* reserved */
6528    /* Block size */
6529    AllPages[9]  = 0x00;
6530    AllPages[10] = 0x02;   /* Block size is always 512 bytes */
6531    AllPages[11] = 0x00;
6532
6533    /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
6534    AllPages[12] = 0x01; /* page code */
6535    AllPages[13] = 0x0A; /* page length */
6536    AllPages[14] = 0x40; /* ARRE is set */
6537    AllPages[15] = 0x00;
6538    AllPages[16] = 0x00;
6539    AllPages[17] = 0x00;
6540    AllPages[18] = 0x00;
6541    AllPages[19] = 0x00;
6542    AllPages[20] = 0x00;
6543    AllPages[21] = 0x00;
6544    AllPages[22] = 0x00;
6545    AllPages[23] = 0x00;
6546    /* MODESENSE_CACHING */
6547    AllPages[24] = 0x08; /* page code */
6548    AllPages[25] = 0x12; /* page length */
6549#ifdef NOT_YET
6550    if (pSatDevData->satWriteCacheEnabled == agTRUE)
6551    {
6552      AllPages[26] = 0x04;/* WCE bit is set */
6553    }
6554    else
6555    {
6556      AllPages[26] = 0x00;/* WCE bit is NOT set */
6557    }
6558#endif
6559    AllPages[26] = 0x00;/* WCE bit is NOT set */
6560
6561    AllPages[27] = 0x00;
6562    AllPages[28] = 0x00;
6563    AllPages[29] = 0x00;
6564    AllPages[30] = 0x00;
6565    AllPages[31] = 0x00;
6566    AllPages[32] = 0x00;
6567    AllPages[33] = 0x00;
6568    AllPages[34] = 0x00;
6569    AllPages[35] = 0x00;
6570    if (pSatDevData->satLookAheadEnabled == agTRUE)
6571    {
6572      AllPages[36] = 0x00;/* DRA bit is NOT set */
6573    }
6574    else
6575    {
6576      AllPages[36] = 0x20;/* DRA bit is set */
6577    }
6578    AllPages[37] = 0x00;
6579    AllPages[38] = 0x00;
6580    AllPages[39] = 0x00;
6581    AllPages[40] = 0x00;
6582    AllPages[41] = 0x00;
6583    AllPages[42] = 0x00;
6584    AllPages[43] = 0x00;
6585    /* MODESENSE_CONTROL_PAGE */
6586    AllPages[44] = 0x0A; /* page code */
6587    AllPages[45] = 0x0A; /* page length */
6588    AllPages[46] = 0x02; /* only GLTSD bit is set */
6589    if (pSatDevData->satNCQ == agTRUE)
6590    {
6591      AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6592    }
6593    else
6594    {
6595      AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6596    }
6597    AllPages[48] = 0x00;
6598    AllPages[49] = 0x00;
6599    AllPages[50] = 0x00; /* obsolete */
6600    AllPages[51] = 0x00; /* obsolete */
6601    AllPages[52] = 0xFF; /* Busy Timeout Period */
6602    AllPages[53] = 0xFF; /* Busy Timeout Period */
6603    AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */
6604    AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */
6605    /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
6606    AllPages[56] = 0x1C; /* page code */
6607    AllPages[57] = 0x0A; /* page length */
6608    if (pSatDevData->satSMARTEnabled == agTRUE)
6609    {
6610      AllPages[58] = 0x00;/* DEXCPT bit is NOT set */
6611    }
6612    else
6613    {
6614      AllPages[58] = 0x08;/* DEXCPT bit is set */
6615    }
6616    AllPages[59] = 0x00; /* We don't support MRIE */
6617    AllPages[60] = 0x00; /* Interval timer vendor-specific */
6618    AllPages[61] = 0x00;
6619    AllPages[62] = 0x00;
6620    AllPages[63] = 0x00;
6621    AllPages[64] = 0x00; /* REPORT-COUNT */
6622    AllPages[65] = 0x00;
6623    AllPages[66] = 0x00;
6624    AllPages[67] = 0x00;
6625
6626    osti_memcpy(pModeSense, &AllPages, lenRead);
6627  }
6628  else if (page == MODESENSE_CONTROL_PAGE)
6629  {
6630    TI_DBG5(("satModeSense6: MODESENSE_CONTROL_PAGE\n"));
6631    Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1;
6632    Control[1] = 0x00; /* default medium type (currently mounted medium type) */
6633    Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6634    Control[3] = 0x08; /* block descriptor length */
6635    /*
6636     * Fill-up direct-access device block-descriptor, SAT, Table 19
6637     */
6638
6639    /* density code */
6640    Control[4]  = 0x04; /* density-code : reserved for direct-access */
6641    /* number of blocks */
6642    Control[5]  = 0x00; /* unspecified */
6643    Control[6]  = 0x00; /* unspecified */
6644    Control[7]  = 0x00; /* unspecified */
6645    /* reserved */
6646    Control[8]  = 0x00; /* reserved */
6647    /* Block size */
6648    Control[9]  = 0x00;
6649    Control[10] = 0x02;   /* Block size is always 512 bytes */
6650    Control[11] = 0x00;
6651    /*
6652     * Fill-up control mode page, SAT, Table 65
6653     */
6654    Control[12] = 0x0A; /* page code */
6655    Control[13] = 0x0A; /* page length */
6656    Control[14] = 0x02; /* only GLTSD bit is set */
6657    if (pSatDevData->satNCQ == agTRUE)
6658    {
6659      Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6660    }
6661    else
6662    {
6663      Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6664    }
6665    Control[16] = 0x00;
6666    Control[17] = 0x00;
6667    Control[18] = 0x00; /* obsolete */
6668    Control[19] = 0x00; /* obsolete */
6669    Control[20] = 0xFF; /* Busy Timeout Period */
6670    Control[21] = 0xFF; /* Busy Timeout Period */
6671    Control[22] = 0x00; /* we don't support non-000b value for the self-test code */
6672    Control[23] = 0x00; /* we don't support non-000b value for the self-test code */
6673
6674    osti_memcpy(pModeSense, &Control, lenRead);
6675
6676  }
6677  else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
6678  {
6679    TI_DBG5(("satModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
6680    RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1;
6681    RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */
6682    RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6683    RWErrorRecovery[3] = 0x08; /* block descriptor length */
6684    /*
6685     * Fill-up direct-access device block-descriptor, SAT, Table 19
6686     */
6687
6688    /* density code */
6689    RWErrorRecovery[4]  = 0x04; /* density-code : reserved for direct-access */
6690    /* number of blocks */
6691    RWErrorRecovery[5]  = 0x00; /* unspecified */
6692    RWErrorRecovery[6]  = 0x00; /* unspecified */
6693    RWErrorRecovery[7]  = 0x00; /* unspecified */
6694    /* reserved */
6695    RWErrorRecovery[8]  = 0x00; /* reserved */
6696    /* Block size */
6697    RWErrorRecovery[9]  = 0x00;
6698    RWErrorRecovery[10] = 0x02;   /* Block size is always 512 bytes */
6699    RWErrorRecovery[11] = 0x00;
6700    /*
6701     * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
6702     */
6703    RWErrorRecovery[12] = 0x01; /* page code */
6704    RWErrorRecovery[13] = 0x0A; /* page length */
6705    RWErrorRecovery[14] = 0x40; /* ARRE is set */
6706    RWErrorRecovery[15] = 0x00;
6707    RWErrorRecovery[16] = 0x00;
6708    RWErrorRecovery[17] = 0x00;
6709    RWErrorRecovery[18] = 0x00;
6710    RWErrorRecovery[19] = 0x00;
6711    RWErrorRecovery[20] = 0x00;
6712    RWErrorRecovery[21] = 0x00;
6713    RWErrorRecovery[22] = 0x00;
6714    RWErrorRecovery[23] = 0x00;
6715
6716    osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
6717
6718  }
6719  else if (page == MODESENSE_CACHING)
6720  {
6721    TI_DBG5(("satModeSense6: MODESENSE_CACHING\n"));
6722    /* special case */
6723    if (requestLen == 4 && page == MODESENSE_CACHING)
6724    {
6725      TI_DBG5(("satModeSense6: linux 2.6.8.24 support\n"));
6726
6727      pModeSense[0] = 0x20 - 1; /* 32 - 1 */
6728      pModeSense[1] = 0x00; /* default medium type (currently mounted medium type) */
6729      pModeSense[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6730      pModeSense[3] = 0x08; /* block descriptor length */
6731      ostiInitiatorIOCompleted( tiRoot,
6732                                tiIORequest,
6733                                tiIOSuccess,
6734                                SCSI_STAT_GOOD,
6735                                agNULL,
6736                                satIOContext->interruptContext);
6737      return tiSuccess;
6738    }
6739    Caching[0] = MODE_SENSE6_CACHING_LEN - 1;
6740    Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
6741    Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6742    Caching[3] = 0x08; /* block descriptor length */
6743    /*
6744     * Fill-up direct-access device block-descriptor, SAT, Table 19
6745     */
6746
6747    /* density code */
6748    Caching[4]  = 0x04; /* density-code : reserved for direct-access */
6749    /* number of blocks */
6750    Caching[5]  = 0x00; /* unspecified */
6751    Caching[6]  = 0x00; /* unspecified */
6752    Caching[7]  = 0x00; /* unspecified */
6753    /* reserved */
6754    Caching[8]  = 0x00; /* reserved */
6755    /* Block size */
6756    Caching[9]  = 0x00;
6757    Caching[10] = 0x02;   /* Block size is always 512 bytes */
6758    Caching[11] = 0x00;
6759    /*
6760     * Fill-up Caching mode page, SAT, Table 67
6761     */
6762    /* length 20 */
6763    Caching[12] = 0x08; /* page code */
6764    Caching[13] = 0x12; /* page length */
6765#ifdef NOT_YET
6766    if (pSatDevData->satWriteCacheEnabled == agTRUE)
6767    {
6768      Caching[14] = 0x04;/* WCE bit is set */
6769    }
6770    else
6771    {
6772      Caching[14] = 0x00;/* WCE bit is NOT set */
6773    }
6774#endif
6775    Caching[14] = 0x00;/* WCE bit is NOT set */
6776
6777    Caching[15] = 0x00;
6778    Caching[16] = 0x00;
6779    Caching[17] = 0x00;
6780    Caching[18] = 0x00;
6781    Caching[19] = 0x00;
6782    Caching[20] = 0x00;
6783    Caching[21] = 0x00;
6784    Caching[22] = 0x00;
6785    Caching[23] = 0x00;
6786    if (pSatDevData->satLookAheadEnabled == agTRUE)
6787    {
6788      Caching[24] = 0x00;/* DRA bit is NOT set */
6789    }
6790    else
6791    {
6792      Caching[24] = 0x20;/* DRA bit is set */
6793    }
6794    Caching[25] = 0x00;
6795    Caching[26] = 0x00;
6796    Caching[27] = 0x00;
6797    Caching[28] = 0x00;
6798    Caching[29] = 0x00;
6799    Caching[30] = 0x00;
6800    Caching[31] = 0x00;
6801
6802    osti_memcpy(pModeSense, &Caching, lenRead);
6803
6804  }
6805  else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
6806  {
6807    TI_DBG5(("satModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
6808    InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1;
6809    InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */
6810    InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6811    InfoExceptionCtrl[3] = 0x08; /* block descriptor length */
6812    /*
6813     * Fill-up direct-access device block-descriptor, SAT, Table 19
6814     */
6815
6816    /* density code */
6817    InfoExceptionCtrl[4]  = 0x04; /* density-code : reserved for direct-access */
6818    /* number of blocks */
6819    InfoExceptionCtrl[5]  = 0x00; /* unspecified */
6820    InfoExceptionCtrl[6]  = 0x00; /* unspecified */
6821    InfoExceptionCtrl[7]  = 0x00; /* unspecified */
6822    /* reserved */
6823    InfoExceptionCtrl[8]  = 0x00; /* reserved */
6824    /* Block size */
6825    InfoExceptionCtrl[9]  = 0x00;
6826    InfoExceptionCtrl[10] = 0x02;   /* Block size is always 512 bytes */
6827    InfoExceptionCtrl[11] = 0x00;
6828    /*
6829     * Fill-up informational-exceptions control mode page, SAT, Table 68
6830     */
6831    InfoExceptionCtrl[12] = 0x1C; /* page code */
6832    InfoExceptionCtrl[13] = 0x0A; /* page length */
6833     if (pSatDevData->satSMARTEnabled == agTRUE)
6834    {
6835      InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */
6836    }
6837    else
6838    {
6839      InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */
6840    }
6841    InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */
6842    InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */
6843    InfoExceptionCtrl[17] = 0x00;
6844    InfoExceptionCtrl[18] = 0x00;
6845    InfoExceptionCtrl[19] = 0x00;
6846    InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */
6847    InfoExceptionCtrl[21] = 0x00;
6848    InfoExceptionCtrl[22] = 0x00;
6849    InfoExceptionCtrl[23] = 0x00;
6850    osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
6851
6852  }
6853  else
6854  {
6855    /* Error */
6856    TI_DBG1(("satModeSense6: Error page %d\n", page));
6857    satSetSensePayload( pSense,
6858                        SCSI_SNSKEY_ILLEGAL_REQUEST,
6859                        0,
6860                        SCSI_SNSCODE_INVALID_COMMAND,
6861                        satIOContext);
6862
6863    ostiInitiatorIOCompleted( tiRoot,
6864                              tiIORequest,
6865                              tiIOSuccess,
6866                              SCSI_STAT_CHECK_CONDITION,
6867                              satIOContext->pTiSenseData,
6868                              satIOContext->interruptContext );
6869    return tiSuccess;
6870  }
6871
6872  /* there can be only underrun not overrun in error case */
6873  if (requestLen > lenRead)
6874  {
6875    TI_DBG6(("satModeSense6 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
6876
6877    ostiInitiatorIOCompleted( tiRoot,
6878                              tiIORequest,
6879                              tiIOUnderRun,
6880                              requestLen - lenRead,
6881                              agNULL,
6882                              satIOContext->interruptContext );
6883
6884
6885  }
6886  else
6887  {
6888    ostiInitiatorIOCompleted( tiRoot,
6889                              tiIORequest,
6890                              tiIOSuccess,
6891                              SCSI_STAT_GOOD,
6892                              agNULL,
6893                              satIOContext->interruptContext);
6894  }
6895
6896  return tiSuccess;
6897
6898}
6899
6900/*****************************************************************************/
6901/*! \brief SAT implementation for SCSI MODE SENSE (10).
6902 *
6903 *  SAT implementation for SCSI MODE SENSE (10).
6904 *
6905 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
6906 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
6907 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
6908 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
6909 *  \param   satIOContext_t:   Pointer to the SAT IO Context
6910 *
6911 *  \return If command is started successfully
6912 *    - \e tiSuccess:     I/O request successfully initiated.
6913 *    - \e tiBusy:        No resources available, try again later.
6914 *    - \e tiIONoDevice:  Invalid device handle.
6915 *    - \e tiError:       Other errors.
6916 */
6917/*****************************************************************************/
6918GLOBAL bit32  satModeSense10(
6919                   tiRoot_t                  *tiRoot,
6920                   tiIORequest_t             *tiIORequest,
6921                   tiDeviceHandle_t          *tiDeviceHandle,
6922                   tiScsiInitiatorRequest_t *tiScsiRequest,
6923                   satIOContext_t            *satIOContext)
6924{
6925
6926  scsiRspSense_t          *pSense;
6927  bit32                   requestLen;
6928  tiIniScsiCmnd_t         *scsiCmnd;
6929  bit32                   pageSupported;
6930  bit8                    page;
6931  bit8                    *pModeSense;    /* Mode Sense data buffer */
6932  satDeviceData_t         *pSatDevData;
6933  bit8                    PC; /* page control */
6934  bit8                    LLBAA; /* Long LBA Accepted */
6935  bit32                   index;
6936  bit8                    AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN];
6937  bit8                    Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN];
6938  bit8                    RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN];
6939  bit8                    Caching[MODE_SENSE10_CACHING_LLBAA_LEN];
6940  bit8                    InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN];
6941  bit8                    lenRead = 0;
6942
6943  TI_DBG5(("satModeSense10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6944      tiDeviceHandle, tiIORequest));
6945
6946  pSense      = satIOContext->pSense;
6947  scsiCmnd    = &tiScsiRequest->scsiCmnd;
6948  pModeSense  = (bit8 *) tiScsiRequest->sglVirtualAddr;
6949  pSatDevData = satIOContext->pSatDevData;
6950
6951  /* checking CONTROL */
6952  /* NACA == 1 or LINK == 1*/
6953  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
6954  {
6955    satSetSensePayload( pSense,
6956                        SCSI_SNSKEY_ILLEGAL_REQUEST,
6957                        0,
6958                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6959                        satIOContext);
6960
6961    ostiInitiatorIOCompleted( tiRoot,
6962                              tiIORequest,
6963                              tiIOSuccess,
6964                              SCSI_STAT_CHECK_CONDITION,
6965                              satIOContext->pTiSenseData,
6966                              satIOContext->interruptContext );
6967
6968    TI_DBG2(("satModeSense10: return control\n"));
6969    return tiSuccess;
6970  }
6971
6972  /* checking PC(Page Control)
6973     SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6974  */
6975  PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
6976  if (PC != 0)
6977  {
6978    satSetSensePayload( pSense,
6979                        SCSI_SNSKEY_ILLEGAL_REQUEST,
6980                        0,
6981                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6982                        satIOContext);
6983
6984    ostiInitiatorIOCompleted( tiRoot,
6985                              tiIORequest,
6986                              tiIOSuccess,
6987                              SCSI_STAT_CHECK_CONDITION,
6988                              satIOContext->pTiSenseData,
6989                              satIOContext->interruptContext );
6990
6991    TI_DBG1(("satModeSense10: return due to PC value pc 0x%x\n", PC));
6992    return tiSuccess;
6993  }
6994  /* finding LLBAA bit */
6995  LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
6996  /* reading PAGE CODE */
6997  page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
6998
6999  TI_DBG5(("satModeSense10: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
7000             page, tiDeviceHandle, tiIORequest));
7001  requestLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7002
7003  /*
7004    Based on page code value, returns a corresponding mode page
7005    note: no support for subpage
7006  */
7007  switch(page)
7008  {
7009    case MODESENSE_RETURN_ALL_PAGES: /* return all pages */
7010    case MODESENSE_CONTROL_PAGE: /* control */
7011    case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7012    case MODESENSE_CACHING: /* caching */
7013    case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7014      pageSupported = agTRUE;
7015      break;
7016    case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
7017    default:
7018      pageSupported = agFALSE;
7019      break;
7020  }
7021
7022  if (pageSupported == agFALSE)
7023  {
7024
7025    TI_DBG1(("satModeSense10 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
7026        page, tiDeviceHandle, tiIORequest));
7027
7028    satSetSensePayload( pSense,
7029                        SCSI_SNSKEY_ILLEGAL_REQUEST,
7030                        0,
7031                        SCSI_SNSCODE_INVALID_COMMAND,
7032                        satIOContext);
7033
7034    ostiInitiatorIOCompleted( tiRoot,
7035                              tiIORequest,
7036                              tiIOSuccess,
7037                              SCSI_STAT_CHECK_CONDITION,
7038                              satIOContext->pTiSenseData,
7039                              satIOContext->interruptContext );
7040    return tiSuccess;
7041  }
7042
7043  switch(page)
7044  {
7045  case MODESENSE_RETURN_ALL_PAGES:
7046    if (LLBAA)
7047    {
7048      lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
7049    }
7050    else
7051    {
7052      lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
7053    }
7054    break;
7055  case MODESENSE_CONTROL_PAGE: /* control */
7056    if (LLBAA)
7057    {
7058      lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
7059    }
7060    else
7061    {
7062      lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LEN);
7063    }
7064    break;
7065  case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7066    if (LLBAA)
7067    {
7068      lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
7069    }
7070    else
7071    {
7072      lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
7073    }
7074    break;
7075  case MODESENSE_CACHING: /* caching */
7076    if (LLBAA)
7077    {
7078      lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LLBAA_LEN);
7079    }
7080    else
7081    {
7082      lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LEN);
7083    }
7084    break;
7085  case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7086    if (LLBAA)
7087    {
7088      lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
7089    }
7090    else
7091    {
7092      lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
7093    }
7094    break;
7095  default:
7096    TI_DBG1(("satModeSense10: default error page %d\n", page));
7097    break;
7098  }
7099
7100  if (page == MODESENSE_RETURN_ALL_PAGES)
7101  {
7102    TI_DBG5(("satModeSense10: MODESENSE_RETURN_ALL_PAGES\n"));
7103    AllPages[0] = 0;
7104    AllPages[1] = (bit8)(lenRead - 2);
7105    AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7106    AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7107    if (LLBAA)
7108    {
7109      AllPages[4] = 0x00; /* reserved and LONGLBA */
7110      AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */
7111    }
7112    else
7113    {
7114      AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7115    }
7116    AllPages[5] = 0x00; /* reserved */
7117    AllPages[6] = 0x00; /* block descriptot length */
7118    if (LLBAA)
7119    {
7120      AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7121    }
7122    else
7123    {
7124      AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7125    }
7126
7127    /*
7128     * Fill-up direct-access device block-descriptor, SAT, Table 19
7129     */
7130
7131    if (LLBAA)
7132    {
7133      /* density code */
7134      AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
7135      /* number of blocks */
7136      AllPages[9]   = 0x00; /* unspecified */
7137      AllPages[10]  = 0x00; /* unspecified */
7138      AllPages[11]  = 0x00; /* unspecified */
7139      AllPages[12]  = 0x00; /* unspecified */
7140      AllPages[13]  = 0x00; /* unspecified */
7141      AllPages[14]  = 0x00; /* unspecified */
7142      AllPages[15]  = 0x00; /* unspecified */
7143      /* reserved */
7144      AllPages[16]  = 0x00; /* reserved */
7145      AllPages[17]  = 0x00; /* reserved */
7146      AllPages[18]  = 0x00; /* reserved */
7147      AllPages[19]  = 0x00; /* reserved */
7148      /* Block size */
7149      AllPages[20]  = 0x00;
7150      AllPages[21]  = 0x00;
7151      AllPages[22]  = 0x02;   /* Block size is always 512 bytes */
7152      AllPages[23]  = 0x00;
7153    }
7154    else
7155    {
7156      /* density code */
7157      AllPages[8]   = 0x04; /* density-code : reserved for direct-access */
7158      /* number of blocks */
7159      AllPages[9]   = 0x00; /* unspecified */
7160      AllPages[10]  = 0x00; /* unspecified */
7161      AllPages[11]  = 0x00; /* unspecified */
7162      /* reserved */
7163      AllPages[12]  = 0x00; /* reserved */
7164      /* Block size */
7165      AllPages[13]  = 0x00;
7166      AllPages[14]  = 0x02;   /* Block size is always 512 bytes */
7167      AllPages[15]  = 0x00;
7168    }
7169
7170    if (LLBAA)
7171    {
7172      index = 24;
7173    }
7174    else
7175    {
7176      index = 16;
7177    }
7178    /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
7179    AllPages[index+0] = 0x01; /* page code */
7180    AllPages[index+1] = 0x0A; /* page length */
7181    AllPages[index+2] = 0x40; /* ARRE is set */
7182    AllPages[index+3] = 0x00;
7183    AllPages[index+4] = 0x00;
7184    AllPages[index+5] = 0x00;
7185    AllPages[index+6] = 0x00;
7186    AllPages[index+7] = 0x00;
7187    AllPages[index+8] = 0x00;
7188    AllPages[index+9] = 0x00;
7189    AllPages[index+10] = 0x00;
7190    AllPages[index+11] = 0x00;
7191
7192    /* MODESENSE_CACHING */
7193    /*
7194     * Fill-up Caching mode page, SAT, Table 67
7195     */
7196    /* length 20 */
7197    AllPages[index+12] = 0x08; /* page code */
7198    AllPages[index+13] = 0x12; /* page length */
7199#ifdef NOT_YET
7200    if (pSatDevData->satWriteCacheEnabled == agTRUE)
7201    {
7202      AllPages[index+14] = 0x04;/* WCE bit is set */
7203    }
7204    else
7205    {
7206      AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7207    }
7208#endif
7209    AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7210    AllPages[index+15] = 0x00;
7211    AllPages[index+16] = 0x00;
7212    AllPages[index+17] = 0x00;
7213    AllPages[index+18] = 0x00;
7214    AllPages[index+19] = 0x00;
7215    AllPages[index+20] = 0x00;
7216    AllPages[index+21] = 0x00;
7217    AllPages[index+22] = 0x00;
7218    AllPages[index+23] = 0x00;
7219    if (pSatDevData->satLookAheadEnabled == agTRUE)
7220    {
7221      AllPages[index+24] = 0x00;/* DRA bit is NOT set */
7222    }
7223    else
7224    {
7225      AllPages[index+24] = 0x20;/* DRA bit is set */
7226    }
7227    AllPages[index+25] = 0x00;
7228    AllPages[index+26] = 0x00;
7229    AllPages[index+27] = 0x00;
7230    AllPages[index+28] = 0x00;
7231    AllPages[index+29] = 0x00;
7232    AllPages[index+30] = 0x00;
7233    AllPages[index+31] = 0x00;
7234
7235    /* MODESENSE_CONTROL_PAGE */
7236    /*
7237     * Fill-up control mode page, SAT, Table 65
7238     */
7239    AllPages[index+32] = 0x0A; /* page code */
7240    AllPages[index+33] = 0x0A; /* page length */
7241    AllPages[index+34] = 0x02; /* only GLTSD bit is set */
7242    if (pSatDevData->satNCQ == agTRUE)
7243    {
7244      AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7245    }
7246    else
7247    {
7248      AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7249    }
7250    AllPages[index+36] = 0x00;
7251    AllPages[index+37] = 0x00;
7252    AllPages[index+38] = 0x00; /* obsolete */
7253    AllPages[index+39] = 0x00; /* obsolete */
7254    AllPages[index+40] = 0xFF; /* Busy Timeout Period */
7255    AllPages[index+41] = 0xFF; /* Busy Timeout Period */
7256    AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */
7257    AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */
7258
7259    /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
7260    /*
7261     * Fill-up informational-exceptions control mode page, SAT, Table 68
7262     */
7263    AllPages[index+44] = 0x1C; /* page code */
7264    AllPages[index+45] = 0x0A; /* page length */
7265     if (pSatDevData->satSMARTEnabled == agTRUE)
7266    {
7267      AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */
7268    }
7269    else
7270    {
7271      AllPages[index+46] = 0x08;/* DEXCPT bit is set */
7272    }
7273    AllPages[index+47] = 0x00; /* We don't support MRIE */
7274    AllPages[index+48] = 0x00; /* Interval timer vendor-specific */
7275    AllPages[index+49] = 0x00;
7276    AllPages[index+50] = 0x00;
7277    AllPages[index+51] = 0x00;
7278    AllPages[index+52] = 0x00; /* REPORT-COUNT */
7279    AllPages[index+53] = 0x00;
7280    AllPages[index+54] = 0x00;
7281    AllPages[index+55] = 0x00;
7282
7283    osti_memcpy(pModeSense, &AllPages, lenRead);
7284  }
7285  else if (page == MODESENSE_CONTROL_PAGE)
7286  {
7287    TI_DBG5(("satModeSense10: MODESENSE_CONTROL_PAGE\n"));
7288    Control[0] = 0;
7289    Control[1] = (bit8)(lenRead - 2);
7290    Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7291    Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7292    if (LLBAA)
7293    {
7294      Control[4] = 0x00; /* reserved and LONGLBA */
7295      Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */
7296    }
7297    else
7298    {
7299      Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7300    }
7301    Control[5] = 0x00; /* reserved */
7302    Control[6] = 0x00; /* block descriptot length */
7303    if (LLBAA)
7304    {
7305      Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7306    }
7307    else
7308    {
7309      Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7310    }
7311
7312    /*
7313     * Fill-up direct-access device block-descriptor, SAT, Table 19
7314     */
7315
7316    if (LLBAA)
7317    {
7318      /* density code */
7319      Control[8]   = 0x04; /* density-code : reserved for direct-access */
7320      /* number of blocks */
7321      Control[9]   = 0x00; /* unspecified */
7322      Control[10]  = 0x00; /* unspecified */
7323      Control[11]  = 0x00; /* unspecified */
7324      Control[12]  = 0x00; /* unspecified */
7325      Control[13]  = 0x00; /* unspecified */
7326      Control[14]  = 0x00; /* unspecified */
7327      Control[15]  = 0x00; /* unspecified */
7328      /* reserved */
7329      Control[16]  = 0x00; /* reserved */
7330      Control[17]  = 0x00; /* reserved */
7331      Control[18]  = 0x00; /* reserved */
7332      Control[19]  = 0x00; /* reserved */
7333      /* Block size */
7334      Control[20]  = 0x00;
7335      Control[21]  = 0x00;
7336      Control[22]  = 0x02;   /* Block size is always 512 bytes */
7337      Control[23]  = 0x00;
7338    }
7339    else
7340    {
7341      /* density code */
7342      Control[8]   = 0x04; /* density-code : reserved for direct-access */
7343      /* number of blocks */
7344      Control[9]   = 0x00; /* unspecified */
7345      Control[10]  = 0x00; /* unspecified */
7346      Control[11]  = 0x00; /* unspecified */
7347      /* reserved */
7348      Control[12]  = 0x00; /* reserved */
7349      /* Block size */
7350      Control[13]  = 0x00;
7351      Control[14]  = 0x02;   /* Block size is always 512 bytes */
7352      Control[15]  = 0x00;
7353    }
7354
7355    if (LLBAA)
7356    {
7357      index = 24;
7358    }
7359    else
7360    {
7361      index = 16;
7362    }
7363    /*
7364     * Fill-up control mode page, SAT, Table 65
7365     */
7366    Control[index+0] = 0x0A; /* page code */
7367    Control[index+1] = 0x0A; /* page length */
7368    Control[index+2] = 0x02; /* only GLTSD bit is set */
7369    if (pSatDevData->satNCQ == agTRUE)
7370    {
7371      Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7372    }
7373    else
7374    {
7375      Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7376    }
7377    Control[index+4] = 0x00;
7378    Control[index+5] = 0x00;
7379    Control[index+6] = 0x00; /* obsolete */
7380    Control[index+7] = 0x00; /* obsolete */
7381    Control[index+8] = 0xFF; /* Busy Timeout Period */
7382    Control[index+9] = 0xFF; /* Busy Timeout Period */
7383    Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */
7384    Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */
7385
7386    osti_memcpy(pModeSense, &Control, lenRead);
7387  }
7388  else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
7389  {
7390    TI_DBG5(("satModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
7391    RWErrorRecovery[0] = 0;
7392    RWErrorRecovery[1] = (bit8)(lenRead - 2);
7393    RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7394    RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7395    if (LLBAA)
7396    {
7397      RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */
7398      RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */
7399    }
7400    else
7401    {
7402      RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7403    }
7404    RWErrorRecovery[5] = 0x00; /* reserved */
7405    RWErrorRecovery[6] = 0x00; /* block descriptot length */
7406    if (LLBAA)
7407    {
7408      RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7409    }
7410    else
7411    {
7412      RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7413    }
7414
7415    /*
7416     * Fill-up direct-access device block-descriptor, SAT, Table 19
7417     */
7418
7419    if (LLBAA)
7420    {
7421      /* density code */
7422      RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
7423      /* number of blocks */
7424      RWErrorRecovery[9]   = 0x00; /* unspecified */
7425      RWErrorRecovery[10]  = 0x00; /* unspecified */
7426      RWErrorRecovery[11]  = 0x00; /* unspecified */
7427      RWErrorRecovery[12]  = 0x00; /* unspecified */
7428      RWErrorRecovery[13]  = 0x00; /* unspecified */
7429      RWErrorRecovery[14]  = 0x00; /* unspecified */
7430      RWErrorRecovery[15]  = 0x00; /* unspecified */
7431      /* reserved */
7432      RWErrorRecovery[16]  = 0x00; /* reserved */
7433      RWErrorRecovery[17]  = 0x00; /* reserved */
7434      RWErrorRecovery[18]  = 0x00; /* reserved */
7435      RWErrorRecovery[19]  = 0x00; /* reserved */
7436      /* Block size */
7437      RWErrorRecovery[20]  = 0x00;
7438      RWErrorRecovery[21]  = 0x00;
7439      RWErrorRecovery[22]  = 0x02;   /* Block size is always 512 bytes */
7440      RWErrorRecovery[23]  = 0x00;
7441    }
7442    else
7443    {
7444      /* density code */
7445      RWErrorRecovery[8]   = 0x04; /* density-code : reserved for direct-access */
7446      /* number of blocks */
7447      RWErrorRecovery[9]   = 0x00; /* unspecified */
7448      RWErrorRecovery[10]  = 0x00; /* unspecified */
7449      RWErrorRecovery[11]  = 0x00; /* unspecified */
7450      /* reserved */
7451      RWErrorRecovery[12]  = 0x00; /* reserved */
7452      /* Block size */
7453      RWErrorRecovery[13]  = 0x00;
7454      RWErrorRecovery[14]  = 0x02;   /* Block size is always 512 bytes */
7455      RWErrorRecovery[15]  = 0x00;
7456    }
7457
7458    if (LLBAA)
7459    {
7460      index = 24;
7461    }
7462    else
7463    {
7464      index = 16;
7465    }
7466    /*
7467     * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
7468     */
7469    RWErrorRecovery[index+0] = 0x01; /* page code */
7470    RWErrorRecovery[index+1] = 0x0A; /* page length */
7471    RWErrorRecovery[index+2] = 0x40; /* ARRE is set */
7472    RWErrorRecovery[index+3] = 0x00;
7473    RWErrorRecovery[index+4] = 0x00;
7474    RWErrorRecovery[index+5] = 0x00;
7475    RWErrorRecovery[index+6] = 0x00;
7476    RWErrorRecovery[index+7] = 0x00;
7477    RWErrorRecovery[index+8] = 0x00;
7478    RWErrorRecovery[index+9] = 0x00;
7479    RWErrorRecovery[index+10] = 0x00;
7480    RWErrorRecovery[index+11] = 0x00;
7481
7482    osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
7483  }
7484  else if (page == MODESENSE_CACHING)
7485  {
7486    TI_DBG5(("satModeSense10: MODESENSE_CACHING\n"));
7487    Caching[0] = 0;
7488    Caching[1] = (bit8)(lenRead - 2);
7489    Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7490    Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7491    if (LLBAA)
7492    {
7493      Caching[4] = 0x00; /* reserved and LONGLBA */
7494      Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */
7495    }
7496    else
7497    {
7498      Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7499    }
7500    Caching[5] = 0x00; /* reserved */
7501    Caching[6] = 0x00; /* block descriptot length */
7502    if (LLBAA)
7503    {
7504      Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7505    }
7506    else
7507    {
7508      Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7509    }
7510
7511    /*
7512     * Fill-up direct-access device block-descriptor, SAT, Table 19
7513     */
7514
7515    if (LLBAA)
7516    {
7517      /* density code */
7518      Caching[8]   = 0x04; /* density-code : reserved for direct-access */
7519      /* number of blocks */
7520      Caching[9]   = 0x00; /* unspecified */
7521      Caching[10]  = 0x00; /* unspecified */
7522      Caching[11]  = 0x00; /* unspecified */
7523      Caching[12]  = 0x00; /* unspecified */
7524      Caching[13]  = 0x00; /* unspecified */
7525      Caching[14]  = 0x00; /* unspecified */
7526      Caching[15]  = 0x00; /* unspecified */
7527      /* reserved */
7528      Caching[16]  = 0x00; /* reserved */
7529      Caching[17]  = 0x00; /* reserved */
7530      Caching[18]  = 0x00; /* reserved */
7531      Caching[19]  = 0x00; /* reserved */
7532      /* Block size */
7533      Caching[20]  = 0x00;
7534      Caching[21]  = 0x00;
7535      Caching[22]  = 0x02;   /* Block size is always 512 bytes */
7536      Caching[23]  = 0x00;
7537    }
7538    else
7539    {
7540      /* density code */
7541      Caching[8]   = 0x04; /* density-code : reserved for direct-access */
7542      /* number of blocks */
7543      Caching[9]   = 0x00; /* unspecified */
7544      Caching[10]  = 0x00; /* unspecified */
7545      Caching[11]  = 0x00; /* unspecified */
7546      /* reserved */
7547      Caching[12]  = 0x00; /* reserved */
7548      /* Block size */
7549      Caching[13]  = 0x00;
7550      Caching[14]  = 0x02;   /* Block size is always 512 bytes */
7551      Caching[15]  = 0x00;
7552    }
7553
7554    if (LLBAA)
7555    {
7556      index = 24;
7557    }
7558    else
7559    {
7560      index = 16;
7561    }
7562    /*
7563     * Fill-up Caching mode page, SAT, Table 67
7564     */
7565    /* length 20 */
7566    Caching[index+0] = 0x08; /* page code */
7567    Caching[index+1] = 0x12; /* page length */
7568#ifdef NOT_YET
7569    if (pSatDevData->satWriteCacheEnabled == agTRUE)
7570    {
7571      Caching[index+2] = 0x04;/* WCE bit is set */
7572    }
7573    else
7574    {
7575      Caching[index+2] = 0x00;/* WCE bit is NOT set */
7576    }
7577#endif
7578    Caching[index+2] = 0x00;/* WCE bit is NOT set */
7579    Caching[index+3] = 0x00;
7580    Caching[index+4] = 0x00;
7581    Caching[index+5] = 0x00;
7582    Caching[index+6] = 0x00;
7583    Caching[index+7] = 0x00;
7584    Caching[index+8] = 0x00;
7585    Caching[index+9] = 0x00;
7586    Caching[index+10] = 0x00;
7587    Caching[index+11] = 0x00;
7588    if (pSatDevData->satLookAheadEnabled == agTRUE)
7589    {
7590      Caching[index+12] = 0x00;/* DRA bit is NOT set */
7591    }
7592    else
7593    {
7594      Caching[index+12] = 0x20;/* DRA bit is set */
7595    }
7596    Caching[index+13] = 0x00;
7597    Caching[index+14] = 0x00;
7598    Caching[index+15] = 0x00;
7599    Caching[index+16] = 0x00;
7600    Caching[index+17] = 0x00;
7601    Caching[index+18] = 0x00;
7602    Caching[index+19] = 0x00;
7603    osti_memcpy(pModeSense, &Caching, lenRead);
7604
7605  }
7606  else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
7607  {
7608    TI_DBG5(("satModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
7609    InfoExceptionCtrl[0] = 0;
7610    InfoExceptionCtrl[1] = (bit8)(lenRead - 2);
7611    InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7612    InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7613    if (LLBAA)
7614    {
7615      InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */
7616      InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */
7617    }
7618    else
7619    {
7620      InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7621    }
7622    InfoExceptionCtrl[5] = 0x00; /* reserved */
7623    InfoExceptionCtrl[6] = 0x00; /* block descriptot length */
7624    if (LLBAA)
7625    {
7626      InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7627    }
7628    else
7629    {
7630      InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7631    }
7632
7633    /*
7634     * Fill-up direct-access device block-descriptor, SAT, Table 19
7635     */
7636
7637    if (LLBAA)
7638    {
7639      /* density code */
7640      InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
7641      /* number of blocks */
7642      InfoExceptionCtrl[9]   = 0x00; /* unspecified */
7643      InfoExceptionCtrl[10]  = 0x00; /* unspecified */
7644      InfoExceptionCtrl[11]  = 0x00; /* unspecified */
7645      InfoExceptionCtrl[12]  = 0x00; /* unspecified */
7646      InfoExceptionCtrl[13]  = 0x00; /* unspecified */
7647      InfoExceptionCtrl[14]  = 0x00; /* unspecified */
7648      InfoExceptionCtrl[15]  = 0x00; /* unspecified */
7649      /* reserved */
7650      InfoExceptionCtrl[16]  = 0x00; /* reserved */
7651      InfoExceptionCtrl[17]  = 0x00; /* reserved */
7652      InfoExceptionCtrl[18]  = 0x00; /* reserved */
7653      InfoExceptionCtrl[19]  = 0x00; /* reserved */
7654      /* Block size */
7655      InfoExceptionCtrl[20]  = 0x00;
7656      InfoExceptionCtrl[21]  = 0x00;
7657      InfoExceptionCtrl[22]  = 0x02;   /* Block size is always 512 bytes */
7658      InfoExceptionCtrl[23]  = 0x00;
7659    }
7660    else
7661    {
7662      /* density code */
7663      InfoExceptionCtrl[8]   = 0x04; /* density-code : reserved for direct-access */
7664      /* number of blocks */
7665      InfoExceptionCtrl[9]   = 0x00; /* unspecified */
7666      InfoExceptionCtrl[10]  = 0x00; /* unspecified */
7667      InfoExceptionCtrl[11]  = 0x00; /* unspecified */
7668      /* reserved */
7669      InfoExceptionCtrl[12]  = 0x00; /* reserved */
7670      /* Block size */
7671      InfoExceptionCtrl[13]  = 0x00;
7672      InfoExceptionCtrl[14]  = 0x02;   /* Block size is always 512 bytes */
7673      InfoExceptionCtrl[15]  = 0x00;
7674    }
7675
7676    if (LLBAA)
7677    {
7678      index = 24;
7679    }
7680    else
7681    {
7682      index = 16;
7683    }
7684    /*
7685     * Fill-up informational-exceptions control mode page, SAT, Table 68
7686     */
7687    InfoExceptionCtrl[index+0] = 0x1C; /* page code */
7688    InfoExceptionCtrl[index+1] = 0x0A; /* page length */
7689     if (pSatDevData->satSMARTEnabled == agTRUE)
7690    {
7691      InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */
7692    }
7693    else
7694    {
7695      InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */
7696    }
7697    InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */
7698    InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */
7699    InfoExceptionCtrl[index+5] = 0x00;
7700    InfoExceptionCtrl[index+6] = 0x00;
7701    InfoExceptionCtrl[index+7] = 0x00;
7702    InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */
7703    InfoExceptionCtrl[index+9] = 0x00;
7704    InfoExceptionCtrl[index+10] = 0x00;
7705    InfoExceptionCtrl[index+11] = 0x00;
7706    osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
7707
7708  }
7709  else
7710  {
7711    /* Error */
7712    TI_DBG1(("satModeSense10: Error page %d\n", page));
7713    satSetSensePayload( pSense,
7714                        SCSI_SNSKEY_ILLEGAL_REQUEST,
7715                        0,
7716                        SCSI_SNSCODE_INVALID_COMMAND,
7717                        satIOContext);
7718
7719    ostiInitiatorIOCompleted( tiRoot,
7720                              tiIORequest,
7721                              tiIOSuccess,
7722                              SCSI_STAT_CHECK_CONDITION,
7723                              satIOContext->pTiSenseData,
7724                              satIOContext->interruptContext );
7725    return tiSuccess;
7726  }
7727
7728  if (requestLen > lenRead)
7729  {
7730    TI_DBG1(("satModeSense10 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
7731
7732    ostiInitiatorIOCompleted( tiRoot,
7733                              tiIORequest,
7734                              tiIOUnderRun,
7735                              requestLen - lenRead,
7736                              agNULL,
7737                              satIOContext->interruptContext );
7738
7739
7740  }
7741  else
7742  {
7743    ostiInitiatorIOCompleted( tiRoot,
7744                              tiIORequest,
7745                              tiIOSuccess,
7746                              SCSI_STAT_GOOD,
7747                              agNULL,
7748                              satIOContext->interruptContext);
7749  }
7750
7751  return tiSuccess;
7752}
7753
7754
7755/*****************************************************************************/
7756/*! \brief SAT implementation for SCSI VERIFY (10).
7757 *
7758 *  SAT implementation for SCSI VERIFY (10).
7759 *
7760 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
7761 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
7762 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
7763 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
7764 *  \param   satIOContext_t:   Pointer to the SAT IO Context
7765 *
7766 *  \return If command is started successfully
7767 *    - \e tiSuccess:     I/O request successfully initiated.
7768 *    - \e tiBusy:        No resources available, try again later.
7769 *    - \e tiIONoDevice:  Invalid device handle.
7770 *    - \e tiError:       Other errors.
7771 */
7772/*****************************************************************************/
7773GLOBAL bit32  satVerify10(
7774                   tiRoot_t                  *tiRoot,
7775                   tiIORequest_t             *tiIORequest,
7776                   tiDeviceHandle_t          *tiDeviceHandle,
7777                   tiScsiInitiatorRequest_t *tiScsiRequest,
7778                   satIOContext_t            *satIOContext)
7779{
7780  /*
7781    For simple implementation,
7782    no byte comparison supported as of 4/5/06
7783  */
7784  scsiRspSense_t            *pSense;
7785  tiIniScsiCmnd_t           *scsiCmnd;
7786  satDeviceData_t           *pSatDevData;
7787  agsaFisRegHostToDevice_t  *fis;
7788  bit32                     status;
7789  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7790  bit32                     lba = 0;
7791  bit32                     tl = 0;
7792  bit32                     LoopNum = 1;
7793  bit8                      LBA[4];
7794  bit8                      TL[4];
7795  bit32                     rangeChk = agFALSE; /* lba and tl range check */
7796
7797
7798  TI_DBG5(("satVerify10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
7799      tiDeviceHandle, tiIORequest));
7800
7801  pSense            = satIOContext->pSense;
7802  scsiCmnd          = &tiScsiRequest->scsiCmnd;
7803  pSatDevData       = satIOContext->pSatDevData;
7804  fis               = satIOContext->pFis;
7805
7806  /* checking BYTCHK */
7807  if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
7808  {
7809    /*
7810      should do the byte check
7811      but not supported in this version
7812     */
7813    satSetSensePayload( pSense,
7814                        SCSI_SNSKEY_ILLEGAL_REQUEST,
7815                        0,
7816                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7817                        satIOContext);
7818
7819    ostiInitiatorIOCompleted( tiRoot,
7820                              tiIORequest,
7821                              tiIOSuccess,
7822                              SCSI_STAT_CHECK_CONDITION,
7823                              satIOContext->pTiSenseData,
7824                              satIOContext->interruptContext );
7825
7826    TI_DBG1(("satVerify10: no byte checking \n"));
7827    return tiSuccess;
7828  }
7829
7830  /* checking CONTROL */
7831  /* NACA == 1 or LINK == 1*/
7832  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
7833  {
7834    satSetSensePayload( pSense,
7835                        SCSI_SNSKEY_ILLEGAL_REQUEST,
7836                        0,
7837                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7838                        satIOContext);
7839
7840    ostiInitiatorIOCompleted( tiRoot,
7841                              tiIORequest,
7842                              tiIOSuccess,
7843                              SCSI_STAT_CHECK_CONDITION,
7844                              satIOContext->pTiSenseData,
7845                              satIOContext->interruptContext );
7846
7847    TI_DBG2(("satVerify10: return control\n"));
7848    return tiSuccess;
7849  }
7850
7851  osti_memset(LBA, 0, sizeof(LBA));
7852  osti_memset(TL, 0, sizeof(TL));
7853
7854  /* do not use memcpy due to indexing in LBA and TL */
7855  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
7856  LBA[1] = scsiCmnd->cdb[3];
7857  LBA[2] = scsiCmnd->cdb[4];
7858  LBA[3] = scsiCmnd->cdb[5];  /* LSB */
7859
7860  TL[0] = 0;
7861  TL[1] = 0;
7862  TL[2] = scsiCmnd->cdb[7];  /* MSB */
7863  TL[3] = scsiCmnd->cdb[8];  /* LSB */
7864
7865  rangeChk = satAddNComparebit32(LBA, TL);
7866
7867  /* cbd10; computing LBA and transfer length */
7868  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
7869    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
7870  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7871
7872  if (pSatDevData->satNCQ != agTRUE &&
7873      pSatDevData->sat48BitSupport != agTRUE
7874      )
7875  {
7876    if (lba > SAT_TR_LBA_LIMIT - 1)
7877    {
7878      satSetSensePayload( pSense,
7879                          SCSI_SNSKEY_ILLEGAL_REQUEST,
7880                          0,
7881                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7882                          satIOContext);
7883
7884      ostiInitiatorIOCompleted( tiRoot,
7885                                tiIORequest,
7886                                tiIOSuccess,
7887                                SCSI_STAT_CHECK_CONDITION,
7888                                satIOContext->pTiSenseData,
7889                                satIOContext->interruptContext );
7890
7891    TI_DBG1(("satVerify10: return LBA out of range, not EXT\n"));
7892    TI_DBG1(("satVerify10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
7893             scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
7894    TI_DBG1(("satVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
7895    return tiSuccess;
7896    }
7897
7898    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
7899    {
7900      TI_DBG1(("satVerify10: return LBA+TL out of range, not EXT\n"));
7901      satSetSensePayload( pSense,
7902                          SCSI_SNSKEY_ILLEGAL_REQUEST,
7903                          0,
7904                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7905                          satIOContext);
7906
7907      ostiInitiatorIOCompleted( tiRoot,
7908                                tiIORequest,
7909                                tiIOSuccess,
7910                                SCSI_STAT_CHECK_CONDITION,
7911                                satIOContext->pTiSenseData,
7912                                satIOContext->interruptContext );
7913
7914    return tiSuccess;
7915    }
7916  }
7917
7918  if (pSatDevData->sat48BitSupport == agTRUE)
7919  {
7920    TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS_EXT\n"));
7921    fis->h.fisType        = 0x27;                   /* Reg host to device */
7922    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
7923
7924    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
7925    fis->h.features       = 0;                      /* FIS reserve */
7926    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7927    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7928    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7929    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
7930    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
7931    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
7932    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
7933    fis->d.featuresExp    = 0;                      /* FIS reserve */
7934    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7935    fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
7936
7937    fis->d.reserved4      = 0;
7938    fis->d.control        = 0;                      /* FIS HOB bit clear */
7939    fis->d.reserved5      = 0;
7940
7941    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7942    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
7943  }
7944  else
7945  {
7946    TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS\n"));
7947    fis->h.fisType        = 0x27;                   /* Reg host to device */
7948    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
7949    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
7950    fis->h.features       = 0;                      /* FIS reserve */
7951    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
7952    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
7953    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
7954      /* FIS LBA mode set LBA (27:24) */
7955    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7956    fis->d.lbaLowExp      = 0;
7957    fis->d.lbaMidExp      = 0;
7958    fis->d.lbaHighExp     = 0;
7959    fis->d.featuresExp    = 0;
7960    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
7961    fis->d.sectorCountExp = 0;
7962    fis->d.reserved4      = 0;
7963    fis->d.control        = 0;                      /* FIS HOB bit clear */
7964    fis->d.reserved5      = 0;
7965
7966    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7967    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
7968
7969 }
7970
7971  satIOContext->currentLBA = lba;
7972  satIOContext->OrgTL = tl;
7973
7974  /*
7975    computing number of loop and remainder for tl
7976    0xFF in case not ext
7977    0xFFFF in case EXT
7978  */
7979  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7980  {
7981    LoopNum = satComputeLoopNum(tl, 0xFF);
7982  }
7983  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
7984  {
7985    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7986    LoopNum = satComputeLoopNum(tl, 0xFFFF);
7987  }
7988  else
7989  {
7990    TI_DBG1(("satVerify10: error case 1!!!\n"));
7991    LoopNum = 1;
7992  }
7993
7994  satIOContext->LoopNum = LoopNum;
7995
7996  if (LoopNum == 1)
7997  {
7998    TI_DBG5(("satVerify10: NON CHAINED data\n"));
7999    /* Initialize CB for SATA completion.
8000     */
8001    satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8002  }
8003  else
8004  {
8005    TI_DBG1(("satVerify10: CHAINED data\n"));
8006    /* re-setting tl */
8007    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8008    {
8009       fis->d.sectorCount    = 0xFF;
8010    }
8011    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8012    {
8013      fis->d.sectorCount    = 0xFF;
8014      fis->d.sectorCountExp = 0xFF;
8015    }
8016    else
8017    {
8018      TI_DBG1(("satVerify10: error case 2!!!\n"));
8019    }
8020
8021    /* Initialize CB for SATA completion.
8022     */
8023    satIOContext->satCompleteCB = &satChainedVerifyCB;
8024  }
8025
8026
8027  /*
8028   * Prepare SGL and send FIS to LL layer.
8029   */
8030  satIOContext->reqType = agRequestType;       /* Save it */
8031
8032  status = sataLLIOStart( tiRoot,
8033                          tiIORequest,
8034                          tiDeviceHandle,
8035                          tiScsiRequest,
8036                          satIOContext);
8037  return (status);
8038}
8039
8040GLOBAL bit32  satChainedVerify(
8041                   tiRoot_t                  *tiRoot,
8042                   tiIORequest_t             *tiIORequest,
8043                   tiDeviceHandle_t          *tiDeviceHandle,
8044                   tiScsiInitiatorRequest_t *tiScsiRequest,
8045                   satIOContext_t            *satIOContext)
8046{
8047  bit32                     status;
8048  satIOContext_t            *satOrgIOContext = agNULL;
8049  agsaFisRegHostToDevice_t  *fis;
8050  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8051  bit32                     lba = 0;
8052  bit32                     DenomTL = 0xFF;
8053  bit32                     Remainder = 0;
8054  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
8055
8056  TI_DBG2(("satChainedVerify: start\n"));
8057
8058  fis             = satIOContext->pFis;
8059  satOrgIOContext = satIOContext->satOrgIOContext;
8060  osti_memset(LBA,0, sizeof(LBA));
8061
8062  switch (satOrgIOContext->ATACmd)
8063  {
8064  case SAT_READ_VERIFY_SECTORS:
8065    DenomTL = 0xFF;
8066    break;
8067  case SAT_READ_VERIFY_SECTORS_EXT:
8068    DenomTL = 0xFFFF;
8069    break;
8070  default:
8071    TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8072    return tiError;
8073    break;
8074  }
8075
8076  Remainder = satOrgIOContext->OrgTL % DenomTL;
8077  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
8078  lba = satOrgIOContext->currentLBA;
8079
8080  LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
8081  LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
8082  LBA[2] = (bit8)((lba & 0xF0) >> 8);
8083  LBA[3] = (bit8)(lba & 0xF);               /* LSB */
8084
8085  switch (satOrgIOContext->ATACmd)
8086  {
8087  case SAT_READ_VERIFY_SECTORS:
8088    fis->h.fisType        = 0x27;                   /* Reg host to device */
8089    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8090    fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
8091    fis->h.features       = 0;                      /* FIS reserve */
8092    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
8093    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
8094    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
8095
8096    /* FIS LBA mode set LBA (27:24) */
8097    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
8098
8099    fis->d.lbaLowExp      = 0;
8100    fis->d.lbaMidExp      = 0;
8101    fis->d.lbaHighExp     = 0;
8102    fis->d.featuresExp    = 0;
8103    if (satOrgIOContext->LoopNum == 1)
8104    {
8105      /* last loop */
8106      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
8107    }
8108    else
8109    {
8110      fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
8111    }
8112    fis->d.sectorCountExp = 0;
8113    fis->d.reserved4      = 0;
8114    fis->d.control        = 0;                      /* FIS HOB bit clear */
8115    fis->d.reserved5      = 0;
8116
8117    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8118
8119    break;
8120  case SAT_READ_VERIFY_SECTORS_EXT:
8121    fis->h.fisType        = 0x27;                   /* Reg host to device */
8122    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8123    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
8124    fis->h.features       = 0;                      /* FIS reserve */
8125    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
8126    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
8127    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
8128    fis->d.device         = 0x40;                   /* FIS LBA mode set */
8129    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
8130    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
8131    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
8132    fis->d.featuresExp    = 0;                      /* FIS reserve */
8133    if (satOrgIOContext->LoopNum == 1)
8134    {
8135      /* last loop */
8136      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
8137      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
8138    }
8139    else
8140    {
8141      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
8142      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
8143    }
8144    fis->d.reserved4      = 0;
8145    fis->d.control        = 0;                       /* FIS HOB bit clear */
8146    fis->d.reserved5      = 0;
8147
8148    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8149
8150    break;
8151
8152  default:
8153    TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8154    return tiError;
8155    break;
8156  }
8157
8158  /* Initialize CB for SATA completion.
8159   */
8160  /* chained data */
8161  satIOContext->satCompleteCB = &satChainedVerifyCB;
8162
8163
8164  /*
8165   * Prepare SGL and send FIS to LL layer.
8166   */
8167  satIOContext->reqType = agRequestType;       /* Save it */
8168
8169  status = sataLLIOStart( tiRoot,
8170                          tiIORequest,
8171                          tiDeviceHandle,
8172                          tiScsiRequest,
8173                          satIOContext);
8174
8175  TI_DBG5(("satChainedVerify: return\n"));
8176  return (status);
8177
8178}
8179
8180
8181/*****************************************************************************/
8182/*! \brief SAT implementation for SCSI VERIFY (12).
8183 *
8184 *  SAT implementation for SCSI VERIFY (12).
8185 *
8186 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8187 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8188 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8189 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8190 *  \param   satIOContext_t:   Pointer to the SAT IO Context
8191 *
8192 *  \return If command is started successfully
8193 *    - \e tiSuccess:     I/O request successfully initiated.
8194 *    - \e tiBusy:        No resources available, try again later.
8195 *    - \e tiIONoDevice:  Invalid device handle.
8196 *    - \e tiError:       Other errors.
8197 */
8198/*****************************************************************************/
8199GLOBAL bit32  satVerify12(
8200                   tiRoot_t                  *tiRoot,
8201                   tiIORequest_t             *tiIORequest,
8202                   tiDeviceHandle_t          *tiDeviceHandle,
8203                   tiScsiInitiatorRequest_t *tiScsiRequest,
8204                   satIOContext_t            *satIOContext)
8205{
8206  /*
8207    For simple implementation,
8208    no byte comparison supported as of 4/5/06
8209  */
8210  scsiRspSense_t            *pSense;
8211  tiIniScsiCmnd_t           *scsiCmnd;
8212  satDeviceData_t           *pSatDevData;
8213  agsaFisRegHostToDevice_t  *fis;
8214  bit32                     status;
8215  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8216  bit32                     lba = 0;
8217  bit32                     tl = 0;
8218  bit32                     LoopNum = 1;
8219  bit8                      LBA[4];
8220  bit8                      TL[4];
8221  bit32                     rangeChk = agFALSE; /* lba and tl range check */
8222
8223  TI_DBG5(("satVerify12 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8224           tiDeviceHandle, tiIORequest));
8225
8226  pSense            = satIOContext->pSense;
8227  scsiCmnd          = &tiScsiRequest->scsiCmnd;
8228  pSatDevData       = satIOContext->pSatDevData;
8229  fis               = satIOContext->pFis;
8230
8231
8232  /* checking BYTCHK */
8233  if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8234  {
8235    /*
8236      should do the byte check
8237      but not supported in this version
8238     */
8239    satSetSensePayload( pSense,
8240                        SCSI_SNSKEY_ILLEGAL_REQUEST,
8241                        0,
8242                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8243                        satIOContext);
8244
8245    ostiInitiatorIOCompleted( tiRoot,
8246                              tiIORequest,
8247                              tiIOSuccess,
8248                              SCSI_STAT_CHECK_CONDITION,
8249                              satIOContext->pTiSenseData,
8250                              satIOContext->interruptContext );
8251
8252    TI_DBG1(("satVerify12: no byte checking \n"));
8253    return tiSuccess;
8254  }
8255
8256  /* checking CONTROL */
8257  /* NACA == 1 or LINK == 1*/
8258  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
8259  {
8260    satSetSensePayload( pSense,
8261                        SCSI_SNSKEY_ILLEGAL_REQUEST,
8262                        0,
8263                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8264                        satIOContext);
8265
8266    ostiInitiatorIOCompleted( tiRoot,
8267                              tiIORequest,
8268                              tiIOSuccess,
8269                              SCSI_STAT_CHECK_CONDITION,
8270                              satIOContext->pTiSenseData,
8271                              satIOContext->interruptContext );
8272
8273    TI_DBG1(("satVerify12: return control\n"));
8274    return tiSuccess;
8275  }
8276
8277  osti_memset(LBA, 0, sizeof(LBA));
8278  osti_memset(TL, 0, sizeof(TL));
8279
8280  /* do not use memcpy due to indexing in LBA and TL */
8281  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
8282  LBA[1] = scsiCmnd->cdb[3];
8283  LBA[2] = scsiCmnd->cdb[4];
8284  LBA[3] = scsiCmnd->cdb[5];  /* LSB */
8285
8286  TL[0] = scsiCmnd->cdb[6];   /* MSB */
8287  TL[1] = scsiCmnd->cdb[7];
8288  TL[2] = scsiCmnd->cdb[7];
8289  TL[3] = scsiCmnd->cdb[8];   /* LSB */
8290
8291  rangeChk = satAddNComparebit32(LBA, TL);
8292
8293  lba = satComputeCDB12LBA(satIOContext);
8294  tl = satComputeCDB12TL(satIOContext);
8295
8296  if (pSatDevData->satNCQ != agTRUE &&
8297      pSatDevData->sat48BitSupport != agTRUE
8298      )
8299  {
8300    if (lba > SAT_TR_LBA_LIMIT - 1)
8301    {
8302      satSetSensePayload( pSense,
8303                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8304                          0,
8305                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8306                          satIOContext);
8307
8308      ostiInitiatorIOCompleted( tiRoot,
8309                                tiIORequest,
8310                                tiIOSuccess,
8311                                SCSI_STAT_CHECK_CONDITION,
8312                                satIOContext->pTiSenseData,
8313                                satIOContext->interruptContext );
8314
8315    TI_DBG1(("satVerify12: return LBA out of range, not EXT\n"));
8316    TI_DBG1(("satVerify12: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
8317             scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
8318    TI_DBG1(("satVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
8319    return tiSuccess;
8320    }
8321
8322    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
8323    {
8324      TI_DBG1(("satVerify12: return LBA+TL out of range, not EXT\n"));
8325      satSetSensePayload( pSense,
8326                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8327                          0,
8328                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8329                          satIOContext);
8330
8331      ostiInitiatorIOCompleted( tiRoot,
8332                                tiIORequest,
8333                                tiIOSuccess,
8334                                SCSI_STAT_CHECK_CONDITION,
8335                                satIOContext->pTiSenseData,
8336                                satIOContext->interruptContext );
8337
8338    return tiSuccess;
8339    }
8340  }
8341
8342  if (pSatDevData->sat48BitSupport == agTRUE)
8343  {
8344    TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS_EXT\n"));
8345    fis->h.fisType        = 0x27;                   /* Reg host to device */
8346    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8347
8348    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8349    fis->h.features       = 0;                      /* FIS reserve */
8350    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8351    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8352    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8353    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8354    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
8355    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
8356    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
8357    fis->d.featuresExp    = 0;                      /* FIS reserve */
8358    fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8359    fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
8360
8361    fis->d.reserved4      = 0;
8362    fis->d.control        = 0;                      /* FIS HOB bit clear */
8363    fis->d.reserved5      = 0;
8364
8365    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8366    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8367  }
8368  else
8369  {
8370    TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8371    fis->h.fisType        = 0x27;                   /* Reg host to device */
8372    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8373    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8374    fis->h.features       = 0;                      /* FIS reserve */
8375    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
8376    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
8377    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
8378      /* FIS LBA mode set LBA (27:24) */
8379    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
8380    fis->d.lbaLowExp      = 0;
8381    fis->d.lbaMidExp      = 0;
8382    fis->d.lbaHighExp     = 0;
8383    fis->d.featuresExp    = 0;
8384    fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
8385    fis->d.sectorCountExp = 0;
8386    fis->d.reserved4      = 0;
8387    fis->d.control        = 0;                      /* FIS HOB bit clear */
8388    fis->d.reserved5      = 0;
8389
8390    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8391    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8392
8393 }
8394
8395  satIOContext->currentLBA = lba;
8396  satIOContext->OrgTL = tl;
8397
8398  /*
8399    computing number of loop and remainder for tl
8400    0xFF in case not ext
8401    0xFFFF in case EXT
8402  */
8403  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8404  {
8405    LoopNum = satComputeLoopNum(tl, 0xFF);
8406  }
8407  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8408  {
8409    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8410    LoopNum = satComputeLoopNum(tl, 0xFFFF);
8411  }
8412  else
8413  {
8414    TI_DBG1(("satVerify12: error case 1!!!\n"));
8415    LoopNum = 1;
8416  }
8417
8418  satIOContext->LoopNum = LoopNum;
8419
8420  if (LoopNum == 1)
8421  {
8422    TI_DBG5(("satVerify12: NON CHAINED data\n"));
8423    /* Initialize CB for SATA completion.
8424     */
8425    satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8426  }
8427  else
8428  {
8429    TI_DBG1(("satVerify12: CHAINED data\n"));
8430    /* re-setting tl */
8431    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8432    {
8433       fis->d.sectorCount    = 0xFF;
8434    }
8435    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8436    {
8437      fis->d.sectorCount    = 0xFF;
8438      fis->d.sectorCountExp = 0xFF;
8439    }
8440    else
8441    {
8442      TI_DBG1(("satVerify10: error case 2!!!\n"));
8443    }
8444
8445    /* Initialize CB for SATA completion.
8446     */
8447    satIOContext->satCompleteCB = &satChainedVerifyCB;
8448  }
8449
8450
8451  /*
8452   * Prepare SGL and send FIS to LL layer.
8453   */
8454  satIOContext->reqType = agRequestType;       /* Save it */
8455
8456  status = sataLLIOStart( tiRoot,
8457                          tiIORequest,
8458                          tiDeviceHandle,
8459                          tiScsiRequest,
8460                          satIOContext);
8461  return (status);
8462}
8463/*****************************************************************************/
8464/*! \brief SAT implementation for SCSI VERIFY (16).
8465 *
8466 *  SAT implementation for SCSI VERIFY (16).
8467 *
8468 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8469 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8470 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8471 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8472 *  \param   satIOContext_t:   Pointer to the SAT IO Context
8473 *
8474 *  \return If command is started successfully
8475 *    - \e tiSuccess:     I/O request successfully initiated.
8476 *    - \e tiBusy:        No resources available, try again later.
8477 *    - \e tiIONoDevice:  Invalid device handle.
8478 *    - \e tiError:       Other errors.
8479 */
8480/*****************************************************************************/
8481GLOBAL bit32  satVerify16(
8482                   tiRoot_t                  *tiRoot,
8483                   tiIORequest_t             *tiIORequest,
8484                   tiDeviceHandle_t          *tiDeviceHandle,
8485                   tiScsiInitiatorRequest_t *tiScsiRequest,
8486                   satIOContext_t            *satIOContext)
8487{
8488  /*
8489    For simple implementation,
8490    no byte comparison supported as of 4/5/06
8491  */
8492  scsiRspSense_t            *pSense;
8493  tiIniScsiCmnd_t           *scsiCmnd;
8494  satDeviceData_t           *pSatDevData;
8495  agsaFisRegHostToDevice_t  *fis;
8496  bit32                     status;
8497  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8498  bit32                     lba = 0;
8499  bit32                     tl = 0;
8500  bit32                     LoopNum = 1;
8501  bit8                      LBA[8];
8502  bit8                      TL[8];
8503  bit32                     rangeChk = agFALSE; /* lba and tl range check */
8504  bit32                     limitChk = agFALSE; /* lba and tl range check */
8505
8506  TI_DBG5(("satVerify16 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8507      tiDeviceHandle, tiIORequest));
8508
8509  pSense            = satIOContext->pSense;
8510  scsiCmnd          = &tiScsiRequest->scsiCmnd;
8511  pSatDevData       = satIOContext->pSatDevData;
8512  fis               = satIOContext->pFis;
8513
8514  /* checking BYTCHK */
8515  if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8516  {
8517    /*
8518      should do the byte check
8519      but not supported in this version
8520     */
8521    satSetSensePayload( pSense,
8522                        SCSI_SNSKEY_ILLEGAL_REQUEST,
8523                        0,
8524                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8525                        satIOContext);
8526
8527    ostiInitiatorIOCompleted( tiRoot,
8528                              tiIORequest,
8529                              tiIOSuccess,
8530                              SCSI_STAT_CHECK_CONDITION,
8531                              satIOContext->pTiSenseData,
8532                              satIOContext->interruptContext );
8533
8534    TI_DBG1(("satVerify16: no byte checking \n"));
8535    return tiSuccess;
8536  }
8537
8538  /* checking CONTROL */
8539  /* NACA == 1 or LINK == 1*/
8540  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
8541  {
8542    satSetSensePayload( pSense,
8543                        SCSI_SNSKEY_ILLEGAL_REQUEST,
8544                        0,
8545                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8546                        satIOContext);
8547
8548    ostiInitiatorIOCompleted( tiRoot,
8549                              tiIORequest,
8550                              tiIOSuccess,
8551                              SCSI_STAT_CHECK_CONDITION,
8552                              satIOContext->pTiSenseData,
8553                              satIOContext->interruptContext );
8554
8555    TI_DBG2(("satVerify16: return control\n"));
8556    return tiSuccess;
8557  }
8558
8559  osti_memset(LBA, 0, sizeof(LBA));
8560  osti_memset(TL, 0, sizeof(TL));
8561
8562
8563  /* do not use memcpy due to indexing in LBA and TL */
8564  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
8565  LBA[1] = scsiCmnd->cdb[3];
8566  LBA[2] = scsiCmnd->cdb[4];
8567  LBA[3] = scsiCmnd->cdb[5];
8568  LBA[4] = scsiCmnd->cdb[6];
8569  LBA[5] = scsiCmnd->cdb[7];
8570  LBA[6] = scsiCmnd->cdb[8];
8571  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
8572
8573  TL[0] = 0;
8574  TL[1] = 0;
8575  TL[2] = 0;
8576  TL[3] = 0;
8577  TL[4] = scsiCmnd->cdb[10];   /* MSB */
8578  TL[5] = scsiCmnd->cdb[11];
8579  TL[6] = scsiCmnd->cdb[12];
8580  TL[7] = scsiCmnd->cdb[13];   /* LSB */
8581
8582  rangeChk = satAddNComparebit64(LBA, TL);
8583
8584  limitChk = satCompareLBALimitbit(LBA);
8585
8586  lba = satComputeCDB16LBA(satIOContext);
8587  tl = satComputeCDB16TL(satIOContext);
8588
8589  if (pSatDevData->satNCQ != agTRUE &&
8590     pSatDevData->sat48BitSupport != agTRUE
8591     )
8592  {
8593    if (limitChk)
8594    {
8595      TI_DBG1(("satVerify16: return LBA out of range, not EXT\n"));
8596      satSetSensePayload( pSense,
8597                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8598                          0,
8599                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8600                          satIOContext);
8601
8602      ostiInitiatorIOCompleted( tiRoot,
8603                                tiIORequest,
8604                                tiIOSuccess,
8605                                SCSI_STAT_CHECK_CONDITION,
8606                                satIOContext->pTiSenseData,
8607                                satIOContext->interruptContext );
8608
8609    return tiSuccess;
8610    }
8611    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
8612    {
8613      TI_DBG1(("satVerify16: return LBA+TL out of range, not EXT\n"));
8614      satSetSensePayload( pSense,
8615                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8616                          0,
8617                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8618                          satIOContext);
8619
8620      ostiInitiatorIOCompleted( tiRoot,
8621                                tiIORequest,
8622                                tiIOSuccess,
8623                                SCSI_STAT_CHECK_CONDITION,
8624                                satIOContext->pTiSenseData,
8625                                satIOContext->interruptContext );
8626
8627    return tiSuccess;
8628    }
8629  }
8630
8631  if (pSatDevData->sat48BitSupport == agTRUE)
8632  {
8633    TI_DBG5(("satVerify16: SAT_READ_VERIFY_SECTORS_EXT\n"));
8634    fis->h.fisType        = 0x27;                   /* Reg host to device */
8635    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
8636
8637    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8638    fis->h.features       = 0;                      /* FIS reserve */
8639    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8640    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8641    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8642    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
8643    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
8644    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
8645    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
8646    fis->d.featuresExp    = 0;                      /* FIS reserve */
8647    fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8648    fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
8649
8650    fis->d.reserved4      = 0;
8651    fis->d.control        = 0;                      /* FIS HOB bit clear */
8652    fis->d.reserved5      = 0;
8653
8654    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8655    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8656  }
8657  else
8658  {
8659    TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8660    fis->h.fisType        = 0x27;                   /* Reg host to device */
8661    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
8662    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
8663    fis->h.features       = 0;                      /* FIS reserve */
8664    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
8665    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
8666    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
8667      /* FIS LBA mode set LBA (27:24) */
8668    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
8669    fis->d.lbaLowExp      = 0;
8670    fis->d.lbaMidExp      = 0;
8671    fis->d.lbaHighExp     = 0;
8672    fis->d.featuresExp    = 0;
8673    fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
8674    fis->d.sectorCountExp = 0;
8675    fis->d.reserved4      = 0;
8676    fis->d.control        = 0;                      /* FIS HOB bit clear */
8677    fis->d.reserved5      = 0;
8678
8679    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8680    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8681
8682 }
8683
8684  satIOContext->currentLBA = lba;
8685  satIOContext->OrgTL = tl;
8686
8687  /*
8688    computing number of loop and remainder for tl
8689    0xFF in case not ext
8690    0xFFFF in case EXT
8691  */
8692  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8693  {
8694    LoopNum = satComputeLoopNum(tl, 0xFF);
8695  }
8696  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8697  {
8698    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8699    LoopNum = satComputeLoopNum(tl, 0xFFFF);
8700  }
8701  else
8702  {
8703    TI_DBG1(("satVerify12: error case 1!!!\n"));
8704    LoopNum = 1;
8705  }
8706
8707  satIOContext->LoopNum = LoopNum;
8708
8709  if (LoopNum == 1)
8710  {
8711    TI_DBG5(("satVerify12: NON CHAINED data\n"));
8712    /* Initialize CB for SATA completion.
8713     */
8714    satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8715  }
8716  else
8717  {
8718    TI_DBG1(("satVerify12: CHAINED data\n"));
8719    /* re-setting tl */
8720    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8721    {
8722       fis->d.sectorCount    = 0xFF;
8723    }
8724    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8725    {
8726      fis->d.sectorCount    = 0xFF;
8727      fis->d.sectorCountExp = 0xFF;
8728    }
8729    else
8730    {
8731      TI_DBG1(("satVerify10: error case 2!!!\n"));
8732    }
8733
8734    /* Initialize CB for SATA completion.
8735     */
8736    satIOContext->satCompleteCB = &satChainedVerifyCB;
8737  }
8738
8739
8740  /*
8741   * Prepare SGL and send FIS to LL layer.
8742   */
8743  satIOContext->reqType = agRequestType;       /* Save it */
8744
8745  status = sataLLIOStart( tiRoot,
8746                          tiIORequest,
8747                          tiDeviceHandle,
8748                          tiScsiRequest,
8749                          satIOContext);
8750  return (status);
8751}
8752/*****************************************************************************/
8753/*! \brief SAT implementation for SCSI satFormatUnit.
8754 *
8755 *  SAT implementation for SCSI satFormatUnit.
8756 *
8757 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8758 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8759 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8760 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8761 *  \param   satIOContext_t:   Pointer to the SAT IO Context
8762 *
8763 *  \return If command is started successfully
8764 *    - \e tiSuccess:     I/O request successfully initiated.
8765 *    - \e tiBusy:        No resources available, try again later.
8766 *    - \e tiIONoDevice:  Invalid device handle.
8767 *    - \e tiError:       Other errors.
8768 */
8769/*****************************************************************************/
8770GLOBAL bit32  satFormatUnit(
8771                   tiRoot_t                  *tiRoot,
8772                   tiIORequest_t             *tiIORequest,
8773                   tiDeviceHandle_t          *tiDeviceHandle,
8774                   tiScsiInitiatorRequest_t *tiScsiRequest,
8775                   satIOContext_t            *satIOContext)
8776{
8777  /*
8778    note: we don't support media certification in this version and IP bit
8779    satDevData->satFormatState will be agFalse since SAT does not actually sends
8780    any ATA command
8781   */
8782
8783  scsiRspSense_t          *pSense;
8784  tiIniScsiCmnd_t         *scsiCmnd;
8785  bit32                    index = 0;
8786
8787  pSense        = satIOContext->pSense;
8788  scsiCmnd      = &tiScsiRequest->scsiCmnd;
8789
8790  TI_DBG5(("satFormatUnit:start\n"));
8791
8792  /*
8793    checking opcode
8794    1. FMTDATA bit == 0(no defect list header)
8795    2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided
8796    with DCRT bit set)
8797  */
8798  if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) ||
8799       ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8800        (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK))
8801       )
8802  {
8803    ostiInitiatorIOCompleted( tiRoot,
8804                              tiIORequest,
8805                              tiIOSuccess,
8806                              SCSI_STAT_GOOD,
8807                              agNULL,
8808                              satIOContext->interruptContext);
8809
8810    TI_DBG2(("satFormatUnit: return opcode\n"));
8811    return tiSuccess;
8812  }
8813
8814  /*
8815    checking DEFECT LIST FORMAT and defect list length
8816  */
8817  if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) ||
8818        ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) )
8819  {
8820    /* short parameter header */
8821    if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00)
8822    {
8823      index = 8;
8824    }
8825    /* long parameter header */
8826    if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01)
8827    {
8828      index = 10;
8829    }
8830    /* defect list length */
8831    if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0))
8832    {
8833      satSetSensePayload( pSense,
8834                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8835                          0,
8836                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8837                          satIOContext);
8838
8839      ostiInitiatorIOCompleted( tiRoot,
8840                                tiIORequest,
8841                                tiIOSuccess,
8842                                SCSI_STAT_CHECK_CONDITION,
8843                                satIOContext->pTiSenseData,
8844                                satIOContext->interruptContext );
8845
8846      TI_DBG1(("satFormatUnit: return defect list format\n"));
8847      return tiSuccess;
8848    }
8849  }
8850
8851   /* FMTDATA == 1 && CMPLIST == 1*/
8852  if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8853       (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
8854  {
8855    satSetSensePayload( pSense,
8856                        SCSI_SNSKEY_ILLEGAL_REQUEST,
8857                        0,
8858                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8859                        satIOContext);
8860
8861    ostiInitiatorIOCompleted( tiRoot,
8862                              tiIORequest,
8863                              tiIOSuccess,
8864                              SCSI_STAT_CHECK_CONDITION,
8865                              satIOContext->pTiSenseData,
8866                              satIOContext->interruptContext );
8867
8868    TI_DBG1(("satFormatUnit: return cmplist\n"));
8869    return tiSuccess;
8870
8871  }
8872
8873 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8874  {
8875    satSetSensePayload( pSense,
8876                        SCSI_SNSKEY_ILLEGAL_REQUEST,
8877                        0,
8878                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8879                        satIOContext);
8880
8881    ostiInitiatorIOCompleted( tiRoot,
8882                              tiIORequest,
8883                              tiIOSuccess,
8884                              SCSI_STAT_CHECK_CONDITION,
8885                              satIOContext->pTiSenseData,
8886                              satIOContext->interruptContext );
8887
8888    TI_DBG1(("satFormatUnit: return control\n"));
8889    return tiSuccess;
8890  }
8891
8892  /* defect list header filed, if exists, SAT rev8, Table 37, p48 */
8893  if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK)
8894  {
8895    /* case 1,2,3 */
8896    /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */
8897    if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) ||
8898         ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) ||
8899         ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8900           (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8901           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK))
8902         )
8903    {
8904      ostiInitiatorIOCompleted( tiRoot,
8905                                tiIORequest,
8906                                tiIOSuccess,
8907                                SCSI_STAT_GOOD,
8908                                agNULL,
8909                                satIOContext->interruptContext);
8910
8911      TI_DBG5(("satFormatUnit: return defect list case 1\n"));
8912      return tiSuccess;
8913    }
8914    /* case 4,5,6 */
8915    /*
8916        1. IMMED 0, FOV 1, DCRT 0, IP 0
8917        2. IMMED 0, FOV 1, DCRT 0, IP 1
8918        3. IMMED 0, FOV 1, DCRT 1, IP 1
8919      */
8920
8921    if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8922            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8923           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8924           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8925         ||
8926         ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8927            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8928           !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8929            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8930         ||
8931         ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8932            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8933            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8934            (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8935         )
8936    {
8937
8938      satSetSensePayload( pSense,
8939                          SCSI_SNSKEY_ILLEGAL_REQUEST,
8940                          0,
8941                          SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
8942                          satIOContext);
8943
8944      ostiInitiatorIOCompleted( tiRoot,
8945                                tiIORequest,
8946                                tiIOSuccess,
8947                                SCSI_STAT_CHECK_CONDITION,
8948                                satIOContext->pTiSenseData,
8949                                satIOContext->interruptContext );
8950
8951      TI_DBG5(("satFormatUnit: return defect list case 2\n"));
8952      return tiSuccess;
8953
8954    }
8955  }
8956
8957
8958  /*
8959   * Send the completion response now.
8960   */
8961  ostiInitiatorIOCompleted( tiRoot,
8962                            tiIORequest,
8963                            tiIOSuccess,
8964                            SCSI_STAT_GOOD,
8965                            agNULL,
8966                            satIOContext->interruptContext);
8967
8968  TI_DBG5(("satFormatUnit: return last\n"));
8969  return tiSuccess;
8970}
8971
8972
8973/*****************************************************************************/
8974/*! \brief SAT implementation for SCSI satSendDiagnostic.
8975 *
8976 *  SAT implementation for SCSI satSendDiagnostic.
8977 *
8978 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
8979 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
8980 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
8981 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
8982 *  \param   satIOContext_t:   Pointer to the SAT IO Context
8983 *
8984 *  \return If command is started successfully
8985 *    - \e tiSuccess:     I/O request successfully initiated.
8986 *    - \e tiBusy:        No resources available, try again later.
8987 *    - \e tiIONoDevice:  Invalid device handle.
8988 *    - \e tiError:       Other errors.
8989 */
8990/*****************************************************************************/
8991GLOBAL bit32  satSendDiagnostic(
8992                   tiRoot_t                  *tiRoot,
8993                   tiIORequest_t             *tiIORequest,
8994                   tiDeviceHandle_t          *tiDeviceHandle,
8995                   tiScsiInitiatorRequest_t *tiScsiRequest,
8996                   satIOContext_t            *satIOContext)
8997{
8998  bit32                     status;
8999  bit32                     agRequestType;
9000  satDeviceData_t           *pSatDevData;
9001  scsiRspSense_t            *pSense;
9002  tiIniScsiCmnd_t           *scsiCmnd;
9003  agsaFisRegHostToDevice_t  *fis;
9004  bit32                     parmLen;
9005
9006  pSense        = satIOContext->pSense;
9007  pSatDevData   = satIOContext->pSatDevData;
9008  scsiCmnd      = &tiScsiRequest->scsiCmnd;
9009  fis           = satIOContext->pFis;
9010
9011  TI_DBG5(("satSendDiagnostic:start\n"));
9012
9013  /* reset satVerifyState */
9014  pSatDevData->satVerifyState = 0;
9015  /* no pending diagnostic in background */
9016  pSatDevData->satBGPendingDiag = agFALSE;
9017
9018  /* table 27, 8.10 p39 SAT Rev8 */
9019  /*
9020    1. checking PF == 1
9021    2. checking DEVOFFL == 1
9022    3. checking UNITOFFL == 1
9023    4. checking PARAMETER LIST LENGTH != 0
9024
9025  */
9026  if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) ||
9027       (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) ||
9028       (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) ||
9029       ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) )
9030       )
9031  {
9032    satSetSensePayload( pSense,
9033                        SCSI_SNSKEY_ILLEGAL_REQUEST,
9034                        0,
9035                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9036                        satIOContext);
9037
9038    ostiInitiatorIOCompleted( tiRoot,
9039                              tiIORequest,
9040                              tiIOSuccess,
9041                              SCSI_STAT_CHECK_CONDITION,
9042                              satIOContext->pTiSenseData,
9043                              satIOContext->interruptContext );
9044
9045    TI_DBG1(("satSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST\n"));
9046    return tiSuccess;
9047  }
9048
9049  /* checking CONTROL */
9050  /* NACA == 1 or LINK == 1*/
9051  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9052  {
9053    satSetSensePayload( pSense,
9054                        SCSI_SNSKEY_ILLEGAL_REQUEST,
9055                        0,
9056                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9057                        satIOContext);
9058
9059    ostiInitiatorIOCompleted( tiRoot,
9060                              tiIORequest,
9061                              tiIOSuccess,
9062                              SCSI_STAT_CHECK_CONDITION,
9063                              satIOContext->pTiSenseData,
9064                              satIOContext->interruptContext );
9065
9066    TI_DBG2(("satSendDiagnostic: return control\n"));
9067    return tiSuccess;
9068  }
9069
9070  parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
9071
9072  /* checking SELFTEST bit*/
9073  /* table 29, 8.10.3, p41 SAT Rev8 */
9074  /* case 1 */
9075  if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9076       (pSatDevData->satSMARTSelfTest == agFALSE)
9077       )
9078  {
9079    satSetSensePayload( pSense,
9080                        SCSI_SNSKEY_ILLEGAL_REQUEST,
9081                        0,
9082                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9083                        satIOContext);
9084
9085    ostiInitiatorIOCompleted( tiRoot,
9086                              tiIORequest,
9087                              tiIOSuccess,
9088                              SCSI_STAT_CHECK_CONDITION,
9089                              satIOContext->pTiSenseData,
9090                              satIOContext->interruptContext );
9091
9092    TI_DBG1(("satSendDiagnostic: return Table 29 case 1\n"));
9093    return tiSuccess;
9094  }
9095
9096  /* case 2 */
9097  if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9098       (pSatDevData->satSMARTSelfTest == agTRUE) &&
9099       (pSatDevData->satSMARTEnabled == agFALSE)
9100       )
9101  {
9102    satSetSensePayload( pSense,
9103                        SCSI_SNSKEY_ABORTED_COMMAND,
9104                        0,
9105                        SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
9106                        satIOContext);
9107
9108    ostiInitiatorIOCompleted( tiRoot,
9109                              tiIORequest,
9110                              tiIOSuccess,
9111                              SCSI_STAT_CHECK_CONDITION,
9112                              satIOContext->pTiSenseData,
9113                              satIOContext->interruptContext );
9114
9115    TI_DBG5(("satSendDiagnostic: return Table 29 case 2\n"));
9116    return tiSuccess;
9117  }
9118  /*
9119    case 3
9120     see SELF TEST CODE later
9121  */
9122
9123
9124
9125  /* case 4 */
9126
9127  /*
9128    sends three ATA verify commands
9129
9130  */
9131  if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9132        (pSatDevData->satSMARTSelfTest == agFALSE))
9133       ||
9134       ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9135        (pSatDevData->satSMARTSelfTest == agTRUE) &&
9136        (pSatDevData->satSMARTEnabled == agFALSE))
9137       )
9138  {
9139    /*
9140      sector count 1, LBA 0
9141      sector count 1, LBA MAX
9142      sector count 1, LBA random
9143    */
9144    if (pSatDevData->sat48BitSupport == agTRUE)
9145    {
9146      /* sends READ VERIFY SECTOR(S) EXT*/
9147      fis->h.fisType        = 0x27;                   /* Reg host to device */
9148      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9149      fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9150      fis->h.features       = 0;                      /* FIS reserve */
9151      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9152      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9153      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9154      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9155      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9156      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9157      fis->d.featuresExp    = 0;                      /* FIS reserve */
9158      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9159      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9160      fis->d.reserved4      = 0;
9161      fis->d.device         = 0x40;                   /* 01000000 */
9162      fis->d.control        = 0;                      /* FIS HOB bit clear */
9163      fis->d.reserved5      = 0;
9164
9165      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9166    }
9167    else
9168    {
9169      /* READ VERIFY SECTOR(S)*/
9170      fis->h.fisType        = 0x27;                   /* Reg host to device */
9171      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9172      fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9173      fis->h.features       = 0;                      /* FIS features NA       */
9174      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9175      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9176      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9177      fis->d.lbaLowExp      = 0;
9178      fis->d.lbaMidExp      = 0;
9179      fis->d.lbaHighExp     = 0;
9180      fis->d.featuresExp    = 0;
9181      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9182      fis->d.sectorCountExp = 0;
9183      fis->d.reserved4      = 0;
9184      fis->d.device         = 0x40;                   /* 01000000 */
9185      fis->d.control        = 0;                      /* FIS HOB bit clear */
9186      fis->d.reserved5      = 0;
9187
9188      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9189    }
9190
9191    /* Initialize CB for SATA completion.
9192     */
9193    satIOContext->satCompleteCB = &satSendDiagnosticCB;
9194
9195    /*
9196     * Prepare SGL and send FIS to LL layer.
9197     */
9198    satIOContext->reqType = agRequestType;       /* Save it */
9199
9200    status = sataLLIOStart( tiRoot,
9201                            tiIORequest,
9202                            tiDeviceHandle,
9203                            tiScsiRequest,
9204                            satIOContext);
9205
9206
9207    TI_DBG5(("satSendDiagnostic: return Table 29 case 4\n"));
9208    return (status);
9209  }
9210  /* case 5 */
9211  if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9212       (pSatDevData->satSMARTSelfTest == agTRUE) &&
9213       (pSatDevData->satSMARTEnabled == agTRUE)
9214       )
9215  {
9216    /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9217    fis->h.fisType        = 0x27;                   /* Reg host to device */
9218    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9219    fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0xB0 */
9220    fis->h.features       = 0xD4;                      /* FIS features NA       */
9221    fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
9222    fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9223    fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9224    fis->d.lbaLowExp      = 0;
9225    fis->d.lbaMidExp      = 0;
9226    fis->d.lbaHighExp     = 0;
9227    fis->d.featuresExp    = 0;
9228    fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9229    fis->d.sectorCountExp = 0;
9230    fis->d.reserved4      = 0;
9231    fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9232    fis->d.control        = 0;                         /* FIS HOB bit clear */
9233    fis->d.reserved5      = 0;
9234
9235    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9236
9237    /* Initialize CB for SATA completion.
9238     */
9239    satIOContext->satCompleteCB = &satSendDiagnosticCB;
9240
9241    /*
9242     * Prepare SGL and send FIS to LL layer.
9243     */
9244    satIOContext->reqType = agRequestType;       /* Save it */
9245
9246    status = sataLLIOStart( tiRoot,
9247                            tiIORequest,
9248                            tiDeviceHandle,
9249                            tiScsiRequest,
9250                            satIOContext);
9251
9252
9253    TI_DBG5(("satSendDiagnostic: return Table 29 case 5\n"));
9254    return (status);
9255  }
9256
9257
9258
9259
9260  /* SAT rev8 Table29 p41 case 3*/
9261  /* checking SELF TEST CODE*/
9262  if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9263       (pSatDevData->satSMARTSelfTest == agTRUE) &&
9264       (pSatDevData->satSMARTEnabled == agTRUE)
9265       )
9266  {
9267    /* SAT rev8 Table28 p40 */
9268    /* finding self-test code */
9269    switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5)
9270    {
9271    case 1:
9272      pSatDevData->satBGPendingDiag = agTRUE;
9273
9274      ostiInitiatorIOCompleted( tiRoot,
9275                                tiIORequest,
9276                                tiIOSuccess,
9277                                SCSI_STAT_GOOD,
9278                                agNULL,
9279                                satIOContext->interruptContext );
9280      /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9281      fis->h.fisType        = 0x27;                   /* Reg host to device */
9282      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9283      fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9284      fis->h.features       = 0xD4;                      /* FIS features NA       */
9285      fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
9286      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9287      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9288
9289      fis->d.lbaLowExp      = 0;
9290      fis->d.lbaMidExp      = 0;
9291      fis->d.lbaHighExp     = 0;
9292      fis->d.featuresExp    = 0;
9293      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9294      fis->d.sectorCountExp = 0;
9295      fis->d.reserved4      = 0;
9296      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9297      fis->d.control        = 0;                         /* FIS HOB bit clear */
9298      fis->d.reserved5      = 0;
9299
9300      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9301
9302      /* Initialize CB for SATA completion.
9303       */
9304      satIOContext->satCompleteCB = &satSendDiagnosticCB;
9305
9306      /*
9307       * Prepare SGL and send FIS to LL layer.
9308       */
9309      satIOContext->reqType = agRequestType;       /* Save it */
9310
9311      status = sataLLIOStart( tiRoot,
9312                              tiIORequest,
9313                              tiDeviceHandle,
9314                              tiScsiRequest,
9315                              satIOContext);
9316
9317
9318      TI_DBG5(("satSendDiagnostic: return Table 28 case 1\n"));
9319      return (status);
9320    case 2:
9321      pSatDevData->satBGPendingDiag = agTRUE;
9322
9323      ostiInitiatorIOCompleted( tiRoot,
9324                                tiIORequest,
9325                                tiIOSuccess,
9326                                SCSI_STAT_GOOD,
9327                                agNULL,
9328                                satIOContext->interruptContext );
9329
9330
9331      /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9332      fis->h.fisType        = 0x27;                   /* Reg host to device */
9333      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9334      fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9335      fis->h.features       = 0xD4;                      /* FIS features NA       */
9336      fis->d.lbaLow         = 0x02;                      /* FIS LBA (7 :0 ) */
9337      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9338      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9339      fis->d.lbaLowExp      = 0;
9340      fis->d.lbaMidExp      = 0;
9341      fis->d.lbaHighExp     = 0;
9342      fis->d.featuresExp    = 0;
9343      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9344      fis->d.sectorCountExp = 0;
9345      fis->d.reserved4      = 0;
9346      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9347      fis->d.control        = 0;                         /* FIS HOB bit clear */
9348      fis->d.reserved5      = 0;
9349
9350      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9351
9352      /* Initialize CB for SATA completion.
9353       */
9354      satIOContext->satCompleteCB = &satSendDiagnosticCB;
9355
9356      /*
9357       * Prepare SGL and send FIS to LL layer.
9358       */
9359      satIOContext->reqType = agRequestType;       /* Save it */
9360
9361      status = sataLLIOStart( tiRoot,
9362                              tiIORequest,
9363                              tiDeviceHandle,
9364                              tiScsiRequest,
9365                              satIOContext);
9366
9367
9368      TI_DBG5(("satSendDiagnostic: return Table 28 case 2\n"));
9369      return (status);
9370    case 4:
9371      /* For simplicity, no abort is supported
9372         Returns good status
9373         need a flag in device data for previously sent background Send Diagnostic
9374      */
9375      if (parmLen != 0)
9376      {
9377        /* check condition */
9378        satSetSensePayload( pSense,
9379                            SCSI_SNSKEY_ILLEGAL_REQUEST,
9380                            0,
9381                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9382                            satIOContext);
9383
9384        ostiInitiatorIOCompleted( tiRoot,
9385                                  tiIORequest,
9386                                  tiIOSuccess,
9387                                  SCSI_STAT_CHECK_CONDITION,
9388                                  satIOContext->pTiSenseData,
9389                                  satIOContext->interruptContext );
9390
9391        TI_DBG1(("satSendDiagnostic: case 4, non zero ParmLen %d\n", parmLen));
9392        return tiSuccess;
9393      }
9394      if (pSatDevData->satBGPendingDiag == agTRUE)
9395      {
9396        /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */
9397        fis->h.fisType        = 0x27;                   /* Reg host to device */
9398        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9399        fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9400        fis->h.features       = 0xD4;                      /* FIS features NA       */
9401        fis->d.lbaLow         = 0x7F;                      /* FIS LBA (7 :0 ) */
9402        fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9403        fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9404
9405        fis->d.lbaLowExp      = 0;
9406        fis->d.lbaMidExp      = 0;
9407        fis->d.lbaHighExp     = 0;
9408        fis->d.featuresExp    = 0;
9409        fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9410        fis->d.sectorCountExp = 0;
9411        fis->d.reserved4      = 0;
9412        fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9413        fis->d.control        = 0;                         /* FIS HOB bit clear */
9414        fis->d.reserved5      = 0;
9415
9416        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9417
9418        /* Initialize CB for SATA completion.
9419         */
9420        satIOContext->satCompleteCB = &satSendDiagnosticCB;
9421
9422        /*
9423         * Prepare SGL and send FIS to LL layer.
9424         */
9425        satIOContext->reqType = agRequestType;       /* Save it */
9426
9427        status = sataLLIOStart( tiRoot,
9428                                tiIORequest,
9429                                tiDeviceHandle,
9430                                tiScsiRequest,
9431                                satIOContext);
9432
9433
9434        TI_DBG5(("satSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
9435        TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9436        return (status);
9437      }
9438      else
9439      {
9440        /* check condition */
9441        satSetSensePayload( pSense,
9442                            SCSI_SNSKEY_ILLEGAL_REQUEST,
9443                            0,
9444                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9445                            satIOContext);
9446
9447        ostiInitiatorIOCompleted( tiRoot,
9448                                  tiIORequest,
9449                                  tiIOSuccess,
9450                                  SCSI_STAT_CHECK_CONDITION,
9451                                  satIOContext->pTiSenseData,
9452                                  satIOContext->interruptContext );
9453
9454        TI_DBG1(("satSendDiagnostic: case 4, no pending diagnostic in background\n"));
9455        TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9456        return tiSuccess;
9457      }
9458      break;
9459    case 5:
9460      /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9461      fis->h.fisType        = 0x27;                   /* Reg host to device */
9462      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9463      fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9464      fis->h.features       = 0xD4;                      /* FIS features NA       */
9465      fis->d.lbaLow         = 0x81;                      /* FIS LBA (7 :0 ) */
9466      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9467      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9468      fis->d.lbaLowExp      = 0;
9469      fis->d.lbaMidExp      = 0;
9470      fis->d.lbaHighExp     = 0;
9471      fis->d.featuresExp    = 0;
9472      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9473      fis->d.sectorCountExp = 0;
9474      fis->d.reserved4      = 0;
9475      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9476      fis->d.control        = 0;                         /* FIS HOB bit clear */
9477      fis->d.reserved5      = 0;
9478
9479      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9480
9481      /* Initialize CB for SATA completion.
9482       */
9483      satIOContext->satCompleteCB = &satSendDiagnosticCB;
9484
9485      /*
9486       * Prepare SGL and send FIS to LL layer.
9487       */
9488      satIOContext->reqType = agRequestType;       /* Save it */
9489
9490      status = sataLLIOStart( tiRoot,
9491                              tiIORequest,
9492                              tiDeviceHandle,
9493                              tiScsiRequest,
9494                              satIOContext);
9495
9496
9497      TI_DBG5(("satSendDiagnostic: return Table 28 case 5\n"));
9498      return (status);
9499    case 6:
9500      /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9501      fis->h.fisType        = 0x27;                   /* Reg host to device */
9502      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9503      fis->h.command        = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9504      fis->h.features       = 0xD4;                      /* FIS features NA       */
9505      fis->d.lbaLow         = 0x82;                      /* FIS LBA (7 :0 ) */
9506      fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
9507      fis->d.lbaHigh        = 0xC2;                      /* FIS LBA (23:16) */
9508      fis->d.lbaLowExp      = 0;
9509      fis->d.lbaMidExp      = 0;
9510      fis->d.lbaHighExp     = 0;
9511      fis->d.featuresExp    = 0;
9512      fis->d.sectorCount    = 0;                         /* FIS sector count (7:0) */
9513      fis->d.sectorCountExp = 0;
9514      fis->d.reserved4      = 0;
9515      fis->d.device         = 0;                         /* FIS DEV is discared in SATA */
9516      fis->d.control        = 0;                         /* FIS HOB bit clear */
9517      fis->d.reserved5      = 0;
9518
9519      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9520
9521      /* Initialize CB for SATA completion.
9522       */
9523      satIOContext->satCompleteCB = &satSendDiagnosticCB;
9524
9525      /*
9526       * Prepare SGL and send FIS to LL layer.
9527       */
9528      satIOContext->reqType = agRequestType;       /* Save it */
9529
9530      status = sataLLIOStart( tiRoot,
9531                              tiIORequest,
9532                              tiDeviceHandle,
9533                              tiScsiRequest,
9534                              satIOContext);
9535
9536
9537      TI_DBG5(("satSendDiagnostic: return Table 28 case 6\n"));
9538      return (status);
9539    case 0:
9540    case 3: /* fall through */
9541    case 7: /* fall through */
9542    default:
9543      break;
9544    }/* switch */
9545
9546    /* returns the results of default self-testing, which is good */
9547    ostiInitiatorIOCompleted( tiRoot,
9548                              tiIORequest,
9549                              tiIOSuccess,
9550                              SCSI_STAT_GOOD,
9551                              agNULL,
9552                              satIOContext->interruptContext );
9553
9554    TI_DBG5(("satSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
9555    return tiSuccess;
9556  }
9557
9558
9559  ostiInitiatorIOCompleted( tiRoot,
9560                            tiIORequest,
9561                            tiIOSuccess,
9562                            SCSI_STAT_GOOD,
9563                            agNULL,
9564                            satIOContext->interruptContext );
9565
9566
9567  TI_DBG5(("satSendDiagnostic: return last\n"));
9568  return tiSuccess;
9569}
9570
9571/*****************************************************************************/
9572/*! \brief SAT implementation for SCSI satSendDiagnostic_1.
9573 *
9574 *  SAT implementation for SCSI satSendDiagnostic_1.
9575 *  Sub function of satSendDiagnostic.
9576 *
9577 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
9578 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
9579 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
9580 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
9581 *  \param   satIOContext_t:   Pointer to the SAT IO Context
9582 *
9583 *  \return If command is started successfully
9584 *    - \e tiSuccess:     I/O request successfully initiated.
9585 *    - \e tiBusy:        No resources available, try again later.
9586 *    - \e tiIONoDevice:  Invalid device handle.
9587 *    - \e tiError:       Other errors.
9588 */
9589/*****************************************************************************/
9590GLOBAL bit32  satSendDiagnostic_1(
9591                   tiRoot_t                  *tiRoot,
9592                   tiIORequest_t             *tiIORequest,
9593                   tiDeviceHandle_t          *tiDeviceHandle,
9594                   tiScsiInitiatorRequest_t *tiScsiRequest,
9595                   satIOContext_t            *satIOContext)
9596{
9597  /*
9598    SAT Rev9, Table29, p41
9599    send 2nd SAT_READ_VERIFY_SECTORS(_EXT)
9600  */
9601  bit32                     status;
9602  bit32                     agRequestType;
9603  satDeviceData_t           *pSatDevData;
9604  agsaFisRegHostToDevice_t  *fis;
9605
9606  TI_DBG5(("satSendDiagnostic_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9607      tiDeviceHandle, tiIORequest));
9608
9609  pSatDevData       = satIOContext->pSatDevData;
9610  fis               = satIOContext->pFis;
9611
9612  /*
9613    sector count 1, LBA MAX
9614  */
9615  if (pSatDevData->sat48BitSupport == agTRUE)
9616  {
9617    /* sends READ VERIFY SECTOR(S) EXT*/
9618    fis->h.fisType        = 0x27;                   /* Reg host to device */
9619    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9620    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9621    fis->h.features       = 0;                      /* FIS reserve */
9622    fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9623    fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9624    fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9625    fis->d.lbaLowExp      = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */
9626    fis->d.lbaMidExp      = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */
9627    fis->d.lbaHighExp     = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */
9628    fis->d.featuresExp    = 0;                      /* FIS reserve */
9629    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9630    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9631    fis->d.reserved4      = 0;
9632    fis->d.device         = 0x40;                   /* 01000000 */
9633    fis->d.control        = 0;                      /* FIS HOB bit clear */
9634    fis->d.reserved5      = 0;
9635
9636  }
9637  else
9638  {
9639    /* READ VERIFY SECTOR(S)*/
9640    fis->h.fisType        = 0x27;                   /* Reg host to device */
9641    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9642    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9643    fis->h.features       = 0;                      /* FIS features NA       */
9644    fis->d.lbaLow         = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9645    fis->d.lbaMid         = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9646    fis->d.lbaHigh        = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9647    fis->d.lbaLowExp      = 0;
9648    fis->d.lbaMidExp      = 0;
9649    fis->d.lbaHighExp     = 0;
9650    fis->d.featuresExp    = 0;
9651    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9652    fis->d.sectorCountExp = 0;
9653    fis->d.reserved4      = 0;
9654    fis->d.device         = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF));
9655                            /* DEV and LBA 27:24 */
9656    fis->d.control        = 0;                      /* FIS HOB bit clear */
9657    fis->d.reserved5      = 0;
9658
9659  }
9660
9661  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9662
9663  /* Initialize CB for SATA completion.
9664   */
9665  satIOContext->satCompleteCB = &satSendDiagnosticCB;
9666
9667  /*
9668   * Prepare SGL and send FIS to LL layer.
9669   */
9670  satIOContext->reqType = agRequestType;       /* Save it */
9671
9672  status = sataLLIOStart( tiRoot,
9673                          tiIORequest,
9674                          tiDeviceHandle,
9675                          tiScsiRequest,
9676                          satIOContext);
9677
9678
9679  return status;
9680}
9681
9682/*****************************************************************************/
9683/*! \brief SAT implementation for SCSI satSendDiagnostic_2.
9684 *
9685 *  SAT implementation for SCSI satSendDiagnostic_2.
9686 *  Sub function of satSendDiagnostic.
9687 *
9688 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
9689 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
9690 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
9691 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
9692 *  \param   satIOContext_t:   Pointer to the SAT IO Context
9693 *
9694 *  \return If command is started successfully
9695 *    - \e tiSuccess:     I/O request successfully initiated.
9696 *    - \e tiBusy:        No resources available, try again later.
9697 *    - \e tiIONoDevice:  Invalid device handle.
9698 *    - \e tiError:       Other errors.
9699 */
9700/*****************************************************************************/
9701GLOBAL bit32  satSendDiagnostic_2(
9702                   tiRoot_t                  *tiRoot,
9703                   tiIORequest_t             *tiIORequest,
9704                   tiDeviceHandle_t          *tiDeviceHandle,
9705                   tiScsiInitiatorRequest_t *tiScsiRequest,
9706                   satIOContext_t            *satIOContext)
9707{
9708  /*
9709    SAT Rev9, Table29, p41
9710    send 3rd SAT_READ_VERIFY_SECTORS(_EXT)
9711  */
9712  bit32                     status;
9713  bit32                     agRequestType;
9714  satDeviceData_t           *pSatDevData;
9715  agsaFisRegHostToDevice_t  *fis;
9716
9717  TI_DBG5(("satSendDiagnostic_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9718      tiDeviceHandle, tiIORequest));
9719
9720  pSatDevData       = satIOContext->pSatDevData;
9721  fis               = satIOContext->pFis;
9722
9723  /*
9724    sector count 1, LBA Random
9725  */
9726  if (pSatDevData->sat48BitSupport == agTRUE)
9727  {
9728    /* sends READ VERIFY SECTOR(S) EXT*/
9729    fis->h.fisType        = 0x27;                   /* Reg host to device */
9730    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9731    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9732    fis->h.features       = 0;                      /* FIS reserve */
9733    fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
9734    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9735    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9736    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9737    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9738    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9739    fis->d.featuresExp    = 0;                      /* FIS reserve */
9740    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9741    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9742    fis->d.reserved4      = 0;
9743    fis->d.device         = 0x40;                   /* 01000000 */
9744    fis->d.control        = 0;                      /* FIS HOB bit clear */
9745    fis->d.reserved5      = 0;
9746
9747  }
9748  else
9749  {
9750    /* READ VERIFY SECTOR(S)*/
9751    fis->h.fisType        = 0x27;                   /* Reg host to device */
9752    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9753    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9754    fis->h.features       = 0;                      /* FIS features NA       */
9755    fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
9756    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9757    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9758    fis->d.lbaLowExp      = 0;
9759    fis->d.lbaMidExp      = 0;
9760    fis->d.lbaHighExp     = 0;
9761    fis->d.featuresExp    = 0;
9762    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9763    fis->d.sectorCountExp = 0;
9764    fis->d.reserved4      = 0;
9765    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
9766    fis->d.control        = 0;                      /* FIS HOB bit clear */
9767    fis->d.reserved5      = 0;
9768
9769  }
9770
9771  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9772
9773  /* Initialize CB for SATA completion.
9774   */
9775  satIOContext->satCompleteCB = &satSendDiagnosticCB;
9776
9777  /*
9778   * Prepare SGL and send FIS to LL layer.
9779   */
9780  satIOContext->reqType = agRequestType;       /* Save it */
9781
9782  status = sataLLIOStart( tiRoot,
9783                          tiIORequest,
9784                          tiDeviceHandle,
9785                          tiScsiRequest,
9786                          satIOContext);
9787
9788
9789  return status;
9790}
9791/*****************************************************************************/
9792/*! \brief SAT implementation for SCSI satStartStopUnit.
9793 *
9794 *  SAT implementation for SCSI satStartStopUnit.
9795 *
9796 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
9797 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
9798 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
9799 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
9800 *  \param   satIOContext_t:   Pointer to the SAT IO Context
9801 *
9802 *  \return If command is started successfully
9803 *    - \e tiSuccess:     I/O request successfully initiated.
9804 *    - \e tiBusy:        No resources available, try again later.
9805 *    - \e tiIONoDevice:  Invalid device handle.
9806 *    - \e tiError:       Other errors.
9807 */
9808/*****************************************************************************/
9809GLOBAL bit32  satStartStopUnit(
9810                   tiRoot_t                  *tiRoot,
9811                   tiIORequest_t             *tiIORequest,
9812                   tiDeviceHandle_t          *tiDeviceHandle,
9813                   tiScsiInitiatorRequest_t *tiScsiRequest,
9814                   satIOContext_t            *satIOContext)
9815{
9816  bit32                     status;
9817  bit32                     agRequestType;
9818  satDeviceData_t           *pSatDevData;
9819  scsiRspSense_t            *pSense;
9820  tiIniScsiCmnd_t           *scsiCmnd;
9821  agsaFisRegHostToDevice_t  *fis;
9822
9823  pSense        = satIOContext->pSense;
9824  pSatDevData   = satIOContext->pSatDevData;
9825  scsiCmnd      = &tiScsiRequest->scsiCmnd;
9826  fis           = satIOContext->pFis;
9827
9828  TI_DBG5(("satStartStopUnit:start\n"));
9829
9830  /* checking CONTROL */
9831  /* NACA == 1 or LINK == 1*/
9832  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9833  {
9834    satSetSensePayload( pSense,
9835                        SCSI_SNSKEY_ILLEGAL_REQUEST,
9836                        0,
9837                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9838                        satIOContext);
9839
9840    ostiInitiatorIOCompleted( tiRoot,
9841                              tiIORequest,
9842                              tiIOSuccess,
9843                              SCSI_STAT_CHECK_CONDITION,
9844                              satIOContext->pTiSenseData,
9845                              satIOContext->interruptContext );
9846
9847    TI_DBG1(("satStartStopUnit: return control\n"));
9848    return tiSuccess;
9849  }
9850
9851  /* Spec p55, Table 48 checking START and LOEJ bit */
9852  /* case 1 */
9853  if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9854  {
9855    if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9856    {
9857      /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9858      ostiInitiatorIOCompleted( tiRoot,
9859                                tiIORequest,
9860                                tiIOSuccess,
9861                                SCSI_STAT_GOOD,
9862                                agNULL,
9863                                satIOContext->interruptContext );
9864      TI_DBG5(("satStartStopUnit: return table48 case 1-1\n"));
9865      return tiSuccess;
9866    }
9867    /* sends FLUSH CACHE or FLUSH CACHE EXT */
9868    if (pSatDevData->sat48BitSupport == agTRUE)
9869    {
9870      /* FLUSH CACHE EXT */
9871      fis->h.fisType        = 0x27;                   /* Reg host to device */
9872      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9873
9874      fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
9875      fis->h.features       = 0;                      /* FIS reserve */
9876      fis->d.featuresExp    = 0;                      /* FIS reserve */
9877      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9878      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9879      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9880      fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
9881      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9882      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
9883      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9884      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
9885      fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
9886      fis->d.control        = 0;                      /* FIS HOB bit clear */
9887      fis->d.reserved4      = 0;
9888      fis->d.reserved5      = 0;
9889
9890      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9891    }
9892    else
9893    {
9894      /* FLUSH CACHE */
9895      fis->h.fisType        = 0x27;                   /* Reg host to device */
9896      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9897
9898      fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
9899      fis->h.features       = 0;                      /* FIS features NA       */
9900      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
9901      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
9902      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
9903      fis->d.lbaLowExp      = 0;
9904      fis->d.lbaMidExp      = 0;
9905      fis->d.lbaHighExp     = 0;
9906      fis->d.featuresExp    = 0;
9907      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
9908      fis->d.sectorCountExp = 0;
9909      fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
9910      fis->d.control        = 0;                      /* FIS HOB bit clear */
9911      fis->d.reserved4      = 0;
9912      fis->d.reserved5      = 0;
9913
9914      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9915    }
9916
9917    /* Initialize CB for SATA completion.
9918     */
9919    satIOContext->satCompleteCB = &satStartStopUnitCB;
9920
9921    /*
9922     * Prepare SGL and send FIS to LL layer.
9923     */
9924    satIOContext->reqType = agRequestType;       /* Save it */
9925
9926    status = sataLLIOStart( tiRoot,
9927                            tiIORequest,
9928                            tiDeviceHandle,
9929                            tiScsiRequest,
9930                            satIOContext);
9931
9932
9933    TI_DBG5(("satStartStopUnit: return table48 case 1\n"));
9934    return (status);
9935  }
9936  /* case 2 */
9937  else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9938  {
9939    /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9940    if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9941    {
9942      ostiInitiatorIOCompleted( tiRoot,
9943                                tiIORequest,
9944                                tiIOSuccess,
9945                                SCSI_STAT_GOOD,
9946                                agNULL,
9947                                satIOContext->interruptContext );
9948
9949      TI_DBG5(("satStartStopUnit: return table48 case 2 1\n"));
9950      return tiSuccess;
9951    }
9952    /*
9953      sends READ_VERIFY_SECTORS(_EXT)
9954      sector count 1, any LBA between zero to Maximum
9955    */
9956    if (pSatDevData->sat48BitSupport == agTRUE)
9957    {
9958      /* READ VERIFY SECTOR(S) EXT*/
9959      fis->h.fisType        = 0x27;                   /* Reg host to device */
9960      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9961
9962      fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9963      fis->h.features       = 0;                      /* FIS reserve */
9964      fis->d.lbaLow         = 0x01;                   /* FIS LBA (7 :0 ) */
9965      fis->d.lbaMid         = 0x00;                   /* FIS LBA (15:8 ) */
9966      fis->d.lbaHigh        = 0x00;                   /* FIS LBA (23:16) */
9967      fis->d.lbaLowExp      = 0x00;                   /* FIS LBA (31:24) */
9968      fis->d.lbaMidExp      = 0x00;                   /* FIS LBA (39:32) */
9969      fis->d.lbaHighExp     = 0x00;                   /* FIS LBA (47:40) */
9970      fis->d.featuresExp    = 0;                      /* FIS reserve */
9971      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9972      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
9973      fis->d.reserved4      = 0;
9974      fis->d.device         = 0x40;                   /* 01000000 */
9975      fis->d.control        = 0;                      /* FIS HOB bit clear */
9976      fis->d.reserved5      = 0;
9977
9978    }
9979    else
9980    {
9981      /* READ VERIFY SECTOR(S)*/
9982      fis->h.fisType        = 0x27;                   /* Reg host to device */
9983      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
9984
9985      fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9986      fis->h.features       = 0;                      /* FIS features NA       */
9987      fis->d.lbaLow         = 0x01;                      /* FIS LBA (7 :0 ) */
9988      fis->d.lbaMid         = 0x00;                      /* FIS LBA (15:8 ) */
9989      fis->d.lbaHigh        = 0x00;                      /* FIS LBA (23:16) */
9990      fis->d.lbaLowExp      = 0;
9991      fis->d.lbaMidExp      = 0;
9992      fis->d.lbaHighExp     = 0;
9993      fis->d.featuresExp    = 0;
9994      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
9995      fis->d.sectorCountExp = 0;
9996      fis->d.reserved4      = 0;
9997      fis->d.device         = 0x40;                   /* 01000000 */
9998      fis->d.control        = 0;                      /* FIS HOB bit clear */
9999      fis->d.reserved5      = 0;
10000
10001    }
10002
10003    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10004
10005    /* Initialize CB for SATA completion.
10006     */
10007    satIOContext->satCompleteCB = &satStartStopUnitCB;
10008
10009    /*
10010     * Prepare SGL and send FIS to LL layer.
10011     */
10012    satIOContext->reqType = agRequestType;       /* Save it */
10013
10014    status = sataLLIOStart( tiRoot,
10015                            tiIORequest,
10016                            tiDeviceHandle,
10017                            tiScsiRequest,
10018                            satIOContext);
10019
10020    TI_DBG5(("satStartStopUnit: return table48 case 2 2\n"));
10021    return status;
10022  }
10023  /* case 3 */
10024  else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
10025  {
10026    if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
10027    {
10028      /* support for removal media */
10029      /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
10030      if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
10031      {
10032        ostiInitiatorIOCompleted( tiRoot,
10033                                  tiIORequest,
10034                                  tiIOSuccess,
10035                                  SCSI_STAT_GOOD,
10036                                  agNULL,
10037                                  satIOContext->interruptContext );
10038
10039        TI_DBG5(("satStartStopUnit: return table48 case 3 1\n"));
10040        return tiSuccess;
10041      }
10042      /*
10043        sends MEDIA EJECT
10044      */
10045      /* Media Eject fis */
10046      fis->h.fisType        = 0x27;                   /* Reg host to device */
10047      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10048
10049      fis->h.command        = SAT_MEDIA_EJECT;        /* 0xED */
10050      fis->h.features       = 0;                      /* FIS features NA       */
10051      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
10052      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
10053      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
10054      fis->d.lbaLowExp      = 0;
10055      fis->d.lbaMidExp      = 0;
10056      fis->d.lbaHighExp     = 0;
10057      fis->d.featuresExp    = 0;
10058      /* sector count zero */
10059      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
10060      fis->d.sectorCountExp = 0;
10061      fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
10062      fis->d.control        = 0;                      /* FIS HOB bit clear */
10063      fis->d.reserved4      = 0;
10064      fis->d.reserved5      = 0;
10065
10066      agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10067
10068      /* Initialize CB for SATA completion.
10069       */
10070      satIOContext->satCompleteCB = &satStartStopUnitCB;
10071
10072      /*
10073       * Prepare SGL and send FIS to LL layer.
10074       */
10075      satIOContext->reqType = agRequestType;       /* Save it */
10076
10077      status = sataLLIOStart( tiRoot,
10078                              tiIORequest,
10079                              tiDeviceHandle,
10080                              tiScsiRequest,
10081                              satIOContext);
10082
10083      return status;
10084    }
10085    else
10086    {
10087      /* no support for removal media */
10088      satSetSensePayload( pSense,
10089                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10090                          0,
10091                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10092                          satIOContext);
10093
10094      ostiInitiatorIOCompleted( tiRoot,
10095                                tiIORequest,
10096                                tiIOSuccess,
10097                                SCSI_STAT_CHECK_CONDITION,
10098                                satIOContext->pTiSenseData,
10099                                satIOContext->interruptContext );
10100
10101      TI_DBG5(("satStartStopUnit: return Table 29 case 3 2\n"));
10102      return tiSuccess;
10103    }
10104
10105  }
10106  /* case 4 */
10107  else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */
10108  {
10109    satSetSensePayload( pSense,
10110                        SCSI_SNSKEY_ILLEGAL_REQUEST,
10111                        0,
10112                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10113                        satIOContext);
10114
10115    ostiInitiatorIOCompleted( tiRoot,
10116                              tiIORequest,
10117                              tiIOSuccess,
10118                              SCSI_STAT_CHECK_CONDITION,
10119                              satIOContext->pTiSenseData,
10120                              satIOContext->interruptContext );
10121
10122    TI_DBG5(("satStartStopUnit: return Table 29 case 4\n"));
10123    return tiSuccess;
10124  }
10125
10126
10127}
10128
10129
10130/*****************************************************************************/
10131/*! \brief SAT implementation for SCSI satStartStopUnit_1.
10132 *
10133 *  SAT implementation for SCSI satStartStopUnit_1.
10134 *  Sub function of satStartStopUnit
10135 *
10136 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10137 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10138 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10139 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10140 *  \param   satIOContext_t:   Pointer to the SAT IO Context
10141 *
10142 *  \return If command is started successfully
10143 *    - \e tiSuccess:     I/O request successfully initiated.
10144 *    - \e tiBusy:        No resources available, try again later.
10145 *    - \e tiIONoDevice:  Invalid device handle.
10146 *    - \e tiError:       Other errors.
10147 */
10148/*****************************************************************************/
10149GLOBAL bit32  satStartStopUnit_1(
10150                   tiRoot_t                  *tiRoot,
10151                   tiIORequest_t             *tiIORequest,
10152                   tiDeviceHandle_t          *tiDeviceHandle,
10153                   tiScsiInitiatorRequest_t *tiScsiRequest,
10154                   satIOContext_t            *satIOContext)
10155{
10156  /*
10157    SAT Rev 8, Table 48, 9.11.3 p55
10158    sends STANDBY
10159  */
10160  bit32                     status;
10161  bit32                     agRequestType;
10162  agsaFisRegHostToDevice_t  *fis;
10163
10164  TI_DBG5(("satStartStopUnit_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10165      tiDeviceHandle, tiIORequest));
10166
10167  fis               = satIOContext->pFis;
10168
10169  /* STANDBY */
10170  fis->h.fisType        = 0x27;                   /* Reg host to device */
10171  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10172
10173  fis->h.command        = SAT_STANDBY;            /* 0xE2 */
10174  fis->h.features       = 0;                      /* FIS features NA       */
10175  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
10176  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
10177  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
10178  fis->d.lbaLowExp      = 0;
10179  fis->d.lbaMidExp      = 0;
10180  fis->d.lbaHighExp     = 0;
10181  fis->d.featuresExp    = 0;
10182  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
10183  fis->d.sectorCountExp = 0;
10184  fis->d.reserved4      = 0;
10185  fis->d.device         = 0;                      /* 0 */
10186  fis->d.control        = 0;                      /* FIS HOB bit clear */
10187  fis->d.reserved5      = 0;
10188
10189  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10190
10191  /* Initialize CB for SATA completion.
10192   */
10193  satIOContext->satCompleteCB = &satStartStopUnitCB;
10194
10195  /*
10196   * Prepare SGL and send FIS to LL layer.
10197   */
10198  satIOContext->reqType = agRequestType;       /* Save it */
10199
10200  status = sataLLIOStart( tiRoot,
10201                          tiIORequest,
10202                          tiDeviceHandle,
10203                          tiScsiRequest,
10204                          satIOContext);
10205
10206  TI_DBG5(("satStartStopUnit_1 return status %d\n", status));
10207  return status;
10208}
10209
10210/*****************************************************************************/
10211/*! \brief SAT implementation for SCSI satRead10_2.
10212 *
10213 *  SAT implementation for SCSI satRead10_2
10214 *  Sub function of satRead10
10215 *
10216 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10217 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10218 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10219 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10220 *  \param   satIOContext_t:   Pointer to the SAT IO Context
10221 *
10222 *  \return If command is started successfully
10223 *    - \e tiSuccess:     I/O request successfully initiated.
10224 *    - \e tiBusy:        No resources available, try again later.
10225 *    - \e tiIONoDevice:  Invalid device handle.
10226 *    - \e tiError:       Other errors.
10227 */
10228/*****************************************************************************/
10229GLOBAL bit32  satRead10_2(
10230                          tiRoot_t                  *tiRoot,
10231                          tiIORequest_t             *tiIORequest,
10232                          tiDeviceHandle_t          *tiDeviceHandle,
10233                          tiScsiInitiatorRequest_t *tiScsiRequest,
10234                          satIOContext_t            *satIOContext)
10235{
10236  /*
10237    externally generated ATA cmd, there is corresponding scsi cmnd
10238    called by satStartStopUnit() or maybe satRead10()
10239   */
10240
10241  bit32                     status;
10242  bit32                     agRequestType;
10243  satDeviceData_t           *pSatDevData;
10244  agsaFisRegHostToDevice_t  *fis;
10245
10246  pSatDevData   = satIOContext->pSatDevData;
10247  fis           = satIOContext->pFis;
10248
10249  TI_DBG5(("satReadVerifySectorsNoChain: start\n"));
10250
10251  /* specifying ReadVerifySectors has no chain */
10252  pSatDevData->satVerifyState = 0xFFFFFFFF;
10253
10254  if (pSatDevData->sat48BitSupport == agTRUE)
10255  {
10256    /* READ VERIFY SECTOR(S) EXT*/
10257    fis->h.fisType        = 0x27;                   /* Reg host to device */
10258    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10259    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
10260    fis->h.features       = 0;                      /* FIS reserve */
10261    fis->d.lbaLow         = 0x7F;                   /* FIS LBA (7 :0 ) */
10262    fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
10263    fis->d.lbaHigh        = 0x00;                   /* FIS LBA (23:16) */
10264    fis->d.lbaLowExp      = 0xF1;                   /* FIS LBA (31:24) */
10265    fis->d.lbaMidExp      = 0x5F;                   /* FIS LBA (39:32) */
10266    fis->d.lbaHighExp     = 0xFF;                   /* FIS LBA (47:40) */
10267    fis->d.featuresExp    = 0;                      /* FIS reserve */
10268    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10269    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10270    fis->d.reserved4      = 0;
10271    fis->d.device         = 0x4E;                   /* 01001110 */
10272    fis->d.control        = 0;                      /* FIS HOB bit clear */
10273    fis->d.reserved5      = 0;
10274
10275    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10276  }
10277  else
10278  {
10279    /* READ VERIFY SECTOR(S)*/
10280    fis->h.fisType        = 0x27;                   /* Reg host to device */
10281    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10282    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
10283    fis->h.features       = 0;                      /* FIS features NA       */
10284    fis->d.lbaLow         = 0x7F;                      /* FIS LBA (7 :0 ) */
10285    fis->d.lbaMid         = 0x4F;                      /* FIS LBA (15:8 ) */
10286    fis->d.lbaHigh        = 0x00;                      /* FIS LBA (23:16) */
10287    fis->d.lbaLowExp      = 0;
10288    fis->d.lbaMidExp      = 0;
10289    fis->d.lbaHighExp     = 0;
10290    fis->d.featuresExp    = 0;
10291    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10292    fis->d.sectorCountExp = 0;
10293    fis->d.reserved4      = 0;
10294    fis->d.device         = 0x4E;                   /* 01001110 */
10295    fis->d.control        = 0;                      /* FIS HOB bit clear */
10296    fis->d.reserved5      = 0;
10297
10298    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10299  }
10300
10301  /* Initialize CB for SATA completion.
10302   */
10303  satIOContext->satCompleteCB = &satNonDataIOCB;
10304
10305  /*
10306   * Prepare SGL and send FIS to LL layer.
10307   */
10308  satIOContext->reqType = agRequestType;       /* Save it */
10309
10310  status = sataLLIOStart( tiRoot,
10311                          tiIORequest,
10312                          tiDeviceHandle,
10313                          tiScsiRequest,
10314                          satIOContext);
10315
10316  TI_DBG5(("satReadVerifySectorsNoChain: return last\n"));
10317
10318  return status;
10319}
10320
10321
10322/*****************************************************************************/
10323/*! \brief SAT implementation for SCSI satWriteSame10.
10324 *
10325 *  SAT implementation for SCSI satWriteSame10.
10326 *
10327 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10328 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10329 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10330 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10331 *  \param   satIOContext_t:   Pointer to the SAT IO Context
10332 *
10333 *  \return If command is started successfully
10334 *    - \e tiSuccess:     I/O request successfully initiated.
10335 *    - \e tiBusy:        No resources available, try again later.
10336 *    - \e tiIONoDevice:  Invalid device handle.
10337 *    - \e tiError:       Other errors.
10338 */
10339/*****************************************************************************/
10340GLOBAL bit32  satWriteSame10(
10341                   tiRoot_t                  *tiRoot,
10342                   tiIORequest_t             *tiIORequest,
10343                   tiDeviceHandle_t          *tiDeviceHandle,
10344                   tiScsiInitiatorRequest_t *tiScsiRequest,
10345                   satIOContext_t            *satIOContext)
10346{
10347  bit32                     status;
10348  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10349  satDeviceData_t           *pSatDevData;
10350  scsiRspSense_t            *pSense;
10351  tiIniScsiCmnd_t           *scsiCmnd;
10352  agsaFisRegHostToDevice_t  *fis;
10353  bit32                     lba = 0;
10354  bit32                     tl = 0;
10355
10356  pSense        = satIOContext->pSense;
10357  pSatDevData   = satIOContext->pSatDevData;
10358  scsiCmnd      = &tiScsiRequest->scsiCmnd;
10359  fis           = satIOContext->pFis;
10360
10361  TI_DBG5(("satWriteSame10: start\n"));
10362
10363  /* checking CONTROL */
10364    /* NACA == 1 or LINK == 1*/
10365  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
10366  {
10367    satSetSensePayload( pSense,
10368                        SCSI_SNSKEY_ILLEGAL_REQUEST,
10369                        0,
10370                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10371                        satIOContext);
10372
10373    ostiInitiatorIOCompleted( tiRoot,
10374                              tiIORequest,
10375                              tiIOSuccess,
10376                              SCSI_STAT_CHECK_CONDITION,
10377                              satIOContext->pTiSenseData,
10378                              satIOContext->interruptContext );
10379
10380    TI_DBG1(("satWriteSame10: return control\n"));
10381    return tiSuccess;
10382  }
10383
10384
10385  /* checking LBDATA and PBDATA */
10386  /* case 1 */
10387  if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10388       !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10389  {
10390    TI_DBG5(("satWriteSame10: case 1\n"));
10391    /* spec 9.26.2, Table 62, p64, case 1*/
10392    /*
10393      normal case
10394      just like write in 9.17.1
10395    */
10396
10397    if ( pSatDevData->sat48BitSupport != agTRUE )
10398    {
10399      /*
10400        writeSame10 but no support for 48 bit addressing
10401        -> problem in transfer length. Therefore, return check condition
10402      */
10403      satSetSensePayload( pSense,
10404                          SCSI_SNSKEY_ILLEGAL_REQUEST,
10405                          0,
10406                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10407                          satIOContext);
10408
10409      ostiInitiatorIOCompleted( tiRoot,
10410                                tiIORequest,
10411                                tiIOSuccess,
10412                                SCSI_STAT_CHECK_CONDITION,
10413                                satIOContext->pTiSenseData,
10414                                satIOContext->interruptContext );
10415
10416      TI_DBG1(("satWriteSame10: return internal checking\n"));
10417      return tiSuccess;
10418    }
10419
10420    /* cdb10; computing LBA and transfer length */
10421    lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
10422      + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
10423    tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
10424
10425
10426    /* Table 34, 9.1, p 46 */
10427    /*
10428      note: As of 2/10/2006, no support for DMA QUEUED
10429    */
10430
10431    /*
10432      Table 34, 9.1, p 46, b (footnote)
10433      When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
10434      return check condition
10435    */
10436    if (pSatDevData->satNCQ != agTRUE &&
10437        pSatDevData->sat48BitSupport != agTRUE
10438          )
10439    {
10440      if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */
10441      {
10442        satSetSensePayload( pSense,
10443                            SCSI_SNSKEY_ILLEGAL_REQUEST,
10444                            0,
10445                            SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
10446                            satIOContext);
10447
10448        ostiInitiatorIOCompleted( tiRoot,
10449                                  tiIORequest,
10450                                  tiIOSuccess,
10451                                  SCSI_STAT_CHECK_CONDITION,
10452                                  satIOContext->pTiSenseData,
10453                                  satIOContext->interruptContext );
10454
10455        TI_DBG1(("satWriteSame10: return LBA out of range\n"));
10456          return tiSuccess;
10457      }
10458    }
10459
10460    if (lba + tl <= SAT_TR_LBA_LIMIT)
10461    {
10462      if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10463      {
10464        /* case 2 */
10465        /* WRITE DMA */
10466        /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10467        TI_DBG5(("satWriteSame10: case 1-2 !!! error due to writeSame10\n"));
10468        satSetSensePayload( pSense,
10469                            SCSI_SNSKEY_ILLEGAL_REQUEST,
10470                            0,
10471                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10472                            satIOContext);
10473
10474        ostiInitiatorIOCompleted( tiRoot,
10475                                  tiIORequest,
10476                                  tiIOSuccess,
10477                                  SCSI_STAT_CHECK_CONDITION,
10478                                  satIOContext->pTiSenseData,
10479                                  satIOContext->interruptContext );
10480        return tiSuccess;
10481      }
10482      else
10483      {
10484        /* case 1 */
10485        /* WRITE MULTIPLE or WRITE SECTOR(S) */
10486        /* WRITE SECTORS is chosen for easier implemetation */
10487        /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10488        TI_DBG5(("satWriteSame10: case 1-1 !!! error due to writesame10\n"));
10489        satSetSensePayload( pSense,
10490                            SCSI_SNSKEY_ILLEGAL_REQUEST,
10491                            0,
10492                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10493                            satIOContext);
10494
10495        ostiInitiatorIOCompleted( tiRoot,
10496                                  tiIORequest,
10497                                  tiIOSuccess,
10498                                  SCSI_STAT_CHECK_CONDITION,
10499                                  satIOContext->pTiSenseData,
10500                                  satIOContext->interruptContext );
10501        return tiSuccess;
10502      }
10503    } /* end of case 1 and 2 */
10504
10505    /* case 3 and 4 */
10506    if (pSatDevData->sat48BitSupport == agTRUE)
10507    {
10508      if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10509      {
10510        /* case 3 */
10511        /* WRITE DMA EXT or WRITE DMA FUA EXT */
10512        /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */
10513        TI_DBG5(("satWriteSame10: case 1-3\n"));
10514        fis->h.fisType        = 0x27;                   /* Reg host to device */
10515        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10516
10517        fis->h.command        = SAT_WRITE_DMA_EXT;          /* 0x35 */
10518
10519        fis->h.features       = 0;                      /* FIS reserve */
10520        fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
10521        fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
10522        fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
10523        fis->d.device         = 0x40;                   /* FIS LBA mode set */
10524        fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
10525        fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10526        fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10527        fis->d.featuresExp    = 0;                      /* FIS reserve */
10528        if (tl == 0)
10529        {
10530          /* error check
10531             ATA spec, p125, 6.17.29
10532             pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10533             and allowed value is 0x0FFFFFFF - 1
10534          */
10535          if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10536          {
10537            TI_DBG5(("satWriteSame10: case 3 !!! warning can't fit sectors\n"));
10538            satSetSensePayload( pSense,
10539                                SCSI_SNSKEY_ILLEGAL_REQUEST,
10540                                0,
10541                                SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10542                                satIOContext);
10543
10544            ostiInitiatorIOCompleted( tiRoot,
10545                                      tiIORequest,
10546                                      tiIOSuccess,
10547                                      SCSI_STAT_CHECK_CONDITION,
10548                                      satIOContext->pTiSenseData,
10549                                      satIOContext->interruptContext );
10550            return tiSuccess;
10551          }
10552        }
10553        /* one sector at a time */
10554        fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10555        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10556        fis->d.reserved4      = 0;
10557        fis->d.control        = 0;                      /* FIS HOB bit clear */
10558        fis->d.reserved5      = 0;
10559
10560        agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10561      }
10562      else
10563      {
10564        /* case 4 */
10565        /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
10566        /* WRITE SECTORS EXT is chosen for easier implemetation */
10567        TI_DBG5(("satWriteSame10: case 1-4\n"));
10568        fis->h.fisType        = 0x27;                   /* Reg host to device */
10569        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10570
10571        fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
10572        fis->h.features       = 0;                      /* FIS reserve */
10573        fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
10574        fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
10575        fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
10576        fis->d.device         = 0x40;                   /* FIS LBA mode set */
10577        fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
10578        fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10579        fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10580        fis->d.featuresExp    = 0;                      /* FIS reserve */
10581        if (tl == 0)
10582        {
10583          /* error check
10584             ATA spec, p125, 6.17.29
10585             pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10586             and allowed value is 0x0FFFFFFF - 1
10587          */
10588          if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10589          {
10590            TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10591            satSetSensePayload( pSense,
10592                                SCSI_SNSKEY_ILLEGAL_REQUEST,
10593                                0,
10594                                SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10595                                satIOContext);
10596
10597            ostiInitiatorIOCompleted( tiRoot,
10598                                      tiIORequest,
10599                                      tiIOSuccess,
10600                                      SCSI_STAT_CHECK_CONDITION,
10601                                      satIOContext->pTiSenseData,
10602                                      satIOContext->interruptContext );
10603            return tiSuccess;
10604          }
10605        }
10606        /* one sector at a time */
10607        fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10608        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10609        fis->d.reserved4      = 0;
10610        fis->d.control        = 0;                      /* FIS HOB bit clear */
10611        fis->d.reserved5      = 0;
10612
10613        agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10614      }
10615    }
10616
10617    /* case 5 */
10618    if (pSatDevData->satNCQ == agTRUE)
10619    {
10620      /* WRITE FPDMA QUEUED */
10621      if (pSatDevData->sat48BitSupport != agTRUE)
10622      {
10623        TI_DBG5(("satWriteSame10: case 1-5 !!! error NCQ but 28 bit address support \n"));
10624        satSetSensePayload( pSense,
10625                            SCSI_SNSKEY_ILLEGAL_REQUEST,
10626                            0,
10627                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10628                            satIOContext);
10629
10630        ostiInitiatorIOCompleted( tiRoot,
10631                                  tiIORequest,
10632                                  tiIOSuccess,
10633                                  SCSI_STAT_CHECK_CONDITION,
10634                                  satIOContext->pTiSenseData,
10635                                  satIOContext->interruptContext );
10636        return tiSuccess;
10637      }
10638      TI_DBG5(("satWriteSame10: case 1-5\n"));
10639
10640      /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
10641
10642      fis->h.fisType        = 0x27;                   /* Reg host to device */
10643      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10644      fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
10645
10646      if (tl == 0)
10647      {
10648        /* error check
10649           ATA spec, p125, 6.17.29
10650           pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10651           and allowed value is 0x0FFFFFFF - 1
10652        */
10653        if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10654        {
10655          TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10656          satSetSensePayload( pSense,
10657                              SCSI_SNSKEY_ILLEGAL_REQUEST,
10658                              0,
10659                              SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10660                              satIOContext);
10661
10662          ostiInitiatorIOCompleted( tiRoot,
10663                                    tiIORequest,
10664                                    tiIOSuccess,
10665                                    SCSI_STAT_CHECK_CONDITION,
10666                                    satIOContext->pTiSenseData,
10667                                    satIOContext->interruptContext );
10668          return tiSuccess;
10669        }
10670      }
10671      /* one sector at a time */
10672      fis->h.features       = 1;            /* FIS sector count (7:0) */
10673      fis->d.featuresExp    = 0;            /* FIS sector count (15:8) */
10674
10675
10676      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
10677      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
10678      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
10679
10680      /* NO FUA bit in the WRITE SAME 10 */
10681      fis->d.device       = 0x40;                     /* FIS FUA clear */
10682
10683      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
10684      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10685      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10686      fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
10687      fis->d.sectorCountExp = 0;
10688      fis->d.reserved4      = 0;
10689      fis->d.control        = 0;                      /* FIS HOB bit clear */
10690      fis->d.reserved5      = 0;
10691
10692      agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
10693    }
10694    /* Initialize CB for SATA completion.
10695     */
10696    satIOContext->satCompleteCB = &satWriteSame10CB;
10697
10698    /*
10699     * Prepare SGL and send FIS to LL layer.
10700     */
10701    satIOContext->reqType = agRequestType;       /* Save it */
10702
10703    status = sataLLIOStart( tiRoot,
10704                            tiIORequest,
10705                            tiDeviceHandle,
10706                            tiScsiRequest,
10707                            satIOContext);
10708    return (status);
10709
10710
10711  } /* end of case 1 */
10712  else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10713             (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10714  {
10715    /* spec 9.26.2, Table 62, p64, case 2*/
10716    satSetSensePayload( pSense,
10717                        SCSI_SNSKEY_ILLEGAL_REQUEST,
10718                        0,
10719                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10720                        satIOContext);
10721
10722    ostiInitiatorIOCompleted( tiRoot,
10723                              tiIORequest,
10724                              tiIOSuccess,
10725                              SCSI_STAT_CHECK_CONDITION,
10726                              satIOContext->pTiSenseData,
10727                              satIOContext->interruptContext );
10728
10729    TI_DBG5(("satWriteSame10: return Table 62 case 2\n"));
10730    return tiSuccess;
10731  }
10732  else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10733           !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10734  {
10735    TI_DBG5(("satWriteSame10: Table 62 case 3\n"));
10736
10737  }
10738  else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10739            (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */
10740  {
10741
10742    /* spec 9.26.2, Table 62, p64, case 4*/
10743    satSetSensePayload( pSense,
10744                        SCSI_SNSKEY_ILLEGAL_REQUEST,
10745                        0,
10746                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10747                        satIOContext);
10748
10749    ostiInitiatorIOCompleted( tiRoot,
10750                              tiIORequest,
10751                              tiIOSuccess,
10752                              SCSI_STAT_CHECK_CONDITION,
10753                              satIOContext->pTiSenseData,
10754                              satIOContext->interruptContext );
10755
10756    TI_DBG5(("satWriteSame10: return Table 62 case 4\n"));
10757    return tiSuccess;
10758  }
10759
10760
10761  return tiSuccess;
10762}
10763
10764/*****************************************************************************/
10765/*! \brief SAT implementation for SCSI satWriteSame10_1.
10766 *
10767 *  SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10768 *  This is used when WRITESAME10 is divided into multiple ATA commands
10769 *
10770 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10771 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10772 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10773 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10774 *  \param   satIOContext_t:   Pointer to the SAT IO Context
10775 *  \param   lba:              LBA
10776 *
10777 *  \return If command is started successfully
10778 *    - \e tiSuccess:     I/O request successfully initiated.
10779 *    - \e tiBusy:        No resources available, try again later.
10780 *    - \e tiIONoDevice:  Invalid device handle.
10781 *    - \e tiError:       Other errors.
10782 */
10783/*****************************************************************************/
10784GLOBAL bit32  satWriteSame10_1(
10785                   tiRoot_t                  *tiRoot,
10786                   tiIORequest_t             *tiIORequest,
10787                   tiDeviceHandle_t          *tiDeviceHandle,
10788                   tiScsiInitiatorRequest_t *tiScsiRequest,
10789                   satIOContext_t            *satIOContext,
10790                   bit32                     lba
10791                   )
10792{
10793  /*
10794    sends SAT_WRITE_DMA_EXT
10795  */
10796
10797  bit32                     status;
10798  bit32                     agRequestType;
10799  agsaFisRegHostToDevice_t  *fis;
10800  bit8                      lba1, lba2 ,lba3, lba4;
10801
10802  TI_DBG5(("satWriteSame10_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10803           tiDeviceHandle, tiIORequest));
10804
10805  fis               = satIOContext->pFis;
10806
10807  /* MSB */
10808  lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10809  lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10810  lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10811  /* LSB */
10812  lba4 = (bit8)(lba & 0x000000FF);
10813
10814  /* SAT_WRITE_DMA_EXT */
10815  fis->h.fisType        = 0x27;                   /* Reg host to device */
10816  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10817
10818  fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
10819
10820  fis->h.features       = 0;                      /* FIS reserve */
10821  fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
10822  fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
10823  fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
10824  fis->d.device         = 0x40;                   /* FIS LBA mode set */
10825  fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
10826  fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10827  fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10828  fis->d.featuresExp    = 0;                      /* FIS reserve */
10829  /* one sector at a time */
10830  fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10831  fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10832
10833  fis->d.reserved4      = 0;
10834  fis->d.control        = 0;                      /* FIS HOB bit clear */
10835  fis->d.reserved5      = 0;
10836
10837
10838  agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10839
10840  /* Initialize CB for SATA completion.
10841   */
10842  satIOContext->satCompleteCB = &satWriteSame10CB;
10843
10844  /*
10845   * Prepare SGL and send FIS to LL layer.
10846   */
10847  satIOContext->reqType = agRequestType;       /* Save it */
10848
10849  status = sataLLIOStart( tiRoot,
10850                          tiIORequest,
10851                          tiDeviceHandle,
10852                          tiScsiRequest,
10853                          satIOContext);
10854
10855  TI_DBG5(("satWriteSame10_1 return status %d\n", status));
10856  return status;
10857}
10858
10859/*****************************************************************************/
10860/*! \brief SAT implementation for SCSI satWriteSame10_2.
10861 *
10862 *  SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10863 *  This is used when WRITESAME10 is divided into multiple ATA commands
10864 *
10865 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10866 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10867 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10868 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10869 *  \param   satIOContext_t:   Pointer to the SAT IO Context
10870 *  \param   lba:              LBA
10871 *
10872 *  \return If command is started successfully
10873 *    - \e tiSuccess:     I/O request successfully initiated.
10874 *    - \e tiBusy:        No resources available, try again later.
10875 *    - \e tiIONoDevice:  Invalid device handle.
10876 *    - \e tiError:       Other errors.
10877 */
10878/*****************************************************************************/
10879GLOBAL bit32  satWriteSame10_2(
10880                   tiRoot_t                  *tiRoot,
10881                   tiIORequest_t             *tiIORequest,
10882                   tiDeviceHandle_t          *tiDeviceHandle,
10883                   tiScsiInitiatorRequest_t *tiScsiRequest,
10884                   satIOContext_t            *satIOContext,
10885                   bit32                     lba
10886                   )
10887{
10888  /*
10889    sends SAT_WRITE_SECTORS_EXT
10890  */
10891
10892  bit32                     status;
10893  bit32                     agRequestType;
10894  agsaFisRegHostToDevice_t  *fis;
10895  bit8                      lba1, lba2 ,lba3, lba4;
10896
10897  TI_DBG5(("satWriteSame10_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10898           tiDeviceHandle, tiIORequest));
10899
10900  fis               = satIOContext->pFis;
10901
10902  /* MSB */
10903  lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10904  lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10905  lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10906  /* LSB */
10907  lba4 = (bit8)(lba & 0x000000FF);
10908
10909
10910  /* SAT_WRITE_SECTORS_EXT */
10911  fis->h.fisType        = 0x27;                   /* Reg host to device */
10912  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
10913
10914  fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
10915  fis->h.features       = 0;                      /* FIS reserve */
10916  fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
10917  fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
10918  fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
10919  fis->d.device         = 0x40;                   /* FIS LBA mode set */
10920  fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
10921  fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
10922  fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
10923  fis->d.featuresExp    = 0;                      /* FIS reserve */
10924  /* one sector at a time */
10925  fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
10926  fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
10927
10928  fis->d.reserved4      = 0;
10929  fis->d.control        = 0;                      /* FIS HOB bit clear */
10930  fis->d.reserved5      = 0;
10931
10932
10933  agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10934
10935  /* Initialize CB for SATA completion.
10936   */
10937  satIOContext->satCompleteCB = &satWriteSame10CB;
10938
10939  /*
10940   * Prepare SGL and send FIS to LL layer.
10941   */
10942  satIOContext->reqType = agRequestType;       /* Save it */
10943
10944  status = sataLLIOStart( tiRoot,
10945                          tiIORequest,
10946                          tiDeviceHandle,
10947                          tiScsiRequest,
10948                          satIOContext);
10949
10950  TI_DBG5(("satWriteSame10_2 return status %d\n", status));
10951  return status;
10952}
10953
10954/*****************************************************************************/
10955/*! \brief SAT implementation for SCSI satWriteSame10_3.
10956 *
10957 *  SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10958 *  This is used when WRITESAME10 is divided into multiple ATA commands
10959 *
10960 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
10961 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
10962 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
10963 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
10964 *  \param   satIOContext_t:   Pointer to the SAT IO Context
10965 *  \param   lba:              LBA
10966 *
10967 *  \return If command is started successfully
10968 *    - \e tiSuccess:     I/O request successfully initiated.
10969 *    - \e tiBusy:        No resources available, try again later.
10970 *    - \e tiIONoDevice:  Invalid device handle.
10971 *    - \e tiError:       Other errors.
10972 */
10973/*****************************************************************************/
10974GLOBAL bit32  satWriteSame10_3(
10975                   tiRoot_t                  *tiRoot,
10976                   tiIORequest_t             *tiIORequest,
10977                   tiDeviceHandle_t          *tiDeviceHandle,
10978                   tiScsiInitiatorRequest_t *tiScsiRequest,
10979                   satIOContext_t            *satIOContext,
10980                   bit32                     lba
10981                   )
10982{
10983  /*
10984    sends SAT_WRITE_FPDMA_QUEUED
10985  */
10986
10987  bit32                     status;
10988  bit32                     agRequestType;
10989  agsaFisRegHostToDevice_t  *fis;
10990  bit8                      lba1, lba2 ,lba3, lba4;
10991
10992  TI_DBG5(("satWriteSame10_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10993           tiDeviceHandle, tiIORequest));
10994
10995  fis               = satIOContext->pFis;
10996
10997  /* MSB */
10998  lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10999  lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
11000  lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
11001  /* LSB */
11002  lba4 = (bit8)(lba & 0x000000FF);
11003
11004  /* SAT_WRITE_FPDMA_QUEUED */
11005  fis->h.fisType        = 0x27;                   /* Reg host to device */
11006  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11007  fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
11008
11009
11010  /* one sector at a time */
11011  fis->h.features       = 1;                      /* FIS sector count (7:0) */
11012  fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
11013
11014
11015  fis->d.lbaLow         = lba4;                   /* FIS LBA (7 :0 ) */
11016  fis->d.lbaMid         = lba3;                   /* FIS LBA (15:8 ) */
11017  fis->d.lbaHigh        = lba2;                   /* FIS LBA (23:16) */
11018
11019  /* NO FUA bit in the WRITE SAME 10 */
11020  fis->d.device         = 0x40;                   /* FIS FUA clear */
11021
11022  fis->d.lbaLowExp      = lba1;                   /* FIS LBA (31:24) */
11023  fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
11024  fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
11025  fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
11026  fis->d.sectorCountExp = 0;
11027  fis->d.reserved4      = 0;
11028  fis->d.control        = 0;                      /* FIS HOB bit clear */
11029  fis->d.reserved5      = 0;
11030
11031  agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
11032
11033  /* Initialize CB for SATA completion.
11034   */
11035  satIOContext->satCompleteCB = &satWriteSame10CB;
11036
11037  /*
11038   * Prepare SGL and send FIS to LL layer.
11039   */
11040  satIOContext->reqType = agRequestType;       /* Save it */
11041
11042  status = sataLLIOStart( tiRoot,
11043                          tiIORequest,
11044                          tiDeviceHandle,
11045                          tiScsiRequest,
11046                          satIOContext);
11047
11048  TI_DBG5(("satWriteSame10_2 return status %d\n", status));
11049  return status;
11050}
11051/*****************************************************************************/
11052/*! \brief SAT implementation for SCSI satWriteSame16.
11053 *
11054 *  SAT implementation for SCSI satWriteSame16.
11055 *
11056 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11057 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11058 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11059 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11060 *  \param   satIOContext_t:   Pointer to the SAT IO Context
11061 *
11062 *  \return If command is started successfully
11063 *    - \e tiSuccess:     I/O request successfully initiated.
11064 *    - \e tiBusy:        No resources available, try again later.
11065 *    - \e tiIONoDevice:  Invalid device handle.
11066 *    - \e tiError:       Other errors.
11067 */
11068/*****************************************************************************/
11069GLOBAL bit32  satWriteSame16(
11070                   tiRoot_t                  *tiRoot,
11071                   tiIORequest_t             *tiIORequest,
11072                   tiDeviceHandle_t          *tiDeviceHandle,
11073                   tiScsiInitiatorRequest_t *tiScsiRequest,
11074                   satIOContext_t            *satIOContext)
11075{
11076  scsiRspSense_t            *pSense;
11077
11078  pSense        = satIOContext->pSense;
11079
11080  TI_DBG5(("satWriteSame16:start\n"));
11081
11082
11083  satSetSensePayload( pSense,
11084                      SCSI_SNSKEY_NO_SENSE,
11085                      0,
11086                      SCSI_SNSCODE_NO_ADDITIONAL_INFO,
11087                      satIOContext);
11088
11089  ostiInitiatorIOCompleted( tiRoot,
11090                            tiIORequest, /* == &satIntIo->satOrgTiIORequest */
11091                            tiIOSuccess,
11092                            SCSI_STAT_CHECK_CONDITION,
11093                            satIOContext->pTiSenseData,
11094                            satIOContext->interruptContext );
11095  TI_DBG5(("satWriteSame16: return internal checking\n"));
11096  return tiSuccess;
11097}
11098
11099/*****************************************************************************/
11100/*! \brief SAT implementation for SCSI satLogSense_1.
11101 *
11102 *  Part of SAT implementation for SCSI satLogSense.
11103 *
11104 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11105 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11106 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11107 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11108 *  \param   satIOContext_t:   Pointer to the SAT IO Context
11109 *
11110 *  \return If command is started successfully
11111 *    - \e tiSuccess:     I/O request successfully initiated.
11112 *    - \e tiBusy:        No resources available, try again later.
11113 *    - \e tiIONoDevice:  Invalid device handle.
11114 *    - \e tiError:       Other errors.
11115 */
11116/*****************************************************************************/
11117GLOBAL bit32  satLogSense_1(
11118                   tiRoot_t                  *tiRoot,
11119                   tiIORequest_t             *tiIORequest,
11120                   tiDeviceHandle_t          *tiDeviceHandle,
11121                   tiScsiInitiatorRequest_t *tiScsiRequest,
11122                   satIOContext_t            *satIOContext)
11123{
11124  bit32                     status;
11125  bit32                     agRequestType;
11126  satDeviceData_t           *pSatDevData;
11127  agsaFisRegHostToDevice_t  *fis;
11128
11129  pSatDevData   = satIOContext->pSatDevData;
11130  fis           = satIOContext->pFis;
11131
11132  TI_DBG5(("satLogSense_1: start\n"));
11133
11134
11135  /* SAT Rev 8, 10.2.4 p74 */
11136  if ( pSatDevData->sat48BitSupport == agTRUE )
11137  {
11138    TI_DBG5(("satLogSense_1: case 2-1 sends READ LOG EXT\n"));
11139    /* sends READ LOG EXT */
11140    fis->h.fisType        = 0x27;                   /* Reg host to device */
11141    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11142
11143    fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
11144    fis->h.features       = 0;                      /* FIS reserve */
11145    fis->d.lbaLow         = 0x07;                   /* 0x07 */
11146    fis->d.lbaMid         = 0;                      /*  */
11147    fis->d.lbaHigh        = 0;                      /*  */
11148    fis->d.device         = 0;                      /*  */
11149    fis->d.lbaLowExp      = 0;                      /*  */
11150    fis->d.lbaMidExp      = 0;                      /*  */
11151    fis->d.lbaHighExp     = 0;                      /*  */
11152    fis->d.featuresExp    = 0;                      /* FIS reserve */
11153    fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
11154    fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
11155    fis->d.reserved4      = 0;
11156    fis->d.control        = 0;                      /* FIS HOB bit clear */
11157    fis->d.reserved5      = 0;
11158
11159    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11160
11161    /* Initialize CB for SATA completion.
11162     */
11163    satIOContext->satCompleteCB = &satLogSenseCB;
11164
11165    /*
11166     * Prepare SGL and send FIS to LL layer.
11167     */
11168    satIOContext->reqType = agRequestType;       /* Save it */
11169
11170    status = sataLLIOStart( tiRoot,
11171                            tiIORequest,
11172                            tiDeviceHandle,
11173                            tiScsiRequest,
11174                            satIOContext);
11175    return status;
11176
11177  }
11178  else
11179  {
11180    TI_DBG5(("satLogSense_1: case 2-2 sends SMART READ LOG\n"));
11181    /* sends SMART READ LOG */
11182    fis->h.fisType        = 0x27;                   /* Reg host to device */
11183    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11184
11185    fis->h.command        = SAT_SMART_READ_LOG;     /* 0x2F */
11186    fis->h.features       = 0x00;                   /* 0xd5 */
11187    fis->d.lbaLow         = 0x06;                   /* 0x06 */
11188    fis->d.lbaMid         = 0x00;                   /* 0x4f */
11189    fis->d.lbaHigh        = 0x00;                   /* 0xc2 */
11190    fis->d.device         = 0;                      /*  */
11191    fis->d.lbaLowExp      = 0;                      /*  */
11192    fis->d.lbaMidExp      = 0;                      /*  */
11193    fis->d.lbaHighExp     = 0;                      /*  */
11194    fis->d.featuresExp    = 0;                      /* FIS reserve */
11195    fis->d.sectorCount    = 0x01;                      /*  */
11196    fis->d.sectorCountExp = 0x00;                      /*  */
11197    fis->d.reserved4      = 0;
11198    fis->d.control        = 0;                      /* FIS HOB bit clear */
11199    fis->d.reserved5      = 0;
11200
11201    agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11202
11203    /* Initialize CB for SATA completion.
11204     */
11205    satIOContext->satCompleteCB = &satLogSenseCB;
11206
11207    /*
11208     * Prepare SGL and send FIS to LL layer.
11209     */
11210    satIOContext->reqType = agRequestType;       /* Save it */
11211
11212    status = sataLLIOStart( tiRoot,
11213                            tiIORequest,
11214                            tiDeviceHandle,
11215                            tiScsiRequest,
11216                            satIOContext);
11217    return status;
11218
11219  }
11220}
11221
11222/*****************************************************************************/
11223/*! \brief SAT implementation for SCSI satSMARTEnable.
11224 *
11225 *  Part of SAT implementation for SCSI satLogSense.
11226 *
11227 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11228 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11229 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11230 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11231 *  \param   satIOContext_t:   Pointer to the SAT IO Context
11232 *
11233 *  \return If command is started successfully
11234 *    - \e tiSuccess:     I/O request successfully initiated.
11235 *    - \e tiBusy:        No resources available, try again later.
11236 *    - \e tiIONoDevice:  Invalid device handle.
11237 *    - \e tiError:       Other errors.
11238 */
11239/*****************************************************************************/
11240GLOBAL bit32  satSMARTEnable(
11241                   tiRoot_t                  *tiRoot,
11242                   tiIORequest_t             *tiIORequest,
11243                   tiDeviceHandle_t          *tiDeviceHandle,
11244                   tiScsiInitiatorRequest_t *tiScsiRequest,
11245                   satIOContext_t            *satIOContext)
11246{
11247  bit32                     status;
11248  bit32                     agRequestType;
11249  agsaFisRegHostToDevice_t  *fis;
11250
11251  TI_DBG4(("satSMARTEnable entry: tiDeviceHandle=%p tiIORequest=%p\n",
11252      tiDeviceHandle, tiIORequest));
11253
11254  fis               = satIOContext->pFis;
11255
11256  /*
11257   * Send the SAT_SMART_ENABLE_OPERATIONS command.
11258   */
11259  fis->h.fisType        = 0x27;                   /* Reg host to device */
11260  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11261
11262  fis->h.command        = SAT_SMART_ENABLE_OPERATIONS;   /* 0xB0 */
11263  fis->h.features       = 0xD8;
11264  fis->d.lbaLow         = 0;
11265  fis->d.lbaMid         = 0x4F;
11266  fis->d.lbaHigh        = 0xC2;
11267  fis->d.device         = 0;
11268  fis->d.lbaLowExp      = 0;
11269  fis->d.lbaMidExp      = 0;
11270  fis->d.lbaHighExp     = 0;
11271  fis->d.featuresExp    = 0;
11272  fis->d.sectorCount    = 0;
11273  fis->d.sectorCountExp = 0;
11274  fis->d.reserved4      = 0;
11275  fis->d.control        = 0;                      /* FIS HOB bit clear */
11276  fis->d.reserved5      = 0;
11277
11278  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11279
11280  /* Initialize CB for SATA completion.
11281   */
11282  satIOContext->satCompleteCB = &satSMARTEnableCB;
11283
11284  /*
11285   * Prepare SGL and send FIS to LL layer.
11286   */
11287  satIOContext->reqType = agRequestType;       /* Save it */
11288
11289  status = sataLLIOStart( tiRoot,
11290                          tiIORequest,
11291                          tiDeviceHandle,
11292                          tiScsiRequest,
11293                          satIOContext);
11294
11295
11296  return status;
11297}
11298
11299/*****************************************************************************/
11300/*! \brief SAT implementation for SCSI satLogSense_3.
11301 *
11302 *  Part of SAT implementation for SCSI satLogSense.
11303 *
11304 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11305 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11306 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11307 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11308 *  \param   satIOContext_t:   Pointer to the SAT IO Context
11309 *
11310 *  \return If command is started successfully
11311 *    - \e tiSuccess:     I/O request successfully initiated.
11312 *    - \e tiBusy:        No resources available, try again later.
11313 *    - \e tiIONoDevice:  Invalid device handle.
11314 *    - \e tiError:       Other errors.
11315 */
11316/*****************************************************************************/
11317GLOBAL bit32  satLogSense_3(
11318                   tiRoot_t                  *tiRoot,
11319                   tiIORequest_t             *tiIORequest,
11320                   tiDeviceHandle_t          *tiDeviceHandle,
11321                   tiScsiInitiatorRequest_t *tiScsiRequest,
11322                   satIOContext_t            *satIOContext)
11323{
11324  bit32                     status;
11325  bit32                     agRequestType;
11326  agsaFisRegHostToDevice_t  *fis;
11327
11328  TI_DBG4(("satLogSense_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11329      tiDeviceHandle, tiIORequest));
11330
11331  fis               = satIOContext->pFis;
11332  /* sends READ LOG EXT */
11333  fis->h.fisType        = 0x27;                   /* Reg host to device */
11334  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11335
11336  fis->h.command        = SAT_SMART_READ_LOG;     /* 0x2F */
11337  fis->h.features       = 0xD5;                   /* 0xd5 */
11338  fis->d.lbaLow         = 0x06;                   /* 0x06 */
11339  fis->d.lbaMid         = 0x4F;                   /* 0x4f */
11340  fis->d.lbaHigh        = 0xC2;                   /* 0xc2 */
11341  fis->d.device         = 0;                      /*  */
11342  fis->d.lbaLowExp      = 0;                      /*  */
11343  fis->d.lbaMidExp      = 0;                      /*  */
11344  fis->d.lbaHighExp     = 0;                      /*  */
11345  fis->d.featuresExp    = 0;                      /* FIS reserve */
11346  fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
11347  fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
11348  fis->d.reserved4      = 0;
11349  fis->d.control        = 0;                      /* FIS HOB bit clear */
11350  fis->d.reserved5      = 0;
11351
11352  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11353
11354  /* Initialize CB for SATA completion.
11355   */
11356  satIOContext->satCompleteCB = &satLogSenseCB;
11357
11358  /*
11359   * Prepare SGL and send FIS to LL layer.
11360   */
11361  satIOContext->reqType = agRequestType;       /* Save it */
11362
11363  status = sataLLIOStart( tiRoot,
11364                          tiIORequest,
11365                          tiDeviceHandle,
11366                          tiScsiRequest,
11367                          satIOContext);
11368  return status;
11369}
11370
11371/*****************************************************************************/
11372/*! \brief SAT implementation for SCSI satLogSense_2.
11373 *
11374 *  Part of SAT implementation for SCSI satLogSense.
11375 *
11376 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11377 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11378 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11379 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11380 *  \param   satIOContext_t:   Pointer to the SAT IO Context
11381 *
11382 *  \return If command is started successfully
11383 *    - \e tiSuccess:     I/O request successfully initiated.
11384 *    - \e tiBusy:        No resources available, try again later.
11385 *    - \e tiIONoDevice:  Invalid device handle.
11386 *    - \e tiError:       Other errors.
11387 */
11388/*****************************************************************************/
11389GLOBAL bit32  satLogSense_2(
11390                   tiRoot_t                  *tiRoot,
11391                   tiIORequest_t             *tiIORequest,
11392                   tiDeviceHandle_t          *tiDeviceHandle,
11393                   tiScsiInitiatorRequest_t *tiScsiRequest,
11394                   satIOContext_t            *satIOContext)
11395{
11396  bit32                     status;
11397  bit32                     agRequestType;
11398  agsaFisRegHostToDevice_t  *fis;
11399
11400  TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11401      tiDeviceHandle, tiIORequest));
11402
11403  fis               = satIOContext->pFis;
11404  /* sends READ LOG EXT */
11405  fis->h.fisType        = 0x27;                   /* Reg host to device */
11406  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11407
11408  fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
11409  fis->h.features       = 0;                      /* FIS reserve */
11410  fis->d.lbaLow         = 0x07;                   /* 0x07 */
11411  fis->d.lbaMid         = 0;                      /*  */
11412  fis->d.lbaHigh        = 0;                      /*  */
11413  fis->d.device         = 0;                      /*  */
11414  fis->d.lbaLowExp      = 0;                      /*  */
11415  fis->d.lbaMidExp      = 0;                      /*  */
11416  fis->d.lbaHighExp     = 0;                      /*  */
11417  fis->d.featuresExp    = 0;                      /* FIS reserve */
11418  fis->d.sectorCount    = 0x01;                     /* 1 sector counts */
11419  fis->d.sectorCountExp = 0x00;                      /* 1 sector counts */
11420  fis->d.reserved4      = 0;
11421  fis->d.control        = 0;                      /* FIS HOB bit clear */
11422  fis->d.reserved5      = 0;
11423
11424  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11425
11426  /* Initialize CB for SATA completion.
11427   */
11428  satIOContext->satCompleteCB = &satLogSenseCB;
11429
11430  /*
11431   * Prepare SGL and send FIS to LL layer.
11432   */
11433  satIOContext->reqType = agRequestType;       /* Save it */
11434
11435  status = sataLLIOStart( tiRoot,
11436                          tiIORequest,
11437                          tiDeviceHandle,
11438                          tiScsiRequest,
11439                          satIOContext);
11440  return status;
11441}
11442
11443/*****************************************************************************/
11444/*! \brief SAT implementation for SCSI satLogSenseAllocate.
11445 *
11446 *  Part of SAT implementation for SCSI satLogSense.
11447 *
11448 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11449 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11450 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11451 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11452 *  \param   satIOContext_t:   Pointer to the SAT IO Context
11453 *  \param   payloadSize:      size of payload to be allocated.
11454 *  \param   flag:             flag value
11455 *
11456 *  \return If command is started successfully
11457 *    - \e tiSuccess:     I/O request successfully initiated.
11458 *    - \e tiBusy:        No resources available, try again later.
11459 *    - \e tiIONoDevice:  Invalid device handle.
11460 *    - \e tiError:       Other errors.
11461 *  \note
11462 *    - flag values: LOG_SENSE_0, LOG_SENSE_1, LOG_SENSE_2
11463 */
11464/*****************************************************************************/
11465GLOBAL bit32  satLogSenseAllocate(
11466                   tiRoot_t                  *tiRoot,
11467                   tiIORequest_t             *tiIORequest,
11468                   tiDeviceHandle_t          *tiDeviceHandle,
11469                   tiScsiInitiatorRequest_t *tiScsiRequest,
11470                   satIOContext_t            *satIOContext,
11471                   bit32                      payloadSize,
11472                   bit32                      flag
11473                   )
11474{
11475  satDeviceData_t           *pSatDevData;
11476  tdIORequestBody_t         *tdIORequestBody;
11477  satInternalIo_t           *satIntIo = agNULL;
11478  satIOContext_t            *satIOContext2;
11479  bit32                     status;
11480
11481  TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11482      tiDeviceHandle, tiIORequest));
11483
11484  pSatDevData       = satIOContext->pSatDevData;
11485
11486  /* create internal satIOContext */
11487  satIntIo = satAllocIntIoResource( tiRoot,
11488                                    tiIORequest, /* original request */
11489                                    pSatDevData,
11490                                    payloadSize,
11491                                    satIntIo);
11492
11493  if (satIntIo == agNULL)
11494  {
11495    /* memory allocation failure */
11496    satFreeIntIoResource( tiRoot,
11497                          pSatDevData,
11498                          satIntIo);
11499
11500    ostiInitiatorIOCompleted( tiRoot,
11501                              tiIORequest,
11502                              tiIOFailed,
11503                              tiDetailOtherError,
11504                              agNULL,
11505                              satIOContext->interruptContext );
11506
11507    TI_DBG4(("satLogSense_2: fail in allocation\n"));
11508    return tiSuccess;
11509  } /* end of memory allocation failure */
11510
11511  satIntIo->satOrgTiIORequest = tiIORequest;
11512  tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
11513  satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
11514
11515  satIOContext2->pSatDevData   = pSatDevData;
11516  satIOContext2->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
11517  satIOContext2->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
11518  satIOContext2->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
11519  satIOContext2->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
11520  satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
11521  satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
11522  satIOContext2->interruptContext = satIOContext->interruptContext;
11523  satIOContext2->satIntIoContext  = satIntIo;
11524  satIOContext2->ptiDeviceHandle = tiDeviceHandle;
11525  satIOContext2->satOrgIOContext = satIOContext;
11526
11527  if (flag == LOG_SENSE_0)
11528  {
11529    /* SAT_SMART_ENABLE_OPERATIONS */
11530    status = satSMARTEnable( tiRoot,
11531                         &(satIntIo->satIntTiIORequest),
11532                         tiDeviceHandle,
11533                         &(satIntIo->satIntTiScsiXchg),
11534                         satIOContext2);
11535  }
11536  else if (flag == LOG_SENSE_1)
11537  {
11538    /* SAT_READ_LOG_EXT */
11539    status = satLogSense_2( tiRoot,
11540                         &(satIntIo->satIntTiIORequest),
11541                         tiDeviceHandle,
11542                         &(satIntIo->satIntTiScsiXchg),
11543                         satIOContext2);
11544  }
11545  else
11546  {
11547    /* SAT_SMART_READ_LOG */
11548    /* SAT_READ_LOG_EXT */
11549    status = satLogSense_3( tiRoot,
11550                         &(satIntIo->satIntTiIORequest),
11551                         tiDeviceHandle,
11552                         &(satIntIo->satIntTiScsiXchg),
11553                         satIOContext2);
11554
11555  }
11556  if (status != tiSuccess)
11557  {
11558    satFreeIntIoResource( tiRoot,
11559                          pSatDevData,
11560                          satIntIo);
11561
11562    ostiInitiatorIOCompleted( tiRoot,
11563                              tiIORequest,
11564                              tiIOFailed,
11565                              tiDetailOtherError,
11566                              agNULL,
11567                              satIOContext->interruptContext );
11568    return tiSuccess;
11569  }
11570
11571
11572  return tiSuccess;
11573}
11574
11575
11576/*****************************************************************************/
11577/*! \brief SAT implementation for SCSI satLogSense.
11578 *
11579 *  SAT implementation for SCSI satLogSense.
11580 *
11581 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
11582 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
11583 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
11584 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
11585 *  \param   satIOContext_t:   Pointer to the SAT IO Context
11586 *
11587 *  \return If command is started successfully
11588 *    - \e tiSuccess:     I/O request successfully initiated.
11589 *    - \e tiBusy:        No resources available, try again later.
11590 *    - \e tiIONoDevice:  Invalid device handle.
11591 *    - \e tiError:       Other errors.
11592 */
11593/*****************************************************************************/
11594GLOBAL bit32  satLogSense(
11595                   tiRoot_t                  *tiRoot,
11596                   tiIORequest_t             *tiIORequest,
11597                   tiDeviceHandle_t          *tiDeviceHandle,
11598                   tiScsiInitiatorRequest_t *tiScsiRequest,
11599                   satIOContext_t            *satIOContext)
11600{
11601  bit32                     status;
11602  bit32                     agRequestType;
11603  satDeviceData_t           *pSatDevData;
11604  scsiRspSense_t            *pSense;
11605  tiIniScsiCmnd_t           *scsiCmnd;
11606  agsaFisRegHostToDevice_t  *fis;
11607  bit8                      *pLogPage;    /* Log Page data buffer */
11608  bit32                     flag = 0;
11609  bit16                     AllocLen = 0;       /* allocation length */
11610  bit8                      AllLogPages[8];
11611  bit16                     lenRead = 0;
11612
11613  pSense        = satIOContext->pSense;
11614  pSatDevData   = satIOContext->pSatDevData;
11615  scsiCmnd      = &tiScsiRequest->scsiCmnd;
11616  fis           = satIOContext->pFis;
11617  pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
11618
11619  TI_DBG5(("satLogSense: start\n"));
11620
11621  osti_memset(&AllLogPages, 0, 8);
11622  /* checking CONTROL */
11623  /* NACA == 1 or LINK == 1*/
11624  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
11625  {
11626    satSetSensePayload( pSense,
11627                        SCSI_SNSKEY_ILLEGAL_REQUEST,
11628                        0,
11629                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11630                        satIOContext);
11631
11632    ostiInitiatorIOCompleted( tiRoot,
11633                              tiIORequest,
11634                              tiIOSuccess,
11635                              SCSI_STAT_CHECK_CONDITION,
11636                              satIOContext->pTiSenseData,
11637                              satIOContext->interruptContext );
11638
11639    TI_DBG2(("satLogSense: return control\n"));
11640    return tiSuccess;
11641  }
11642
11643
11644  AllocLen = (bit8)((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
11645
11646  /* checking PC (Page Control) */
11647  /* nothing */
11648
11649  /* special cases */
11650  if (AllocLen == 4)
11651  {
11652    TI_DBG1(("satLogSense: AllocLen is 4\n"));
11653    switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11654    {
11655      case LOGSENSE_SUPPORTED_LOG_PAGES:
11656        TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11657
11658        /* SAT Rev 8, 10.2.5 p76 */
11659        if (pSatDevData->satSMARTFeatureSet == agTRUE)
11660        {
11661          /* add informational exception log */
11662          flag = 1;
11663          if (pSatDevData->satSMARTSelfTest == agTRUE)
11664          {
11665            /* add Self-Test results log page */
11666            flag = 2;
11667          }
11668        }
11669        else
11670        {
11671          /* only supported, no informational exception log, no  Self-Test results log page */
11672          flag = 0;
11673        }
11674        lenRead = 4;
11675        AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES;          /* page code */
11676        AllLogPages[1] = 0;          /* reserved  */
11677        switch (flag)
11678        {
11679          case 0:
11680            /* only supported */
11681            AllLogPages[2] = 0;          /* page length */
11682            AllLogPages[3] = 1;          /* page length */
11683            break;
11684          case 1:
11685            /* supported and informational exception log */
11686            AllLogPages[2] = 0;          /* page length */
11687            AllLogPages[3] = 2;          /* page length */
11688            break;
11689          case 2:
11690            /* supported and informational exception log */
11691            AllLogPages[2] = 0;          /* page length */
11692            AllLogPages[3] = 3;          /* page length */
11693            break;
11694          default:
11695            TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11696            break;
11697        }
11698        osti_memcpy(pLogPage, &AllLogPages, lenRead);
11699        break;
11700      case LOGSENSE_SELFTEST_RESULTS_PAGE:
11701        TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11702        lenRead = 4;
11703        AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE;          /* page code */
11704        AllLogPages[1] = 0;          /* reserved  */
11705        /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */
11706        AllLogPages[2] = 0x01;
11707        AllLogPages[3] = 0x90;       /* page length */
11708        osti_memcpy(pLogPage, &AllLogPages, lenRead);
11709
11710        break;
11711      case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11712        TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11713        lenRead = 4;
11714        AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE;          /* page code */
11715        AllLogPages[1] = 0;          /* reserved  */
11716        AllLogPages[2] = 0;          /* page length */
11717        AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3;       /* page length */
11718        osti_memcpy(pLogPage, &AllLogPages, lenRead);
11719        break;
11720      default:
11721        TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11722        satSetSensePayload( pSense,
11723                            SCSI_SNSKEY_ILLEGAL_REQUEST,
11724                            0,
11725                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11726                            satIOContext);
11727
11728        ostiInitiatorIOCompleted( tiRoot,
11729                                  tiIORequest,
11730                                  tiIOSuccess,
11731                                  SCSI_STAT_CHECK_CONDITION,
11732                                  satIOContext->pTiSenseData,
11733                                  satIOContext->interruptContext );
11734        return tiSuccess;
11735    }
11736    ostiInitiatorIOCompleted( tiRoot,
11737                                tiIORequest,
11738                                tiIOSuccess,
11739                                SCSI_STAT_GOOD,
11740                                agNULL,
11741                                satIOContext->interruptContext);
11742    return tiSuccess;
11743
11744  } /* if */
11745
11746  /* SAT rev8 Table 11  p30*/
11747  /* checking Page Code */
11748  switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11749  {
11750    case LOGSENSE_SUPPORTED_LOG_PAGES:
11751      TI_DBG5(("satLogSense: case 1\n"));
11752
11753      /* SAT Rev 8, 10.2.5 p76 */
11754
11755      if (pSatDevData->satSMARTFeatureSet == agTRUE)
11756      {
11757        /* add informational exception log */
11758        flag = 1;
11759        if (pSatDevData->satSMARTSelfTest == agTRUE)
11760        {
11761          /* add Self-Test results log page */
11762          flag = 2;
11763        }
11764      }
11765      else
11766      {
11767        /* only supported, no informational exception log, no  Self-Test results log page */
11768        flag = 0;
11769      }
11770      AllLogPages[0] = 0;          /* page code */
11771      AllLogPages[1] = 0;          /* reserved  */
11772      switch (flag)
11773      {
11774      case 0:
11775        /* only supported */
11776        AllLogPages[2] = 0;          /* page length */
11777        AllLogPages[3] = 1;          /* page length */
11778        AllLogPages[4] = 0x00;       /* supported page list */
11779        lenRead = (bit8)(MIN(AllocLen, 5));
11780        break;
11781      case 1:
11782        /* supported and informational exception log */
11783        AllLogPages[2] = 0;          /* page length */
11784        AllLogPages[3] = 2;          /* page length */
11785        AllLogPages[4] = 0x00;       /* supported page list */
11786        AllLogPages[5] = 0x10;       /* supported page list */
11787        lenRead = (bit8)(MIN(AllocLen, 6));
11788        break;
11789      case 2:
11790        /* supported and informational exception log */
11791        AllLogPages[2] = 0;          /* page length */
11792        AllLogPages[3] = 3;          /* page length */
11793        AllLogPages[4] = 0x00;       /* supported page list */
11794        AllLogPages[5] = 0x10;       /* supported page list */
11795        AllLogPages[6] = 0x2F;       /* supported page list */
11796       lenRead = (bit8)(MIN(AllocLen, 7));
11797       break;
11798      default:
11799        TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11800        break;
11801      }
11802
11803      osti_memcpy(pLogPage, &AllLogPages, lenRead);
11804      /* comparing allocation length to Log Page byte size */
11805      /* SPC-4, 4.3.4.6, p28 */
11806      if (AllocLen > lenRead )
11807      {
11808        TI_DBG1(("satLogSense reporting underrun lenRead=0x%x AllocLen=0x%x tiIORequest=%p\n", lenRead, AllocLen, tiIORequest));
11809       ostiInitiatorIOCompleted( tiRoot,
11810                                  tiIORequest,
11811                                  tiIOUnderRun,
11812                                  AllocLen - lenRead,
11813                                  agNULL,
11814                                  satIOContext->interruptContext );
11815      }
11816      else
11817      {
11818        ostiInitiatorIOCompleted( tiRoot,
11819                                  tiIORequest,
11820                                  tiIOSuccess,
11821                                  SCSI_STAT_GOOD,
11822                                  agNULL,
11823                                  satIOContext->interruptContext);
11824      }
11825      break;
11826    case LOGSENSE_SELFTEST_RESULTS_PAGE:
11827      TI_DBG5(("satLogSense: case 2\n"));
11828      /* checking SMART self-test */
11829      if (pSatDevData->satSMARTSelfTest == agFALSE)
11830      {
11831        TI_DBG5(("satLogSense: case 2 no SMART Self Test\n"));
11832        satSetSensePayload( pSense,
11833                            SCSI_SNSKEY_ILLEGAL_REQUEST,
11834                            0,
11835                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11836                            satIOContext);
11837
11838        ostiInitiatorIOCompleted( tiRoot,
11839                                  tiIORequest,
11840                                  tiIOSuccess,
11841                                  SCSI_STAT_CHECK_CONDITION,
11842                                  satIOContext->pTiSenseData,
11843                                  satIOContext->interruptContext );
11844      }
11845      else
11846      {
11847        /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */
11848        if (pSatDevData->satSMARTEnabled == agFALSE)
11849        {
11850          TI_DBG5(("satLogSense: case 2 calling satSMARTEnable\n"));
11851          status = satLogSenseAllocate(tiRoot,
11852                                       tiIORequest,
11853                                       tiDeviceHandle,
11854                                       tiScsiRequest,
11855                                       satIOContext,
11856                                       0,
11857                                       LOG_SENSE_0
11858                                       );
11859
11860          return status;
11861
11862        }
11863        else
11864        {
11865        /* SAT Rev 8, 10.2.4 p74 */
11866        if ( pSatDevData->sat48BitSupport == agTRUE )
11867        {
11868          TI_DBG5(("satLogSense: case 2-1 sends READ LOG EXT\n"));
11869          status = satLogSenseAllocate(tiRoot,
11870                                       tiIORequest,
11871                                       tiDeviceHandle,
11872                                       tiScsiRequest,
11873                                       satIOContext,
11874                                       512,
11875                                       LOG_SENSE_1
11876                                       );
11877
11878          return status;
11879        }
11880        else
11881        {
11882          TI_DBG5(("satLogSense: case 2-2 sends SMART READ LOG\n"));
11883          status = satLogSenseAllocate(tiRoot,
11884                                       tiIORequest,
11885                                       tiDeviceHandle,
11886                                       tiScsiRequest,
11887                                       satIOContext,
11888                                       512,
11889                                       LOG_SENSE_2
11890                                       );
11891
11892          return status;
11893        }
11894      }
11895      }
11896      break;
11897    case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11898      TI_DBG5(("satLogSense: case 3\n"));
11899      /* checking SMART feature set */
11900      if (pSatDevData->satSMARTFeatureSet == agFALSE)
11901      {
11902        satSetSensePayload( pSense,
11903                            SCSI_SNSKEY_ILLEGAL_REQUEST,
11904                            0,
11905                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11906                            satIOContext);
11907
11908        ostiInitiatorIOCompleted( tiRoot,
11909                                  tiIORequest,
11910                                  tiIOSuccess,
11911                                  SCSI_STAT_CHECK_CONDITION,
11912                                  satIOContext->pTiSenseData,
11913                                  satIOContext->interruptContext );
11914      }
11915      else
11916      {
11917        /* checking SMART feature enabled */
11918        if (pSatDevData->satSMARTEnabled == agFALSE)
11919        {
11920          satSetSensePayload( pSense,
11921                              SCSI_SNSKEY_ABORTED_COMMAND,
11922                              0,
11923                              SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
11924                              satIOContext);
11925
11926          ostiInitiatorIOCompleted( tiRoot,
11927                                    tiIORequest,
11928                                    tiIOSuccess,
11929                                    SCSI_STAT_CHECK_CONDITION,
11930                                    satIOContext->pTiSenseData,
11931                                    satIOContext->interruptContext );
11932        }
11933        else
11934        {
11935          /* SAT Rev 8, 10.2.3 p72 */
11936          TI_DBG5(("satLogSense: case 3 sends SMART RETURN STATUS\n"));
11937
11938          /* sends SMART RETURN STATUS */
11939          fis->h.fisType        = 0x27;                   /* Reg host to device */
11940          fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
11941
11942          fis->h.command        = SAT_SMART_RETURN_STATUS;/* 0xB0 */
11943          fis->h.features       = 0xDA;                   /* FIS features */
11944          fis->d.featuresExp    = 0;                      /* FIS reserve */
11945          fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
11946          fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
11947          fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
11948          fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
11949          fis->d.lbaMid         = 0x4F;                   /* FIS LBA (15:8 ) */
11950          fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
11951          fis->d.lbaHigh        = 0xC2;                   /* FIS LBA (23:16) */
11952          fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
11953          fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
11954          fis->d.control        = 0;                      /* FIS HOB bit clear */
11955          fis->d.reserved4      = 0;
11956          fis->d.reserved5      = 0;
11957
11958          agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11959          /* Initialize CB for SATA completion.
11960           */
11961          satIOContext->satCompleteCB = &satLogSenseCB;
11962
11963          /*
11964           * Prepare SGL and send FIS to LL layer.
11965           */
11966          satIOContext->reqType = agRequestType;       /* Save it */
11967
11968          status = sataLLIOStart( tiRoot,
11969                                  tiIORequest,
11970                                  tiDeviceHandle,
11971                                  tiScsiRequest,
11972                                  satIOContext);
11973
11974
11975          return status;
11976        }
11977      }
11978      break;
11979    default:
11980      TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11981      satSetSensePayload( pSense,
11982                          SCSI_SNSKEY_ILLEGAL_REQUEST,
11983                          0,
11984                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11985                          satIOContext);
11986
11987      ostiInitiatorIOCompleted( tiRoot,
11988                                tiIORequest,
11989                                tiIOSuccess,
11990                                SCSI_STAT_CHECK_CONDITION,
11991                                satIOContext->pTiSenseData,
11992                                satIOContext->interruptContext );
11993
11994      break;
11995  } /* end switch */
11996
11997  return tiSuccess;
11998
11999
12000}
12001
12002/*****************************************************************************/
12003/*! \brief SAT implementation for SCSI satModeSelect6.
12004 *
12005 *  SAT implementation for SCSI satModeSelect6.
12006 *
12007 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
12008 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
12009 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
12010 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
12011 *  \param   satIOContext_t:   Pointer to the SAT IO Context
12012 *
12013 *  \return If command is started successfully
12014 *    - \e tiSuccess:     I/O request successfully initiated.
12015 *    - \e tiBusy:        No resources available, try again later.
12016 *    - \e tiIONoDevice:  Invalid device handle.
12017 *    - \e tiError:       Other errors.
12018 */
12019/*****************************************************************************/
12020GLOBAL bit32  satModeSelect6(
12021                   tiRoot_t                  *tiRoot,
12022                   tiIORequest_t             *tiIORequest,
12023                   tiDeviceHandle_t          *tiDeviceHandle,
12024                   tiScsiInitiatorRequest_t *tiScsiRequest,
12025                   satIOContext_t            *satIOContext)
12026{
12027  bit32                     status;
12028  bit32                     agRequestType;
12029  satDeviceData_t           *pSatDevData;
12030  scsiRspSense_t            *pSense;
12031  tiIniScsiCmnd_t           *scsiCmnd;
12032  agsaFisRegHostToDevice_t  *fis;
12033  bit8                      *pLogPage;    /* Log Page data buffer */
12034  bit32                     StartingIndex = 0;
12035  bit8                      PageCode = 0;
12036  bit32                     chkCnd = agFALSE;
12037
12038  pSense        = satIOContext->pSense;
12039  pSatDevData   = satIOContext->pSatDevData;
12040  scsiCmnd      = &tiScsiRequest->scsiCmnd;
12041  fis           = satIOContext->pFis;
12042  pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
12043
12044  TI_DBG5(("satModeSelect6: start\n"));
12045
12046  /* checking CONTROL */
12047  /* NACA == 1 or LINK == 1*/
12048  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
12049  {
12050    satSetSensePayload( pSense,
12051                        SCSI_SNSKEY_ILLEGAL_REQUEST,
12052                        0,
12053                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12054                        satIOContext);
12055
12056    ostiInitiatorIOCompleted( tiRoot,
12057                              tiIORequest,
12058                              tiIOSuccess,
12059                              SCSI_STAT_CHECK_CONDITION,
12060                              satIOContext->pTiSenseData,
12061                              satIOContext->interruptContext );
12062
12063    TI_DBG2(("satModeSelect6: return control\n"));
12064    return tiSuccess;
12065  }
12066
12067  /* checking PF bit */
12068  if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
12069  {
12070    satSetSensePayload( pSense,
12071                        SCSI_SNSKEY_ILLEGAL_REQUEST,
12072                        0,
12073                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12074                        satIOContext);
12075
12076    ostiInitiatorIOCompleted( tiRoot,
12077                              tiIORequest,
12078                              tiIOSuccess,
12079                              SCSI_STAT_CHECK_CONDITION,
12080                              satIOContext->pTiSenseData,
12081                              satIOContext->interruptContext );
12082
12083    TI_DBG1(("satModeSelect6: PF bit check \n"));
12084    return tiSuccess;
12085
12086  }
12087
12088  /* checking Block Descriptor Length on Mode parameter header(6)*/
12089  if (pLogPage[3] == 8)
12090  {
12091    /* mode parameter block descriptor exists */
12092    PageCode = (bit8)(pLogPage[12] & 0x3F);   /* page code and index is 4 + 8 */
12093    StartingIndex = 12;
12094  }
12095  else if (pLogPage[3] == 0)
12096  {
12097    /* mode parameter block descriptor does not exist */
12098    PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */
12099    StartingIndex = 4;
12100    ostiInitiatorIOCompleted( tiRoot,
12101                              tiIORequest,
12102                              tiIOSuccess,
12103                              SCSI_STAT_GOOD,
12104                              agNULL,
12105                              satIOContext->interruptContext);
12106    return tiSuccess;
12107  }
12108  else
12109  {
12110    TI_DBG1(("satModeSelect6: return mode parameter block descriptor 0x%x\n", pLogPage[3]));
12111    /* no more than one mode parameter block descriptor shall be supported */
12112    satSetSensePayload( pSense,
12113                        SCSI_SNSKEY_NO_SENSE,
12114                        0,
12115                        SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12116                        satIOContext);
12117
12118    ostiInitiatorIOCompleted( tiRoot,
12119                              tiIORequest,
12120                              tiIOSuccess,
12121                              SCSI_STAT_CHECK_CONDITION,
12122                              satIOContext->pTiSenseData,
12123                              satIOContext->interruptContext );
12124    return tiSuccess;
12125  }
12126
12127
12128
12129  switch (PageCode) /* page code */
12130  {
12131  case MODESELECT_CONTROL_PAGE:
12132    TI_DBG1(("satModeSelect6: Control mode page\n"));
12133    /*
12134      compare pLogPage to expected value (SAT Table 65, p67)
12135      If not match, return check condition
12136     */
12137    if ( pLogPage[StartingIndex+1] != 0x0A ||
12138         pLogPage[StartingIndex+2] != 0x02 ||
12139         (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12140         (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12141         (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12142         (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12143         (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12144
12145         (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12146         (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12147         (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12148         (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12149
12150         pLogPage[StartingIndex+8] != 0xFF ||
12151         pLogPage[StartingIndex+9] != 0xFF ||
12152         pLogPage[StartingIndex+10] != 0x00 ||
12153         pLogPage[StartingIndex+11] != 0x00
12154       )
12155    {
12156      chkCnd = agTRUE;
12157    }
12158    if (chkCnd == agTRUE)
12159    {
12160      satSetSensePayload( pSense,
12161                        SCSI_SNSKEY_ILLEGAL_REQUEST,
12162                        0,
12163                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12164                        satIOContext);
12165
12166      ostiInitiatorIOCompleted( tiRoot,
12167                              tiIORequest,
12168                              tiIOSuccess,
12169                              SCSI_STAT_CHECK_CONDITION,
12170                              satIOContext->pTiSenseData,
12171                              satIOContext->interruptContext );
12172
12173      TI_DBG1(("satModeSelect10: unexpected values\n"));
12174    }
12175    else
12176    {
12177      ostiInitiatorIOCompleted( tiRoot,
12178                                tiIORequest,
12179                                tiIOSuccess,
12180                                SCSI_STAT_GOOD,
12181                                agNULL,
12182                                satIOContext->interruptContext);
12183    }
12184    return tiSuccess;
12185    break;
12186  case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12187    TI_DBG1(("satModeSelect6: Read-Write Error Recovery mode page\n"));
12188
12189    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) ||
12190         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) ||
12191         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) ||
12192         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) ||
12193         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) ||
12194         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) ||
12195         (pLogPage[StartingIndex + 10]) ||
12196         (pLogPage[StartingIndex + 11])
12197         )
12198    {
12199      TI_DBG5(("satModeSelect6: return check condition \n"));
12200
12201      satSetSensePayload( pSense,
12202                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12203                          0,
12204                          SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12205                          satIOContext);
12206
12207      ostiInitiatorIOCompleted( tiRoot,
12208                                tiIORequest,
12209                                tiIOSuccess,
12210                                SCSI_STAT_CHECK_CONDITION,
12211                                satIOContext->pTiSenseData,
12212                                satIOContext->interruptContext );
12213      return tiSuccess;
12214    }
12215    else
12216    {
12217      TI_DBG5(("satModeSelect6: return GOOD \n"));
12218      ostiInitiatorIOCompleted( tiRoot,
12219                                tiIORequest,
12220                                tiIOSuccess,
12221                                SCSI_STAT_GOOD,
12222                                agNULL,
12223                                satIOContext->interruptContext);
12224      return tiSuccess;
12225    }
12226
12227    break;
12228  case MODESELECT_CACHING:
12229    /* SAT rev8 Table67, p69*/
12230    TI_DBG5(("satModeSelect6: Caching mode page\n"));
12231    if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12232         (pLogPage[StartingIndex + 3]) ||
12233         (pLogPage[StartingIndex + 4]) ||
12234         (pLogPage[StartingIndex + 5]) ||
12235         (pLogPage[StartingIndex + 6]) ||
12236         (pLogPage[StartingIndex + 7]) ||
12237         (pLogPage[StartingIndex + 8]) ||
12238         (pLogPage[StartingIndex + 9]) ||
12239         (pLogPage[StartingIndex + 10]) ||
12240         (pLogPage[StartingIndex + 11]) ||
12241
12242         (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12243         (pLogPage[StartingIndex + 13]) ||
12244         (pLogPage[StartingIndex + 14]) ||
12245         (pLogPage[StartingIndex + 15])
12246         )
12247    {
12248      TI_DBG1(("satModeSelect6: return check condition \n"));
12249
12250      satSetSensePayload( pSense,
12251                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12252                          0,
12253                          SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12254                          satIOContext);
12255
12256      ostiInitiatorIOCompleted( tiRoot,
12257                                tiIORequest,
12258                                tiIOSuccess,
12259                                SCSI_STAT_CHECK_CONDITION,
12260                                satIOContext->pTiSenseData,
12261                                satIOContext->interruptContext );
12262      return tiSuccess;
12263
12264    }
12265    else
12266    {
12267      /* sends ATA SET FEATURES based on WCE bit */
12268      if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
12269      {
12270        TI_DBG5(("satModeSelect6: disable write cache\n"));
12271        /* sends SET FEATURES */
12272        fis->h.fisType        = 0x27;                   /* Reg host to device */
12273        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12274
12275        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12276        fis->h.features       = 0x82;                   /* disable write cache */
12277        fis->d.lbaLow         = 0;                      /* */
12278        fis->d.lbaMid         = 0;                      /* */
12279        fis->d.lbaHigh        = 0;                      /* */
12280        fis->d.device         = 0;                      /* */
12281        fis->d.lbaLowExp      = 0;                      /* */
12282        fis->d.lbaMidExp      = 0;                      /* */
12283        fis->d.lbaHighExp     = 0;                      /* */
12284        fis->d.featuresExp    = 0;                      /* */
12285        fis->d.sectorCount    = 0;                      /* */
12286        fis->d.sectorCountExp = 0;                      /* */
12287        fis->d.reserved4      = 0;
12288        fis->d.control        = 0;                      /* FIS HOB bit clear */
12289        fis->d.reserved5      = 0;
12290
12291        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12292
12293        /* Initialize CB for SATA completion.
12294         */
12295        satIOContext->satCompleteCB = &satModeSelect6n10CB;
12296
12297        /*
12298         * Prepare SGL and send FIS to LL layer.
12299         */
12300        satIOContext->reqType = agRequestType;       /* Save it */
12301
12302        status = sataLLIOStart( tiRoot,
12303                                tiIORequest,
12304                                tiDeviceHandle,
12305                                tiScsiRequest,
12306                                satIOContext);
12307        return status;
12308      }
12309      else
12310      {
12311        TI_DBG5(("satModeSelect6: enable write cache\n"));
12312        /* sends SET FEATURES */
12313        fis->h.fisType        = 0x27;                   /* Reg host to device */
12314        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12315
12316        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12317        fis->h.features       = 0x02;                   /* enable write cache */
12318        fis->d.lbaLow         = 0;                      /* */
12319        fis->d.lbaMid         = 0;                      /* */
12320        fis->d.lbaHigh        = 0;                      /* */
12321        fis->d.device         = 0;                      /* */
12322        fis->d.lbaLowExp      = 0;                      /* */
12323        fis->d.lbaMidExp      = 0;                      /* */
12324        fis->d.lbaHighExp     = 0;                      /* */
12325        fis->d.featuresExp    = 0;                      /* */
12326        fis->d.sectorCount    = 0;                      /* */
12327        fis->d.sectorCountExp = 0;                      /* */
12328        fis->d.reserved4      = 0;
12329        fis->d.control        = 0;                      /* FIS HOB bit clear */
12330        fis->d.reserved5      = 0;
12331
12332        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12333
12334        /* Initialize CB for SATA completion.
12335         */
12336        satIOContext->satCompleteCB = &satModeSelect6n10CB;
12337
12338        /*
12339         * Prepare SGL and send FIS to LL layer.
12340         */
12341        satIOContext->reqType = agRequestType;       /* Save it */
12342
12343        status = sataLLIOStart( tiRoot,
12344                                tiIORequest,
12345                                tiDeviceHandle,
12346                                tiScsiRequest,
12347                                satIOContext);
12348        return status;
12349
12350      }
12351    }
12352    break;
12353  case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
12354    TI_DBG5(("satModeSelect6: Informational Exception Control mode page\n"));
12355    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
12356         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
12357         )
12358    {
12359      TI_DBG1(("satModeSelect6: return check condition \n"));
12360
12361      satSetSensePayload( pSense,
12362                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12363                          0,
12364                          SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12365                          satIOContext);
12366
12367      ostiInitiatorIOCompleted( tiRoot,
12368                                tiIORequest,
12369                                tiIOSuccess,
12370                                SCSI_STAT_CHECK_CONDITION,
12371                                satIOContext->pTiSenseData,
12372                                satIOContext->interruptContext );
12373      return tiSuccess;
12374    }
12375    else
12376    {
12377      /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
12378      if ( !(pLogPage[StartingIndex + 2] & 0x08) )
12379      {
12380        TI_DBG5(("satModeSelect6: enable information exceptions reporting\n"));
12381        /* sends SMART ENABLE OPERATIONS */
12382        fis->h.fisType        = 0x27;                   /* Reg host to device */
12383        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12384
12385        fis->h.command        = SAT_SMART_ENABLE_OPERATIONS;       /* 0xB0 */
12386        fis->h.features       = 0xD8;                   /* enable */
12387        fis->d.lbaLow         = 0;                      /* */
12388        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
12389        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
12390        fis->d.device         = 0;                      /* */
12391        fis->d.lbaLowExp      = 0;                      /* */
12392        fis->d.lbaMidExp      = 0;                      /* */
12393        fis->d.lbaHighExp     = 0;                      /* */
12394        fis->d.featuresExp    = 0;                      /* */
12395        fis->d.sectorCount    = 0;                      /* */
12396        fis->d.sectorCountExp = 0;                      /* */
12397        fis->d.reserved4      = 0;
12398        fis->d.control        = 0;                      /* FIS HOB bit clear */
12399        fis->d.reserved5      = 0;
12400
12401        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12402
12403        /* Initialize CB for SATA completion.
12404         */
12405        satIOContext->satCompleteCB = &satModeSelect6n10CB;
12406
12407        /*
12408         * Prepare SGL and send FIS to LL layer.
12409         */
12410        satIOContext->reqType = agRequestType;       /* Save it */
12411
12412        status = sataLLIOStart( tiRoot,
12413                                tiIORequest,
12414                                tiDeviceHandle,
12415                                tiScsiRequest,
12416                                satIOContext);
12417        return status;
12418      }
12419      else
12420      {
12421        TI_DBG5(("satModeSelect6: disable information exceptions reporting\n"));
12422        /* sends SMART DISABLE OPERATIONS */
12423        fis->h.fisType        = 0x27;                   /* Reg host to device */
12424        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12425
12426        fis->h.command        = SAT_SMART_DISABLE_OPERATIONS;       /* 0xB0 */
12427        fis->h.features       = 0xD9;                   /* disable */
12428        fis->d.lbaLow         = 0;                      /* */
12429        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
12430        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
12431        fis->d.device         = 0;                      /* */
12432        fis->d.lbaLowExp      = 0;                      /* */
12433        fis->d.lbaMidExp      = 0;                      /* */
12434        fis->d.lbaHighExp     = 0;                      /* */
12435        fis->d.featuresExp    = 0;                      /* */
12436        fis->d.sectorCount    = 0;                      /* */
12437        fis->d.sectorCountExp = 0;                      /* */
12438        fis->d.reserved4      = 0;
12439        fis->d.control        = 0;                      /* FIS HOB bit clear */
12440        fis->d.reserved5      = 0;
12441
12442        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12443
12444        /* Initialize CB for SATA completion.
12445         */
12446        satIOContext->satCompleteCB = &satModeSelect6n10CB;
12447
12448        /*
12449         * Prepare SGL and send FIS to LL layer.
12450         */
12451        satIOContext->reqType = agRequestType;       /* Save it */
12452
12453        status = sataLLIOStart( tiRoot,
12454                                tiIORequest,
12455                                tiDeviceHandle,
12456                                tiScsiRequest,
12457                                satIOContext);
12458        return status;
12459
12460      }
12461    }
12462    break;
12463  default:
12464    TI_DBG1(("satModeSelect6: Error unknown page code 0x%x\n", pLogPage[12]));
12465    satSetSensePayload( pSense,
12466                        SCSI_SNSKEY_NO_SENSE,
12467                        0,
12468                        SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12469                        satIOContext);
12470
12471    ostiInitiatorIOCompleted( tiRoot,
12472                              tiIORequest,
12473                              tiIOSuccess,
12474                              SCSI_STAT_CHECK_CONDITION,
12475                              satIOContext->pTiSenseData,
12476                              satIOContext->interruptContext );
12477    return tiSuccess;
12478  }
12479
12480}
12481
12482/*****************************************************************************/
12483/*! \brief SAT implementation for SCSI satModeSelect6n10_1.
12484 *
12485 *  This function is part of implementation of ModeSelect6 and ModeSelect10.
12486 *  When ModeSelect6 or ModeSelect10 is coverted into multiple ATA commands,
12487 *  this function is used.
12488 *
12489 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
12490 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
12491 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
12492 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
12493 *  \param   satIOContext_t:   Pointer to the SAT IO Context
12494 *
12495 *  \return If command is started successfully
12496 *    - \e tiSuccess:     I/O request successfully initiated.
12497 *    - \e tiBusy:        No resources available, try again later.
12498 *    - \e tiIONoDevice:  Invalid device handle.
12499 *    - \e tiError:       Other errors.
12500 */
12501/*****************************************************************************/
12502GLOBAL bit32  satModeSelect6n10_1(
12503                   tiRoot_t                  *tiRoot,
12504                   tiIORequest_t             *tiIORequest,
12505                   tiDeviceHandle_t          *tiDeviceHandle,
12506                   tiScsiInitiatorRequest_t *tiScsiRequest,
12507                   satIOContext_t            *satIOContext)
12508{
12509  /* sends either ATA SET FEATURES based on DRA bit */
12510  bit32                     status;
12511  bit32                     agRequestType;
12512  agsaFisRegHostToDevice_t  *fis;
12513  bit8                      *pLogPage;    /* Log Page data buffer */
12514  bit32                     StartingIndex = 0;
12515
12516  fis           = satIOContext->pFis;
12517  pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
12518  TI_DBG5(("satModeSelect6_1: start\n"));
12519  /* checking Block Descriptor Length on Mode parameter header(6)*/
12520  if (pLogPage[3] == 8)
12521  {
12522    /* mode parameter block descriptor exists */
12523    StartingIndex = 12;
12524  }
12525  else
12526  {
12527    /* mode parameter block descriptor does not exist */
12528    StartingIndex = 4;
12529  }
12530
12531  /* sends ATA SET FEATURES based on DRA bit */
12532  if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
12533  {
12534    TI_DBG5(("satModeSelect6_1: enable read look-ahead feature\n"));
12535    /* sends SET FEATURES */
12536    fis->h.fisType        = 0x27;                   /* Reg host to device */
12537    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12538
12539    fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12540    fis->h.features       = 0xAA;                   /* enable read look-ahead */
12541    fis->d.lbaLow         = 0;                      /* */
12542    fis->d.lbaMid         = 0;                      /* */
12543    fis->d.lbaHigh        = 0;                      /* */
12544    fis->d.device         = 0;                      /* */
12545    fis->d.lbaLowExp      = 0;                      /* */
12546    fis->d.lbaMidExp      = 0;                      /* */
12547    fis->d.lbaHighExp     = 0;                      /* */
12548    fis->d.featuresExp    = 0;                      /* */
12549    fis->d.sectorCount    = 0;                      /* */
12550    fis->d.sectorCountExp = 0;                      /* */
12551    fis->d.reserved4      = 0;
12552    fis->d.control        = 0;                      /* FIS HOB bit clear */
12553    fis->d.reserved5      = 0;
12554
12555    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12556
12557    /* Initialize CB for SATA completion.
12558     */
12559    satIOContext->satCompleteCB = &satModeSelect6n10CB;
12560
12561    /*
12562     * Prepare SGL and send FIS to LL layer.
12563     */
12564    satIOContext->reqType = agRequestType;       /* Save it */
12565
12566    status = sataLLIOStart( tiRoot,
12567                            tiIORequest,
12568                            tiDeviceHandle,
12569                            tiScsiRequest,
12570                            satIOContext);
12571    return status;
12572  }
12573  else
12574  {
12575    TI_DBG5(("satModeSelect6_1: disable read look-ahead feature\n"));
12576        /* sends SET FEATURES */
12577    fis->h.fisType        = 0x27;                   /* Reg host to device */
12578    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12579
12580    fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12581    fis->h.features       = 0x55;                   /* disable read look-ahead */
12582    fis->d.lbaLow         = 0;                      /* */
12583    fis->d.lbaMid         = 0;                      /* */
12584    fis->d.lbaHigh        = 0;                      /* */
12585    fis->d.device         = 0;                      /* */
12586    fis->d.lbaLowExp      = 0;                      /* */
12587    fis->d.lbaMidExp      = 0;                      /* */
12588    fis->d.lbaHighExp     = 0;                      /* */
12589    fis->d.featuresExp    = 0;                      /* */
12590    fis->d.sectorCount    = 0;                      /* */
12591    fis->d.sectorCountExp = 0;                      /* */
12592    fis->d.reserved4      = 0;
12593    fis->d.control        = 0;                      /* FIS HOB bit clear */
12594    fis->d.reserved5      = 0;
12595
12596    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12597
12598    /* Initialize CB for SATA completion.
12599     */
12600    satIOContext->satCompleteCB = &satModeSelect6n10CB;
12601
12602    /*
12603     * Prepare SGL and send FIS to LL layer.
12604     */
12605    satIOContext->reqType = agRequestType;       /* Save it */
12606
12607    status = sataLLIOStart( tiRoot,
12608                            tiIORequest,
12609                            tiDeviceHandle,
12610                            tiScsiRequest,
12611                            satIOContext);
12612    return status;
12613  }
12614
12615}
12616
12617
12618/*****************************************************************************/
12619/*! \brief SAT implementation for SCSI satModeSelect10.
12620 *
12621 *  SAT implementation for SCSI satModeSelect10.
12622 *
12623 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
12624 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
12625 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
12626 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
12627 *  \param   satIOContext_t:   Pointer to the SAT IO Context
12628 *
12629 *  \return If command is started successfully
12630 *    - \e tiSuccess:     I/O request successfully initiated.
12631 *    - \e tiBusy:        No resources available, try again later.
12632 *    - \e tiIONoDevice:  Invalid device handle.
12633 *    - \e tiError:       Other errors.
12634 */
12635/*****************************************************************************/
12636GLOBAL bit32  satModeSelect10(
12637                   tiRoot_t                  *tiRoot,
12638                   tiIORequest_t             *tiIORequest,
12639                   tiDeviceHandle_t          *tiDeviceHandle,
12640                   tiScsiInitiatorRequest_t *tiScsiRequest,
12641                   satIOContext_t            *satIOContext)
12642{
12643  bit32                     status;
12644  bit32                     agRequestType;
12645  satDeviceData_t           *pSatDevData;
12646  scsiRspSense_t            *pSense;
12647  tiIniScsiCmnd_t           *scsiCmnd;
12648  agsaFisRegHostToDevice_t  *fis;
12649  bit8                      *pLogPage;    /* Log Page data buffer */
12650  bit16                     BlkDescLen = 0;     /* Block Descriptor Length */
12651  bit32                     StartingIndex = 0;
12652  bit8                      PageCode = 0;
12653  bit32                     chkCnd = agFALSE;
12654
12655  pSense        = satIOContext->pSense;
12656  pSatDevData   = satIOContext->pSatDevData;
12657  scsiCmnd      = &tiScsiRequest->scsiCmnd;
12658  fis           = satIOContext->pFis;
12659  pLogPage      = (bit8 *) tiScsiRequest->sglVirtualAddr;
12660
12661  TI_DBG5(("satModeSelect10: start\n"));
12662
12663  /* checking CONTROL */
12664  /* NACA == 1 or LINK == 1*/
12665  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
12666  {
12667    satSetSensePayload( pSense,
12668                        SCSI_SNSKEY_ILLEGAL_REQUEST,
12669                        0,
12670                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12671                        satIOContext);
12672
12673    ostiInitiatorIOCompleted( tiRoot,
12674                              tiIORequest,
12675                              tiIOSuccess,
12676                              SCSI_STAT_CHECK_CONDITION,
12677                              satIOContext->pTiSenseData,
12678                              satIOContext->interruptContext );
12679
12680    TI_DBG2(("satModeSelect10: return control\n"));
12681    return tiSuccess;
12682  }
12683
12684  /* checking PF bit */
12685  if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
12686  {
12687    satSetSensePayload( pSense,
12688                        SCSI_SNSKEY_ILLEGAL_REQUEST,
12689                        0,
12690                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12691                        satIOContext);
12692
12693    ostiInitiatorIOCompleted( tiRoot,
12694                              tiIORequest,
12695                              tiIOSuccess,
12696                              SCSI_STAT_CHECK_CONDITION,
12697                              satIOContext->pTiSenseData,
12698                              satIOContext->interruptContext );
12699
12700    TI_DBG1(("satModeSelect10: PF bit check \n"));
12701    return tiSuccess;
12702
12703  }
12704
12705  BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]);
12706
12707  /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/
12708  if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12709  {
12710    /* mode parameter block descriptor exists and length is 8 byte */
12711    PageCode = (bit8)(pLogPage[16] & 0x3F);   /* page code and index is 8 + 8 */
12712    StartingIndex = 16;
12713  }
12714  else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12715  {
12716    /* mode parameter block descriptor exists and length is 16 byte */
12717    PageCode = (bit8)(pLogPage[24] & 0x3F);   /* page code and index is 8 + 16 */
12718    StartingIndex = 24;
12719  }
12720  else if (BlkDescLen == 0)
12721  {
12722    /*
12723      mode parameter block descriptor does not exist
12724      */
12725    PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */
12726    StartingIndex = 8;
12727    ostiInitiatorIOCompleted( tiRoot,
12728                              tiIORequest,
12729                              tiIOSuccess,
12730                              SCSI_STAT_GOOD,
12731                              agNULL,
12732                              satIOContext->interruptContext);
12733    return tiSuccess;
12734  }
12735  else
12736  {
12737    TI_DBG1(("satModeSelect10: return mode parameter block descriptor 0x%x\n",  BlkDescLen));
12738    /* no more than one mode parameter block descriptor shall be supported */
12739    satSetSensePayload( pSense,
12740                        SCSI_SNSKEY_NO_SENSE,
12741                        0,
12742                        SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12743                        satIOContext);
12744
12745    ostiInitiatorIOCompleted( tiRoot,
12746                              tiIORequest,
12747                              tiIOSuccess,
12748                              SCSI_STAT_CHECK_CONDITION,
12749                              satIOContext->pTiSenseData,
12750                              satIOContext->interruptContext );
12751    return tiSuccess;
12752  }
12753  /*
12754    for debugging only
12755  */
12756  if (StartingIndex == 8)
12757  {
12758    tdhexdump("startingindex 8", (bit8 *)pLogPage, 8);
12759  }
12760  else if(StartingIndex == 16)
12761  {
12762    if (PageCode == MODESELECT_CACHING)
12763    {
12764      tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
12765    }
12766    else
12767    {
12768      tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
12769    }
12770  }
12771  else
12772  {
12773    if (PageCode == MODESELECT_CACHING)
12774    {
12775      tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
12776    }
12777    else
12778    {
12779      tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
12780    }
12781  }
12782  switch (PageCode) /* page code */
12783  {
12784  case MODESELECT_CONTROL_PAGE:
12785    TI_DBG5(("satModeSelect10: Control mode page\n"));
12786    /*
12787      compare pLogPage to expected value (SAT Table 65, p67)
12788      If not match, return check condition
12789     */
12790    if ( pLogPage[StartingIndex+1] != 0x0A ||
12791         pLogPage[StartingIndex+2] != 0x02 ||
12792         (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12793         (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12794         (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12795         (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12796         (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12797
12798         (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12799         (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12800         (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12801         (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12802
12803         pLogPage[StartingIndex+8] != 0xFF ||
12804         pLogPage[StartingIndex+9] != 0xFF ||
12805         pLogPage[StartingIndex+10] != 0x00 ||
12806         pLogPage[StartingIndex+11] != 0x00
12807       )
12808    {
12809      chkCnd = agTRUE;
12810    }
12811    if (chkCnd == agTRUE)
12812    {
12813      satSetSensePayload( pSense,
12814                        SCSI_SNSKEY_ILLEGAL_REQUEST,
12815                        0,
12816                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12817                        satIOContext);
12818
12819      ostiInitiatorIOCompleted( tiRoot,
12820                              tiIORequest,
12821                              tiIOSuccess,
12822                              SCSI_STAT_CHECK_CONDITION,
12823                              satIOContext->pTiSenseData,
12824                              satIOContext->interruptContext );
12825
12826      TI_DBG1(("satModeSelect10: unexpected values\n"));
12827    }
12828    else
12829    {
12830      ostiInitiatorIOCompleted( tiRoot,
12831                              tiIORequest,
12832                              tiIOSuccess,
12833                              SCSI_STAT_GOOD,
12834                              agNULL,
12835                              satIOContext->interruptContext);
12836    }
12837    return tiSuccess;
12838    break;
12839  case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12840    TI_DBG5(("satModeSelect10: Read-Write Error Recovery mode page\n"));
12841    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) ||
12842         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) ||
12843         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) ||
12844         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) ||
12845         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) ||
12846         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) ||
12847         (pLogPage[StartingIndex + 10]) ||
12848         (pLogPage[StartingIndex + 11])
12849         )
12850    {
12851      TI_DBG1(("satModeSelect10: return check condition \n"));
12852
12853      satSetSensePayload( pSense,
12854                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12855                          0,
12856                          SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12857                          satIOContext);
12858
12859      ostiInitiatorIOCompleted( tiRoot,
12860                                tiIORequest,
12861                                tiIOSuccess,
12862                                SCSI_STAT_CHECK_CONDITION,
12863                                satIOContext->pTiSenseData,
12864                                satIOContext->interruptContext );
12865      return tiSuccess;
12866    }
12867    else
12868    {
12869      TI_DBG2(("satModeSelect10: return GOOD \n"));
12870      ostiInitiatorIOCompleted( tiRoot,
12871                                tiIORequest,
12872                                tiIOSuccess,
12873                                SCSI_STAT_GOOD,
12874                                agNULL,
12875                                satIOContext->interruptContext);
12876      return tiSuccess;
12877    }
12878
12879    break;
12880  case MODESELECT_CACHING:
12881    /* SAT rev8 Table67, p69*/
12882    TI_DBG5(("satModeSelect10: Caching mode page\n"));
12883    if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12884         (pLogPage[StartingIndex + 3]) ||
12885         (pLogPage[StartingIndex + 4]) ||
12886         (pLogPage[StartingIndex + 5]) ||
12887         (pLogPage[StartingIndex + 6]) ||
12888         (pLogPage[StartingIndex + 7]) ||
12889         (pLogPage[StartingIndex + 8]) ||
12890         (pLogPage[StartingIndex + 9]) ||
12891         (pLogPage[StartingIndex + 10]) ||
12892         (pLogPage[StartingIndex + 11]) ||
12893
12894         (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12895         (pLogPage[StartingIndex + 13]) ||
12896         (pLogPage[StartingIndex + 14]) ||
12897         (pLogPage[StartingIndex + 15])
12898         )
12899    {
12900      TI_DBG1(("satModeSelect10: return check condition \n"));
12901
12902      satSetSensePayload( pSense,
12903                          SCSI_SNSKEY_ILLEGAL_REQUEST,
12904                          0,
12905                          SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12906                          satIOContext);
12907
12908      ostiInitiatorIOCompleted( tiRoot,
12909                                tiIORequest,
12910                                tiIOSuccess,
12911                                SCSI_STAT_CHECK_CONDITION,
12912                                satIOContext->pTiSenseData,
12913                                satIOContext->interruptContext );
12914      return tiSuccess;
12915
12916    }
12917    else
12918    {
12919      /* sends ATA SET FEATURES based on WCE bit */
12920      if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
12921      {
12922        TI_DBG5(("satModeSelect10: disable write cache\n"));
12923        /* sends SET FEATURES */
12924        fis->h.fisType        = 0x27;                   /* Reg host to device */
12925        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12926
12927        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12928        fis->h.features       = 0x82;                   /* disable write cache */
12929        fis->d.lbaLow         = 0;                      /* */
12930        fis->d.lbaMid         = 0;                      /* */
12931        fis->d.lbaHigh        = 0;                      /* */
12932        fis->d.device         = 0;                      /* */
12933        fis->d.lbaLowExp      = 0;                      /* */
12934        fis->d.lbaMidExp      = 0;                      /* */
12935        fis->d.lbaHighExp     = 0;                      /* */
12936        fis->d.featuresExp    = 0;                      /* */
12937        fis->d.sectorCount    = 0;                      /* */
12938        fis->d.sectorCountExp = 0;                      /* */
12939        fis->d.reserved4      = 0;
12940        fis->d.control        = 0;                      /* FIS HOB bit clear */
12941        fis->d.reserved5      = 0;
12942
12943        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12944
12945        /* Initialize CB for SATA completion.
12946         */
12947        satIOContext->satCompleteCB = &satModeSelect6n10CB;
12948
12949        /*
12950         * Prepare SGL and send FIS to LL layer.
12951         */
12952        satIOContext->reqType = agRequestType;       /* Save it */
12953
12954        status = sataLLIOStart( tiRoot,
12955                                tiIORequest,
12956                                tiDeviceHandle,
12957                                tiScsiRequest,
12958                                satIOContext);
12959        return status;
12960      }
12961      else
12962      {
12963        TI_DBG5(("satModeSelect10: enable write cache\n"));
12964        /* sends SET FEATURES */
12965        fis->h.fisType        = 0x27;                   /* Reg host to device */
12966        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
12967
12968        fis->h.command        = SAT_SET_FEATURES;       /* 0xEF */
12969        fis->h.features       = 0x02;                   /* enable write cache */
12970        fis->d.lbaLow         = 0;                      /* */
12971        fis->d.lbaMid         = 0;                      /* */
12972        fis->d.lbaHigh        = 0;                      /* */
12973        fis->d.device         = 0;                      /* */
12974        fis->d.lbaLowExp      = 0;                      /* */
12975        fis->d.lbaMidExp      = 0;                      /* */
12976        fis->d.lbaHighExp     = 0;                      /* */
12977        fis->d.featuresExp    = 0;                      /* */
12978        fis->d.sectorCount    = 0;                      /* */
12979        fis->d.sectorCountExp = 0;                      /* */
12980        fis->d.reserved4      = 0;
12981        fis->d.control        = 0;                      /* FIS HOB bit clear */
12982        fis->d.reserved5      = 0;
12983
12984        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12985
12986        /* Initialize CB for SATA completion.
12987         */
12988        satIOContext->satCompleteCB = &satModeSelect6n10CB;
12989
12990        /*
12991         * Prepare SGL and send FIS to LL layer.
12992         */
12993        satIOContext->reqType = agRequestType;       /* Save it */
12994
12995        status = sataLLIOStart( tiRoot,
12996                                tiIORequest,
12997                                tiDeviceHandle,
12998                                tiScsiRequest,
12999                                satIOContext);
13000        return status;
13001
13002      }
13003    }
13004    break;
13005  case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
13006    TI_DBG5(("satModeSelect10: Informational Exception Control mode page\n"));
13007
13008    if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
13009         (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
13010         )
13011    {
13012      TI_DBG1(("satModeSelect10: return check condition \n"));
13013
13014      satSetSensePayload( pSense,
13015                          SCSI_SNSKEY_ILLEGAL_REQUEST,
13016                          0,
13017                          SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13018                          satIOContext);
13019
13020      ostiInitiatorIOCompleted( tiRoot,
13021                                tiIORequest,
13022                                tiIOSuccess,
13023                                SCSI_STAT_CHECK_CONDITION,
13024                                satIOContext->pTiSenseData,
13025                                satIOContext->interruptContext );
13026      return tiSuccess;
13027    }
13028    else
13029    {
13030      /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
13031      if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
13032      {
13033        TI_DBG5(("satModeSelect10: enable information exceptions reporting\n"));
13034        /* sends SMART ENABLE OPERATIONS */
13035        fis->h.fisType        = 0x27;                   /* Reg host to device */
13036        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13037
13038        fis->h.command        = SAT_SMART_ENABLE_OPERATIONS;       /* 0xB0 */
13039        fis->h.features       = 0xD8;                   /* enable */
13040        fis->d.lbaLow         = 0;                      /* */
13041        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
13042        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
13043        fis->d.device         = 0;                      /* */
13044        fis->d.lbaLowExp      = 0;                      /* */
13045        fis->d.lbaMidExp      = 0;                      /* */
13046        fis->d.lbaHighExp     = 0;                      /* */
13047        fis->d.featuresExp    = 0;                      /* */
13048        fis->d.sectorCount    = 0;                      /* */
13049        fis->d.sectorCountExp = 0;                      /* */
13050        fis->d.reserved4      = 0;
13051        fis->d.control        = 0;                      /* FIS HOB bit clear */
13052        fis->d.reserved5      = 0;
13053
13054        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13055
13056        /* Initialize CB for SATA completion.
13057         */
13058        satIOContext->satCompleteCB = &satModeSelect6n10CB;
13059
13060        /*
13061         * Prepare SGL and send FIS to LL layer.
13062         */
13063        satIOContext->reqType = agRequestType;       /* Save it */
13064
13065        status = sataLLIOStart( tiRoot,
13066                                tiIORequest,
13067                                tiDeviceHandle,
13068                                tiScsiRequest,
13069                                satIOContext);
13070        return status;
13071      }
13072      else
13073      {
13074        TI_DBG5(("satModeSelect10: disable information exceptions reporting\n"));
13075        /* sends SMART DISABLE OPERATIONS */
13076        fis->h.fisType        = 0x27;                   /* Reg host to device */
13077        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13078
13079        fis->h.command        = SAT_SMART_DISABLE_OPERATIONS;       /* 0xB0 */
13080        fis->h.features       = 0xD9;                   /* disable */
13081        fis->d.lbaLow         = 0;                      /* */
13082        fis->d.lbaMid         = 0x4F;                   /* 0x4F */
13083        fis->d.lbaHigh        = 0xC2;                   /* 0xC2 */
13084        fis->d.device         = 0;                      /* */
13085        fis->d.lbaLowExp      = 0;                      /* */
13086        fis->d.lbaMidExp      = 0;                      /* */
13087        fis->d.lbaHighExp     = 0;                      /* */
13088        fis->d.featuresExp    = 0;                      /* */
13089        fis->d.sectorCount    = 0;                      /* */
13090        fis->d.sectorCountExp = 0;                      /* */
13091        fis->d.reserved4      = 0;
13092        fis->d.control        = 0;                      /* FIS HOB bit clear */
13093        fis->d.reserved5      = 0;
13094
13095        agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13096
13097        /* Initialize CB for SATA completion.
13098         */
13099        satIOContext->satCompleteCB = &satModeSelect6n10CB;
13100
13101        /*
13102         * Prepare SGL and send FIS to LL layer.
13103         */
13104        satIOContext->reqType = agRequestType;       /* Save it */
13105
13106        status = sataLLIOStart( tiRoot,
13107                                tiIORequest,
13108                                tiDeviceHandle,
13109                                tiScsiRequest,
13110                                satIOContext);
13111        return status;
13112
13113      }
13114    }
13115    break;
13116  default:
13117    TI_DBG1(("satModeSelect10: Error unknown page code 0x%x\n", pLogPage[12]));
13118    satSetSensePayload( pSense,
13119                        SCSI_SNSKEY_NO_SENSE,
13120                        0,
13121                        SCSI_SNSCODE_NO_ADDITIONAL_INFO,
13122                        satIOContext);
13123
13124    ostiInitiatorIOCompleted( tiRoot,
13125                              tiIORequest,
13126                              tiIOSuccess,
13127                              SCSI_STAT_CHECK_CONDITION,
13128                              satIOContext->pTiSenseData,
13129                              satIOContext->interruptContext );
13130    return tiSuccess;
13131  }
13132
13133}
13134
13135
13136/*****************************************************************************/
13137/*! \brief SAT implementation for SCSI satSynchronizeCache10.
13138 *
13139 *  SAT implementation for SCSI satSynchronizeCache10.
13140 *
13141 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
13142 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
13143 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
13144 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
13145 *  \param   satIOContext_t:   Pointer to the SAT IO Context
13146 *
13147 *  \return If command is started successfully
13148 *    - \e tiSuccess:     I/O request successfully initiated.
13149 *    - \e tiBusy:        No resources available, try again later.
13150 *    - \e tiIONoDevice:  Invalid device handle.
13151 *    - \e tiError:       Other errors.
13152 */
13153/*****************************************************************************/
13154GLOBAL bit32  satSynchronizeCache10(
13155                   tiRoot_t                  *tiRoot,
13156                   tiIORequest_t             *tiIORequest,
13157                   tiDeviceHandle_t          *tiDeviceHandle,
13158                   tiScsiInitiatorRequest_t *tiScsiRequest,
13159                   satIOContext_t            *satIOContext)
13160{
13161  bit32                     status;
13162  bit32                     agRequestType;
13163  satDeviceData_t           *pSatDevData;
13164  scsiRspSense_t            *pSense;
13165  tiIniScsiCmnd_t           *scsiCmnd;
13166  agsaFisRegHostToDevice_t  *fis;
13167
13168  pSense        = satIOContext->pSense;
13169  pSatDevData   = satIOContext->pSatDevData;
13170  scsiCmnd      = &tiScsiRequest->scsiCmnd;
13171  fis           = satIOContext->pFis;
13172
13173  TI_DBG5(("satSynchronizeCache10: start\n"));
13174
13175  /* checking CONTROL */
13176  /* NACA == 1 or LINK == 1*/
13177  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13178  {
13179    satSetSensePayload( pSense,
13180                        SCSI_SNSKEY_ILLEGAL_REQUEST,
13181                        0,
13182                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13183                        satIOContext);
13184
13185    ostiInitiatorIOCompleted( tiRoot,
13186                              tiIORequest,
13187                              tiIOSuccess,
13188                              SCSI_STAT_CHECK_CONDITION,
13189                              satIOContext->pTiSenseData,
13190                              satIOContext->interruptContext );
13191
13192    TI_DBG2(("satSynchronizeCache10: return control\n"));
13193    return tiSuccess;
13194  }
13195
13196  /* checking IMMED bit */
13197  if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13198  {
13199    TI_DBG1(("satSynchronizeCache10: GOOD status due to IMMED bit\n"));
13200
13201    /* return GOOD status first here */
13202    ostiInitiatorIOCompleted( tiRoot,
13203                              tiIORequest,
13204                              tiIOSuccess,
13205                              SCSI_STAT_GOOD,
13206                              agNULL,
13207                              satIOContext->interruptContext);
13208  }
13209
13210  /* sends FLUSH CACHE or FLUSH CACHE EXT */
13211  if (pSatDevData->sat48BitSupport == agTRUE)
13212  {
13213    TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE EXT\n"));
13214    /* FLUSH CACHE EXT */
13215    fis->h.fisType        = 0x27;                   /* Reg host to device */
13216    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13217
13218    fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
13219    fis->h.features       = 0;                      /* FIS reserve */
13220    fis->d.featuresExp    = 0;                      /* FIS reserve */
13221    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13222    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
13223    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13224    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
13225    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13226    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13227    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13228    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13229    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13230    fis->d.control        = 0;                      /* FIS HOB bit clear */
13231    fis->d.reserved4      = 0;
13232    fis->d.reserved5      = 0;
13233
13234  }
13235  else
13236  {
13237    TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE\n"));
13238    /* FLUSH CACHE */
13239    fis->h.fisType        = 0x27;                   /* Reg host to device */
13240    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13241
13242    fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
13243    fis->h.features       = 0;                      /* FIS features NA       */
13244    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13245    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13246    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13247    fis->d.lbaLowExp      = 0;
13248    fis->d.lbaMidExp      = 0;
13249    fis->d.lbaHighExp     = 0;
13250    fis->d.featuresExp    = 0;
13251    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13252    fis->d.sectorCountExp = 0;
13253    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13254    fis->d.control        = 0;                      /* FIS HOB bit clear */
13255    fis->d.reserved4      = 0;
13256    fis->d.reserved5      = 0;
13257
13258  }
13259
13260  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13261
13262  /* Initialize CB for SATA completion.
13263   */
13264  satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13265
13266  /*
13267   * Prepare SGL and send FIS to LL layer.
13268   */
13269  satIOContext->reqType = agRequestType;       /* Save it */
13270
13271  status = sataLLIOStart( tiRoot,
13272                          tiIORequest,
13273                          tiDeviceHandle,
13274                          tiScsiRequest,
13275                          satIOContext);
13276
13277
13278  return (status);
13279}
13280
13281/*****************************************************************************/
13282/*! \brief SAT implementation for SCSI satSynchronizeCache16.
13283 *
13284 *  SAT implementation for SCSI satSynchronizeCache16.
13285 *
13286 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
13287 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
13288 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
13289 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
13290 *  \param   satIOContext_t:   Pointer to the SAT IO Context
13291 *
13292 *  \return If command is started successfully
13293 *    - \e tiSuccess:     I/O request successfully initiated.
13294 *    - \e tiBusy:        No resources available, try again later.
13295 *    - \e tiIONoDevice:  Invalid device handle.
13296 *    - \e tiError:       Other errors.
13297 */
13298/*****************************************************************************/
13299GLOBAL bit32  satSynchronizeCache16(
13300                   tiRoot_t                  *tiRoot,
13301                   tiIORequest_t             *tiIORequest,
13302                   tiDeviceHandle_t          *tiDeviceHandle,
13303                   tiScsiInitiatorRequest_t *tiScsiRequest,
13304                   satIOContext_t            *satIOContext)
13305{
13306  bit32                     status;
13307  bit32                     agRequestType;
13308  satDeviceData_t           *pSatDevData;
13309  scsiRspSense_t            *pSense;
13310  tiIniScsiCmnd_t           *scsiCmnd;
13311  agsaFisRegHostToDevice_t  *fis;
13312
13313  pSense        = satIOContext->pSense;
13314  pSatDevData   = satIOContext->pSatDevData;
13315  scsiCmnd      = &tiScsiRequest->scsiCmnd;
13316  fis           = satIOContext->pFis;
13317
13318  TI_DBG5(("satSynchronizeCache16: start\n"));
13319
13320  /* checking CONTROL */
13321  /* NACA == 1 or LINK == 1*/
13322  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
13323  {
13324    satSetSensePayload( pSense,
13325                        SCSI_SNSKEY_ILLEGAL_REQUEST,
13326                        0,
13327                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13328                        satIOContext);
13329
13330    ostiInitiatorIOCompleted( tiRoot,
13331                              tiIORequest,
13332                              tiIOSuccess,
13333                              SCSI_STAT_CHECK_CONDITION,
13334                              satIOContext->pTiSenseData,
13335                              satIOContext->interruptContext );
13336
13337    TI_DBG1(("satSynchronizeCache16: return control\n"));
13338    return tiSuccess;
13339  }
13340
13341
13342  /* checking IMMED bit */
13343  if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13344  {
13345    TI_DBG1(("satSynchronizeCache16: GOOD status due to IMMED bit\n"));
13346
13347    /* return GOOD status first here */
13348    ostiInitiatorIOCompleted( tiRoot,
13349                              tiIORequest,
13350                              tiIOSuccess,
13351                              SCSI_STAT_GOOD,
13352                              agNULL,
13353                              satIOContext->interruptContext);
13354  }
13355
13356  /* sends FLUSH CACHE or FLUSH CACHE EXT */
13357  if (pSatDevData->sat48BitSupport == agTRUE)
13358  {
13359    TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE EXT\n"));
13360    /* FLUSH CACHE EXT */
13361    fis->h.fisType        = 0x27;                   /* Reg host to device */
13362    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13363
13364    fis->h.command        = SAT_FLUSH_CACHE_EXT;    /* 0xEA */
13365    fis->h.features       = 0;                      /* FIS reserve */
13366    fis->d.featuresExp    = 0;                      /* FIS reserve */
13367    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13368    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
13369    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13370    fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
13371    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13372    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13373    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13374    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13375    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13376    fis->d.control        = 0;                      /* FIS HOB bit clear */
13377    fis->d.reserved4      = 0;
13378    fis->d.reserved5      = 0;
13379
13380  }
13381  else
13382  {
13383    TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE\n"));
13384    /* FLUSH CACHE */
13385    fis->h.fisType        = 0x27;                   /* Reg host to device */
13386    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13387
13388    fis->h.command        = SAT_FLUSH_CACHE;        /* 0xE7 */
13389    fis->h.features       = 0;                      /* FIS features NA       */
13390    fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
13391    fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
13392    fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
13393    fis->d.lbaLowExp      = 0;
13394    fis->d.lbaMidExp      = 0;
13395    fis->d.lbaHighExp     = 0;
13396    fis->d.featuresExp    = 0;
13397    fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
13398    fis->d.sectorCountExp = 0;
13399    fis->d.device         = 0;                      /* FIS DEV is discared in SATA */
13400    fis->d.control        = 0;                      /* FIS HOB bit clear */
13401    fis->d.reserved4      = 0;
13402    fis->d.reserved5      = 0;
13403
13404  }
13405
13406  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13407
13408  /* Initialize CB for SATA completion.
13409   */
13410  satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13411
13412  /*
13413   * Prepare SGL and send FIS to LL layer.
13414   */
13415  satIOContext->reqType = agRequestType;       /* Save it */
13416
13417  status = sataLLIOStart( tiRoot,
13418                          tiIORequest,
13419                          tiDeviceHandle,
13420                          tiScsiRequest,
13421                          satIOContext);
13422
13423
13424  return (status);
13425}
13426
13427
13428/*****************************************************************************/
13429/*! \brief SAT implementation for SCSI satWriteAndVerify10.
13430 *
13431 *  SAT implementation for SCSI satWriteAndVerify10.
13432 *
13433 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
13434 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
13435 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
13436 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
13437 *  \param   satIOContext_t:   Pointer to the SAT IO Context
13438 *
13439 *  \return If command is started successfully
13440 *    - \e tiSuccess:     I/O request successfully initiated.
13441 *    - \e tiBusy:        No resources available, try again later.
13442 *    - \e tiIONoDevice:  Invalid device handle.
13443 *    - \e tiError:       Other errors.
13444 */
13445/*****************************************************************************/
13446GLOBAL bit32  satWriteAndVerify10(
13447                   tiRoot_t                  *tiRoot,
13448                   tiIORequest_t             *tiIORequest,
13449                   tiDeviceHandle_t          *tiDeviceHandle,
13450                   tiScsiInitiatorRequest_t *tiScsiRequest,
13451                   satIOContext_t            *satIOContext)
13452{
13453  /*
13454    combination of write10 and verify10
13455  */
13456
13457  bit32                     status;
13458  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13459  satDeviceData_t           *pSatDevData;
13460  scsiRspSense_t            *pSense;
13461  tiIniScsiCmnd_t           *scsiCmnd;
13462  agsaFisRegHostToDevice_t  *fis;
13463  bit32                     lba = 0;
13464  bit32                     tl = 0;
13465  bit32                     LoopNum = 1;
13466  bit8                      LBA[4];
13467  bit8                      TL[4];
13468  bit32                     rangeChk = agFALSE; /* lba and tl range check */
13469
13470  pSense        = satIOContext->pSense;
13471  pSatDevData   = satIOContext->pSatDevData;
13472  scsiCmnd      = &tiScsiRequest->scsiCmnd;
13473  fis           = satIOContext->pFis;
13474
13475  TI_DBG5(("satWriteAndVerify10: start\n"));
13476
13477
13478  /* checking BYTCHK bit */
13479  if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13480  {
13481    satSetSensePayload( pSense,
13482                        SCSI_SNSKEY_ILLEGAL_REQUEST,
13483                        0,
13484                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13485                        satIOContext);
13486
13487    ostiInitiatorIOCompleted( tiRoot,
13488                              tiIORequest,
13489                              tiIOSuccess,
13490                              SCSI_STAT_CHECK_CONDITION,
13491                              satIOContext->pTiSenseData,
13492                              satIOContext->interruptContext );
13493
13494    TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13495    return tiSuccess;
13496  }
13497
13498
13499  /* checking CONTROL */
13500  /* NACA == 1 or LINK == 1*/
13501  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13502  {
13503    satSetSensePayload( pSense,
13504                        SCSI_SNSKEY_ILLEGAL_REQUEST,
13505                        0,
13506                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13507                        satIOContext);
13508
13509    ostiInitiatorIOCompleted( tiRoot,
13510                              tiIORequest,
13511                              tiIOSuccess,
13512                              SCSI_STAT_CHECK_CONDITION,
13513                              satIOContext->pTiSenseData,
13514                              satIOContext->interruptContext );
13515
13516    TI_DBG1(("satWriteAndVerify10: return control\n"));
13517    return tiSuccess;
13518  }
13519
13520  osti_memset(LBA, 0, sizeof(LBA));
13521  osti_memset(TL, 0, sizeof(TL));
13522
13523  /* do not use memcpy due to indexing in LBA and TL */
13524  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
13525  LBA[1] = scsiCmnd->cdb[3];
13526  LBA[2] = scsiCmnd->cdb[4];
13527  LBA[3] = scsiCmnd->cdb[5];  /* LSB */
13528
13529  TL[0] = 0;
13530  TL[1] = 0;
13531  TL[2] = scsiCmnd->cdb[7];  /* MSB */
13532  TL[3] = scsiCmnd->cdb[8];  /* LSB */
13533
13534  rangeChk = satAddNComparebit32(LBA, TL);
13535
13536  /* cbd10; computing LBA and transfer length */
13537  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13538    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13539  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13540
13541
13542  /* Table 34, 9.1, p 46 */
13543  /*
13544    note: As of 2/10/2006, no support for DMA QUEUED
13545   */
13546
13547  /*
13548    Table 34, 9.1, p 46, b
13549    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13550    return check condition
13551  */
13552  if (pSatDevData->satNCQ != agTRUE &&
13553      pSatDevData->sat48BitSupport != agTRUE
13554      )
13555  {
13556    if (lba > SAT_TR_LBA_LIMIT - 1)
13557    {
13558      satSetSensePayload( pSense,
13559                          SCSI_SNSKEY_ILLEGAL_REQUEST,
13560                          0,
13561                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13562                          satIOContext);
13563
13564      ostiInitiatorIOCompleted( tiRoot,
13565                                tiIORequest,
13566                                tiIOSuccess,
13567                                SCSI_STAT_CHECK_CONDITION,
13568                                satIOContext->pTiSenseData,
13569                                satIOContext->interruptContext );
13570
13571    TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13572    return tiSuccess;
13573    }
13574
13575    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
13576    {
13577      TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
13578      satSetSensePayload( pSense,
13579                          SCSI_SNSKEY_ILLEGAL_REQUEST,
13580                          0,
13581                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13582                          satIOContext);
13583
13584      ostiInitiatorIOCompleted( tiRoot,
13585                                tiIORequest,
13586                                tiIOSuccess,
13587                                SCSI_STAT_CHECK_CONDITION,
13588                                satIOContext->pTiSenseData,
13589                                satIOContext->interruptContext );
13590
13591    return tiSuccess;
13592    }
13593  }
13594
13595
13596  /* case 1 and 2 */
13597  if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
13598  {
13599    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13600    {
13601      /* case 2 */
13602      /* WRITE DMA*/
13603      /* can't fit the transfer length */
13604      TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
13605      fis->h.fisType        = 0x27;                   /* Reg host to device */
13606      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
13607      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
13608      fis->h.features       = 0;                      /* FIS reserve */
13609      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13610      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13611      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13612
13613      /* FIS LBA mode set LBA (27:24) */
13614      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13615
13616      fis->d.lbaLowExp      = 0;
13617      fis->d.lbaMidExp      = 0;
13618      fis->d.lbaHighExp     = 0;
13619      fis->d.featuresExp    = 0;
13620      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13621      fis->d.sectorCountExp = 0;
13622      fis->d.reserved4      = 0;
13623      fis->d.control        = 0;                      /* FIS HOB bit clear */
13624      fis->d.reserved5      = 0;
13625
13626      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13627      satIOContext->ATACmd = SAT_WRITE_DMA;
13628    }
13629    else
13630    {
13631      /* case 1 */
13632      /* WRITE MULTIPLE or WRITE SECTOR(S) */
13633      /* WRITE SECTORS for easier implemetation */
13634      /* can't fit the transfer length */
13635      TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
13636      fis->h.fisType        = 0x27;                   /* Reg host to device */
13637      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
13638      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
13639      fis->h.features       = 0;                      /* FIS reserve */
13640      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13641      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13642      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13643
13644      /* FIS LBA mode set LBA (27:24) */
13645      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13646
13647      fis->d.lbaLowExp      = 0;
13648      fis->d.lbaMidExp      = 0;
13649      fis->d.lbaHighExp     = 0;
13650      fis->d.featuresExp    = 0;
13651      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13652      fis->d.sectorCountExp = 0;
13653      fis->d.reserved4      = 0;
13654      fis->d.control        = 0;                      /* FIS HOB bit clear */
13655      fis->d.reserved5      = 0;
13656
13657      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13658      satIOContext->ATACmd = SAT_WRITE_SECTORS;
13659
13660    }
13661  }
13662
13663  /* case 3 and 4 */
13664  if (pSatDevData->sat48BitSupport == agTRUE)
13665  {
13666    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13667    {
13668      /* case 3 */
13669      /* WRITE DMA EXT or WRITE DMA FUA EXT */
13670      TI_DBG5(("satWriteAndVerify10: case 3\n"));
13671      fis->h.fisType        = 0x27;                   /* Reg host to device */
13672      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13673
13674      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
13675      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
13676
13677      fis->h.features       = 0;                      /* FIS reserve */
13678      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13679      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13680      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13681      fis->d.device         = 0x40;                   /* FIS LBA mode set */
13682      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
13683      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13684      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13685      fis->d.featuresExp    = 0;                      /* FIS reserve */
13686      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13687      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
13688      fis->d.reserved4      = 0;
13689      fis->d.control        = 0;                      /* FIS HOB bit clear */
13690      fis->d.reserved5      = 0;
13691
13692      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13693      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
13694    }
13695    else
13696    {
13697      /* case 4 */
13698      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
13699      /* WRITE SECTORS EXT for easier implemetation */
13700      TI_DBG5(("satWriteAndVerify10: case 4\n"));
13701      fis->h.fisType        = 0x27;                   /* Reg host to device */
13702      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13703      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
13704
13705      fis->h.features       = 0;                      /* FIS reserve */
13706      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13707      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13708      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13709      fis->d.device         = 0x40;                   /* FIS LBA mode set */
13710      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
13711      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13712      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13713      fis->d.featuresExp    = 0;                      /* FIS reserve */
13714      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13715      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
13716      fis->d.reserved4      = 0;
13717      fis->d.control        = 0;                      /* FIS HOB bit clear */
13718      fis->d.reserved5      = 0;
13719
13720      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13721      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
13722    }
13723  }
13724  /* case 5 */
13725  if (pSatDevData->satNCQ == agTRUE)
13726  {
13727    /* WRITE FPDMA QUEUED */
13728    if (pSatDevData->sat48BitSupport != agTRUE)
13729    {
13730      TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
13731      satSetSensePayload( pSense,
13732                          SCSI_SNSKEY_ILLEGAL_REQUEST,
13733                          0,
13734                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13735                          satIOContext);
13736
13737      ostiInitiatorIOCompleted( tiRoot,
13738                                tiIORequest,
13739                                tiIOSuccess,
13740                                SCSI_STAT_CHECK_CONDITION,
13741                                satIOContext->pTiSenseData,
13742                                satIOContext->interruptContext );
13743      return tiSuccess;
13744    }
13745    TI_DBG5(("satWriteAndVerify10: case 5\n"));
13746
13747    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
13748
13749    fis->h.fisType        = 0x27;                   /* Reg host to device */
13750    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
13751    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
13752    fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
13753    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
13754    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
13755    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
13756
13757    /* Check FUA bit */
13758    if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
13759      fis->d.device       = 0xC0;                   /* FIS FUA set */
13760    else
13761      fis->d.device       = 0x40;                   /* FIS FUA clear */
13762
13763    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
13764    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
13765    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
13766    fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
13767    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
13768    fis->d.sectorCountExp = 0;
13769    fis->d.reserved4      = 0;
13770    fis->d.control        = 0;                      /* FIS HOB bit clear */
13771    fis->d.reserved5      = 0;
13772
13773    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
13774    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
13775  }
13776
13777  satIOContext->currentLBA = lba;
13778  satIOContext->OrgTL = tl;
13779
13780  /*
13781    computing number of loop and remainder for tl
13782    0xFF in case not ext
13783    0xFFFF in case EXT
13784  */
13785  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13786  {
13787    LoopNum = satComputeLoopNum(tl, 0xFF);
13788  }
13789  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13790           fis->h.command == SAT_WRITE_DMA_EXT     ||
13791           fis->h.command == SAT_WRITE_DMA_FUA_EXT
13792           )
13793  {
13794    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
13795    LoopNum = satComputeLoopNum(tl, 0xFFFF);
13796  }
13797  else
13798  {
13799    /* SAT_WRITE_FPDMA_QUEUED */
13800    LoopNum = satComputeLoopNum(tl, 0xFFFF);
13801  }
13802
13803  satIOContext->LoopNum = LoopNum;
13804
13805
13806  if (LoopNum == 1)
13807  {
13808    TI_DBG5(("satWriteAndVerify10: NON CHAINED data\n"));
13809    /* Initialize CB for SATA completion.
13810     */
13811    satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
13812  }
13813  else
13814  {
13815    TI_DBG1(("satWriteAndVerify10: CHAINED data\n"));
13816    /* re-setting tl */
13817    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13818    {
13819       fis->d.sectorCount    = 0xFF;
13820    }
13821    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13822             fis->h.command == SAT_WRITE_DMA_EXT ||
13823             fis->h.command == SAT_WRITE_DMA_FUA_EXT
13824             )
13825    {
13826      fis->d.sectorCount    = 0xFF;
13827      fis->d.sectorCountExp = 0xFF;
13828    }
13829    else
13830    {
13831      /* SAT_WRITE_FPDMA_QUEUED */
13832      fis->h.features       = 0xFF;
13833      fis->d.featuresExp    = 0xFF;
13834    }
13835
13836    /* Initialize CB for SATA completion.
13837     */
13838    satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
13839  }
13840
13841
13842  /*
13843   * Prepare SGL and send FIS to LL layer.
13844   */
13845  satIOContext->reqType = agRequestType;       /* Save it */
13846
13847  status = sataLLIOStart( tiRoot,
13848                          tiIORequest,
13849                          tiDeviceHandle,
13850                          tiScsiRequest,
13851                          satIOContext);
13852  return (status);
13853
13854}
13855
13856
13857
13858
13859
13860
13861#ifdef REMOVED
13862GLOBAL bit32  satWriteAndVerify10(
13863                   tiRoot_t                  *tiRoot,
13864                   tiIORequest_t             *tiIORequest,
13865                   tiDeviceHandle_t          *tiDeviceHandle,
13866                   tiScsiInitiatorRequest_t *tiScsiRequest,
13867                   satIOContext_t            *satIOContext)
13868{
13869  /*
13870    combination of write10 and verify10
13871  */
13872
13873  bit32                     status;
13874  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13875  satDeviceData_t           *pSatDevData;
13876  scsiRspSense_t            *pSense;
13877  tiIniScsiCmnd_t           *scsiCmnd;
13878  agsaFisRegHostToDevice_t  *fis;
13879  bit32                     lba = 0;
13880  bit32                     tl = 0;
13881
13882  pSense        = satIOContext->pSense;
13883  pSatDevData   = satIOContext->pSatDevData;
13884  scsiCmnd      = &tiScsiRequest->scsiCmnd;
13885  fis           = satIOContext->pFis;
13886
13887  TI_DBG5(("satWriteAndVerify10: start\n"));
13888
13889
13890  /* checking BYTCHK bit */
13891  if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13892  {
13893    satSetSensePayload( pSense,
13894                        SCSI_SNSKEY_ILLEGAL_REQUEST,
13895                        0,
13896                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13897                        satIOContext);
13898
13899    ostiInitiatorIOCompleted( tiRoot,
13900                              tiIORequest,
13901                              tiIOSuccess,
13902                              SCSI_STAT_CHECK_CONDITION,
13903                              satIOContext->pTiSenseData,
13904                              satIOContext->interruptContext );
13905
13906    TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13907    return tiSuccess;
13908  }
13909
13910
13911  /* checking CONTROL */
13912  /* NACA == 1 or LINK == 1*/
13913  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13914  {
13915    satSetSensePayload( pSense,
13916                        SCSI_SNSKEY_ILLEGAL_REQUEST,
13917                        0,
13918                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13919                        satIOContext);
13920
13921    ostiInitiatorIOCompleted( tiRoot,
13922                              tiIORequest,
13923                              tiIOSuccess,
13924                              SCSI_STAT_CHECK_CONDITION,
13925                              satIOContext->pTiSenseData,
13926                              satIOContext->interruptContext );
13927
13928    TI_DBG2(("satWriteAndVerify10: return control\n"));
13929    return tiSuccess;
13930  }
13931
13932  /* let's do write10 */
13933  if ( pSatDevData->sat48BitSupport != agTRUE )
13934  {
13935    /*
13936      writeandverify10 but no support for 48 bit addressing -> problem in transfer
13937      length(sector count)
13938    */
13939    satSetSensePayload( pSense,
13940                        SCSI_SNSKEY_ILLEGAL_REQUEST,
13941                        0,
13942                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13943                        satIOContext);
13944
13945    ostiInitiatorIOCompleted( tiRoot,
13946                              tiIORequest,
13947                              tiIOSuccess,
13948                              SCSI_STAT_CHECK_CONDITION,
13949                              satIOContext->pTiSenseData,
13950                              satIOContext->interruptContext );
13951
13952    TI_DBG1(("satWriteAndVerify10: return internal checking\n"));
13953    return tiSuccess;
13954  }
13955
13956  /* cbd10; computing LBA and transfer length */
13957  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13958    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13959  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13960
13961
13962  /* Table 34, 9.1, p 46 */
13963  /*
13964    note: As of 2/10/2006, no support for DMA QUEUED
13965   */
13966
13967  /*
13968    Table 34, 9.1, p 46, b
13969    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13970    return check condition
13971  */
13972  if (pSatDevData->satNCQ != agTRUE &&
13973      pSatDevData->sat48BitSupport != agTRUE
13974      )
13975  {
13976    if (lba > SAT_TR_LBA_LIMIT - 1)
13977    {
13978      satSetSensePayload( pSense,
13979                          SCSI_SNSKEY_ILLEGAL_REQUEST,
13980                          0,
13981                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13982                          satIOContext);
13983
13984      ostiInitiatorIOCompleted( tiRoot,
13985                                tiIORequest,
13986                                tiIOSuccess,
13987                                SCSI_STAT_CHECK_CONDITION,
13988                                satIOContext->pTiSenseData,
13989                                satIOContext->interruptContext );
13990
13991    TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13992    return tiSuccess;
13993    }
13994  }
13995
13996
13997  /* case 1 and 2 */
13998  if (lba + tl <= SAT_TR_LBA_LIMIT)
13999  {
14000    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14001    {
14002      /* case 2 */
14003      /* WRITE DMA*/
14004      /* can't fit the transfer length */
14005      TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
14006      fis->h.fisType        = 0x27;                   /* Reg host to device */
14007      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14008      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
14009      fis->h.features       = 0;                      /* FIS reserve */
14010      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14011      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14012      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14013
14014      /* FIS LBA mode set LBA (27:24) */
14015      fis->d.device         = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14016
14017      fis->d.lbaLowExp      = 0;
14018      fis->d.lbaMidExp      = 0;
14019      fis->d.lbaHighExp     = 0;
14020      fis->d.featuresExp    = 0;
14021      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14022      fis->d.sectorCountExp = 0;
14023      fis->d.reserved4      = 0;
14024      fis->d.control        = 0;                      /* FIS HOB bit clear */
14025      fis->d.reserved5      = 0;
14026
14027      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14028      satIOContext->ATACmd = SAT_WRITE_DMA;
14029    }
14030    else
14031    {
14032      /* case 1 */
14033      /* WRITE MULTIPLE or WRITE SECTOR(S) */
14034      /* WRITE SECTORS for easier implemetation */
14035      /* can't fit the transfer length */
14036      TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
14037      fis->h.fisType        = 0x27;                   /* Reg host to device */
14038      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14039      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
14040      fis->h.features       = 0;                      /* FIS reserve */
14041      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14042      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14043      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14044
14045      /* FIS LBA mode set LBA (27:24) */
14046      fis->d.device         = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14047
14048      fis->d.lbaLowExp      = 0;
14049      fis->d.lbaMidExp      = 0;
14050      fis->d.lbaHighExp     = 0;
14051      fis->d.featuresExp    = 0;
14052      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14053      fis->d.sectorCountExp = 0;
14054      fis->d.reserved4      = 0;
14055      fis->d.control        = 0;                      /* FIS HOB bit clear */
14056      fis->d.reserved5      = 0;
14057
14058      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14059      satIOContext->ATACmd = SAT_WRITE_SECTORS;
14060
14061    }
14062  }
14063
14064  /* case 3 and 4 */
14065  if (pSatDevData->sat48BitSupport == agTRUE)
14066  {
14067    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14068    {
14069      /* case 3 */
14070      /* WRITE DMA EXT or WRITE DMA FUA EXT */
14071      TI_DBG5(("satWriteAndVerify10: case 3\n"));
14072      fis->h.fisType        = 0x27;                   /* Reg host to device */
14073      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14074
14075      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14076      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
14077
14078      fis->h.features       = 0;                      /* FIS reserve */
14079      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14080      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14081      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14082      fis->d.device         = 0x40;                   /* FIS LBA mode set */
14083      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14084      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14085      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14086      fis->d.featuresExp    = 0;                      /* FIS reserve */
14087      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14088      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14089      fis->d.reserved4      = 0;
14090      fis->d.control        = 0;                      /* FIS HOB bit clear */
14091      fis->d.reserved5      = 0;
14092
14093      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14094    }
14095    else
14096    {
14097      /* case 4 */
14098      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14099      /* WRITE SECTORS EXT for easier implemetation */
14100      TI_DBG5(("satWriteAndVerify10: case 4\n"));
14101      fis->h.fisType        = 0x27;                   /* Reg host to device */
14102      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14103      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
14104
14105      fis->h.features       = 0;                      /* FIS reserve */
14106      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14107      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14108      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14109      fis->d.device         = 0x40;                   /* FIS LBA mode set */
14110      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14111      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14112      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14113      fis->d.featuresExp    = 0;                      /* FIS reserve */
14114      fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14115      fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14116      fis->d.reserved4      = 0;
14117      fis->d.control        = 0;                      /* FIS HOB bit clear */
14118      fis->d.reserved5      = 0;
14119
14120      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14121    }
14122  }
14123  /* case 5 */
14124  if (pSatDevData->satNCQ == agTRUE)
14125  {
14126    /* WRITE FPDMA QUEUED */
14127    if (pSatDevData->sat48BitSupport != agTRUE)
14128    {
14129      TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
14130      satSetSensePayload( pSense,
14131                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14132                          0,
14133                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14134                          satIOContext);
14135
14136      ostiInitiatorIOCompleted( tiRoot,
14137                                tiIORequest,
14138                                tiIOSuccess,
14139                                SCSI_STAT_CHECK_CONDITION,
14140                                satIOContext->pTiSenseData,
14141                                satIOContext->interruptContext );
14142      return tiSuccess;
14143    }
14144    TI_DBG5(("satWriteAndVerify10: case 5\n"));
14145
14146    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14147
14148    fis->h.fisType        = 0x27;                   /* Reg host to device */
14149    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14150    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14151    fis->h.features       = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14152    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14153    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14154    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14155
14156    /* Check FUA bit */
14157    if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
14158      fis->d.device       = 0xC0;                   /* FIS FUA set */
14159    else
14160      fis->d.device       = 0x40;                   /* FIS FUA clear */
14161
14162    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14163    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14164    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14165    fis->d.featuresExp    = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14166    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
14167    fis->d.sectorCountExp = 0;
14168    fis->d.reserved4      = 0;
14169    fis->d.control        = 0;                      /* FIS HOB bit clear */
14170    fis->d.reserved5      = 0;
14171
14172    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14173  }
14174
14175  /* Initialize CB for SATA completion.
14176   */
14177  satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14178
14179  /*
14180   * Prepare SGL and send FIS to LL layer.
14181   */
14182  satIOContext->reqType = agRequestType;       /* Save it */
14183
14184  status = sataLLIOStart( tiRoot,
14185                          tiIORequest,
14186                          tiDeviceHandle,
14187                          tiScsiRequest,
14188                          satIOContext);
14189  return (status);
14190
14191}
14192#endif /* REMOVED */
14193
14194#ifdef REMOVED
14195/*****************************************************************************/
14196/*! \brief SAT implementation for SCSI satWriteAndVerify10_1.
14197 *
14198 *  SAT implementation for SCSI satWriteAndVerify10_1.
14199 *  Sub function of satWriteAndVerify10
14200 *
14201 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
14202 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
14203 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
14204 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
14205 *  \param   satIOContext_t:   Pointer to the SAT IO Context
14206 *
14207 *  \return If command is started successfully
14208 *    - \e tiSuccess:     I/O request successfully initiated.
14209 *    - \e tiBusy:        No resources available, try again later.
14210 *    - \e tiIONoDevice:  Invalid device handle.
14211 *    - \e tiError:       Other errors.
14212 */
14213/*****************************************************************************/
14214GLOBAL bit32  satWriteAndVerify10_1(
14215                   tiRoot_t                  *tiRoot,
14216                   tiIORequest_t             *tiIORequest,
14217                   tiDeviceHandle_t          *tiDeviceHandle,
14218                   tiScsiInitiatorRequest_t *tiScsiRequest,
14219                   satIOContext_t            *satIOContext)
14220{
14221  bit32                     status;
14222  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14223  satDeviceData_t           *pSatDevData;
14224  scsiRspSense_t            *pSense;
14225  tiIniScsiCmnd_t           *scsiCmnd;
14226  agsaFisRegHostToDevice_t  *fis;
14227
14228  pSense        = satIOContext->pSense;
14229  pSatDevData   = satIOContext->pSatDevData;
14230  scsiCmnd      = &tiScsiRequest->scsiCmnd;
14231  fis           = satIOContext->pFis;
14232
14233  TI_DBG5(("satWriteAndVerify10_1: start\n"));
14234
14235  if (pSatDevData->sat48BitSupport == agTRUE)
14236  {
14237    fis->h.fisType        = 0x27;                   /* Reg host to device */
14238    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14239
14240    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14241    fis->h.features       = 0;                      /* FIS reserve */
14242    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14243    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14244    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14245    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
14246    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14247    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14248    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14249    fis->d.featuresExp    = 0;                      /* FIS reserve */
14250    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14251    fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14252
14253    fis->d.reserved4      = 0;
14254    fis->d.control        = 0;                      /* FIS HOB bit clear */
14255    fis->d.reserved5      = 0;
14256
14257    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14258
14259    /* Initialize CB for SATA completion.
14260     */
14261    satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14262
14263    /*
14264     * Prepare SGL and send FIS to LL layer.
14265     */
14266    satIOContext->reqType = agRequestType;       /* Save it */
14267
14268    status = sataLLIOStart( tiRoot,
14269                            tiIORequest,
14270                            tiDeviceHandle,
14271                            tiScsiRequest,
14272                            satIOContext);
14273
14274
14275    TI_DBG1(("satWriteAndVerify10_1: return status %d\n", status));
14276    return (status);
14277  }
14278  else
14279  {
14280    /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14281    TI_DBG1(("satWriteAndVerify10_1: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14282    return tiError;
14283  }
14284
14285
14286  return tiSuccess;
14287}
14288#endif /* REMOVED */
14289
14290/*****************************************************************************/
14291/*! \brief SAT implementation for SCSI satWriteAndVerify12.
14292 *
14293 *  SAT implementation for SCSI satWriteAndVerify12.
14294 *
14295 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
14296 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
14297 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
14298 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
14299 *  \param   satIOContext_t:   Pointer to the SAT IO Context
14300 *
14301 *  \return If command is started successfully
14302 *    - \e tiSuccess:     I/O request successfully initiated.
14303 *    - \e tiBusy:        No resources available, try again later.
14304 *    - \e tiIONoDevice:  Invalid device handle.
14305 *    - \e tiError:       Other errors.
14306 */
14307/*****************************************************************************/
14308GLOBAL bit32  satWriteAndVerify12(
14309                   tiRoot_t                  *tiRoot,
14310                   tiIORequest_t             *tiIORequest,
14311                   tiDeviceHandle_t          *tiDeviceHandle,
14312                   tiScsiInitiatorRequest_t *tiScsiRequest,
14313                   satIOContext_t            *satIOContext)
14314{
14315  /*
14316    combination of write12 and verify12
14317    temp: since write12 is not support (due to internal checking), no support
14318  */
14319  bit32                     status;
14320  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14321  satDeviceData_t           *pSatDevData;
14322  scsiRspSense_t            *pSense;
14323  tiIniScsiCmnd_t           *scsiCmnd;
14324  agsaFisRegHostToDevice_t  *fis;
14325  bit32                     lba = 0;
14326  bit32                     tl = 0;
14327  bit32                     LoopNum = 1;
14328  bit8                      LBA[4];
14329  bit8                      TL[4];
14330  bit32                     rangeChk = agFALSE; /* lba and tl range check */
14331
14332  pSense        = satIOContext->pSense;
14333  pSatDevData   = satIOContext->pSatDevData;
14334  scsiCmnd      = &tiScsiRequest->scsiCmnd;
14335  fis           = satIOContext->pFis;
14336
14337  TI_DBG5(("satWriteAndVerify12: start\n"));
14338
14339  /* checking BYTCHK bit */
14340  if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
14341  {
14342    satSetSensePayload( pSense,
14343                        SCSI_SNSKEY_ILLEGAL_REQUEST,
14344                        0,
14345                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14346                        satIOContext);
14347
14348    ostiInitiatorIOCompleted( tiRoot,
14349                              tiIORequest,
14350                              tiIOSuccess,
14351                              SCSI_STAT_CHECK_CONDITION,
14352                              satIOContext->pTiSenseData,
14353                              satIOContext->interruptContext );
14354
14355    TI_DBG1(("satWriteAndVerify12: BYTCHK bit checking \n"));
14356    return tiSuccess;
14357  }
14358
14359  /* checking CONTROL */
14360  /* NACA == 1 or LINK == 1*/
14361  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
14362  {
14363    satSetSensePayload( pSense,
14364                        SCSI_SNSKEY_ILLEGAL_REQUEST,
14365                        0,
14366                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14367                        satIOContext);
14368
14369    ostiInitiatorIOCompleted( tiRoot,
14370                              tiIORequest,
14371                              tiIOSuccess,
14372                              SCSI_STAT_CHECK_CONDITION,
14373                              satIOContext->pTiSenseData,
14374                              satIOContext->interruptContext );
14375
14376    TI_DBG2(("satWriteAndVerify12: return control\n"));
14377    return tiSuccess;
14378  }
14379
14380  osti_memset(LBA, 0, sizeof(LBA));
14381  osti_memset(TL, 0, sizeof(TL));
14382
14383  /* do not use memcpy due to indexing in LBA and TL */
14384  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
14385  LBA[1] = scsiCmnd->cdb[3];
14386  LBA[2] = scsiCmnd->cdb[4];
14387  LBA[3] = scsiCmnd->cdb[5];  /* LSB */
14388
14389  TL[0] = scsiCmnd->cdb[6];   /* MSB */
14390  TL[1] = scsiCmnd->cdb[7];
14391  TL[2] = scsiCmnd->cdb[7];
14392  TL[3] = scsiCmnd->cdb[8];   /* LSB */
14393
14394  rangeChk = satAddNComparebit32(LBA, TL);
14395
14396  lba = satComputeCDB12LBA(satIOContext);
14397  tl = satComputeCDB12TL(satIOContext);
14398
14399
14400  /* Table 34, 9.1, p 46 */
14401  /*
14402    note: As of 2/10/2006, no support for DMA QUEUED
14403   */
14404
14405  /*
14406    Table 34, 9.1, p 46, b
14407    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
14408    return check condition
14409  */
14410  if (pSatDevData->satNCQ != agTRUE &&
14411      pSatDevData->sat48BitSupport != agTRUE
14412      )
14413  {
14414    if (lba > SAT_TR_LBA_LIMIT - 1)
14415    {
14416      satSetSensePayload( pSense,
14417                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14418                          0,
14419                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14420                          satIOContext);
14421
14422      ostiInitiatorIOCompleted( tiRoot,
14423                                tiIORequest,
14424                                tiIOSuccess,
14425                                SCSI_STAT_CHECK_CONDITION,
14426                                satIOContext->pTiSenseData,
14427                                satIOContext->interruptContext );
14428
14429    TI_DBG1(("satWriteAndVerify12: return LBA out of range, not EXT\n"));
14430    return tiSuccess;
14431    }
14432
14433    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
14434    {
14435      TI_DBG1(("satWriteAndVerify12: return LBA+TL out of range, not EXT\n"));
14436      satSetSensePayload( pSense,
14437                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14438                          0,
14439                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14440                          satIOContext);
14441
14442      ostiInitiatorIOCompleted( tiRoot,
14443                                tiIORequest,
14444                                tiIOSuccess,
14445                                SCSI_STAT_CHECK_CONDITION,
14446                                satIOContext->pTiSenseData,
14447                                satIOContext->interruptContext );
14448
14449    return tiSuccess;
14450    }
14451  }
14452
14453  /* case 1 and 2 */
14454  if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
14455  {
14456    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14457    {
14458      /* case 2 */
14459      /* WRITE DMA*/
14460      /* In case that we can't fit the transfer length, we loop */
14461      TI_DBG5(("satWriteAndVerify12: case 2\n"));
14462      fis->h.fisType        = 0x27;                   /* Reg host to device */
14463      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14464      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
14465      fis->h.features       = 0;                      /* FIS reserve */
14466      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14467      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14468      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14469
14470      /* FIS LBA mode set LBA (27:24) */
14471      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14472
14473      fis->d.lbaLowExp      = 0;
14474      fis->d.lbaMidExp      = 0;
14475      fis->d.lbaHighExp     = 0;
14476      fis->d.featuresExp    = 0;
14477      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14478      fis->d.sectorCountExp = 0;
14479      fis->d.reserved4      = 0;
14480      fis->d.control        = 0;                      /* FIS HOB bit clear */
14481      fis->d.reserved5      = 0;
14482
14483      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14484      satIOContext->ATACmd = SAT_WRITE_DMA;
14485    }
14486    else
14487    {
14488      /* case 1 */
14489      /* WRITE MULTIPLE or WRITE SECTOR(S) */
14490      /* WRITE SECTORS for easier implemetation */
14491      /* In case that we can't fit the transfer length, we loop */
14492      TI_DBG5(("satWriteAndVerify12: case 1\n"));
14493      fis->h.fisType        = 0x27;                   /* Reg host to device */
14494      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14495      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
14496      fis->h.features       = 0;                      /* FIS reserve */
14497      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14498      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14499      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14500
14501      /* FIS LBA mode set LBA (27:24) */
14502      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14503
14504      fis->d.lbaLowExp      = 0;
14505      fis->d.lbaMidExp      = 0;
14506      fis->d.lbaHighExp     = 0;
14507      fis->d.featuresExp    = 0;
14508      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14509      fis->d.sectorCountExp = 0;
14510      fis->d.reserved4      = 0;
14511      fis->d.control        = 0;                      /* FIS HOB bit clear */
14512      fis->d.reserved5      = 0;
14513
14514      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14515      satIOContext->ATACmd = SAT_WRITE_SECTORS;
14516    }
14517  }
14518
14519  /* case 3 and 4 */
14520  if (pSatDevData->sat48BitSupport == agTRUE)
14521  {
14522    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14523    {
14524      /* case 3 */
14525      /* WRITE DMA EXT or WRITE DMA FUA EXT */
14526      TI_DBG5(("satWriteAndVerify12: case 3\n"));
14527      fis->h.fisType        = 0x27;                   /* Reg host to device */
14528      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14529
14530      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14531      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
14532
14533      fis->h.features       = 0;                      /* FIS reserve */
14534      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14535      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14536      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14537      fis->d.device         = 0x40;                   /* FIS LBA mode set */
14538      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14539      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14540      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14541      fis->d.featuresExp    = 0;                      /* FIS reserve */
14542      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14543      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
14544      fis->d.reserved4      = 0;
14545      fis->d.control        = 0;                      /* FIS HOB bit clear */
14546      fis->d.reserved5      = 0;
14547
14548      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14549      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
14550    }
14551    else
14552    {
14553      /* case 4 */
14554      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14555      /* WRITE SECTORS EXT for easier implemetation */
14556      TI_DBG5(("satWriteAndVerify12: case 4\n"));
14557      fis->h.fisType        = 0x27;                   /* Reg host to device */
14558      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14559      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
14560
14561      fis->h.features       = 0;                      /* FIS reserve */
14562      fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14563      fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14564      fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14565      fis->d.device         = 0x40;                   /* FIS LBA mode set */
14566      fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14567      fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14568      fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14569      fis->d.featuresExp    = 0;                      /* FIS reserve */
14570      fis->d.sectorCount    = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14571      fis->d.sectorCountExp = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
14572      fis->d.reserved4      = 0;
14573      fis->d.control        = 0;                      /* FIS HOB bit clear */
14574      fis->d.reserved5      = 0;
14575
14576      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14577      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
14578    }
14579  }
14580
14581  /* case 5 */
14582  if (pSatDevData->satNCQ == agTRUE)
14583  {
14584    /* WRITE FPDMA QUEUED */
14585    if (pSatDevData->sat48BitSupport != agTRUE)
14586    {
14587      TI_DBG5(("satWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support \n"));
14588       satSetSensePayload( pSense,
14589                          SCSI_SNSKEY_ILLEGAL_REQUEST,
14590                          0,
14591                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14592                          satIOContext);
14593
14594      ostiInitiatorIOCompleted( tiRoot,
14595                                tiIORequest,
14596                                tiIOSuccess,
14597                                SCSI_STAT_CHECK_CONDITION,
14598                                satIOContext->pTiSenseData,
14599                                satIOContext->interruptContext );
14600      return tiSuccess;
14601    }
14602    TI_DBG6(("satWriteAndVerify12: case 5\n"));
14603
14604    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14605
14606    fis->h.fisType        = 0x27;                   /* Reg host to device */
14607    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14608    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14609    fis->h.features       = scsiCmnd->cdb[9];       /* FIS sector count (7:0) */
14610    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14611    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14612    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14613
14614    /* Check FUA bit */
14615    if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
14616      fis->d.device       = 0xC0;                   /* FIS FUA set */
14617    else
14618      fis->d.device       = 0x40;                   /* FIS FUA clear */
14619
14620    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14621    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14622    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14623    fis->d.featuresExp    = scsiCmnd->cdb[8];       /* FIS sector count (15:8) */
14624    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
14625    fis->d.sectorCountExp = 0;
14626    fis->d.reserved4      = 0;
14627    fis->d.control        = 0;                      /* FIS HOB bit clear */
14628    fis->d.reserved5      = 0;
14629
14630    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14631    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
14632  }
14633
14634  satIOContext->currentLBA = lba;
14635//  satIOContext->OrgLBA = lba;
14636  satIOContext->OrgTL = tl;
14637
14638  /*
14639    computing number of loop and remainder for tl
14640    0xFF in case not ext
14641    0xFFFF in case EXT
14642  */
14643  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14644  {
14645    LoopNum = satComputeLoopNum(tl, 0xFF);
14646  }
14647  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14648           fis->h.command == SAT_WRITE_DMA_EXT     ||
14649           fis->h.command == SAT_WRITE_DMA_FUA_EXT
14650           )
14651  {
14652    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
14653    LoopNum = satComputeLoopNum(tl, 0xFFFF);
14654  }
14655  else
14656  {
14657    /* SAT_WRITE_FPDMA_QUEUEDK */
14658    LoopNum = satComputeLoopNum(tl, 0xFFFF);
14659  }
14660
14661  satIOContext->LoopNum = LoopNum;
14662  satIOContext->LoopNum2 = LoopNum;
14663
14664
14665  if (LoopNum == 1)
14666  {
14667    TI_DBG5(("satWriteAndVerify12: NON CHAINED data\n"));
14668    /* Initialize CB for SATA completion.
14669     */
14670    satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14671  }
14672  else
14673  {
14674    TI_DBG1(("satWriteAndVerify12: CHAINED data\n"));
14675    /* re-setting tl */
14676    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14677    {
14678       fis->d.sectorCount    = 0xFF;
14679    }
14680    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14681             fis->h.command == SAT_WRITE_DMA_EXT ||
14682             fis->h.command == SAT_WRITE_DMA_FUA_EXT
14683             )
14684    {
14685      fis->d.sectorCount    = 0xFF;
14686      fis->d.sectorCountExp = 0xFF;
14687    }
14688    else
14689    {
14690      /* SAT_WRITE_FPDMA_QUEUED */
14691      fis->h.features       = 0xFF;
14692      fis->d.featuresExp    = 0xFF;
14693    }
14694
14695    /* Initialize CB for SATA completion.
14696     */
14697    satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
14698  }
14699
14700
14701  /*
14702   * Prepare SGL and send FIS to LL layer.
14703   */
14704  satIOContext->reqType = agRequestType;       /* Save it */
14705
14706  status = sataLLIOStart( tiRoot,
14707                          tiIORequest,
14708                          tiDeviceHandle,
14709                          tiScsiRequest,
14710                          satIOContext);
14711  return (status);
14712}
14713
14714GLOBAL bit32  satNonChainedWriteNVerify_Verify(
14715                   tiRoot_t                  *tiRoot,
14716                   tiIORequest_t             *tiIORequest,
14717                   tiDeviceHandle_t          *tiDeviceHandle,
14718                   tiScsiInitiatorRequest_t *tiScsiRequest,
14719                   satIOContext_t            *satIOContext)
14720{
14721  bit32                     status;
14722  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14723  satDeviceData_t           *pSatDevData;
14724  tiIniScsiCmnd_t           *scsiCmnd;
14725  agsaFisRegHostToDevice_t  *fis;
14726
14727  pSatDevData   = satIOContext->pSatDevData;
14728  scsiCmnd      = &tiScsiRequest->scsiCmnd;
14729  fis           = satIOContext->pFis;
14730
14731  TI_DBG5(("satNonChainedWriteNVerify_Verify: start\n"));
14732
14733  if (pSatDevData->sat48BitSupport == agTRUE)
14734  {
14735    fis->h.fisType        = 0x27;                   /* Reg host to device */
14736    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14737
14738    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14739    fis->h.features       = 0;                      /* FIS reserve */
14740    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
14741    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
14742    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
14743    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
14744    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
14745    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14746    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14747    fis->d.featuresExp    = 0;                      /* FIS reserve */
14748    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
14749    fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
14750
14751    fis->d.reserved4      = 0;
14752    fis->d.control        = 0;                      /* FIS HOB bit clear */
14753    fis->d.reserved5      = 0;
14754
14755    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14756
14757    /* Initialize CB for SATA completion.
14758     */
14759    satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14760
14761    /*
14762     * Prepare SGL and send FIS to LL layer.
14763     */
14764    satIOContext->reqType = agRequestType;       /* Save it */
14765
14766    status = sataLLIOStart( tiRoot,
14767                            tiIORequest,
14768                            tiDeviceHandle,
14769                            tiScsiRequest,
14770                            satIOContext);
14771
14772
14773    TI_DBG1(("satNonChainedWriteNVerify_Verify: return status %d\n", status));
14774    return (status);
14775  }
14776  else
14777  {
14778    /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14779    TI_DBG1(("satNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14780    return tiError;
14781  }
14782
14783}
14784
14785GLOBAL bit32  satChainedWriteNVerify_Write(
14786                   tiRoot_t                  *tiRoot,
14787                   tiIORequest_t             *tiIORequest,
14788                   tiDeviceHandle_t          *tiDeviceHandle,
14789                   tiScsiInitiatorRequest_t *tiScsiRequest,
14790                   satIOContext_t            *satIOContext)
14791{
14792  /*
14793    Assumption: error check on lba and tl has been done in satWrite*()
14794    lba = lba + tl;
14795  */
14796  bit32                     status;
14797  satIOContext_t            *satOrgIOContext = agNULL;
14798  tiIniScsiCmnd_t           *scsiCmnd;
14799  agsaFisRegHostToDevice_t  *fis;
14800  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14801  bit32                     lba = 0;
14802  bit32                     DenomTL = 0xFF;
14803  bit32                     Remainder = 0;
14804  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
14805
14806  TI_DBG1(("satChainedWriteNVerify_Write: start\n"));
14807
14808  fis             = satIOContext->pFis;
14809  satOrgIOContext = satIOContext->satOrgIOContext;
14810  scsiCmnd        = satOrgIOContext->pScsiCmnd;
14811
14812  osti_memset(LBA,0, sizeof(LBA));
14813
14814  switch (satOrgIOContext->ATACmd)
14815  {
14816  case SAT_WRITE_DMA:
14817    DenomTL = 0xFF;
14818    break;
14819  case SAT_WRITE_SECTORS:
14820    DenomTL = 0xFF;
14821    break;
14822  case SAT_WRITE_DMA_EXT:
14823    DenomTL = 0xFFFF;
14824    break;
14825  case SAT_WRITE_DMA_FUA_EXT:
14826    DenomTL = 0xFFFF;
14827    break;
14828  case SAT_WRITE_SECTORS_EXT:
14829    DenomTL = 0xFFFF;
14830    break;
14831  case SAT_WRITE_FPDMA_QUEUED:
14832    DenomTL = 0xFFFF;
14833    break;
14834  default:
14835    TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
14836    return tiError;
14837    break;
14838  }
14839
14840  Remainder = satOrgIOContext->OrgTL % DenomTL;
14841  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
14842  lba = satOrgIOContext->currentLBA;
14843
14844  LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
14845  LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
14846  LBA[2] = (bit8)((lba & 0xF0) >> 8);
14847  LBA[3] = (bit8)(lba & 0xF);               /* LSB */
14848
14849  switch (satOrgIOContext->ATACmd)
14850  {
14851  case SAT_WRITE_DMA:
14852    fis->h.fisType        = 0x27;                   /* Reg host to device */
14853    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14854    fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
14855    fis->h.features       = 0;                      /* FIS reserve */
14856    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14857    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14858    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14859
14860    /* FIS LBA mode set LBA (27:24) */
14861    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14862
14863    fis->d.lbaLowExp      = 0;
14864    fis->d.lbaMidExp      = 0;
14865    fis->d.lbaHighExp     = 0;
14866    fis->d.featuresExp    = 0;
14867    if (satOrgIOContext->LoopNum == 1)
14868    {
14869      /* last loop */
14870      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
14871    }
14872    else
14873    {
14874      fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
14875    }
14876    fis->d.sectorCountExp = 0;
14877    fis->d.reserved4      = 0;
14878    fis->d.control        = 0;                      /* FIS HOB bit clear */
14879    fis->d.reserved5      = 0;
14880
14881    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14882
14883    break;
14884  case SAT_WRITE_SECTORS:
14885    fis->h.fisType        = 0x27;                   /* Reg host to device */
14886    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
14887    fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
14888    fis->h.features       = 0;                      /* FIS reserve */
14889    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14890    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14891    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14892
14893    /* FIS LBA mode set LBA (27:24) */
14894    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14895
14896    fis->d.lbaLowExp      = 0;
14897    fis->d.lbaMidExp      = 0;
14898    fis->d.lbaHighExp     = 0;
14899    fis->d.featuresExp    = 0;
14900    if (satOrgIOContext->LoopNum == 1)
14901    {
14902      /* last loop */
14903      fis->d.sectorCount    = (bit8)Remainder;            /* FIS sector count (7:0) */
14904    }
14905    else
14906    {
14907      fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
14908    }
14909    fis->d.sectorCountExp = 0;
14910    fis->d.reserved4      = 0;
14911    fis->d.control        = 0;                      /* FIS HOB bit clear */
14912    fis->d.reserved5      = 0;
14913
14914    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14915
14916    break;
14917  case SAT_WRITE_DMA_EXT:
14918    fis->h.fisType        = 0x27;                   /* Reg host to device */
14919    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14920    fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x3D */
14921    fis->h.features       = 0;                      /* FIS reserve */
14922    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14923    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14924    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14925    fis->d.device         = 0x40;                   /* FIS LBA mode set */
14926    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
14927    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14928    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14929    fis->d.featuresExp    = 0;                      /* FIS reserve */
14930    if (satOrgIOContext->LoopNum == 1)
14931    {
14932      /* last loop */
14933      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
14934      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
14935    }
14936    else
14937    {
14938      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
14939      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
14940    }
14941    fis->d.reserved4      = 0;
14942    fis->d.control        = 0;                       /* FIS HOB bit clear */
14943    fis->d.reserved5      = 0;
14944
14945    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14946
14947    break;
14948  case SAT_WRITE_SECTORS_EXT:
14949    fis->h.fisType        = 0x27;                   /* Reg host to device */
14950    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14951    fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
14952
14953    fis->h.features       = 0;                      /* FIS reserve */
14954    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14955    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14956    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14957    fis->d.device         = 0x40;                   /* FIS LBA mode set */
14958    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
14959    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14960    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14961    fis->d.featuresExp    = 0;                      /* FIS reserve */
14962    if (satOrgIOContext->LoopNum == 1)
14963    {
14964      /* last loop */
14965      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
14966      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);   /* FIS sector count (15:8) */
14967    }
14968    else
14969    {
14970      fis->d.sectorCount    = 0xFF;                 /* FIS sector count (7:0) */
14971      fis->d.sectorCountExp = 0xFF;                 /* FIS sector count (15:8) */
14972    }
14973    fis->d.reserved4      = 0;
14974    fis->d.control        = 0;                      /* FIS HOB bit clear */
14975    fis->d.reserved5      = 0;
14976
14977    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14978
14979    break;
14980  case SAT_WRITE_FPDMA_QUEUED:
14981    fis->h.fisType        = 0x27;                   /* Reg host to device */
14982    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
14983    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14984    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
14985    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
14986    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
14987
14988    /* Check FUA bit */
14989    if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
14990      fis->d.device       = 0xC0;                   /* FIS FUA set */
14991    else
14992      fis->d.device       = 0x40;                   /* FIS FUA clear */
14993
14994    fis->d.lbaLowExp      = LBA[0];;                /* FIS LBA (31:24) */
14995    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
14996    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
14997    if (satOrgIOContext->LoopNum == 1)
14998    {
14999      /* last loop */
15000      fis->h.features       = (bit8)(Remainder & 0xFF);     /* FIS sector count (7:0) */
15001      fis->d.featuresExp    = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
15002    }
15003    else
15004    {
15005      fis->h.features       = 0xFF;                 /* FIS sector count (7:0) */
15006      fis->d.featuresExp    = 0xFF;                 /* FIS sector count (15:8) */
15007    }
15008    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15009    fis->d.sectorCountExp = 0;
15010    fis->d.reserved4      = 0;
15011    fis->d.control        = 0;                      /* FIS HOB bit clear */
15012    fis->d.reserved5      = 0;
15013
15014    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15015    break;
15016
15017  default:
15018    TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15019    return tiError;
15020    break;
15021  }
15022
15023  /* Initialize CB for SATA completion.
15024   */
15025  /* chained data */
15026  satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15027
15028
15029  /*
15030   * Prepare SGL and send FIS to LL layer.
15031   */
15032  satIOContext->reqType = agRequestType;       /* Save it */
15033
15034  status = sataLLIOStart( tiRoot,
15035                          tiIORequest,
15036                          tiDeviceHandle,
15037                          tiScsiRequest,
15038                          satIOContext);
15039
15040  TI_DBG5(("satChainedWriteNVerify_Write: return\n"));
15041  return (status);
15042
15043}
15044
15045/*
15046  similar to write12 and verify10;
15047  this will be similar to verify12
15048  */
15049GLOBAL bit32  satChainedWriteNVerify_Start_Verify(
15050                   tiRoot_t                  *tiRoot,
15051                   tiIORequest_t             *tiIORequest,
15052                   tiDeviceHandle_t          *tiDeviceHandle,
15053                   tiScsiInitiatorRequest_t *tiScsiRequest,
15054                   satIOContext_t            *satIOContext)
15055{
15056  /*
15057    deal with transfer length; others have been handled previously at this point;
15058    no LBA check; no range check;
15059  */
15060  bit32                     status;
15061  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15062  satDeviceData_t           *pSatDevData;
15063  tiIniScsiCmnd_t           *scsiCmnd;
15064  agsaFisRegHostToDevice_t  *fis;
15065  bit32                     lba = 0;
15066  bit32                     tl = 0;
15067  bit32                     LoopNum = 1;
15068  bit8                      LBA[4];
15069  bit8                      TL[4];
15070
15071  pSatDevData   = satIOContext->pSatDevData;
15072  scsiCmnd      = &tiScsiRequest->scsiCmnd;
15073  fis           = satIOContext->pFis;
15074
15075  TI_DBG5(("satChainedWriteNVerify_Start_Verify: start\n"));
15076
15077  osti_memset(LBA, 0, sizeof(LBA));
15078  osti_memset(TL, 0, sizeof(TL));
15079
15080  /* do not use memcpy due to indexing in LBA and TL */
15081  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
15082  LBA[1] = scsiCmnd->cdb[3];
15083  LBA[2] = scsiCmnd->cdb[4];
15084  LBA[3] = scsiCmnd->cdb[5];  /* LSB */
15085
15086  TL[0] = scsiCmnd->cdb[6];   /* MSB */
15087  TL[1] = scsiCmnd->cdb[7];
15088  TL[2] = scsiCmnd->cdb[7];
15089  TL[3] = scsiCmnd->cdb[8];   /* LSB */
15090
15091  lba = satComputeCDB12LBA(satIOContext);
15092  tl = satComputeCDB12TL(satIOContext);
15093
15094  if (pSatDevData->sat48BitSupport == agTRUE)
15095  {
15096    TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n"));
15097    fis->h.fisType        = 0x27;                   /* Reg host to device */
15098    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15099
15100    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
15101    fis->h.features       = 0;                      /* FIS reserve */
15102    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15103    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15104    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15105    fis->d.device         = 0x40;                   /* FIS LBA mode set 01000000 */
15106    fis->d.lbaLowExp      = scsiCmnd->cdb[2];       /* FIS LBA (31:24) */
15107    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15108    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15109    fis->d.featuresExp    = 0;                      /* FIS reserve */
15110    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15111    fis->d.sectorCountExp = scsiCmnd->cdb[7];       /* FIS sector count (15:8) */
15112
15113    fis->d.reserved4      = 0;
15114    fis->d.control        = 0;                      /* FIS HOB bit clear */
15115    fis->d.reserved5      = 0;
15116
15117    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15118    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
15119  }
15120  else
15121  {
15122    TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n"));
15123    fis->h.fisType        = 0x27;                   /* Reg host to device */
15124    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15125    fis->h.command        = SAT_READ_VERIFY_SECTORS;      /* 0x40 */
15126    fis->h.features       = 0;                      /* FIS reserve */
15127    fis->d.lbaLow         = scsiCmnd->cdb[5];       /* FIS LBA (7 :0 ) */
15128    fis->d.lbaMid         = scsiCmnd->cdb[4];       /* FIS LBA (15:8 ) */
15129    fis->d.lbaHigh        = scsiCmnd->cdb[3];       /* FIS LBA (23:16) */
15130      /* FIS LBA mode set LBA (27:24) */
15131    fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15132    fis->d.lbaLowExp      = 0;
15133    fis->d.lbaMidExp      = 0;
15134    fis->d.lbaHighExp     = 0;
15135    fis->d.featuresExp    = 0;
15136    fis->d.sectorCount    = scsiCmnd->cdb[8];       /* FIS sector count (7:0) */
15137    fis->d.sectorCountExp = 0;
15138    fis->d.reserved4      = 0;
15139    fis->d.control        = 0;                      /* FIS HOB bit clear */
15140    fis->d.reserved5      = 0;
15141
15142    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15143    satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
15144
15145 }
15146
15147  satIOContext->currentLBA = lba;
15148  satIOContext->OrgTL = tl;
15149
15150  /*
15151    computing number of loop and remainder for tl
15152    0xFF in case not ext
15153    0xFFFF in case EXT
15154  */
15155  if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15156  {
15157    LoopNum = satComputeLoopNum(tl, 0xFF);
15158  }
15159  else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15160  {
15161    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15162    LoopNum = satComputeLoopNum(tl, 0xFFFF);
15163  }
15164  else
15165  {
15166    TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
15167    LoopNum = 1;
15168  }
15169
15170  satIOContext->LoopNum = LoopNum;
15171
15172  if (LoopNum == 1)
15173  {
15174    TI_DBG5(("satChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
15175    /* Initialize CB for SATA completion.
15176     */
15177    satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15178  }
15179  else
15180  {
15181    TI_DBG1(("satChainedWriteNVerify_Start_Verify: CHAINED data\n"));
15182    /* re-setting tl */
15183    if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15184    {
15185       fis->d.sectorCount    = 0xFF;
15186    }
15187    else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15188    {
15189      fis->d.sectorCount    = 0xFF;
15190      fis->d.sectorCountExp = 0xFF;
15191    }
15192    else
15193    {
15194      TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
15195    }
15196
15197    /* Initialize CB for SATA completion.
15198     */
15199    satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15200  }
15201
15202
15203  /*
15204   * Prepare SGL and send FIS to LL layer.
15205   */
15206  satIOContext->reqType = agRequestType;       /* Save it */
15207
15208  status = sataLLIOStart( tiRoot,
15209                          tiIORequest,
15210                          tiDeviceHandle,
15211                          tiScsiRequest,
15212                          satIOContext);
15213  return (status);
15214}
15215
15216GLOBAL bit32  satChainedWriteNVerify_Verify(
15217                   tiRoot_t                  *tiRoot,
15218                   tiIORequest_t             *tiIORequest,
15219                   tiDeviceHandle_t          *tiDeviceHandle,
15220                   tiScsiInitiatorRequest_t *tiScsiRequest,
15221                   satIOContext_t            *satIOContext)
15222{
15223  bit32                     status;
15224  satIOContext_t            *satOrgIOContext = agNULL;
15225  agsaFisRegHostToDevice_t  *fis;
15226  bit32                     agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15227  bit32                     lba = 0;
15228  bit32                     DenomTL = 0xFF;
15229  bit32                     Remainder = 0;
15230  bit8                      LBA[4]; /* 0 MSB, 3 LSB */
15231
15232  TI_DBG2(("satChainedWriteNVerify_Verify: start\n"));
15233
15234  fis             = satIOContext->pFis;
15235  satOrgIOContext = satIOContext->satOrgIOContext;
15236
15237  osti_memset(LBA,0, sizeof(LBA));
15238
15239  switch (satOrgIOContext->ATACmd)
15240  {
15241  case SAT_READ_VERIFY_SECTORS:
15242    DenomTL = 0xFF;
15243    break;
15244  case SAT_READ_VERIFY_SECTORS_EXT:
15245    DenomTL = 0xFFFF;
15246    break;
15247  default:
15248    TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15249    return tiError;
15250    break;
15251  }
15252
15253  Remainder = satOrgIOContext->OrgTL % DenomTL;
15254  satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
15255  lba = satOrgIOContext->currentLBA;
15256
15257  LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
15258  LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
15259  LBA[2] = (bit8)((lba & 0xF0) >> 8);
15260  LBA[3] = (bit8)(lba & 0xF);               /* LSB */
15261
15262  switch (satOrgIOContext->ATACmd)
15263  {
15264  case SAT_READ_VERIFY_SECTORS:
15265    fis->h.fisType        = 0x27;                   /* Reg host to device */
15266    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15267    fis->h.command        = SAT_READ_VERIFY_SECTORS;          /* 0x40 */
15268    fis->h.features       = 0;                      /* FIS reserve */
15269    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
15270    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
15271    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
15272
15273    /* FIS LBA mode set LBA (27:24) */
15274    fis->d.device         = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
15275
15276    fis->d.lbaLowExp      = 0;
15277    fis->d.lbaMidExp      = 0;
15278    fis->d.lbaHighExp     = 0;
15279    fis->d.featuresExp    = 0;
15280    if (satOrgIOContext->LoopNum == 1)
15281    {
15282      /* last loop */
15283      fis->d.sectorCount    = (bit8)Remainder;             /* FIS sector count (7:0) */
15284    }
15285    else
15286    {
15287      fis->d.sectorCount    = 0xFF;                   /* FIS sector count (7:0) */
15288    }
15289    fis->d.sectorCountExp = 0;
15290    fis->d.reserved4      = 0;
15291    fis->d.control        = 0;                      /* FIS HOB bit clear */
15292    fis->d.reserved5      = 0;
15293
15294    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15295
15296    break;
15297  case SAT_READ_VERIFY_SECTORS_EXT:
15298    fis->h.fisType        = 0x27;                   /* Reg host to device */
15299    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15300    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;      /* 0x42 */
15301    fis->h.features       = 0;                      /* FIS reserve */
15302    fis->d.lbaLow         = LBA[3];                 /* FIS LBA (7 :0 ) */
15303    fis->d.lbaMid         = LBA[2];                 /* FIS LBA (15:8 ) */
15304    fis->d.lbaHigh        = LBA[1];                 /* FIS LBA (23:16) */
15305    fis->d.device         = 0x40;                   /* FIS LBA mode set */
15306    fis->d.lbaLowExp      = LBA[0];                 /* FIS LBA (31:24) */
15307    fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15308    fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15309    fis->d.featuresExp    = 0;                      /* FIS reserve */
15310    if (satOrgIOContext->LoopNum == 1)
15311    {
15312      /* last loop */
15313      fis->d.sectorCount    = (bit8)(Remainder & 0xFF);       /* FIS sector count (7:0) */
15314      fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8);       /* FIS sector count (15:8) */
15315    }
15316    else
15317    {
15318      fis->d.sectorCount    = 0xFF;                  /* FIS sector count (7:0) */
15319      fis->d.sectorCountExp = 0xFF;                  /* FIS sector count (15:8) */
15320    }
15321    fis->d.reserved4      = 0;
15322    fis->d.control        = 0;                       /* FIS HOB bit clear */
15323    fis->d.reserved5      = 0;
15324
15325    agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15326
15327    break;
15328
15329  default:
15330    TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15331    return tiError;
15332    break;
15333  }
15334
15335  /* Initialize CB for SATA completion.
15336   */
15337  /* chained data */
15338  satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15339
15340
15341  /*
15342   * Prepare SGL and send FIS to LL layer.
15343   */
15344  satIOContext->reqType = agRequestType;       /* Save it */
15345
15346  status = sataLLIOStart( tiRoot,
15347                          tiIORequest,
15348                          tiDeviceHandle,
15349                          tiScsiRequest,
15350                          satIOContext);
15351
15352  TI_DBG5(("satChainedWriteNVerify_Verify: return\n"));
15353  return (status);
15354
15355}
15356
15357
15358/*****************************************************************************/
15359/*! \brief SAT implementation for SCSI satWriteAndVerify16.
15360 *
15361 *  SAT implementation for SCSI satWriteAndVerify16.
15362 *
15363 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
15364 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
15365 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
15366 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
15367 *  \param   satIOContext_t:   Pointer to the SAT IO Context
15368 *
15369 *  \return If command is started successfully
15370 *    - \e tiSuccess:     I/O request successfully initiated.
15371 *    - \e tiBusy:        No resources available, try again later.
15372 *    - \e tiIONoDevice:  Invalid device handle.
15373 *    - \e tiError:       Other errors.
15374 */
15375/*****************************************************************************/
15376GLOBAL bit32  satWriteAndVerify16(
15377                   tiRoot_t                  *tiRoot,
15378                   tiIORequest_t             *tiIORequest,
15379                   tiDeviceHandle_t          *tiDeviceHandle,
15380                   tiScsiInitiatorRequest_t *tiScsiRequest,
15381                   satIOContext_t            *satIOContext)
15382{
15383  /*
15384    combination of write16 and verify16
15385    since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support
15386  */
15387  bit32                     status;
15388  bit32                     agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15389  satDeviceData_t           *pSatDevData;
15390  scsiRspSense_t            *pSense;
15391  tiIniScsiCmnd_t           *scsiCmnd;
15392  agsaFisRegHostToDevice_t  *fis;
15393  bit32                     lba = 0;
15394  bit32                     tl = 0;
15395  bit32                     LoopNum = 1;
15396  bit8                      LBA[8];
15397  bit8                      TL[8];
15398  bit32                     rangeChk = agFALSE; /* lba and tl range check */
15399  bit32                     limitChk = agFALSE; /* lba and tl range check */
15400
15401  pSense        = satIOContext->pSense;
15402  pSatDevData   = satIOContext->pSatDevData;
15403  scsiCmnd      = &tiScsiRequest->scsiCmnd;
15404  fis           = satIOContext->pFis;
15405  TI_DBG5(("satWriteAndVerify16:start\n"));
15406
15407  /* checking BYTCHK bit */
15408  if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15409  {
15410    satSetSensePayload( pSense,
15411                        SCSI_SNSKEY_ILLEGAL_REQUEST,
15412                        0,
15413                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15414                        satIOContext);
15415
15416    ostiInitiatorIOCompleted( tiRoot,
15417                              tiIORequest,
15418                              tiIOSuccess,
15419                              SCSI_STAT_CHECK_CONDITION,
15420                              satIOContext->pTiSenseData,
15421                              satIOContext->interruptContext );
15422
15423    TI_DBG1(("satWriteAndVerify16: BYTCHK bit checking \n"));
15424    return tiSuccess;
15425  }
15426
15427
15428  /* checking CONTROL */
15429  /* NACA == 1 or LINK == 1*/
15430  if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
15431  {
15432    satSetSensePayload( pSense,
15433                        SCSI_SNSKEY_ILLEGAL_REQUEST,
15434                        0,
15435                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15436                        satIOContext);
15437
15438    ostiInitiatorIOCompleted( tiRoot,
15439                              tiIORequest,
15440                              tiIOSuccess,
15441                              SCSI_STAT_CHECK_CONDITION,
15442                              satIOContext->pTiSenseData,
15443                              satIOContext->interruptContext );
15444
15445    TI_DBG2(("satWriteAndVerify16: return control\n"));
15446    return tiSuccess;
15447  }
15448
15449  osti_memset(LBA, 0, sizeof(LBA));
15450  osti_memset(TL, 0, sizeof(TL));
15451
15452
15453  /* do not use memcpy due to indexing in LBA and TL */
15454  LBA[0] = scsiCmnd->cdb[2];  /* MSB */
15455  LBA[1] = scsiCmnd->cdb[3];
15456  LBA[2] = scsiCmnd->cdb[4];
15457  LBA[3] = scsiCmnd->cdb[5];
15458  LBA[4] = scsiCmnd->cdb[6];
15459  LBA[5] = scsiCmnd->cdb[7];
15460  LBA[6] = scsiCmnd->cdb[8];
15461  LBA[7] = scsiCmnd->cdb[9];  /* LSB */
15462
15463  TL[0] = 0;
15464  TL[1] = 0;
15465  TL[2] = 0;
15466  TL[3] = 0;
15467  TL[4] = scsiCmnd->cdb[10];   /* MSB */
15468  TL[5] = scsiCmnd->cdb[11];
15469  TL[6] = scsiCmnd->cdb[12];
15470  TL[7] = scsiCmnd->cdb[13];   /* LSB */
15471
15472  rangeChk = satAddNComparebit64(LBA, TL);
15473
15474  limitChk = satCompareLBALimitbit(LBA);
15475
15476  lba = satComputeCDB16LBA(satIOContext);
15477  tl = satComputeCDB16TL(satIOContext);
15478
15479
15480  /* Table 34, 9.1, p 46 */
15481  /*
15482    note: As of 2/10/2006, no support for DMA QUEUED
15483  */
15484
15485  /*
15486    Table 34, 9.1, p 46, b
15487    When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15488    return check condition
15489  */
15490  if (pSatDevData->satNCQ != agTRUE &&
15491     pSatDevData->sat48BitSupport != agTRUE
15492     )
15493  {
15494    if (limitChk)
15495    {
15496      TI_DBG1(("satWriteAndVerify16: return LBA out of range, not EXT\n"));
15497      satSetSensePayload( pSense,
15498                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15499                          0,
15500                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15501                          satIOContext);
15502
15503      ostiInitiatorIOCompleted( tiRoot,
15504                                tiIORequest,
15505                                tiIOSuccess,
15506                                SCSI_STAT_CHECK_CONDITION,
15507                                satIOContext->pTiSenseData,
15508                                satIOContext->interruptContext );
15509
15510    return tiSuccess;
15511    }
15512    if (rangeChk) //    if (lba + tl > SAT_TR_LBA_LIMIT)
15513    {
15514      TI_DBG1(("satWriteAndVerify16: return LBA+TL out of range, not EXT\n"));
15515      satSetSensePayload( pSense,
15516                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15517                          0,
15518                          SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15519                          satIOContext);
15520
15521      ostiInitiatorIOCompleted( tiRoot,
15522                                tiIORequest,
15523                                tiIOSuccess,
15524                                SCSI_STAT_CHECK_CONDITION,
15525                                satIOContext->pTiSenseData,
15526                                satIOContext->interruptContext );
15527
15528    return tiSuccess;
15529    }
15530  }
15531
15532
15533  /* case 1 and 2 */
15534  if (!rangeChk) //  if (lba + tl <= SAT_TR_LBA_LIMIT)
15535  {
15536    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15537    {
15538      /* case 2 */
15539      /* WRITE DMA*/
15540      /* In case that we can't fit the transfer length, we loop */
15541      TI_DBG5(("satWriteAndVerify16: case 2\n"));
15542      fis->h.fisType        = 0x27;                   /* Reg host to device */
15543      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15544      fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
15545      fis->h.features       = 0;                      /* FIS reserve */
15546      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15547      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15548      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15549
15550      /* FIS LBA mode set LBA (27:24) */
15551      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15552
15553      fis->d.lbaLowExp      = 0;
15554      fis->d.lbaMidExp      = 0;
15555      fis->d.lbaHighExp     = 0;
15556      fis->d.featuresExp    = 0;
15557      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15558      fis->d.sectorCountExp = 0;
15559      fis->d.reserved4      = 0;
15560      fis->d.control        = 0;                      /* FIS HOB bit clear */
15561      fis->d.reserved5      = 0;
15562
15563      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15564      satIOContext->ATACmd = SAT_WRITE_DMA;
15565    }
15566    else
15567    {
15568      /* case 1 */
15569      /* WRITE MULTIPLE or WRITE SECTOR(S) */
15570      /* WRITE SECTORS for easier implemetation */
15571      /* In case that we can't fit the transfer length, we loop */
15572      TI_DBG5(("satWriteAndVerify16: case 1\n"));
15573      fis->h.fisType        = 0x27;                   /* Reg host to device */
15574      fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
15575      fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
15576      fis->h.features       = 0;                      /* FIS reserve */
15577      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15578      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15579      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15580
15581      /* FIS LBA mode set LBA (27:24) */
15582      fis->d.device         = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15583
15584      fis->d.lbaLowExp      = 0;
15585      fis->d.lbaMidExp      = 0;
15586      fis->d.lbaHighExp     = 0;
15587      fis->d.featuresExp    = 0;
15588      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15589      fis->d.sectorCountExp = 0;
15590      fis->d.reserved4      = 0;
15591      fis->d.control        = 0;                      /* FIS HOB bit clear */
15592      fis->d.reserved5      = 0;
15593
15594      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15595      satIOContext->ATACmd = SAT_WRITE_SECTORS;
15596    }
15597  }
15598
15599  /* case 3 and 4 */
15600  if (pSatDevData->sat48BitSupport == agTRUE)
15601  {
15602    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15603    {
15604      /* case 3 */
15605      /* WRITE DMA EXT or WRITE DMA FUA EXT */
15606      TI_DBG5(("satWriteAndVerify16: case 3\n"));
15607      fis->h.fisType        = 0x27;                   /* Reg host to device */
15608      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15609
15610      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15611      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
15612
15613      fis->h.features       = 0;                      /* FIS reserve */
15614      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15615      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15616      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15617      fis->d.device         = 0x40;                   /* FIS LBA mode set */
15618      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
15619      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
15620      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
15621      fis->d.featuresExp    = 0;                      /* FIS reserve */
15622      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15623      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
15624      fis->d.reserved4      = 0;
15625      fis->d.control        = 0;                      /* FIS HOB bit clear */
15626      fis->d.reserved5      = 0;
15627
15628      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15629      satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15630    }
15631    else
15632    {
15633      /* case 4 */
15634      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15635      /* WRITE SECTORS EXT for easier implemetation */
15636      TI_DBG5(("satWriteAndVerify16: case 4\n"));
15637      fis->h.fisType        = 0x27;                   /* Reg host to device */
15638      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15639      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
15640
15641      fis->h.features       = 0;                      /* FIS reserve */
15642      fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15643      fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15644      fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15645      fis->d.device         = 0x40;                   /* FIS LBA mode set */
15646      fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
15647      fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
15648      fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
15649      fis->d.featuresExp    = 0;                      /* FIS reserve */
15650      fis->d.sectorCount    = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15651      fis->d.sectorCountExp = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
15652      fis->d.reserved4      = 0;
15653      fis->d.control        = 0;                      /* FIS HOB bit clear */
15654      fis->d.reserved5      = 0;
15655
15656      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15657      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15658    }
15659  }
15660
15661  /* case 5 */
15662  if (pSatDevData->satNCQ == agTRUE)
15663  {
15664    /* WRITE FPDMA QUEUED */
15665    if (pSatDevData->sat48BitSupport != agTRUE)
15666    {
15667      TI_DBG5(("satWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support \n"));
15668      satSetSensePayload( pSense,
15669                          SCSI_SNSKEY_ILLEGAL_REQUEST,
15670                          0,
15671                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15672                          satIOContext);
15673
15674      ostiInitiatorIOCompleted( tiRoot,
15675                                tiIORequest,
15676                                tiIOSuccess,
15677                                SCSI_STAT_CHECK_CONDITION,
15678                                satIOContext->pTiSenseData,
15679                                satIOContext->interruptContext );
15680      return tiSuccess;
15681    }
15682    TI_DBG6(("satWriteAndVerify16: case 5\n"));
15683
15684    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15685
15686    fis->h.fisType        = 0x27;                   /* Reg host to device */
15687    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15688    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15689    fis->h.features       = scsiCmnd->cdb[13];       /* FIS sector count (7:0) */
15690    fis->d.lbaLow         = scsiCmnd->cdb[9];       /* FIS LBA (7 :0 ) */
15691    fis->d.lbaMid         = scsiCmnd->cdb[8];       /* FIS LBA (15:8 ) */
15692    fis->d.lbaHigh        = scsiCmnd->cdb[7];       /* FIS LBA (23:16) */
15693
15694    /* Check FUA bit */
15695    if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
15696      fis->d.device       = 0xC0;                   /* FIS FUA set */
15697    else
15698      fis->d.device       = 0x40;                   /* FIS FUA clear */
15699
15700    fis->d.lbaLowExp      = scsiCmnd->cdb[6];       /* FIS LBA (31:24) */
15701    fis->d.lbaMidExp      = scsiCmnd->cdb[5];       /* FIS LBA (39:32) */
15702    fis->d.lbaHighExp     = scsiCmnd->cdb[4];       /* FIS LBA (47:40) */
15703    fis->d.featuresExp    = scsiCmnd->cdb[12];       /* FIS sector count (15:8) */
15704    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
15705    fis->d.sectorCountExp = 0;
15706    fis->d.reserved4      = 0;
15707    fis->d.control        = 0;                      /* FIS HOB bit clear */
15708    fis->d.reserved5      = 0;
15709
15710    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15711    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15712  }
15713
15714  satIOContext->currentLBA = lba;
15715  satIOContext->OrgTL = tl;
15716
15717  /*
15718    computing number of loop and remainder for tl
15719    0xFF in case not ext
15720    0xFFFF in case EXT
15721  */
15722  if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15723  {
15724    LoopNum = satComputeLoopNum(tl, 0xFF);
15725  }
15726  else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15727           fis->h.command == SAT_WRITE_DMA_EXT     ||
15728           fis->h.command == SAT_WRITE_DMA_FUA_EXT
15729           )
15730  {
15731    /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15732    LoopNum = satComputeLoopNum(tl, 0xFFFF);
15733  }
15734  else
15735  {
15736    /* SAT_WRITE_FPDMA_QUEUEDK */
15737    LoopNum = satComputeLoopNum(tl, 0xFFFF);
15738  }
15739
15740  satIOContext->LoopNum = LoopNum;
15741
15742
15743  if (LoopNum == 1)
15744  {
15745    TI_DBG5(("satWriteAndVerify16: NON CHAINED data\n"));
15746    /* Initialize CB for SATA completion.
15747     */
15748    satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15749  }
15750  else
15751  {
15752    TI_DBG1(("satWriteAndVerify16: CHAINED data\n"));
15753    /* re-setting tl */
15754    if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15755    {
15756       fis->d.sectorCount    = 0xFF;
15757    }
15758    else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15759             fis->h.command == SAT_WRITE_DMA_EXT ||
15760             fis->h.command == SAT_WRITE_DMA_FUA_EXT
15761             )
15762    {
15763      fis->d.sectorCount    = 0xFF;
15764      fis->d.sectorCountExp = 0xFF;
15765    }
15766    else
15767    {
15768      /* SAT_WRITE_FPDMA_QUEUED */
15769      fis->h.features       = 0xFF;
15770      fis->d.featuresExp    = 0xFF;
15771    }
15772
15773    /* Initialize CB for SATA completion.
15774     */
15775    satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15776  }
15777
15778
15779  /*
15780   * Prepare SGL and send FIS to LL layer.
15781   */
15782  satIOContext->reqType = agRequestType;       /* Save it */
15783
15784  status = sataLLIOStart( tiRoot,
15785                          tiIORequest,
15786                          tiDeviceHandle,
15787                          tiScsiRequest,
15788                          satIOContext);
15789  return (status);
15790}
15791
15792/*****************************************************************************/
15793/*! \brief SAT implementation for SCSI satReadMediaSerialNumber.
15794 *
15795 *  SAT implementation for SCSI Read Media Serial Number.
15796 *
15797 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
15798 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
15799 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
15800 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
15801 *  \param   satIOContext_t:   Pointer to the SAT IO Context
15802 *
15803 *  \return If command is started successfully
15804 *    - \e tiSuccess:     I/O request successfully initiated.
15805 *    - \e tiBusy:        No resources available, try again later.
15806 *    - \e tiIONoDevice:  Invalid device handle.
15807 *    - \e tiError:       Other errors.
15808 */
15809/*****************************************************************************/
15810GLOBAL bit32  satReadMediaSerialNumber(
15811                   tiRoot_t                  *tiRoot,
15812                   tiIORequest_t             *tiIORequest,
15813                   tiDeviceHandle_t          *tiDeviceHandle,
15814                   tiScsiInitiatorRequest_t  *tiScsiRequest,
15815                   satIOContext_t            *satIOContext)
15816{
15817  bit32                     status;
15818  bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15819  satDeviceData_t           *pSatDevData;
15820  scsiRspSense_t            *pSense;
15821  tiIniScsiCmnd_t           *scsiCmnd;
15822  agsaFisRegHostToDevice_t  *fis;
15823  agsaSATAIdentifyData_t    *pSATAIdData;
15824  bit8                      *pSerialNumber;
15825
15826  pSense        = satIOContext->pSense;
15827  pSatDevData   = satIOContext->pSatDevData;
15828  scsiCmnd      = &tiScsiRequest->scsiCmnd;
15829  fis           = satIOContext->pFis;
15830  pSATAIdData   = &(pSatDevData->satIdentifyData);
15831  pSerialNumber = (bit8 *) tiScsiRequest->sglVirtualAddr;
15832
15833
15834  TI_DBG1(("satReadMediaSerialNumber: start\n"));
15835
15836  /* checking CONTROL */
15837  /* NACA == 1 or LINK == 1*/
15838  if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
15839  {
15840    satSetSensePayload( pSense,
15841                        SCSI_SNSKEY_ILLEGAL_REQUEST,
15842                        0,
15843                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15844                        satIOContext);
15845
15846    ostiInitiatorIOCompleted( tiRoot,
15847                              tiIORequest,
15848                              tiIOSuccess,
15849                              SCSI_STAT_CHECK_CONDITION,
15850                              satIOContext->pTiSenseData,
15851                              satIOContext->interruptContext );
15852
15853    TI_DBG1(("satReadMediaSerialNumber: return control\n"));
15854    return tiSuccess;
15855  }
15856
15857  if (tiScsiRequest->scsiCmnd.expDataLength == 4)
15858  {
15859    if (pSATAIdData->commandSetFeatureDefault & 0x4)
15860    {
15861      TI_DBG1(("satReadMediaSerialNumber: Media serial number returning only length\n"));
15862      /* SPC-3 6.16 p192; filling in length */
15863      pSerialNumber[0] = 0;
15864      pSerialNumber[1] = 0;
15865      pSerialNumber[2] = 0;
15866      pSerialNumber[3] = 0x3C;
15867    }
15868    else
15869    {
15870      /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/
15871      pSerialNumber[0] = 0;
15872      pSerialNumber[1] = 0;
15873      pSerialNumber[2] = 0x1;
15874      pSerialNumber[3] = 0xfc;
15875    }
15876
15877    ostiInitiatorIOCompleted( tiRoot,
15878                              tiIORequest,
15879                              tiIOSuccess,
15880                              SCSI_STAT_GOOD,
15881                              agNULL,
15882                              satIOContext->interruptContext);
15883
15884    return tiSuccess;
15885  }
15886
15887  if ( pSatDevData->IDDeviceValid == agTRUE)
15888  {
15889    if (pSATAIdData->commandSetFeatureDefault & 0x4)
15890    {
15891      /* word87 bit2 Media serial number is valid */
15892      /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/
15893      tdhexdump("ID satReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
15894      /* SPC-3 6.16 p192; filling in length */
15895      pSerialNumber[0] = 0;
15896      pSerialNumber[1] = 0;
15897      pSerialNumber[2] = 0;
15898      pSerialNumber[3] = 0x3C;
15899      osti_memcpy(&pSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
15900      tdhexdump("satReadMediaSerialNumber", (bit8*)pSerialNumber, 2*30 + 4);
15901
15902      ostiInitiatorIOCompleted( tiRoot,
15903                                tiIORequest,
15904                                tiIOSuccess,
15905                                SCSI_STAT_GOOD,
15906                                agNULL,
15907                                satIOContext->interruptContext);
15908      return tiSuccess;
15909
15910
15911    }
15912    else
15913    {
15914     /* word87 bit2 Media serial number is NOT valid */
15915      TI_DBG1(("satReadMediaSerialNumber: Media serial number is NOT valid \n"));
15916
15917      if (pSatDevData->sat48BitSupport == agTRUE)
15918      {
15919        /* READ VERIFY SECTORS EXT */
15920        fis->h.fisType        = 0x27;                   /* Reg host to device */
15921        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15922        fis->h.command        = SAT_READ_SECTORS_EXT;      /* 0x24 */
15923
15924        fis->h.features       = 0;                      /* FIS reserve */
15925        fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
15926        fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
15927        fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
15928        fis->d.device         = 0x40;                   /* FIS LBA mode set */
15929        fis->d.lbaLowExp      = 0;                      /* FIS LBA (31:24) */
15930        fis->d.lbaMidExp      = 0;                      /* FIS LBA (39:32) */
15931        fis->d.lbaHighExp     = 0;                      /* FIS LBA (47:40) */
15932        fis->d.featuresExp    = 0;                      /* FIS reserve */
15933        fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
15934        fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
15935        fis->d.reserved4      = 0;
15936        fis->d.control        = 0;                      /* FIS HOB bit clear */
15937        fis->d.reserved5      = 0;
15938
15939        agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15940      }
15941      else
15942      {
15943        /* READ VERIFY SECTORS */
15944        fis->h.fisType        = 0x27;                   /* Reg host to device */
15945        fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
15946        fis->h.command        = SAT_READ_SECTORS;       /* 0x20 */
15947        fis->h.features       = 0;                      /* FIS reserve */
15948        fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
15949        fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
15950        fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
15951        fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
15952        fis->d.lbaLowExp      = 0;
15953        fis->d.lbaMidExp      = 0;
15954        fis->d.lbaHighExp     = 0;
15955        fis->d.featuresExp    = 0;
15956        fis->d.sectorCount    = 1;                       /* FIS sector count (7:0) */
15957        fis->d.sectorCountExp = 0;
15958        fis->d.reserved4      = 0;
15959        fis->d.control        = 0;                      /* FIS HOB bit clear */
15960        fis->d.reserved5      = 0;
15961
15962
15963        agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15964      }
15965      satIOContext->satCompleteCB = &satReadMediaSerialNumberCB;
15966      satIOContext->reqType = agRequestType;       /* Save it */
15967      status = sataLLIOStart( tiRoot,
15968                             tiIORequest,
15969                             tiDeviceHandle,
15970                             tiScsiRequest,
15971                             satIOContext);
15972
15973      return status;
15974    }
15975  }
15976  else
15977  {
15978     /* temporary failure */
15979    ostiInitiatorIOCompleted( tiRoot,
15980                              tiIORequest,
15981                              tiIOFailed,
15982                              tiDetailOtherError,
15983                              agNULL,
15984                              satIOContext->interruptContext);
15985
15986    return tiSuccess;
15987
15988  }
15989
15990}
15991
15992/*****************************************************************************/
15993/*! \brief SAT implementation for SCSI satReadBuffer.
15994 *
15995 *  SAT implementation for SCSI Read Buffer.
15996 *
15997 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
15998 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
15999 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16000 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16001 *  \param   satIOContext_t:   Pointer to the SAT IO Context
16002 *
16003 *  \return If command is started successfully
16004 *    - \e tiSuccess:     I/O request successfully initiated.
16005 *    - \e tiBusy:        No resources available, try again later.
16006 *    - \e tiIONoDevice:  Invalid device handle.
16007 *    - \e tiError:       Other errors.
16008 */
16009/*****************************************************************************/
16010/* SAT-2, Revision 00*/
16011GLOBAL bit32  satReadBuffer(
16012                   tiRoot_t                  *tiRoot,
16013                   tiIORequest_t             *tiIORequest,
16014                   tiDeviceHandle_t          *tiDeviceHandle,
16015                   tiScsiInitiatorRequest_t *tiScsiRequest,
16016                   satIOContext_t            *satIOContext)
16017{
16018  bit32                     status = tiSuccess;
16019  bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16020  scsiRspSense_t            *pSense;
16021  tiIniScsiCmnd_t           *scsiCmnd;
16022  agsaFisRegHostToDevice_t  *fis;
16023  bit32                     bufferOffset;
16024  bit32                     tl;
16025  bit8                      mode;
16026  bit8                      bufferID;
16027  bit8                      *pBuff;
16028
16029  pSense        = satIOContext->pSense;
16030  scsiCmnd      = &tiScsiRequest->scsiCmnd;
16031  fis           = satIOContext->pFis;
16032  pBuff         = (bit8 *) tiScsiRequest->sglVirtualAddr;
16033
16034  TI_DBG2(("satReadBuffer: start\n"));
16035  /* checking CONTROL */
16036  /* NACA == 1 or LINK == 1*/
16037  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16038  {
16039    satSetSensePayload( pSense,
16040                        SCSI_SNSKEY_ILLEGAL_REQUEST,
16041                        0,
16042                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16043                        satIOContext);
16044    ostiInitiatorIOCompleted( tiRoot,
16045                              tiIORequest,
16046                              tiIOSuccess,
16047                              SCSI_STAT_CHECK_CONDITION,
16048                              satIOContext->pTiSenseData,
16049                              satIOContext->interruptContext );
16050    TI_DBG1(("satReadBuffer: return control\n"));
16051    return tiSuccess;
16052  }
16053
16054  bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16055  tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16056
16057  mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16058  bufferID = scsiCmnd->cdb[2];
16059
16060  if (mode == READ_BUFFER_DATA_MODE) /* 2 */
16061  {
16062    if (bufferID == 0 && bufferOffset == 0 && tl == 512)
16063    {
16064      /* send ATA READ BUFFER */
16065      fis->h.fisType        = 0x27;                   /* Reg host to device */
16066      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16067      fis->h.command        = SAT_READ_BUFFER;        /* 0xE4 */
16068      fis->h.features       = 0;                      /* FIS reserve */
16069      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16070      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16071      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16072      fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16073      fis->d.lbaLowExp      = 0;
16074      fis->d.lbaMidExp      = 0;
16075      fis->d.lbaHighExp     = 0;
16076      fis->d.featuresExp    = 0;
16077      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16078      fis->d.sectorCountExp = 0;
16079      fis->d.reserved4      = 0;
16080      fis->d.control        = 0;                      /* FIS HOB bit clear */
16081      fis->d.reserved5      = 0;
16082
16083      agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16084      satIOContext->satCompleteCB = &satReadBufferCB;
16085      satIOContext->reqType = agRequestType;       /* Save it */
16086
16087      status = sataLLIOStart( tiRoot,
16088                              tiIORequest,
16089                              tiDeviceHandle,
16090                              tiScsiRequest,
16091                              satIOContext);
16092      return status;
16093    }
16094    if (bufferID == 0 && bufferOffset == 0 && tl != 512)
16095    {
16096      satSetSensePayload( pSense,
16097                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16098                          0,
16099                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16100                          satIOContext);
16101      ostiInitiatorIOCompleted( tiRoot,
16102                                tiIORequest,
16103                                tiIOSuccess,
16104                                SCSI_STAT_CHECK_CONDITION,
16105                                satIOContext->pTiSenseData,
16106                                satIOContext->interruptContext );
16107      TI_DBG1(("satReadBuffer: allocation length is not 512; it is %d\n", tl));
16108      return tiSuccess;
16109    }
16110    if (bufferID == 0 && bufferOffset != 0)
16111    {
16112      satSetSensePayload( pSense,
16113                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16114                          0,
16115                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16116                          satIOContext);
16117      ostiInitiatorIOCompleted( tiRoot,
16118                                tiIORequest,
16119                                tiIOSuccess,
16120                                SCSI_STAT_CHECK_CONDITION,
16121                                satIOContext->pTiSenseData,
16122                                satIOContext->interruptContext );
16123      TI_DBG1(("satReadBuffer: buffer offset is not 0; it is %d\n", bufferOffset));
16124      return tiSuccess;
16125    }
16126    /* all other cases unsupported */
16127    TI_DBG1(("satReadBuffer: unsupported case 1\n"));
16128    satSetSensePayload( pSense,
16129                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16130                          0,
16131                          SCSI_SNSCODE_INVALID_COMMAND,
16132                          satIOContext);
16133
16134    ostiInitiatorIOCompleted( tiRoot,
16135                                tiIORequest,
16136                                tiIOSuccess,
16137                                SCSI_STAT_CHECK_CONDITION,
16138                                satIOContext->pTiSenseData,
16139                                satIOContext->interruptContext );
16140    return tiSuccess;
16141  }
16142  else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */
16143  {
16144    if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */
16145    {
16146      satSetSensePayload( pSense,
16147                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16148                          0,
16149                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16150                          satIOContext);
16151      ostiInitiatorIOCompleted( tiRoot,
16152                                tiIORequest,
16153                                tiIOSuccess,
16154                                SCSI_STAT_CHECK_CONDITION,
16155                                satIOContext->pTiSenseData,
16156                                satIOContext->interruptContext );
16157      TI_DBG1(("satReadBuffer: tl < 4; tl is %d\n", tl));
16158      return tiSuccess;
16159    }
16160    if (bufferID == 0)
16161    {
16162      /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/
16163      pBuff[0] = 0xFF;
16164      pBuff[1] = 0x00;
16165      pBuff[2] = 0x02;
16166      pBuff[3] = 0x00;
16167      if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
16168      {
16169        /* underrrun */
16170        TI_DBG1(("satReadBuffer: underrun tl %d data %d\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
16171        ostiInitiatorIOCompleted( tiRoot,
16172                                tiIORequest,
16173                                tiIOUnderRun,
16174                                tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
16175                                agNULL,
16176                                satIOContext->interruptContext );
16177        return tiSuccess;
16178      }
16179      else
16180      {
16181        ostiInitiatorIOCompleted( tiRoot,
16182                                  tiIORequest,
16183                                  tiIOSuccess,
16184                                  SCSI_STAT_GOOD,
16185                                  agNULL,
16186                                  satIOContext->interruptContext);
16187        return tiSuccess;
16188      }
16189    }
16190    else
16191    {
16192      /* We don't support other than bufferID 0 */
16193      satSetSensePayload( pSense,
16194                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16195                          0,
16196                          SCSI_SNSCODE_INVALID_COMMAND,
16197                          satIOContext);
16198
16199      ostiInitiatorIOCompleted( tiRoot,
16200                                tiIORequest,
16201                                tiIOSuccess,
16202                                SCSI_STAT_CHECK_CONDITION,
16203                                satIOContext->pTiSenseData,
16204                                satIOContext->interruptContext );
16205      return tiSuccess;
16206    }
16207  }
16208  else
16209  {
16210    /* We don't support any other mode */
16211    TI_DBG1(("satReadBuffer: unsupported mode %d\n", mode));
16212    satSetSensePayload( pSense,
16213                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16214                          0,
16215                          SCSI_SNSCODE_INVALID_COMMAND,
16216                          satIOContext);
16217
16218    ostiInitiatorIOCompleted( tiRoot,
16219                                tiIORequest,
16220                                tiIOSuccess,
16221                                SCSI_STAT_CHECK_CONDITION,
16222                                satIOContext->pTiSenseData,
16223                                satIOContext->interruptContext );
16224    return tiSuccess;
16225  }
16226}
16227
16228/*****************************************************************************/
16229/*! \brief SAT implementation for SCSI satWriteBuffer.
16230 *
16231 *  SAT implementation for SCSI Write Buffer.
16232 *
16233 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16234 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16235 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16236 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16237 *  \param   satIOContext_t:   Pointer to the SAT IO Context
16238 *
16239 *  \return If command is started successfully
16240 *    - \e tiSuccess:     I/O request successfully initiated.
16241 *    - \e tiBusy:        No resources available, try again later.
16242 *    - \e tiIONoDevice:  Invalid device handle.
16243 *    - \e tiError:       Other errors.
16244 */
16245/*****************************************************************************/
16246/* SAT-2, Revision 00*/
16247GLOBAL bit32  satWriteBuffer(
16248                   tiRoot_t                  *tiRoot,
16249                   tiIORequest_t             *tiIORequest,
16250                   tiDeviceHandle_t          *tiDeviceHandle,
16251                   tiScsiInitiatorRequest_t *tiScsiRequest,
16252                   satIOContext_t            *satIOContext)
16253{
16254#ifdef NOT_YET
16255  bit32                     agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16256#endif
16257  scsiRspSense_t            *pSense;
16258  tiIniScsiCmnd_t           *scsiCmnd;
16259  bit32                     bufferOffset;
16260  bit32                     parmLen;
16261  bit8                      mode;
16262  bit8                      bufferID;
16263  bit8                      *pBuff;
16264
16265  pSense        = satIOContext->pSense;
16266  scsiCmnd      = &tiScsiRequest->scsiCmnd;
16267  pBuff         = (bit8 *) tiScsiRequest->sglVirtualAddr;
16268
16269  TI_DBG2(("satWriteBuffer: start\n"));
16270
16271  /* checking CONTROL */
16272  /* NACA == 1 or LINK == 1*/
16273  if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16274  {
16275    satSetSensePayload( pSense,
16276                        SCSI_SNSKEY_ILLEGAL_REQUEST,
16277                        0,
16278                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16279                        satIOContext);
16280
16281    ostiInitiatorIOCompleted( tiRoot,
16282                              tiIORequest,
16283                              tiIOSuccess,
16284                              SCSI_STAT_CHECK_CONDITION,
16285                              satIOContext->pTiSenseData,
16286                              satIOContext->interruptContext );
16287
16288    TI_DBG1(("satWriteBuffer: return control\n"));
16289    return tiSuccess;
16290  }
16291
16292  bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16293  parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16294
16295  mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16296  bufferID = scsiCmnd->cdb[2];
16297
16298  /* for debugging only */
16299  tdhexdump("satWriteBuffer pBuff", (bit8 *)pBuff, 24);
16300
16301  if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */
16302  {
16303    if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
16304    {
16305      TI_DBG1(("satWriteBuffer: sending ATA WRITE BUFFER\n"));
16306      /* send ATA WRITE BUFFER */
16307#ifdef NOT_YET
16308      fis->h.fisType        = 0x27;                   /* Reg host to device */
16309      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16310      fis->h.command        = SAT_WRITE_BUFFER;       /* 0xE8 */
16311      fis->h.features       = 0;                      /* FIS reserve */
16312      fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
16313      fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
16314      fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
16315      fis->d.device         = 0x40;                   /* FIS LBA (27:24) and FIS LBA mode  */
16316      fis->d.lbaLowExp      = 0;
16317      fis->d.lbaMidExp      = 0;
16318      fis->d.lbaHighExp     = 0;
16319      fis->d.featuresExp    = 0;
16320      fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
16321      fis->d.sectorCountExp = 0;
16322      fis->d.reserved4      = 0;
16323      fis->d.control        = 0;                      /* FIS HOB bit clear */
16324      fis->d.reserved5      = 0;
16325
16326
16327      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16328
16329      satIOContext->satCompleteCB = &satWriteBufferCB;
16330
16331      satIOContext->reqType = agRequestType;       /* Save it */
16332
16333      status = sataLLIOStart( tiRoot,
16334                              tiIORequest,
16335                              tiDeviceHandle,
16336                              tiScsiRequest,
16337                              satIOContext);
16338      return status;
16339#endif
16340      /* temp */
16341      ostiInitiatorIOCompleted( tiRoot,
16342                                  tiIORequest,
16343                                  tiIOSuccess,
16344                                  SCSI_STAT_GOOD,
16345                                  agNULL,
16346                                  satIOContext->interruptContext);
16347      return tiSuccess;
16348    }
16349    if ( (bufferID == 0 && bufferOffset != 0) ||
16350         (bufferID == 0 && parmLen != 512)
16351        )
16352    {
16353      satSetSensePayload( pSense,
16354                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16355                          0,
16356                          SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16357                          satIOContext);
16358
16359      ostiInitiatorIOCompleted( tiRoot,
16360                                tiIORequest,
16361                                tiIOSuccess,
16362                                SCSI_STAT_CHECK_CONDITION,
16363                                satIOContext->pTiSenseData,
16364                                satIOContext->interruptContext );
16365
16366      TI_DBG1(("satWriteBuffer: wrong buffer offset %d or parameter length parmLen %d\n", bufferOffset, parmLen));
16367      return tiSuccess;
16368    }
16369
16370    /* all other cases unsupported */
16371    TI_DBG1(("satWriteBuffer: unsupported case 1\n"));
16372    satSetSensePayload( pSense,
16373                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16374                          0,
16375                          SCSI_SNSCODE_INVALID_COMMAND,
16376                          satIOContext);
16377
16378    ostiInitiatorIOCompleted( tiRoot,
16379                                tiIORequest,
16380                                tiIOSuccess,
16381                                SCSI_STAT_CHECK_CONDITION,
16382                                satIOContext->pTiSenseData,
16383                                satIOContext->interruptContext );
16384
16385    return tiSuccess;
16386
16387  }
16388  else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */
16389  {
16390    TI_DBG1(("satWriteBuffer: not yet supported mode %d\n", mode));
16391    satSetSensePayload( pSense,
16392                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16393                          0,
16394                          SCSI_SNSCODE_INVALID_COMMAND,
16395                          satIOContext);
16396
16397    ostiInitiatorIOCompleted( tiRoot,
16398                                tiIORequest,
16399                                tiIOSuccess,
16400                                SCSI_STAT_CHECK_CONDITION,
16401                                satIOContext->pTiSenseData,
16402                                satIOContext->interruptContext );
16403
16404    return tiSuccess;
16405  }
16406  else
16407  {
16408    /* We don't support any other mode */
16409    TI_DBG1(("satWriteBuffer: unsupported mode %d\n", mode));
16410    satSetSensePayload( pSense,
16411                          SCSI_SNSKEY_ILLEGAL_REQUEST,
16412                          0,
16413                          SCSI_SNSCODE_INVALID_COMMAND,
16414                          satIOContext);
16415
16416    ostiInitiatorIOCompleted( tiRoot,
16417                                tiIORequest,
16418                                tiIOSuccess,
16419                                SCSI_STAT_CHECK_CONDITION,
16420                                satIOContext->pTiSenseData,
16421                                satIOContext->interruptContext );
16422
16423    return tiSuccess;
16424  }
16425
16426}
16427
16428/*****************************************************************************/
16429/*! \brief SAT implementation for SCSI satReassignBlocks.
16430 *
16431 *  SAT implementation for SCSI Reassign Blocks.
16432 *
16433 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16434 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16435 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16436 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16437 *  \param   satIOContext_t:   Pointer to the SAT IO Context
16438 *
16439 *  \return If command is started successfully
16440 *    - \e tiSuccess:     I/O request successfully initiated.
16441 *    - \e tiBusy:        No resources available, try again later.
16442 *    - \e tiIONoDevice:  Invalid device handle.
16443 *    - \e tiError:       Other errors.
16444 */
16445/*****************************************************************************/
16446GLOBAL bit32  satReassignBlocks(
16447                   tiRoot_t                  *tiRoot,
16448                   tiIORequest_t             *tiIORequest,
16449                   tiDeviceHandle_t          *tiDeviceHandle,
16450                   tiScsiInitiatorRequest_t *tiScsiRequest,
16451                   satIOContext_t            *satIOContext)
16452{
16453  /*
16454    assumes all LBA fits in ATA command; no boundary condition is checked here yet
16455  */
16456  bit32                     status;
16457  bit32                     agRequestType;
16458  satDeviceData_t           *pSatDevData;
16459  scsiRspSense_t            *pSense;
16460  tiIniScsiCmnd_t           *scsiCmnd;
16461  agsaFisRegHostToDevice_t  *fis;
16462  bit8                      *pParmList;    /* Log Page data buffer */
16463  bit8                      LongLBA;
16464  bit8                      LongList;
16465  bit32                     defectListLen;
16466  bit8                      LBA[8];
16467  bit32                     startingIndex;
16468
16469  pSense        = satIOContext->pSense;
16470  pSatDevData   = satIOContext->pSatDevData;
16471  scsiCmnd      = &tiScsiRequest->scsiCmnd;
16472  fis           = satIOContext->pFis;
16473  pParmList     = (bit8 *) tiScsiRequest->sglVirtualAddr;
16474
16475  TI_DBG5(("satReassignBlocks: start\n"));
16476
16477  /* checking CONTROL */
16478  /* NACA == 1 or LINK == 1*/
16479  if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
16480  {
16481    satSetSensePayload( pSense,
16482                        SCSI_SNSKEY_ILLEGAL_REQUEST,
16483                        0,
16484                        SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16485                        satIOContext);
16486
16487    ostiInitiatorIOCompleted( tiRoot,
16488                              tiIORequest,
16489                              tiIOSuccess,
16490                              SCSI_STAT_CHECK_CONDITION,
16491                              satIOContext->pTiSenseData,
16492                              satIOContext->interruptContext );
16493
16494    TI_DBG1(("satReassignBlocks: return control\n"));
16495    return tiSuccess;
16496  }
16497
16498  osti_memset(satIOContext->LBA, 0, 8);
16499  satIOContext->ParmIndex = 0;
16500  satIOContext->ParmLen = 0;
16501
16502  LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK);
16503  LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16504  osti_memset(LBA, 0, sizeof(LBA));
16505
16506  if (LongList == 0)
16507  {
16508    defectListLen = (pParmList[2] << 8) + pParmList[3];
16509  }
16510  else
16511  {
16512    defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2))
16513                  + (pParmList[2] << 8) + pParmList[3];
16514  }
16515  /* SBC 5.16.2, p61*/
16516  satIOContext->ParmLen = defectListLen + 4 /* header size */;
16517
16518  startingIndex = 4;
16519
16520  if (LongLBA == 0)
16521  {
16522    LBA[4] = pParmList[startingIndex];   /* MSB */
16523    LBA[5] = pParmList[startingIndex+1];
16524    LBA[6] = pParmList[startingIndex+2];
16525    LBA[7] = pParmList[startingIndex+3];  /* LSB */
16526    startingIndex = startingIndex + 4;
16527  }
16528  else
16529  {
16530    LBA[0] = pParmList[startingIndex];    /* MSB */
16531    LBA[1] = pParmList[startingIndex+1];
16532    LBA[2] = pParmList[startingIndex+2];
16533    LBA[3] = pParmList[startingIndex+3];
16534    LBA[4] = pParmList[startingIndex+4];
16535    LBA[5] = pParmList[startingIndex+5];
16536    LBA[6] = pParmList[startingIndex+6];
16537    LBA[7] = pParmList[startingIndex+7];  /* LSB */
16538    startingIndex = startingIndex + 8;
16539  }
16540
16541  tdhexdump("satReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen);
16542
16543  if (pSatDevData->sat48BitSupport == agTRUE)
16544  {
16545    /* sends READ VERIFY SECTOR(S) EXT*/
16546    fis->h.fisType        = 0x27;                   /* Reg host to device */
16547    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16548    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16549    fis->h.features       = 0;                      /* FIS reserve */
16550    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16551    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16552    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16553    fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16554    fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16555    fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16556    fis->d.featuresExp    = 0;                      /* FIS reserve */
16557    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16558    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16559    fis->d.reserved4      = 0;
16560    fis->d.device         = 0x40;                   /* 01000000 */
16561    fis->d.control        = 0;                      /* FIS HOB bit clear */
16562    fis->d.reserved5      = 0;
16563  }
16564  else
16565  {
16566    /* READ VERIFY SECTOR(S)*/
16567    fis->h.fisType        = 0x27;                   /* Reg host to device */
16568    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16569    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16570    fis->h.features       = 0;                      /* FIS features NA       */
16571    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16572    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16573    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16574    fis->d.lbaLowExp      = 0;
16575    fis->d.lbaMidExp      = 0;
16576    fis->d.lbaHighExp     = 0;
16577    fis->d.featuresExp    = 0;
16578    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16579    fis->d.sectorCountExp = 0;
16580    fis->d.reserved4      = 0;
16581    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16582                            /* DEV and LBA 27:24 */
16583    fis->d.control        = 0;                      /* FIS HOB bit clear */
16584    fis->d.reserved5      = 0;
16585  }
16586
16587  osti_memcpy(satIOContext->LBA, LBA, 8);
16588  satIOContext->ParmIndex = startingIndex;
16589
16590  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16591
16592  /* Initialize CB for SATA completion.
16593   */
16594  satIOContext->satCompleteCB = &satReassignBlocksCB;
16595
16596  /*
16597   * Prepare SGL and send FIS to LL layer.
16598   */
16599  satIOContext->reqType = agRequestType;       /* Save it */
16600
16601  status = sataLLIOStart( tiRoot,
16602                          tiIORequest,
16603                          tiDeviceHandle,
16604                          tiScsiRequest,
16605                          satIOContext);
16606
16607  return status;
16608}
16609
16610/*****************************************************************************/
16611/*! \brief SAT implementation for SCSI satReassignBlocks_1.
16612 *
16613 *  SAT implementation for SCSI Reassign Blocks. This is helper function for
16614 *  satReassignBlocks and satReassignBlocksCB. This sends ATA verify command.
16615 *
16616 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16617 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16618 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16619 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16620 *  \param   satIOContext_t:   Pointer to the SAT IO Context
16621 *
16622 *  \return If command is started successfully
16623 *    - \e tiSuccess:     I/O request successfully initiated.
16624 *    - \e tiBusy:        No resources available, try again later.
16625 *    - \e tiIONoDevice:  Invalid device handle.
16626 *    - \e tiError:       Other errors.
16627 */
16628/*****************************************************************************/
16629/* next LBA; sends READ VERIFY SECTOR; update LBA and ParmIdx */
16630GLOBAL bit32  satReassignBlocks_1(
16631                   tiRoot_t                  *tiRoot,
16632                   tiIORequest_t             *tiIORequest,
16633                   tiDeviceHandle_t          *tiDeviceHandle,
16634                   tiScsiInitiatorRequest_t *tiScsiRequest,
16635                   satIOContext_t            *satIOContext,
16636                   satIOContext_t            *satOrgIOContext
16637                   )
16638{
16639  /*
16640    assumes all LBA fits in ATA command; no boundary condition is checked here yet
16641    tiScsiRequest is OS generated; needs for accessing parameter list
16642  */
16643  bit32                     agRequestType;
16644  satDeviceData_t           *pSatDevData;
16645  tiIniScsiCmnd_t           *scsiCmnd;
16646  agsaFisRegHostToDevice_t  *fis;
16647  bit8                      *pParmList;    /* Log Page data buffer */
16648  bit8                      LongLBA;
16649  bit8                      LBA[8];
16650  bit32                     startingIndex;
16651
16652  pSatDevData   = satIOContext->pSatDevData;
16653  scsiCmnd      = &tiScsiRequest->scsiCmnd;
16654  fis           = satIOContext->pFis;
16655  pParmList     = (bit8 *) tiScsiRequest->sglVirtualAddr;
16656
16657  TI_DBG5(("satReassignBlocks_1: start\n"));
16658
16659  LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16660  osti_memset(LBA, 0, sizeof(LBA));
16661
16662  startingIndex = satOrgIOContext->ParmIndex;
16663
16664  if (LongLBA == 0)
16665  {
16666    LBA[4] = pParmList[startingIndex];
16667    LBA[5] = pParmList[startingIndex+1];
16668    LBA[6] = pParmList[startingIndex+2];
16669    LBA[7] = pParmList[startingIndex+3];
16670    startingIndex = startingIndex + 4;
16671  }
16672  else
16673  {
16674    LBA[0] = pParmList[startingIndex];
16675    LBA[1] = pParmList[startingIndex+1];
16676    LBA[2] = pParmList[startingIndex+2];
16677    LBA[3] = pParmList[startingIndex+3];
16678    LBA[4] = pParmList[startingIndex+4];
16679    LBA[5] = pParmList[startingIndex+5];
16680    LBA[6] = pParmList[startingIndex+6];
16681    LBA[7] = pParmList[startingIndex+7];
16682    startingIndex = startingIndex + 8;
16683  }
16684
16685  if (pSatDevData->sat48BitSupport == agTRUE)
16686  {
16687    /* sends READ VERIFY SECTOR(S) EXT*/
16688    fis->h.fisType        = 0x27;                   /* Reg host to device */
16689    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16690    fis->h.command        = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16691    fis->h.features       = 0;                      /* FIS reserve */
16692    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16693    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16694    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16695    fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16696    fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16697    fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16698    fis->d.featuresExp    = 0;                      /* FIS reserve */
16699    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16700    fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16701    fis->d.reserved4      = 0;
16702    fis->d.device         = 0x40;                   /* 01000000 */
16703    fis->d.control        = 0;                      /* FIS HOB bit clear */
16704    fis->d.reserved5      = 0;
16705  }
16706  else
16707  {
16708    /* READ VERIFY SECTOR(S)*/
16709    fis->h.fisType        = 0x27;                   /* Reg host to device */
16710    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16711    fis->h.command        = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16712    fis->h.features       = 0;                      /* FIS features NA       */
16713    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16714    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16715    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16716    fis->d.lbaLowExp      = 0;
16717    fis->d.lbaMidExp      = 0;
16718    fis->d.lbaHighExp     = 0;
16719    fis->d.featuresExp    = 0;
16720    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16721    fis->d.sectorCountExp = 0;
16722    fis->d.reserved4      = 0;
16723    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16724                            /* DEV and LBA 27:24 */
16725    fis->d.control        = 0;                      /* FIS HOB bit clear */
16726    fis->d.reserved5      = 0;
16727  }
16728  osti_memcpy(satOrgIOContext->LBA, LBA, 8);
16729  satOrgIOContext->ParmIndex = startingIndex;
16730  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16731  /* Initialize CB for SATA completion.
16732   */
16733  satIOContext->satCompleteCB = &satReassignBlocksCB;
16734  /*
16735   * Prepare SGL and send FIS to LL layer.
16736   */
16737  satIOContext->reqType = agRequestType;       /* Save it */
16738
16739  sataLLIOStart( tiRoot,
16740                 tiIORequest,
16741                 tiDeviceHandle,
16742                 tiScsiRequest,
16743                 satIOContext );
16744  return tiSuccess;
16745}
16746
16747/*****************************************************************************/
16748/*! \brief SAT implementation for SCSI satReassignBlocks_2.
16749 *
16750 *  SAT implementation for SCSI Reassign Blocks. This is helper function for
16751 *  satReassignBlocks and satReassignBlocksCB. This sends ATA write command.
16752 *
16753 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
16754 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
16755 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
16756 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
16757 *  \param   satIOContext_t:   Pointer to the SAT IO Context
16758 *  \param   LBA:              Pointer to the LBA to be processed
16759 *
16760 *  \return If command is started successfully
16761 *    - \e tiSuccess:     I/O request successfully initiated.
16762 *    - \e tiBusy:        No resources available, try again later.
16763 *    - \e tiIONoDevice:  Invalid device handle.
16764 *    - \e tiError:       Other errors.
16765 */
16766/*****************************************************************************/
16767/* current LBA; sends WRITE */
16768GLOBAL bit32  satReassignBlocks_2(
16769                   tiRoot_t                  *tiRoot,
16770                   tiIORequest_t             *tiIORequest,
16771                   tiDeviceHandle_t          *tiDeviceHandle,
16772                   tiScsiInitiatorRequest_t *tiScsiRequest,
16773                   satIOContext_t            *satIOContext,
16774                   bit8                      *LBA
16775                   )
16776{
16777  /*
16778    assumes all LBA fits in ATA command; no boundary condition is checked here yet
16779    tiScsiRequest is TD generated for writing
16780  */
16781  bit32                     status;
16782  bit32                     agRequestType;
16783  satDeviceData_t           *pSatDevData;
16784  scsiRspSense_t            *pSense;
16785  agsaFisRegHostToDevice_t  *fis;
16786
16787  pSense        = satIOContext->pSense;
16788  pSatDevData   = satIOContext->pSatDevData;
16789  fis           = satIOContext->pFis;
16790
16791  if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16792  {
16793    /* case 2 */
16794    /* WRITE DMA*/
16795    /* can't fit the transfer length */
16796    TI_DBG5(("satReassignBlocks_2: case 2\n"));
16797    fis->h.fisType        = 0x27;                   /* Reg host to device */
16798    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16799    fis->h.command        = SAT_WRITE_DMA;          /* 0xCA */
16800    fis->h.features       = 0;                      /* FIS reserve */
16801    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16802    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16803    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16804
16805    /* FIS LBA mode set LBA (27:24) */
16806    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16807
16808    fis->d.lbaLowExp      = 0;
16809    fis->d.lbaMidExp      = 0;
16810    fis->d.lbaHighExp     = 0;
16811    fis->d.featuresExp    = 0;
16812    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16813    fis->d.sectorCountExp = 0;
16814    fis->d.reserved4      = 0;
16815    fis->d.control        = 0;                      /* FIS HOB bit clear */
16816    fis->d.reserved5      = 0;
16817
16818    agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16819    satIOContext->ATACmd = SAT_WRITE_DMA;
16820  }
16821  else
16822  {
16823    /* case 1 */
16824    /* WRITE MULTIPLE or WRITE SECTOR(S) */
16825    /* WRITE SECTORS for easier implemetation */
16826    /* can't fit the transfer length */
16827    TI_DBG5(("satReassignBlocks_2: case 1\n"));
16828    fis->h.fisType        = 0x27;                   /* Reg host to device */
16829    fis->h.c_pmPort       = 0x80;                   /* C bit is set       */
16830    fis->h.command        = SAT_WRITE_SECTORS;      /* 0x30 */
16831    fis->h.features       = 0;                      /* FIS reserve */
16832    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16833    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16834    fis->d.lbaHigh        = LBA[7];                 /* FIS LBA (23:16) */
16835
16836    /* FIS LBA mode set LBA (27:24) */
16837    fis->d.device         = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16838
16839    fis->d.lbaLowExp      = 0;
16840    fis->d.lbaMidExp      = 0;
16841    fis->d.lbaHighExp     = 0;
16842    fis->d.featuresExp    = 0;
16843    fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16844    fis->d.sectorCountExp = 0;
16845    fis->d.reserved4      = 0;
16846    fis->d.control        = 0;                      /* FIS HOB bit clear */
16847    fis->d.reserved5      = 0;
16848
16849    agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16850    satIOContext->ATACmd = SAT_WRITE_SECTORS;
16851  }
16852
16853  /* case 3 and 4 */
16854  if (pSatDevData->sat48BitSupport == agTRUE)
16855  {
16856    if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16857    {
16858      /* case 3 */
16859      /* WRITE DMA EXT or WRITE DMA FUA EXT */
16860      TI_DBG5(("satReassignBlocks_2: case 3\n"));
16861      fis->h.fisType        = 0x27;                   /* Reg host to device */
16862      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16863
16864      /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
16865      fis->h.command        = SAT_WRITE_DMA_EXT;      /* 0x35 */
16866      satIOContext->ATACmd  = SAT_WRITE_DMA_EXT;
16867
16868      fis->h.features       = 0;                      /* FIS reserve */
16869      fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16870      fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16871      fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16872      fis->d.device         = 0x40;                   /* FIS LBA mode set */
16873      fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16874      fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16875      fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16876      fis->d.featuresExp    = 0;                      /* FIS reserve */
16877      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16878      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16879      fis->d.reserved4      = 0;
16880      fis->d.control        = 0;                      /* FIS HOB bit clear */
16881      fis->d.reserved5      = 0;
16882
16883      agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16884    }
16885    else
16886    {
16887      /* case 4 */
16888      /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
16889      /* WRITE SECTORS EXT for easier implemetation */
16890      TI_DBG5(("satReassignBlocks_2: case 4\n"));
16891      fis->h.fisType        = 0x27;                   /* Reg host to device */
16892      fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16893      fis->h.command        = SAT_WRITE_SECTORS_EXT;  /* 0x34 */
16894
16895      fis->h.features       = 0;                      /* FIS reserve */
16896      fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16897      fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16898      fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16899      fis->d.device         = 0x40;                   /* FIS LBA mode set */
16900      fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16901      fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16902      fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16903      fis->d.featuresExp    = 0;                      /* FIS reserve */
16904      fis->d.sectorCount    = 1;                      /* FIS sector count (7:0) */
16905      fis->d.sectorCountExp = 0;                      /* FIS sector count (15:8) */
16906      fis->d.reserved4      = 0;
16907      fis->d.control        = 0;                      /* FIS HOB bit clear */
16908      fis->d.reserved5      = 0;
16909
16910      agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16911      satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
16912    }
16913  }
16914  /* case 5 */
16915  if (pSatDevData->satNCQ == agTRUE)
16916  {
16917    /* WRITE FPDMA QUEUED */
16918    if (pSatDevData->sat48BitSupport != agTRUE)
16919    {
16920      TI_DBG5(("satReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
16921      satSetSensePayload( pSense,
16922                          SCSI_SNSKEY_HARDWARE_ERROR,
16923                          0,
16924                          SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
16925                          satIOContext);
16926
16927      ostiInitiatorIOCompleted( tiRoot,
16928                                tiIORequest,
16929                                tiIOSuccess,
16930                                SCSI_STAT_CHECK_CONDITION,
16931                                satIOContext->pTiSenseData,
16932                                satIOContext->interruptContext );
16933      return tiSuccess;
16934    }
16935    TI_DBG6(("satWrite10: case 5\n"));
16936
16937    /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
16938
16939    fis->h.fisType        = 0x27;                   /* Reg host to device */
16940    fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
16941    fis->h.command        = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
16942    fis->h.features       = 1;                      /* FIS sector count (7:0) */
16943    fis->d.lbaLow         = LBA[7];                 /* FIS LBA (7 :0 ) */
16944    fis->d.lbaMid         = LBA[6];                 /* FIS LBA (15:8 ) */
16945    fis->d.lbaHigh        = LBA[5];                 /* FIS LBA (23:16) */
16946
16947    /* Check FUA bit */
16948    fis->d.device       = 0x40;                     /* FIS FUA clear */
16949
16950    fis->d.lbaLowExp      = LBA[4];                 /* FIS LBA (31:24) */
16951    fis->d.lbaMidExp      = LBA[3];                 /* FIS LBA (39:32) */
16952    fis->d.lbaHighExp     = LBA[2];                 /* FIS LBA (47:40) */
16953    fis->d.featuresExp    = 0;                      /* FIS sector count (15:8) */
16954    fis->d.sectorCount    = 0;                      /* Tag (7:3) set by LL layer */
16955    fis->d.sectorCountExp = 0;
16956    fis->d.reserved4      = 0;
16957    fis->d.control        = 0;                      /* FIS HOB bit clear */
16958    fis->d.reserved5      = 0;
16959
16960    agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
16961    satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
16962  }
16963
16964  satIOContext->satCompleteCB = &satReassignBlocksCB;
16965
16966  /*
16967   * Prepare SGL and send FIS to LL layer.
16968   */
16969  satIOContext->reqType = agRequestType;       /* Save it */
16970
16971  status = sataLLIOStart( tiRoot,
16972                          tiIORequest,
16973                          tiDeviceHandle,
16974                          /* not the original, should be the TD generated one */
16975                          tiScsiRequest,
16976                          satIOContext);
16977  return (status);
16978}
16979
16980
16981/*****************************************************************************/
16982/*! \brief SAT implementation for SCSI satPrepareNewIO.
16983 *
16984 *  This function fills in the fields of internal IO generated by TD layer.
16985 *  This is mostly used in the callback functions.
16986 *
16987 *  \param   satNewIntIo:      Pointer to the internal IO structure.
16988 *  \param   tiOrgIORequest:   Pointer to the original tiIOrequest sent by OS layer
16989 *  \param   satDevData:       Pointer to the device data.
16990 *  \param   scsiCmnd:         Pointer to SCSI command.
16991 *  \param   satOrgIOContext:  Pointer to the original SAT IO Context
16992 *
16993 *  \return
16994 *    - \e Pointer to the new SAT IO Context
16995 */
16996/*****************************************************************************/
16997GLOBAL satIOContext_t *satPrepareNewIO(
16998                            satInternalIo_t         *satNewIntIo,
16999                            tiIORequest_t           *tiOrgIORequest,
17000                            satDeviceData_t         *satDevData,
17001                            tiIniScsiCmnd_t         *scsiCmnd,
17002                            satIOContext_t          *satOrgIOContext
17003                            )
17004{
17005  satIOContext_t          *satNewIOContext;
17006  tdIORequestBody_t       *tdNewIORequestBody;
17007
17008  TI_DBG2(("satPrepareNewIO: start\n"));
17009
17010  /* the one to be used; good 8/2/07 */
17011  satNewIntIo->satOrgTiIORequest = tiOrgIORequest; /* this is already done in
17012                                                        satAllocIntIoResource() */
17013
17014  tdNewIORequestBody = (tdIORequestBody_t *)satNewIntIo->satIntRequestBody;
17015  satNewIOContext = &(tdNewIORequestBody->transport.SATA.satIOContext);
17016
17017  satNewIOContext->pSatDevData   = satDevData;
17018  satNewIOContext->pFis          = &(tdNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
17019  satNewIOContext->pScsiCmnd     = &(satNewIntIo->satIntTiScsiXchg.scsiCmnd);
17020  if (scsiCmnd != agNULL)
17021  {
17022    /* saves only CBD; not scsi command for LBA and number of blocks */
17023    osti_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
17024  }
17025  satNewIOContext->pSense        = &(tdNewIORequestBody->transport.SATA.sensePayload);
17026  satNewIOContext->pTiSenseData  = &(tdNewIORequestBody->transport.SATA.tiSenseData);
17027  satNewIOContext->pTiSenseData->senseData = satNewIOContext->pSense;
17028  satNewIOContext->tiRequestBody = satNewIntIo->satIntRequestBody;
17029  satNewIOContext->interruptContext = satNewIOContext->interruptContext;
17030  satNewIOContext->satIntIoContext  = satNewIntIo;
17031  satNewIOContext->ptiDeviceHandle = satOrgIOContext->ptiDeviceHandle;
17032  satNewIOContext->satOrgIOContext = satOrgIOContext;
17033  /* saves tiScsiXchg; only for writesame10() */
17034  satNewIOContext->tiScsiXchg = satOrgIOContext->tiScsiXchg;
17035
17036  return satNewIOContext;
17037}
17038/*****************************************************************************
17039 *! \brief  satIOAbort
17040 *
17041 *   This routine is called to initiate a I/O abort to SATL.
17042 *   This routine is independent of HW/LL API.
17043 *
17044 *  \param  tiRoot:     Pointer to TISA initiator driver/port instance.
17045 *  \param  taskTag:    Pointer to TISA I/O request context/tag to be aborted.
17046 *
17047 *  \return:
17048 *
17049 *  \e tiSuccess:     I/O request successfully initiated.
17050 *  \e tiBusy:        No resources available, try again later.
17051 *  \e tiError:       Other errors that prevent the I/O request to be started.
17052 *
17053 *
17054 *****************************************************************************/
17055GLOBAL bit32 satIOAbort(
17056                          tiRoot_t      *tiRoot,
17057                          tiIORequest_t *taskTag )
17058{
17059
17060  tdsaRoot_t          *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
17061  tdsaContext_t       *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
17062  agsaRoot_t          *agRoot;
17063  tdIORequestBody_t   *tdIORequestBody;
17064  tdIORequestBody_t   *tdIONewRequestBody;
17065  agsaIORequest_t     *agIORequest;
17066  bit32               status;
17067  agsaIORequest_t     *agAbortIORequest;
17068  tdIORequestBody_t   *tdAbortIORequestBody;
17069  bit32               PhysUpper32;
17070  bit32               PhysLower32;
17071  bit32               memAllocStatus;
17072  void                *osMemHandle;
17073  satIOContext_t      *satIOContext;
17074  satInternalIo_t     *satIntIo;
17075
17076  TI_DBG2(("satIOAbort: start\n"));
17077
17078  agRoot          = &(tdsaAllShared->agRootNonInt);
17079  tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData;
17080
17081  /* needs to distinguish internally generated or externally generated */
17082  satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17083  satIntIo     = satIOContext->satIntIoContext;
17084  if (satIntIo == agNULL)
17085  {
17086    TI_DBG1(("satIOAbort: External, OS generated\n"));
17087    agIORequest     = &(tdIORequestBody->agIORequest);
17088  }
17089  else
17090  {
17091    TI_DBG1(("satIOAbort: Internal, TD generated\n"));
17092    tdIONewRequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
17093    agIORequest     = &(tdIONewRequestBody->agIORequest);
17094  }
17095
17096  /* allocating agIORequest for abort itself */
17097  memAllocStatus = ostiAllocMemory(
17098                                   tiRoot,
17099                                   &osMemHandle,
17100                                   (void **)&tdAbortIORequestBody,
17101                                   &PhysUpper32,
17102                                   &PhysLower32,
17103                                   8,
17104                                   sizeof(tdIORequestBody_t),
17105                                   agTRUE
17106                                   );
17107  if (memAllocStatus != tiSuccess)
17108  {
17109    /* let os process IO */
17110    TI_DBG1(("satIOAbort: ostiAllocMemory failed...\n"));
17111    return tiError;
17112  }
17113
17114  if (tdAbortIORequestBody == agNULL)
17115  {
17116    /* let os process IO */
17117    TI_DBG1(("satIOAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17118    return tiError;
17119  }
17120
17121  /* setup task management structure */
17122  tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17123  tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
17124
17125  /* initialize agIORequest */
17126  agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17127  agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17128  agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17129
17130  /* remember IO to be aborted */
17131  tdAbortIORequestBody->tiIOToBeAbortedRequest = taskTag;
17132
17133  status = saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, agNULL );
17134
17135  TI_DBG5(("satIOAbort: return status=0x%x\n", status));
17136
17137  if (status == AGSA_RC_SUCCESS)
17138    return tiSuccess;
17139  else
17140    return tiError;
17141
17142}
17143
17144
17145/*****************************************************************************
17146 *! \brief  satTM
17147 *
17148 *   This routine is called to initiate a TM request to SATL.
17149 *   This routine is independent of HW/LL API.
17150 *
17151 *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17152 *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17153 *  \param  task:             SAM-3 task management request.
17154 *  \param  lun:              Pointer to LUN.
17155 *  \param  taskTag:          Pointer to the associated task where the TM
17156 *                            command is to be applied.
17157 *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17158 *
17159 *  \return:
17160 *
17161 *  \e tiSuccess:     I/O request successfully initiated.
17162 *  \e tiBusy:        No resources available, try again later.
17163 *  \e tiIONoDevice:  Invalid device handle.
17164 *  \e tiError:       Other errors that prevent the I/O request to be started.
17165 *
17166 *
17167 *****************************************************************************/
17168 /* save task in satIOContext */
17169osGLOBAL bit32 satTM(
17170                        tiRoot_t          *tiRoot,
17171                        tiDeviceHandle_t  *tiDeviceHandle,
17172                        bit32             task,
17173                        tiLUN_t           *lun,
17174                        tiIORequest_t     *taskTag,
17175                        tiIORequest_t     *currentTaskTag,
17176                        tdIORequestBody_t *tiRequestBody,
17177                        bit32              NotifyOS
17178                        )
17179{
17180  tdIORequestBody_t           *tdIORequestBody = agNULL;
17181  satIOContext_t              *satIOContext = agNULL;
17182  tdsaDeviceData_t            *oneDeviceData = agNULL;
17183  bit32                       status;
17184
17185  TI_DBG3(("satTM: tiDeviceHandle=%p task=0x%x\n", tiDeviceHandle, task ));
17186
17187  /* set satIOContext fields and etc */
17188  oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17189
17190
17191  tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
17192  satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17193
17194  satIOContext->pSatDevData   = &oneDeviceData->satDevData;
17195  satIOContext->pFis          =
17196    &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
17197
17198
17199  satIOContext->tiRequestBody = tiRequestBody;
17200  satIOContext->ptiDeviceHandle = tiDeviceHandle;
17201  satIOContext->satIntIoContext  = agNULL;
17202  satIOContext->satOrgIOContext  = agNULL;
17203
17204  /* followings are used only for internal IO */
17205  satIOContext->currentLBA = 0;
17206  satIOContext->OrgTL = 0;
17207
17208  /* saving task in satIOContext */
17209  satIOContext->TMF = task;
17210
17211  satIOContext->satToBeAbortedIOContext = agNULL;
17212
17213  if (NotifyOS == agTRUE)
17214  {
17215    satIOContext->NotifyOS = agTRUE;
17216  }
17217  else
17218  {
17219    satIOContext->NotifyOS = agFALSE;
17220  }
17221  /*
17222   * Our SAT supports RESET LUN and partially support ABORT TASK (only if there
17223   * is no more than one I/O pending on the drive.
17224   */
17225
17226  if (task == AG_LOGICAL_UNIT_RESET)
17227  {
17228    status = satTmResetLUN( tiRoot,
17229                            currentTaskTag,
17230                            tiDeviceHandle,
17231                            agNULL,
17232                            satIOContext,
17233                            lun);
17234    return status;
17235  }
17236#ifdef TO_BE_REMOVED
17237  else if (task == AG_TARGET_WARM_RESET)
17238  {
17239    status = satTmWarmReset( tiRoot,
17240                             currentTaskTag,
17241                             tiDeviceHandle,
17242                             agNULL,
17243                             satIOContext);
17244
17245    return status;
17246  }
17247#endif
17248  else if (task == AG_ABORT_TASK)
17249  {
17250    status = satTmAbortTask( tiRoot,
17251                             currentTaskTag,
17252                             tiDeviceHandle,
17253                             agNULL,
17254                             satIOContext,
17255                             taskTag);
17256
17257    return status;
17258  }
17259  else if (task == TD_INTERNAL_TM_RESET)
17260  {
17261    status = satTDInternalTmReset( tiRoot,
17262                                   currentTaskTag,
17263                                   tiDeviceHandle,
17264                                   agNULL,
17265                                   satIOContext);
17266   return status;
17267  }
17268  else
17269  {
17270    TI_DBG1(("satTM: tiDeviceHandle=%p UNSUPPORTED TM task=0x%x\n",
17271        tiDeviceHandle, task ));
17272
17273    /* clean up TD layer's IORequestBody */
17274    ostiFreeMemory(
17275                   tiRoot,
17276                   tiRequestBody->IOType.InitiatorTMIO.osMemHandle,
17277                   sizeof(tdIORequestBody_t)
17278                   );
17279    return tiError;
17280  }
17281
17282}
17283
17284
17285/*****************************************************************************
17286 *! \brief  satTmResetLUN
17287 *
17288 *   This routine is called to initiate a TM RESET LUN request to SATL.
17289 *   This routine is independent of HW/LL API.
17290 *
17291 *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17292 *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17293 *  \param  lun:              Pointer to LUN.
17294 *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17295 *
17296 *  \return:
17297 *
17298 *  \e tiSuccess:     I/O request successfully initiated.
17299 *  \e tiBusy:        No resources available, try again later.
17300 *  \e tiIONoDevice:  Invalid device handle.
17301 *  \e tiError:       Other errors that prevent the I/O request to be started.
17302 *
17303 *
17304 *****************************************************************************/
17305osGLOBAL bit32 satTmResetLUN(
17306                            tiRoot_t                  *tiRoot,
17307                            tiIORequest_t             *tiIORequest, /* current task tag */
17308                            tiDeviceHandle_t          *tiDeviceHandle,
17309                            tiScsiInitiatorRequest_t *tiScsiRequest,
17310                            satIOContext_t            *satIOContext,
17311                            tiLUN_t                   *lun)
17312{
17313
17314  tdsaDeviceData_t        *tdsaDeviceData;
17315  satDeviceData_t         *satDevData;
17316
17317  tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17318  satDevData      = &tdsaDeviceData->satDevData;
17319
17320  TI_DBG1(("satTmResetLUN: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17321
17322  /*
17323   * Only support LUN 0
17324   */
17325  if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
17326        lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
17327  {
17328    TI_DBG1(("satTmResetLUN: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n",
17329                tiDeviceHandle));
17330    return tiError;
17331  }
17332
17333  /*
17334   * Check if there is other TM request pending
17335   */
17336  if (satDevData->satTmTaskTag != agNULL)
17337  {
17338    TI_DBG1(("satTmResetLUN: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17339                tiDeviceHandle));
17340    return tiError;
17341  }
17342
17343  /*
17344   * Save tiIORequest, will be returned at device reset completion to return
17345   * the TM completion.
17346   */
17347   satDevData->satTmTaskTag = tiIORequest;
17348
17349  /*
17350   * Set flag to indicate device in recovery mode.
17351   */
17352  satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17353
17354  /*
17355   * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17356   * at the completion of SATA device reset.
17357   */
17358  satDevData->satAbortAfterReset = agFALSE;
17359
17360  /* SAT rev8 6.3.6 p22 */
17361  satStartResetDevice(
17362                      tiRoot,
17363                      tiIORequest, /* currentTaskTag */
17364                      tiDeviceHandle,
17365                      tiScsiRequest,
17366                      satIOContext
17367                      );
17368
17369
17370  return tiSuccess;
17371
17372}
17373
17374/*****************************************************************************
17375 *! \brief  satTmWarmReset
17376 *
17377 *   This routine is called to initiate a TM warm RESET request to SATL.
17378 *   This routine is independent of HW/LL API.
17379 *
17380 *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17381 *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17382 *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17383 *
17384 *  \return:
17385 *
17386 *  \e tiSuccess:     I/O request successfully initiated.
17387 *  \e tiBusy:        No resources available, try again later.
17388 *  \e tiIONoDevice:  Invalid device handle.
17389 *  \e tiError:       Other errors that prevent the I/O request to be started.
17390 *
17391 *
17392 *****************************************************************************/
17393osGLOBAL bit32 satTmWarmReset(
17394                            tiRoot_t                  *tiRoot,
17395                            tiIORequest_t             *tiIORequest, /* current task tag */
17396                            tiDeviceHandle_t          *tiDeviceHandle,
17397                            tiScsiInitiatorRequest_t *tiScsiRequest,
17398                            satIOContext_t            *satIOContext)
17399{
17400
17401  tdsaDeviceData_t        *tdsaDeviceData;
17402  satDeviceData_t         *satDevData;
17403
17404  tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17405  satDevData      = &tdsaDeviceData->satDevData;
17406
17407  TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17408
17409  /*
17410   * Check if there is other TM request pending
17411   */
17412  if (satDevData->satTmTaskTag != agNULL)
17413  {
17414    TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17415                tiDeviceHandle));
17416    return tiError;
17417  }
17418
17419  /*
17420   * Save tiIORequest, will be returned at device reset completion to return
17421   * the TM completion.
17422   */
17423   satDevData->satTmTaskTag = tiIORequest;
17424
17425  /*
17426   * Set flag to indicate device in recovery mode.
17427   */
17428  satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17429
17430  /*
17431   * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17432   * at the completion of SATA device reset.
17433   */
17434  satDevData->satAbortAfterReset = agFALSE;
17435
17436  /* SAT rev8 6.3.6 p22 */
17437  satStartResetDevice(
17438                      tiRoot,
17439                      tiIORequest, /* currentTaskTag */
17440                      tiDeviceHandle,
17441                      tiScsiRequest,
17442                      satIOContext
17443                      );
17444
17445  return tiSuccess;
17446
17447}
17448
17449osGLOBAL bit32 satTDInternalTmReset(
17450                            tiRoot_t                  *tiRoot,
17451                            tiIORequest_t             *tiIORequest, /* current task tag */
17452                            tiDeviceHandle_t          *tiDeviceHandle,
17453                            tiScsiInitiatorRequest_t *tiScsiRequest,
17454                            satIOContext_t            *satIOContext)
17455{
17456
17457  tdsaDeviceData_t        *tdsaDeviceData;
17458  satDeviceData_t         *satDevData;
17459
17460  tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17461  satDevData      = &tdsaDeviceData->satDevData;
17462
17463  TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17464
17465  /*
17466   * Check if there is other TM request pending
17467   */
17468  if (satDevData->satTmTaskTag != agNULL)
17469  {
17470    TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17471                tiDeviceHandle));
17472    return tiError;
17473  }
17474
17475  /*
17476   * Save tiIORequest, will be returned at device reset completion to return
17477   * the TM completion.
17478   */
17479   satDevData->satTmTaskTag = tiIORequest;
17480
17481  /*
17482   * Set flag to indicate device in recovery mode.
17483   */
17484  satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17485
17486  /*
17487   * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17488   * at the completion of SATA device reset.
17489   */
17490  satDevData->satAbortAfterReset = agFALSE;
17491
17492  /* SAT rev8 6.3.6 p22 */
17493  satStartResetDevice(
17494                      tiRoot,
17495                      tiIORequest, /* currentTaskTag */
17496                      tiDeviceHandle,
17497                      tiScsiRequest,
17498                      satIOContext
17499                      );
17500
17501  return tiSuccess;
17502
17503}
17504
17505/*****************************************************************************
17506 *! \brief  satTmAbortTask
17507 *
17508 *   This routine is called to initiate a TM ABORT TASK request to SATL.
17509 *   This routine is independent of HW/LL API.
17510 *
17511 *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17512 *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17513 *  \param  taskTag:          Pointer to the associated task where the TM
17514 *                            command is to be applied.
17515 *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
17516 *
17517 *  \return:
17518 *
17519 *  \e tiSuccess:     I/O request successfully initiated.
17520 *  \e tiBusy:        No resources available, try again later.
17521 *  \e tiIONoDevice:  Invalid device handle.
17522 *  \e tiError:       Other errors that prevent the I/O request to be started.
17523 *
17524 *
17525 *****************************************************************************/
17526osGLOBAL bit32 satTmAbortTask(
17527                            tiRoot_t                  *tiRoot,
17528                            tiIORequest_t             *tiIORequest,  /* current task tag */
17529                            tiDeviceHandle_t          *tiDeviceHandle,
17530                            tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */
17531                            satIOContext_t            *satIOContext,
17532                            tiIORequest_t             *taskTag)
17533{
17534
17535  tdsaDeviceData_t        *tdsaDeviceData;
17536  satDeviceData_t         *satDevData;
17537  satIOContext_t          *satTempIOContext = agNULL;
17538  tdIORequestBody_t       *tdIORequestBody;
17539  tdIORequestBody_t       *TMtdIORequestBody;
17540  tdList_t                *elementHdr;
17541  bit32                   found = agFALSE;
17542  tiIORequest_t           *tiIOReq;
17543
17544  tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17545  satDevData      = &tdsaDeviceData->satDevData;
17546  TMtdIORequestBody = (tdIORequestBody_t *)tiIORequest->tdData;
17547
17548  TI_DBG1(("satTmAbortTask: tiDeviceHandle=%p taskTag=%p.\n", tiDeviceHandle, taskTag ));
17549  /*
17550   * Check if there is other TM request pending
17551   */
17552  if (satDevData->satTmTaskTag != agNULL)
17553  {
17554    TI_DBG1(("satTmAbortTask: REJECT other TM pending, tiDeviceHandle=%p\n",
17555                tiDeviceHandle));
17556    /* clean up TD layer's IORequestBody */
17557    ostiFreeMemory(
17558                   tiRoot,
17559                   TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17560                   sizeof(tdIORequestBody_t)
17561                   );
17562    return tiError;
17563  }
17564
17565#ifdef REMOVED
17566  /*
17567   * Check if there is only one I/O pending.
17568   */
17569  if (satDevData->satPendingIO > 0)
17570  {
17571    TI_DBG1(("satTmAbortTask: REJECT num pending I/O, tiDeviceHandle=%p, satPendingIO=0x%x\n",
17572                tiDeviceHandle, satDevData->satPendingIO));
17573    /* clean up TD layer's IORequestBody */
17574    ostiFreeMemory(
17575                   tiRoot,
17576                   TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17577                   sizeof(tdIORequestBody_t)
17578                   );
17579
17580    return tiError;
17581  }
17582#endif
17583
17584  /*
17585   * Check that the only pending I/O matches taskTag. If not return tiError.
17586   */
17587  elementHdr = satDevData->satIoLinkList.flink;
17588
17589  while (elementHdr != &satDevData->satIoLinkList)
17590  {
17591    satTempIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17592                                           satIoContextLink,
17593                                           elementHdr );
17594
17595    tdIORequestBody = (tdIORequestBody_t *) satTempIOContext->tiRequestBody;
17596    tiIOReq = tdIORequestBody->tiIORequest;
17597
17598    elementHdr = elementHdr->flink;   /* for the next while loop  */
17599
17600    /*
17601     * Check if the tag matches
17602     */
17603    if ( tiIOReq == taskTag)
17604    {
17605      found = agTRUE;
17606      satIOContext->satToBeAbortedIOContext = satTempIOContext;
17607      TI_DBG1(("satTmAbortTask: found matching tag.\n"));
17608
17609      break;
17610
17611    } /* if matching tag */
17612
17613  } /* while loop */
17614
17615
17616  if (found == agFALSE )
17617  {
17618    TI_DBG1(("satTmAbortTask: *** REJECT *** no match, tiDeviceHandle=%p\n",
17619                tiDeviceHandle ));
17620
17621    /* clean up TD layer's IORequestBody */
17622    ostiFreeMemory(
17623                   tiRoot,
17624                   TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17625                   sizeof(tdIORequestBody_t)
17626                   );
17627
17628    return tiError;
17629  }
17630
17631  /*
17632   * Save tiIORequest, will be returned at device reset completion to return
17633   * the TM completion.
17634   */
17635   satDevData->satTmTaskTag = tiIORequest;
17636
17637  /*
17638   * Set flag to indicate device in recovery mode.
17639   */
17640  satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17641
17642
17643  /*
17644   * Issue SATA device reset or check power mode. Set flag to to automatically abort
17645   * at the completion of SATA device reset.
17646   * SAT r09 p25
17647   */
17648  satDevData->satAbortAfterReset = agTRUE;
17649
17650  if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
17651       (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
17652      )
17653  {
17654    TI_DBG1(("satTmAbortTask: calling satStartCheckPowerMode\n"));
17655    /* send check power mode */
17656    satStartCheckPowerMode(
17657                      tiRoot,
17658                      tiIORequest, /* currentTaskTag */
17659                      tiDeviceHandle,
17660                      tiScsiRequest,
17661                      satIOContext
17662                      );
17663  }
17664  else
17665  {
17666    TI_DBG1(("satTmAbortTask: calling satStartResetDevice\n"));
17667    /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */
17668    satStartResetDevice(
17669                      tiRoot,
17670                      tiIORequest, /* currentTaskTag */
17671                      tiDeviceHandle,
17672                      tiScsiRequest,
17673                      satIOContext
17674                      );
17675  }
17676
17677
17678  return tiSuccess;
17679}
17680
17681/*****************************************************************************
17682 *! \brief  osSatResetCB
17683 *
17684 *   This routine is called to notify the completion of SATA device reset
17685 *   which was initiated previously through the call to sataLLReset().
17686 *   This routine is independent of HW/LL API.
17687 *
17688 *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
17689 *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
17690 *  \param  resetStatus:      Reset status either tiSuccess or tiError.
17691 *  \param  respFis:          Pointer to the Register Device-To-Host FIS
17692 *                            received from the device.
17693 *
17694 *  \return: None
17695 *
17696 *****************************************************************************/
17697osGLOBAL void osSatResetCB(
17698                tiRoot_t          *tiRoot,
17699                tiDeviceHandle_t  *tiDeviceHandle,
17700                bit32             resetStatus,
17701                void              *respFis)
17702{
17703
17704  agsaRoot_t              *agRoot;
17705  tdsaDeviceData_t        *tdsaDeviceData;
17706  satDeviceData_t         *satDevData;
17707  satIOContext_t          *satIOContext;
17708  tdIORequestBody_t       *tdIORequestBodyTmp;
17709  tdList_t                *elementHdr;
17710  agsaIORequest_t         *agAbortIORequest;
17711  tdIORequestBody_t       *tdAbortIORequestBody;
17712  bit32                   PhysUpper32;
17713  bit32                   PhysLower32;
17714  bit32                   memAllocStatus;
17715  void                    *osMemHandle;
17716
17717  tdsaDeviceData  = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17718  agRoot          = tdsaDeviceData->agRoot;
17719  satDevData      = &tdsaDeviceData->satDevData;
17720
17721  TI_DBG5(("osSatResetCB: tiDeviceHandle=%p resetStatus=0x%x\n",
17722      tiDeviceHandle, resetStatus ));
17723
17724  /* We may need to check FIS to check device operating condition */
17725
17726
17727  /*
17728   * Check if need to abort all pending I/Os
17729   */
17730  if ( satDevData->satAbortAfterReset == agTRUE )
17731  {
17732    /*
17733     * Issue abort to LL layer to all other pending I/Os for the same SATA drive
17734     */
17735    elementHdr = satDevData->satIoLinkList.flink;
17736    while (elementHdr != &satDevData->satIoLinkList)
17737    {
17738      satIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17739                                         satIoContextLink,
17740                                         elementHdr );
17741
17742      tdIORequestBodyTmp = (tdIORequestBody_t *)satIOContext->tiRequestBody;
17743
17744      /*
17745       * Issue abort
17746       */
17747      TI_DBG5(("osSatResetCB: issuing ABORT tiDeviceHandle=%p agIORequest=%p\n",
17748      tiDeviceHandle, &tdIORequestBodyTmp->agIORequest ));
17749
17750      /* allocating agIORequest for abort itself */
17751      memAllocStatus = ostiAllocMemory(
17752                                       tiRoot,
17753                                       &osMemHandle,
17754                                       (void **)&tdAbortIORequestBody,
17755                                       &PhysUpper32,
17756                                       &PhysLower32,
17757                                       8,
17758                                       sizeof(tdIORequestBody_t),
17759                                       agTRUE
17760                                       );
17761
17762      if (memAllocStatus != tiSuccess)
17763      {
17764        /* let os process IO */
17765        TI_DBG1(("osSatResetCB: ostiAllocMemory failed...\n"));
17766        return;
17767      }
17768
17769      if (tdAbortIORequestBody == agNULL)
17770      {
17771        /* let os process IO */
17772        TI_DBG1(("osSatResetCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17773        return;
17774      }
17775      /* setup task management structure */
17776      tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17777      tdAbortIORequestBody->tiDevHandle = tiDeviceHandle;
17778
17779      /* initialize agIORequest */
17780      agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17781      agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17782      agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17783
17784      saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, &(tdIORequestBodyTmp->agIORequest), agNULL );
17785      elementHdr = elementHdr->flink;   /* for the next while loop  */
17786
17787    } /* while */
17788
17789    /* Reset flag */
17790    satDevData->satAbortAfterReset = agFALSE;
17791
17792  }
17793
17794
17795  /*
17796   * Check if the device reset if the result of TM request.
17797   */
17798  if ( satDevData->satTmTaskTag != agNULL )
17799  {
17800    TI_DBG5(("osSatResetCB: calling TM completion tiDeviceHandle=%p satTmTaskTag=%p\n",
17801    tiDeviceHandle, satDevData->satTmTaskTag ));
17802
17803    ostiInitiatorEvent( tiRoot,
17804                        agNULL,               /* portalContext not used */
17805                        tiDeviceHandle,
17806                        tiIntrEventTypeTaskManagement,
17807                        tiTMOK,
17808                        satDevData->satTmTaskTag);
17809    /*
17810     * Reset flag
17811     */
17812    satDevData->satTmTaskTag = agNULL;
17813  }
17814
17815}
17816
17817
17818/*****************************************************************************
17819 *! \brief  osSatIOCompleted
17820 *
17821 *   This routine is a callback for SATA completion that required FIS status
17822 *   translation to SCSI status.
17823 *
17824 *  \param   tiRoot:          Pointer to TISA initiator driver/port instance.
17825 *  \param   tiIORequest:     Pointer to TISA I/O request context for this I/O.
17826 *  \param   respFis:         Pointer to status FIS to read.
17827 *  \param   respFisLen:      Length of response FIS to read.
17828 *  \param   satIOContext:    Pointer to SAT context.
17829 *  \param   interruptContext:      Interrupt context
17830 *
17831 *  \return: None
17832 *
17833 *****************************************************************************/
17834osGLOBAL void osSatIOCompleted(
17835                          tiRoot_t           *tiRoot,
17836                          tiIORequest_t      *tiIORequest,
17837                          agsaFisHeader_t    *agFirstDword,
17838                          bit32              respFisLen,
17839                          agsaFrameHandle_t  agFrameHandle,
17840                          satIOContext_t     *satIOContext,
17841                          bit32              interruptContext)
17842
17843{
17844  satDeviceData_t           *pSatDevData;
17845  scsiRspSense_t            *pSense;
17846#ifdef  TD_DEBUG_ENABLE
17847  tiIniScsiCmnd_t           *pScsiCmnd;
17848#endif
17849  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
17850  bit32                     ataStatus = 0;
17851  bit32                     ataError;
17852  satInternalIo_t           *satIntIo = agNULL;
17853  bit32                     status;
17854  tiDeviceHandle_t          *tiDeviceHandle;
17855  satIOContext_t            *satIOContext2;
17856  tdIORequestBody_t         *tdIORequestBody;
17857  agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
17858  agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL;
17859  tiIORequest_t             tiIORequestTMP;
17860
17861  pSense          = satIOContext->pSense;
17862  pSatDevData     = satIOContext->pSatDevData;
17863#ifdef  TD_DEBUG_ENABLE
17864  pScsiCmnd       = satIOContext->pScsiCmnd;
17865#endif
17866  hostToDevFis    = satIOContext->pFis;
17867
17868  tiDeviceHandle  = &((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->tiDeviceHandle;
17869  /*
17870   * Find out the type of response FIS:
17871   * Set Device Bit FIS or Reg Device To Host FIS.
17872   */
17873
17874  /* First assume it is Reg Device to Host FIS */
17875  statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
17876  ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
17877  ataError      = statDevToHostFisHeader->error;    /* ATA Eror register   */
17878
17879  /* for debugging */
17880  TI_DBG1(("osSatIOCompleted: H to D command 0x%x\n", hostToDevFis->h.command));
17881  TI_DBG1(("osSatIOCompleted: D to H fistype 0x%x\n", statDevToHostFisHeader->fisType));
17882
17883
17884  if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS)
17885  {
17886    /* It is Set Device Bits FIS */
17887    statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H);
17888    /* Get ATA Status register */
17889    ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70);               /* bits 4,5,6 */
17890    ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07);   /* bits 0,1,2 */
17891
17892    /* ATA Eror register   */
17893    ataError  = statSetDevBitFisHeader->error;
17894
17895    statDevToHostFisHeader = agNULL;
17896  }
17897
17898  else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
17899  {
17900    TI_DBG1(("osSatIOCompleted: *** UNEXPECTED RESP FIS TYPE 0x%x *** tiIORequest=%p\n",
17901                 statDevToHostFisHeader->fisType, tiIORequest));
17902
17903    satSetSensePayload( pSense,
17904                        SCSI_SNSKEY_HARDWARE_ERROR,
17905                        0,
17906                        SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
17907                        satIOContext);
17908
17909    ostiInitiatorIOCompleted( tiRoot,
17910                              tiIORequest,
17911                              tiIOSuccess,
17912                              SCSI_STAT_CHECK_CONDITION,
17913                              satIOContext->pTiSenseData,
17914                              interruptContext );
17915    return;
17916
17917  }
17918
17919  if ( ataStatus & DF_ATA_STATUS_MASK )
17920  {
17921    pSatDevData->satDeviceFaultState = agTRUE;
17922  }
17923  else
17924  {
17925    pSatDevData->satDeviceFaultState = agFALSE;
17926  }
17927
17928  TI_DBG5(("osSatIOCompleted: tiIORequest=%p  CDB=0x%x ATA CMD =0x%x\n",
17929    tiIORequest, pScsiCmnd->cdb[0], hostToDevFis->h.command));
17930
17931  /*
17932   * Decide which ATA command is the translation needed
17933   */
17934  switch(hostToDevFis->h.command)
17935  {
17936    case SAT_READ_FPDMA_QUEUED:
17937    case SAT_WRITE_FPDMA_QUEUED:
17938
17939      /************************************************************************
17940       *
17941       * !!!! See Section 13.5.2.4 of SATA 2.5 specs.                      !!!!
17942       * !!!! If the NCQ error ends up here, it means that the device sent !!!!
17943       * !!!! Set Device Bit FIS (which has SActive register) instead of   !!!!
17944       * !!!! Register Device To Host FIS (which does not have SActive     !!!!
17945       * !!!! register). The callback ossaSATAEvent() deals with the case  !!!!
17946       * !!!! where Register Device To Host FIS was sent by the device.    !!!!
17947       *
17948       * For NCQ we need to issue READ LOG EXT command with log page 10h
17949       * to get the error and to allow other I/Os to continue.
17950       *
17951       * Here is the basic flow or sequence of error recovery, note that due
17952       * to the SATA HW assist that we have, this sequence is slighly different
17953       * from the one described in SATA 2.5:
17954       *
17955       * 1. Set SATA device flag to indicate error condition and returning busy
17956       *    for all new request.
17957       *   return tiSuccess;
17958
17959       * 2. Because the HW/LL layer received Set Device Bit FIS, it can get the
17960       *    tag or I/O context for NCQ request, SATL would translate the ATA error
17961       *    to SCSI status and return the original NCQ I/O with the appopriate
17962       *    SCSI status.
17963       *
17964       * 3. Prepare READ LOG EXT page 10h command. Set flag to indicate that
17965       *    the failed I/O has been returned to the OS Layer. Send command.
17966       *
17967       * 4. When the device receives READ LOG EXT page 10h request all other
17968       *    pending I/O are implicitly aborted. No completion (aborted) status
17969       *    will be sent to the host for these aborted commands.
17970       *
17971       * 5. SATL receives the completion for READ LOG EXT command in
17972       *    satReadLogExtCB(). Steps 6,7,8,9 below are the step 1,2,3,4 in
17973       *    satReadLogExtCB().
17974       *
17975       * 6. Check flag that indicates whether the failed I/O has been returned
17976       *    to the OS Layer. If not, search the I/O context in device data
17977       *    looking for a matched tag. Then return the completion of the failed
17978       *    NCQ command with the appopriate/trasnlated SCSI status.
17979       *
17980       * 7. Issue abort to LL layer to all other pending I/Os for the same SATA
17981       *    drive.
17982       *
17983       * 8. Free resource allocated for the internally generated READ LOG EXT.
17984       *
17985       * 9. At the completion of abort, in the context of ossaSATACompleted(),
17986       *    return the I/O with error status to the OS-App Specific layer.
17987       *    When all I/O aborts are completed, clear SATA device flag to
17988       *    indicate ready to process new request.
17989       *
17990       ***********************************************************************/
17991
17992      TI_DBG1(("osSatIOCompleted: NCQ ERROR tiIORequest=%p ataStatus=0x%x ataError=0x%x\n",
17993          tiIORequest, ataStatus, ataError ));
17994
17995      /* Set flag to indicate we are in recovery */
17996      pSatDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17997
17998      /* Return the failed NCQ I/O to OS-Apps Specifiic layer */
17999      osSatDefaultTranslation( tiRoot,
18000                               tiIORequest,
18001                               satIOContext,
18002                               pSense,
18003                               (bit8)ataStatus,
18004                               (bit8)ataError,
18005                               interruptContext );
18006
18007      /*
18008       * Allocate resource for READ LOG EXT page 10h
18009       */
18010      satIntIo = satAllocIntIoResource( tiRoot,
18011                                        &(tiIORequestTMP), /* anything but NULL */
18012                                        pSatDevData,
18013                                        sizeof (satReadLogExtPage10h_t),
18014                                        satIntIo);
18015
18016      if (satIntIo == agNULL)
18017      {
18018        TI_DBG1(("osSatIOCompleted: can't send RLE due to resource lack\n"));
18019
18020        /* Abort I/O after completion of device reset */
18021        pSatDevData->satAbortAfterReset = agTRUE;
18022#ifdef NOT_YET
18023        /* needs further investigation */
18024        /* no report to OS layer */
18025        satSubTM(tiRoot,
18026                 tiDeviceHandle,
18027                 TD_INTERNAL_TM_RESET,
18028                 agNULL,
18029                 agNULL,
18030                 agNULL,
18031                 agFALSE);
18032#endif
18033
18034
18035        TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 1\n"));
18036        return;
18037      }
18038
18039
18040      /*
18041       * Set flag to indicate that the failed I/O has been returned to the
18042       * OS-App specific Layer.
18043       */
18044      satIntIo->satIntFlag = AG_SAT_INT_IO_FLAG_ORG_IO_COMPLETED;
18045
18046      /* compare to satPrepareNewIO() */
18047      /* Send READ LOG EXIT page 10h command */
18048
18049      /*
18050       * Need to initialize all the fields within satIOContext except
18051       * reqType and satCompleteCB which will be set depending on cmd.
18052       */
18053
18054      tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
18055      satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
18056
18057      satIOContext2->pSatDevData   = pSatDevData;
18058      satIOContext2->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
18059      satIOContext2->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
18060      satIOContext2->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
18061      satIOContext2->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
18062      satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
18063
18064      satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
18065      satIOContext2->interruptContext = interruptContext;
18066      satIOContext2->satIntIoContext  = satIntIo;
18067
18068      satIOContext2->ptiDeviceHandle = tiDeviceHandle;
18069      satIOContext2->satOrgIOContext = agNULL;
18070      satIOContext2->tiScsiXchg = agNULL;
18071
18072      status = satSendReadLogExt( tiRoot,
18073                                  &satIntIo->satIntTiIORequest,
18074                                  tiDeviceHandle,
18075                                  &satIntIo->satIntTiScsiXchg,
18076                                  satIOContext2);
18077
18078      if (status != tiSuccess)
18079      {
18080        TI_DBG1(("osSatIOCompleted: can't send RLE due to LL api failure\n"));
18081        satFreeIntIoResource( tiRoot,
18082                              pSatDevData,
18083                              satIntIo);
18084
18085        /* Abort I/O after completion of device reset */
18086        pSatDevData->satAbortAfterReset = agTRUE;
18087#ifdef NOT_YET
18088        /* needs further investigation */
18089        /* no report to OS layer */
18090        satSubTM(tiRoot,
18091                 tiDeviceHandle,
18092                 TD_INTERNAL_TM_RESET,
18093                 agNULL,
18094                 agNULL,
18095                 agNULL,
18096                 agFALSE);
18097#endif
18098
18099        TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 2\n"));
18100        return;
18101      }
18102
18103      break;
18104
18105    case SAT_READ_DMA_EXT:
18106      /* fall through */
18107      /* Use default status/error translation */
18108
18109    case SAT_READ_DMA:
18110      /* fall through */
18111      /* Use default status/error translation */
18112
18113    default:
18114      osSatDefaultTranslation( tiRoot,
18115                               tiIORequest,
18116                               satIOContext,
18117                               pSense,
18118                               (bit8)ataStatus,
18119                               (bit8)ataError,
18120                               interruptContext );
18121      break;
18122
18123  }  /* end switch  */
18124}
18125
18126
18127/*****************************************************************************/
18128/*! \brief SAT implementation for SCSI STANDARD INQUIRY.
18129 *
18130 *  SAT implementation for SCSI STANDARD INQUIRY.
18131 *
18132 *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18133 *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18134 *
18135 *  \return None.
18136 */
18137/*****************************************************************************/
18138GLOBAL void  satInquiryStandard(
18139                                bit8                    *pInquiry,
18140                                agsaSATAIdentifyData_t  *pSATAIdData,
18141                                tiIniScsiCmnd_t          *scsiCmnd
18142                                )
18143{
18144  tiLUN_t       *pLun;
18145  pLun          = &scsiCmnd->lun;
18146
18147  /*
18148    Assumption: Basic Task Mangement is supported
18149    -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147
18150  */
18151 /*
18152    See SPC-4, 6.4.2, p 143
18153    and SAT revision 8, 8.1.2, p 28
18154   */
18155
18156  TI_DBG5(("satInquiryStandard: start\n"));
18157
18158  if (pInquiry == agNULL)
18159  {
18160    TI_DBG1(("satInquiryStandard: pInquiry is NULL, wrong\n"));
18161    return;
18162  }
18163  else
18164  {
18165    TI_DBG5(("satInquiryStandard: pInquiry is NOT NULL\n"));
18166  }
18167  /*
18168   * Reject all other LUN other than LUN 0.
18169   */
18170  if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
18171         pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) )
18172  {
18173    /* SAT Spec Table 8, p27, footnote 'a' */
18174    pInquiry[0] = 0x7F;
18175
18176  }
18177  else
18178  {
18179    pInquiry[0] = 0x00;
18180  }
18181
18182  if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
18183  {
18184    pInquiry[1] = 0x80;
18185  }
18186  else
18187  {
18188    pInquiry[1] = 0x00;
18189  }
18190  pInquiry[2] = 0x05;   /* SPC-3 */
18191  pInquiry[3] = 0x12;   /* set HiSup 1; resp data format set to 2 */
18192  pInquiry[4] = 0x1F;   /* 35 - 4 = 31; Additional length */
18193  pInquiry[5] = 0x00;
18194  /* The following two are for task management. SAT Rev8, p20 */
18195  if (pSATAIdData->sataCapabilities & 0x100)
18196  {
18197    /* NCQ supported; multiple outstanding SCSI IO are supported */
18198    pInquiry[6] = 0x00;   /* BQUE bit is not set */
18199    pInquiry[7] = 0x02;   /* CMDQUE bit is set */
18200  }
18201  else
18202  {
18203    pInquiry[6] = 0x80;   /* BQUE bit is set */
18204    pInquiry[7] = 0x00;   /* CMDQUE bit is not set */
18205  }
18206  /*
18207   * Vendor ID.
18208   */
18209  osti_strncpy((char*)&pInquiry[8],  AG_SAT_VENDOR_ID_STRING,8);   /* 8 bytes   */
18210
18211  /*
18212   * Product ID
18213   */
18214  /* when flipped by LL */
18215  pInquiry[16] = pSATAIdData->modelNumber[1];
18216  pInquiry[17] = pSATAIdData->modelNumber[0];
18217  pInquiry[18] = pSATAIdData->modelNumber[3];
18218  pInquiry[19] = pSATAIdData->modelNumber[2];
18219  pInquiry[20] = pSATAIdData->modelNumber[5];
18220  pInquiry[21] = pSATAIdData->modelNumber[4];
18221  pInquiry[22] = pSATAIdData->modelNumber[7];
18222  pInquiry[23] = pSATAIdData->modelNumber[6];
18223  pInquiry[24] = pSATAIdData->modelNumber[9];
18224  pInquiry[25] = pSATAIdData->modelNumber[8];
18225  pInquiry[26] = pSATAIdData->modelNumber[11];
18226  pInquiry[27] = pSATAIdData->modelNumber[10];
18227  pInquiry[28] = pSATAIdData->modelNumber[13];
18228  pInquiry[29] = pSATAIdData->modelNumber[12];
18229  pInquiry[30] = pSATAIdData->modelNumber[15];
18230  pInquiry[31] = pSATAIdData->modelNumber[14];
18231
18232  /* when flipped */
18233  /*
18234   * Product Revision level.
18235   */
18236
18237  /*
18238   * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18239   * device are ASCII spaces (20h), do this translation.
18240   */
18241  if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18242       (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18243       (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18244       (pSATAIdData->firmwareVersion[7] == 0x00 )
18245       )
18246  {
18247    pInquiry[32] = pSATAIdData->firmwareVersion[1];
18248    pInquiry[33] = pSATAIdData->firmwareVersion[0];
18249    pInquiry[34] = pSATAIdData->firmwareVersion[3];
18250    pInquiry[35] = pSATAIdData->firmwareVersion[2];
18251  }
18252  else
18253  {
18254    pInquiry[32] = pSATAIdData->firmwareVersion[5];
18255    pInquiry[33] = pSATAIdData->firmwareVersion[4];
18256    pInquiry[34] = pSATAIdData->firmwareVersion[7];
18257    pInquiry[35] = pSATAIdData->firmwareVersion[6];
18258  }
18259
18260
18261#ifdef REMOVED
18262  /*
18263   * Product ID
18264   */
18265  /* when flipped by LL */
18266  pInquiry[16] = pSATAIdData->modelNumber[0];
18267  pInquiry[17] = pSATAIdData->modelNumber[1];
18268  pInquiry[18] = pSATAIdData->modelNumber[2];
18269  pInquiry[19] = pSATAIdData->modelNumber[3];
18270  pInquiry[20] = pSATAIdData->modelNumber[4];
18271  pInquiry[21] = pSATAIdData->modelNumber[5];
18272  pInquiry[22] = pSATAIdData->modelNumber[6];
18273  pInquiry[23] = pSATAIdData->modelNumber[7];
18274  pInquiry[24] = pSATAIdData->modelNumber[8];
18275  pInquiry[25] = pSATAIdData->modelNumber[9];
18276  pInquiry[26] = pSATAIdData->modelNumber[10];
18277  pInquiry[27] = pSATAIdData->modelNumber[11];
18278  pInquiry[28] = pSATAIdData->modelNumber[12];
18279  pInquiry[29] = pSATAIdData->modelNumber[13];
18280  pInquiry[30] = pSATAIdData->modelNumber[14];
18281  pInquiry[31] = pSATAIdData->modelNumber[15];
18282
18283  /* when flipped */
18284  /*
18285   * Product Revision level.
18286   */
18287
18288  /*
18289   * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18290   * device are ASCII spaces (20h), do this translation.
18291   */
18292  if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18293       (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18294       (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18295       (pSATAIdData->firmwareVersion[7] == 0x00 )
18296       )
18297  {
18298    pInquiry[32] = pSATAIdData->firmwareVersion[0];
18299    pInquiry[33] = pSATAIdData->firmwareVersion[1];
18300    pInquiry[34] = pSATAIdData->firmwareVersion[2];
18301    pInquiry[35] = pSATAIdData->firmwareVersion[3];
18302  }
18303  else
18304  {
18305    pInquiry[32] = pSATAIdData->firmwareVersion[4];
18306    pInquiry[33] = pSATAIdData->firmwareVersion[5];
18307    pInquiry[34] = pSATAIdData->firmwareVersion[6];
18308    pInquiry[35] = pSATAIdData->firmwareVersion[7];
18309  }
18310#endif
18311
18312  TI_DBG5(("satInquiryStandard: end\n"));
18313
18314}
18315
18316
18317/*****************************************************************************/
18318/*! \brief SAT implementation for SCSI INQUIRY page 0.
18319 *
18320 *  SAT implementation for SCSI INQUIRY page 0.
18321 *
18322 *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18323 *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18324 *
18325 *  \return None.
18326 */
18327/*****************************************************************************/
18328GLOBAL void  satInquiryPage0(
18329                    bit8                    *pInquiry,
18330                    agsaSATAIdentifyData_t  *pSATAIdData)
18331{
18332
18333  TI_DBG5(("satInquiryPage0: entry\n"));
18334
18335  /*
18336    See SPC-4, 7.6.9, p 345
18337    and SAT revision 8, 10.3.2, p 77
18338   */
18339  pInquiry[0] = 0x00;
18340  pInquiry[1] = 0x00; /* page code */
18341  pInquiry[2] = 0x00; /* reserved */
18342  pInquiry[3] = 7 - 3; /* last index(in this case, 6) - 3; page length */
18343
18344  /* supported vpd page list */
18345  pInquiry[4] = 0x00; /* page 0x00 supported */
18346  pInquiry[5] = 0x80; /* page 0x80 supported */
18347  pInquiry[6] = 0x83; /* page 0x83 supported */
18348  pInquiry[7] = 0x89; /* page 0x89 supported */
18349
18350}
18351
18352
18353/*****************************************************************************/
18354/*! \brief SAT implementation for SCSI INQUIRY page 83.
18355 *
18356 *  SAT implementation for SCSI INQUIRY page 83.
18357 *
18358 *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18359 *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18360 *
18361 *  \return None.
18362 */
18363/*****************************************************************************/
18364GLOBAL void  satInquiryPage83(
18365                    bit8                    *pInquiry,
18366                    agsaSATAIdentifyData_t  *pSATAIdData,
18367                    satDeviceData_t         *pSatDevData)
18368{
18369
18370  satSimpleSATAIdentifyData_t   *pSimpleData;
18371
18372  /*
18373   * When translating the fields, in some cases using the simple form of SATA
18374   * Identify Device Data is easier. So we define it here.
18375   * Both pSimpleData and pSATAIdData points to the same data.
18376   */
18377  pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18378
18379  TI_DBG5(("satInquiryPage83: entry\n"));
18380
18381  pInquiry[0] = 0x00;
18382  pInquiry[1] = 0x83; /* page code */
18383  pInquiry[2] = 0;    /* Reserved */
18384
18385  /*
18386   * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE
18387   * data indicating that it supports the WORLD WIDE NAME field
18388   * (i.e., words 108-111), the SATL shall include an identification descriptor
18389   * containing a logical unit name.
18390   */
18391  if ( pSatDevData->satWWNSupport)
18392  {
18393    /* Fill in SAT Rev8 Table85 */
18394    /*
18395     * Logical unit name derived from the world wide name.
18396     */
18397    pInquiry[3] = 12;         /* 15-3; page length, no addition ID descriptor assumed*/
18398
18399    /*
18400     * Identifier descriptor
18401     */
18402    pInquiry[4]  = 0x01;                        /* Code set: binary codes */
18403    pInquiry[5]  = 0x03;                        /* Identifier type : NAA  */
18404    pInquiry[6]  = 0x00;                        /* Reserved               */
18405    pInquiry[7]  = 0x08;                        /* Identifier length      */
18406
18407    /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
18408    pInquiry[8]  = (bit8)((pSATAIdData->namingAuthority) >> 8);
18409    pInquiry[9]  = (bit8)((pSATAIdData->namingAuthority) & 0xFF);           /* IEEE Company ID */
18410    pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8);            /* IEEE Company ID */
18411    /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
18412    pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
18413    pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8);       /* Vendor Specific ID  */
18414    pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF);     /* Vendor Specific ID  */
18415    pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8);        /* Vendor Specific ID  */
18416    pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF);      /* Vendor Specific ID  */
18417
18418  }
18419  else
18420  {
18421    /* Fill in SAT Rev8 Table86 */
18422    /*
18423     * Logical unit name derived from the model number and serial number.
18424     */
18425    pInquiry[3] = 72;    /* 75 - 3; page length */
18426
18427    /*
18428     * Identifier descriptor
18429     */
18430    pInquiry[4] = 0x02;             /* Code set: ASCII codes */
18431    pInquiry[5] = 0x01;             /* Identifier type : T10 vendor ID based */
18432    pInquiry[6] = 0x00;             /* Reserved */
18433    pInquiry[7] = 0x44;               /* 0x44, 68 Identifier length */
18434
18435    /* Byte 8 to 15 is the vendor id string 'ATA     '. */
18436    osti_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
18437
18438
18439        /*
18440     * Byte 16 to 75 is vendor specific id
18441     */
18442    pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
18443    pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
18444    pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
18445    pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
18446    pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
18447    pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
18448    pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
18449    pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
18450    pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
18451    pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
18452    pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
18453    pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
18454    pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
18455    pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
18456    pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
18457    pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
18458    pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
18459    pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
18460    pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
18461    pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
18462    pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
18463    pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
18464    pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
18465    pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
18466    pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
18467    pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
18468    pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
18469    pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
18470    pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
18471    pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
18472    pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
18473    pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
18474    pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
18475    pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
18476    pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
18477    pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
18478    pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
18479    pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
18480    pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
18481    pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
18482
18483    pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
18484    pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
18485    pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
18486    pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
18487    pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
18488    pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
18489    pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
18490    pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
18491    pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
18492    pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
18493    pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
18494    pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
18495    pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
18496    pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
18497    pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
18498    pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
18499    pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
18500    pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
18501    pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
18502    pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
18503  }
18504
18505}
18506
18507/*****************************************************************************/
18508/*! \brief SAT implementation for SCSI INQUIRY page 89.
18509 *
18510 *  SAT implementation for SCSI INQUIRY page 89.
18511 *
18512 *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18513 *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18514 *  \param   pSatDevData       Pointer to internal device data structure
18515 *
18516 *  \return None.
18517 */
18518/*****************************************************************************/
18519GLOBAL void  satInquiryPage89(
18520                    bit8                    *pInquiry,
18521                    agsaSATAIdentifyData_t  *pSATAIdData,
18522                    satDeviceData_t         *pSatDevData)
18523{
18524  /*
18525    SAT revision 8, 10.3.5, p 83
18526   */
18527  satSimpleSATAIdentifyData_t   *pSimpleData;
18528
18529  /*
18530   * When translating the fields, in some cases using the simple form of SATA
18531   * Identify Device Data is easier. So we define it here.
18532   * Both pSimpleData and pSATAIdData points to the same data.
18533   */
18534  pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18535
18536  TI_DBG5(("satInquiryPage89: start\n"));
18537
18538  pInquiry[0] = 0x00;   /* Peripheral Qualifier and Peripheral Device Type */
18539  pInquiry[1] = 0x89;   /* page code */
18540
18541  /* Page length 0x238 */
18542  pInquiry[2] = 0x02;
18543  pInquiry[3] = 0x38;
18544
18545  pInquiry[4] = 0x0;    /* reserved */
18546  pInquiry[5] = 0x0;    /* reserved */
18547  pInquiry[6] = 0x0;    /* reserved */
18548  pInquiry[7] = 0x0;    /* reserved */
18549
18550  /* SAT Vendor Identification */
18551  osti_strncpy((char*)&pInquiry[8],  "PMC-SIERRA", 8);   /* 8 bytes   */
18552
18553  /* SAT Product Idetification */
18554  osti_strncpy((char*)&pInquiry[16],  "Tachyon-SPC    ", 16);   /* 16 bytes   */
18555
18556  /* SAT Product Revision Level */
18557  osti_strncpy((char*)&pInquiry[32],  "01", 4);   /* 4 bytes   */
18558
18559  /* Signature, SAT revision8, Table88, p85 */
18560
18561
18562  pInquiry[36] = 0x34;    /* FIS type */
18563  if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18564  {
18565    /* interrupt assume to be 0 */
18566    pInquiry[37] = (bit8)((pSatDevData->satPMField) >> (4 * 7)); /* first four bits of PM field */
18567  }
18568  else
18569  {
18570    /* interrupt assume to be 1 */
18571    pInquiry[37] = (bit8)(0x40 + (bit8)(((pSatDevData->satPMField) >> (4 * 7)))); /* first four bits of PM field */
18572  }
18573  pInquiry[38] = 0;
18574  pInquiry[39] = 0;
18575
18576  if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18577  {
18578    pInquiry[40] = 0x01; /* LBA Low          */
18579    pInquiry[41] = 0x00; /* LBA Mid          */
18580    pInquiry[42] = 0x00; /* LBA High         */
18581    pInquiry[43] = 0x00; /* Device           */
18582    pInquiry[44] = 0x00; /* LBA Low Exp      */
18583    pInquiry[45] = 0x00; /* LBA Mid Exp      */
18584    pInquiry[46] = 0x00; /* LBA High Exp     */
18585    pInquiry[47] = 0x00; /* Reserved         */
18586    pInquiry[48] = 0x01; /* Sector Count     */
18587    pInquiry[49] = 0x00; /* Sector Count Exp */
18588  }
18589  else
18590  {
18591    pInquiry[40] = 0x01; /* LBA Low          */
18592    pInquiry[41] = 0x00; /* LBA Mid          */
18593    pInquiry[42] = 0x00; /* LBA High         */
18594    pInquiry[43] = 0x00; /* Device           */
18595    pInquiry[44] = 0x00; /* LBA Low Exp      */
18596    pInquiry[45] = 0x00; /* LBA Mid Exp      */
18597    pInquiry[46] = 0x00; /* LBA High Exp     */
18598    pInquiry[47] = 0x00; /* Reserved         */
18599    pInquiry[48] = 0x01; /* Sector Count     */
18600    pInquiry[49] = 0x00; /* Sector Count Exp */
18601  }
18602
18603  /* Reserved */
18604  pInquiry[50] = 0x00;
18605  pInquiry[51] = 0x00;
18606  pInquiry[52] = 0x00;
18607  pInquiry[53] = 0x00;
18608  pInquiry[54] = 0x00;
18609  pInquiry[55] = 0x00;
18610
18611  /* Command Code */
18612  if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18613  {
18614    pInquiry[56] = 0xEC;    /* IDENTIFY DEVICE */
18615  }
18616  else
18617  {
18618    pInquiry[56] = 0xA1;    /* IDENTIFY PACKET DEVICE */
18619  }
18620  /* Reserved */
18621  pInquiry[57] = 0x0;
18622  pInquiry[58] = 0x0;
18623  pInquiry[59] = 0x0;
18624
18625  /* Identify Device */
18626  osti_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
18627  return;
18628}
18629
18630/*****************************************************************************/
18631/*! \brief SAT implementation for SCSI INQUIRY page 0.
18632 *
18633 *  SAT implementation for SCSI INQUIRY page 0.
18634 *
18635 *  \param   pInquiry:         Pointer to Inquiry Data buffer.
18636 *  \param   pSATAIdData:      Pointer to ATA IDENTIFY DEVICE data.
18637 *
18638 *  \return None.
18639 */
18640/*****************************************************************************/
18641GLOBAL void  satInquiryPage80(
18642                    bit8                    *pInquiry,
18643                    agsaSATAIdentifyData_t  *pSATAIdData)
18644{
18645
18646  TI_DBG5(("satInquiryPage80: entry\n"));
18647
18648  /*
18649    See SPC-4, 7.6.9, p 345
18650    and SAT revision 8, 10.3.3, p 77
18651   */
18652  pInquiry[0] = 0x00;
18653  pInquiry[1] = 0x80; /* page code */
18654  pInquiry[2] = 0x00; /* reserved */
18655  pInquiry[3] = 0x14; /* page length */
18656
18657  /* supported vpd page list */
18658  pInquiry[4] = pSATAIdData->serialNumber[1];
18659  pInquiry[5] = pSATAIdData->serialNumber[0];
18660  pInquiry[6] = pSATAIdData->serialNumber[3];
18661  pInquiry[7] = pSATAIdData->serialNumber[2];
18662  pInquiry[8] = pSATAIdData->serialNumber[5];
18663  pInquiry[9] = pSATAIdData->serialNumber[4];
18664  pInquiry[10] = pSATAIdData->serialNumber[7];
18665  pInquiry[11] = pSATAIdData->serialNumber[6];
18666  pInquiry[12] = pSATAIdData->serialNumber[9];
18667  pInquiry[13] = pSATAIdData->serialNumber[8];
18668  pInquiry[14] = pSATAIdData->serialNumber[11];
18669  pInquiry[15] = pSATAIdData->serialNumber[10];
18670  pInquiry[16] = pSATAIdData->serialNumber[13];
18671  pInquiry[17] = pSATAIdData->serialNumber[12];
18672  pInquiry[18] = pSATAIdData->serialNumber[15];
18673  pInquiry[19] = pSATAIdData->serialNumber[14];
18674  pInquiry[20] = pSATAIdData->serialNumber[17];
18675  pInquiry[21] = pSATAIdData->serialNumber[16];
18676  pInquiry[22] = pSATAIdData->serialNumber[19];
18677  pInquiry[23] = pSATAIdData->serialNumber[18];
18678
18679
18680}
18681
18682
18683
18684/*****************************************************************************/
18685/*! \brief  Send READ LOG EXT ATA PAGE 10h command to sata drive.
18686 *
18687 *  Send READ LOG EXT ATA command PAGE 10h request to LL layer.
18688 *
18689 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
18690 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
18691 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
18692 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
18693 *  \param   satIOContext_t:   Pointer to the SAT IO Context
18694 *
18695 *  \return If command is started successfully
18696 *    - \e tiSuccess:     I/O request successfully initiated.
18697 *    - \e tiBusy:        No resources available, try again later.
18698 *    - \e tiIONoDevice:  Invalid device handle.
18699 *    - \e tiError:       Other errors.
18700 */
18701/*****************************************************************************/
18702GLOBAL bit32  satSendReadLogExt(
18703                   tiRoot_t                  *tiRoot,
18704                   tiIORequest_t             *tiIORequest,
18705                   tiDeviceHandle_t          *tiDeviceHandle,
18706                   tiScsiInitiatorRequest_t *tiScsiRequest,
18707                   satIOContext_t            *satIOContext)
18708
18709{
18710
18711  bit32                     status;
18712  bit32                     agRequestType;
18713  agsaFisRegHostToDevice_t  *fis;
18714
18715  fis           = satIOContext->pFis;
18716
18717  TI_DBG1(("satSendReadLogExt: tiDeviceHandle=%p tiIORequest=%p\n",
18718      tiDeviceHandle, tiIORequest));
18719
18720  fis->h.fisType        = 0x27;                   /* Reg host to device */
18721  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
18722  fis->h.command        = SAT_READ_LOG_EXT;       /* 0x2F */
18723  fis->h.features       = 0;                      /* FIS reserve */
18724  fis->d.lbaLow         = 0x10;                   /* Page number */
18725  fis->d.lbaMid         = 0;                      /*  */
18726  fis->d.lbaHigh        = 0;                      /*  */
18727  fis->d.device         = 0;                      /* DEV is ignored in SATA */
18728  fis->d.lbaLowExp      = 0;                      /*  */
18729  fis->d.lbaMidExp      = 0;                      /*  */
18730  fis->d.lbaHighExp     = 0;                      /*  */
18731  fis->d.featuresExp    = 0;                      /* FIS reserve */
18732  fis->d.sectorCount    = 0x01;                   /*  1 sector counts*/
18733  fis->d.sectorCountExp = 0x00;                   /*  1 sector counts */
18734  fis->d.reserved4      = 0;
18735  fis->d.control        = 0;                      /* FIS HOB bit clear */
18736  fis->d.reserved5      = 0;
18737
18738  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
18739
18740  /* Initialize CB for SATA completion.
18741   */
18742  satIOContext->satCompleteCB = &satReadLogExtCB;
18743
18744  /*
18745   * Prepare SGL and send FIS to LL layer.
18746   */
18747  satIOContext->reqType = agRequestType;       /* Save it */
18748
18749  status = sataLLIOStart( tiRoot,
18750                          tiIORequest,
18751                          tiDeviceHandle,
18752                          tiScsiRequest,
18753                          satIOContext);
18754
18755  TI_DBG1(("satSendReadLogExt: end status %d\n", status));
18756
18757  return (status);
18758
18759}
18760
18761
18762/*****************************************************************************/
18763/*! \brief  SAT default ATA status and ATA error translation to SCSI.
18764 *
18765 *  SSAT default ATA status and ATA error translation to SCSI.
18766 *
18767 *  \param   tiRoot:        Pointer to TISA initiator driver/port instance.
18768 *  \param   tiIORequest:   Pointer to TISA I/O request context for this I/O.
18769 *  \param   satIOContext:  Pointer to the SAT IO Context
18770 *  \param   pSense:        Pointer to scsiRspSense_t
18771 *  \param   ataStatus:     ATA status register
18772 *  \param   ataError:      ATA error register
18773 *  \param   interruptContext:    Interrupt context
18774 *
18775 *  \return  None
18776 */
18777/*****************************************************************************/
18778GLOBAL void  osSatDefaultTranslation(
18779                   tiRoot_t             *tiRoot,
18780                   tiIORequest_t        *tiIORequest,
18781                   satIOContext_t       *satIOContext,
18782                   scsiRspSense_t       *pSense,
18783                   bit8                 ataStatus,
18784                   bit8                 ataError,
18785                   bit32                interruptContext )
18786{
18787
18788  /*
18789   * Check for device fault case
18790   */
18791  if ( ataStatus & DF_ATA_STATUS_MASK )
18792  {
18793    satSetSensePayload( pSense,
18794                        SCSI_SNSKEY_HARDWARE_ERROR,
18795                        0,
18796                        SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18797                        satIOContext);
18798
18799    ostiInitiatorIOCompleted( tiRoot,
18800                              tiIORequest,
18801                              tiIOSuccess,
18802                              SCSI_STAT_CHECK_CONDITION,
18803                              satIOContext->pTiSenseData,
18804                              interruptContext );
18805    return;
18806  }
18807
18808  /*
18809   * If status error bit it set, need to check the error register
18810   */
18811  if ( ataStatus & ERR_ATA_STATUS_MASK )
18812  {
18813    if ( ataError & NM_ATA_ERROR_MASK )
18814    {
18815      TI_DBG1(("osSatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18816                 ataError, tiIORequest));
18817      satSetSensePayload( pSense,
18818                          SCSI_SNSKEY_NOT_READY,
18819                          0,
18820                          SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
18821                          satIOContext);
18822    }
18823
18824    else if (ataError & UNC_ATA_ERROR_MASK)
18825    {
18826      TI_DBG1(("osSatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18827                 ataError, tiIORequest));
18828      satSetSensePayload( pSense,
18829                          SCSI_SNSKEY_MEDIUM_ERROR,
18830                          0,
18831                          SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
18832                          satIOContext);
18833    }
18834
18835    else if (ataError & IDNF_ATA_ERROR_MASK)
18836    {
18837      TI_DBG1(("osSatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18838                 ataError, tiIORequest));
18839      satSetSensePayload( pSense,
18840                          SCSI_SNSKEY_MEDIUM_ERROR,
18841                          0,
18842                          SCSI_SNSCODE_RECORD_NOT_FOUND,
18843                          satIOContext);
18844    }
18845
18846    else if (ataError & MC_ATA_ERROR_MASK)
18847    {
18848      TI_DBG1(("osSatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18849                 ataError, tiIORequest));
18850      satSetSensePayload( pSense,
18851                          SCSI_SNSKEY_UNIT_ATTENTION,
18852                          0,
18853                          SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
18854                          satIOContext);
18855    }
18856
18857    else if (ataError & MCR_ATA_ERROR_MASK)
18858    {
18859      TI_DBG1(("osSatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18860                 ataError, tiIORequest));
18861      satSetSensePayload( pSense,
18862                          SCSI_SNSKEY_UNIT_ATTENTION,
18863                          0,
18864                          SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
18865                          satIOContext);
18866    }
18867
18868    else if (ataError & ICRC_ATA_ERROR_MASK)
18869    {
18870      TI_DBG1(("osSatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18871                 ataError, tiIORequest));
18872      satSetSensePayload( pSense,
18873                          SCSI_SNSKEY_ABORTED_COMMAND,
18874                          0,
18875                          SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
18876                          satIOContext);
18877    }
18878
18879    else if (ataError & ABRT_ATA_ERROR_MASK)
18880    {
18881      TI_DBG1(("osSatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18882                 ataError, tiIORequest));
18883      satSetSensePayload( pSense,
18884                          SCSI_SNSKEY_ABORTED_COMMAND,
18885                          0,
18886                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
18887                          satIOContext);
18888    }
18889
18890    else
18891    {
18892      TI_DBG1(("osSatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, tiIORequest=%p\n",
18893                 ataError, tiIORequest));
18894      satSetSensePayload( pSense,
18895                          SCSI_SNSKEY_HARDWARE_ERROR,
18896                          0,
18897                          SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18898                          satIOContext);
18899    }
18900
18901    /* Send the completion response now */
18902    ostiInitiatorIOCompleted( tiRoot,
18903                              tiIORequest,
18904                              tiIOSuccess,
18905                              SCSI_STAT_CHECK_CONDITION,
18906                              satIOContext->pTiSenseData,
18907                              interruptContext );
18908    return;
18909
18910
18911  }
18912
18913  else /*  (ataStatus & ERR_ATA_STATUS_MASK ) is false */
18914  {
18915    /* This case should never happen */
18916    TI_DBG1(("osSatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** tiIORequest=%p\n",
18917                 ataStatus, tiIORequest));
18918    satSetSensePayload( pSense,
18919                        SCSI_SNSKEY_HARDWARE_ERROR,
18920                        0,
18921                        SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18922                        satIOContext);
18923
18924    ostiInitiatorIOCompleted( tiRoot,
18925                              tiIORequest,
18926                              tiIOSuccess,
18927                              SCSI_STAT_CHECK_CONDITION,
18928                              satIOContext->pTiSenseData,
18929                              interruptContext );
18930    return;
18931
18932  }
18933
18934
18935}
18936
18937/*****************************************************************************/
18938/*! \brief  Allocate resource for SAT intervally generated I/O.
18939 *
18940 *  Allocate resource for SAT intervally generated I/O.
18941 *
18942 *  \param   tiRoot:      Pointer to TISA driver/port instance.
18943 *  \param   satDevData:  Pointer to SAT specific device data.
18944 *  \param   allocLength: Length in byte of the DMA mem to allocate, upto
18945 *                        one page size.
18946 *  \param   satIntIo:    Pointer (output) to context for SAT internally
18947 *                        generated I/O that is allocated by this routine.
18948 *
18949 *  \return If command is started successfully
18950 *    - \e tiSuccess:     Success.
18951 *    - \e tiError:       Failed allocating resource.
18952 */
18953/*****************************************************************************/
18954GLOBAL satInternalIo_t * satAllocIntIoResource(
18955                    tiRoot_t              *tiRoot,
18956                    tiIORequest_t         *tiIORequest,
18957                    satDeviceData_t       *satDevData,
18958                    bit32                 dmaAllocLength,
18959                    satInternalIo_t       *satIntIo)
18960{
18961  tdList_t          *tdList = agNULL;
18962  bit32             memAllocStatus;
18963
18964  TI_DBG1(("satAllocIntIoResource: start\n"));
18965  TI_DBG6(("satAllocIntIoResource: satIntIo %p\n", satIntIo));
18966  if (satDevData == agNULL)
18967  {
18968    TI_DBG1(("satAllocIntIoResource: ***** ASSERT satDevData is null\n"));
18969    return agNULL;
18970  }
18971
18972  tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
18973  if (!TDLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
18974  {
18975    TDLIST_DEQUEUE_FROM_HEAD(&tdList, &(satDevData->satFreeIntIoLinkList));
18976  }
18977  else
18978  {
18979    tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18980    TI_DBG1(("satAllocIntIoResource() no more internal free link.\n"));
18981    return agNULL;
18982  }
18983
18984  if (tdList == agNULL)
18985  {
18986    tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18987    TI_DBG1(("satAllocIntIoResource() FAIL to alloc satIntIo.\n"));
18988    return agNULL;
18989  }
18990
18991  satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
18992  TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
18993
18994  /* Put in active list */
18995  TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
18996  TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
18997  tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18998
18999#ifdef REMOVED
19000  /* Put in active list */
19001  tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19002  TDLIST_DEQUEUE_THIS (tdList);
19003  TDLIST_ENQUEUE_AT_TAIL (tdList, &(satDevData->satActiveIntIoLinkList));
19004  tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19005
19006  satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
19007  TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19008#endif
19009
19010  /*
19011    typedef struct
19012    {
19013      tdList_t                    satIntIoLink;
19014      tiIORequest_t               satIntTiIORequest;
19015      void                        *satIntRequestBody;
19016      tiScsiInitiatorRequest_t   satIntTiScsiXchg;
19017      tiMem_t                     satIntDmaMem;
19018      tiMem_t                     satIntReqBodyMem;
19019      bit32                       satIntFlag;
19020    } satInternalIo_t;
19021  */
19022
19023  /*
19024   * Allocate mem for Request Body
19025   */
19026  satIntIo->satIntReqBodyMem.totalLength = sizeof(tdIORequestBody_t);
19027
19028  memAllocStatus = ostiAllocMemory( tiRoot,
19029                                    &satIntIo->satIntReqBodyMem.osHandle,
19030                                    (void **)&satIntIo->satIntRequestBody,
19031                                    &satIntIo->satIntReqBodyMem.physAddrUpper,
19032                                    &satIntIo->satIntReqBodyMem.physAddrLower,
19033                                    8,
19034                                    satIntIo->satIntReqBodyMem.totalLength,
19035                                    agTRUE );
19036
19037  if (memAllocStatus != tiSuccess)
19038  {
19039    TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for Req Body.\n"));
19040    /*
19041     * Return satIntIo to the free list
19042     */
19043    tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19044    TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19045    TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19046    tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19047
19048    return agNULL;
19049  }
19050
19051  /*
19052   *   Allocate DMA memory if required
19053   */
19054  if (dmaAllocLength != 0)
19055  {
19056    satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
19057
19058    memAllocStatus = ostiAllocMemory( tiRoot,
19059                                      &satIntIo->satIntDmaMem.osHandle,
19060                                      (void **)&satIntIo->satIntDmaMem.virtPtr,
19061                                      &satIntIo->satIntDmaMem.physAddrUpper,
19062                                      &satIntIo->satIntDmaMem.physAddrLower,
19063                                      8,
19064                                      satIntIo->satIntDmaMem.totalLength,
19065                                      agFALSE);
19066    TI_DBG6(("satAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
19067    TI_DBG6(("satAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
19068
19069    if (memAllocStatus != tiSuccess)
19070    {
19071      TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for DMA mem.\n"));
19072      /*
19073       * Return satIntIo to the free list
19074       */
19075      tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19076      TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19077      TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19078      tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19079
19080      /*
19081       * Free mem allocated for Req body
19082       */
19083      ostiFreeMemory( tiRoot,
19084                      satIntIo->satIntReqBodyMem.osHandle,
19085                      satIntIo->satIntReqBodyMem.totalLength);
19086
19087      return agNULL;
19088    }
19089  }
19090
19091  /*
19092    typedef struct
19093    {
19094      tdList_t                    satIntIoLink;
19095      tiIORequest_t               satIntTiIORequest;
19096      void                        *satIntRequestBody;
19097      tiScsiInitiatorRequest_t   satIntTiScsiXchg;
19098      tiMem_t                     satIntDmaMem;
19099      tiMem_t                     satIntReqBodyMem;
19100      bit32                       satIntFlag;
19101    } satInternalIo_t;
19102  */
19103
19104  /*
19105   * Initialize satIntTiIORequest field
19106   */
19107  satIntIo->satIntTiIORequest.osData = agNULL;  /* Not used for internal SAT I/O */
19108  satIntIo->satIntTiIORequest.tdData = satIntIo->satIntRequestBody;
19109
19110  /*
19111   * saves the original tiIOrequest
19112   */
19113  satIntIo->satOrgTiIORequest = tiIORequest;
19114  /*
19115    typedef struct tiIniScsiCmnd
19116    {
19117      tiLUN_t     lun;
19118      bit32       expDataLength;
19119      bit32       taskAttribute;
19120      bit32       crn;
19121      bit8        cdb[16];
19122    } tiIniScsiCmnd_t;
19123
19124    typedef struct tiScsiInitiatorExchange
19125    {
19126      void                *sglVirtualAddr;
19127      tiIniScsiCmnd_t     scsiCmnd;
19128      tiSgl_t             agSgl1;
19129      tiSgl_t             agSgl2;
19130      tiDataDirection_t   dataDirection;
19131    } tiScsiInitiatorRequest_t;
19132
19133  */
19134
19135  /*
19136   * Initialize satIntTiScsiXchg. Since the internal SAT request is NOT
19137   * originated from SCSI request, only the following fields are initialized:
19138   *  - sglVirtualAddr if DMA transfer is involved
19139   *  - agSgl1 if DMA transfer is involved
19140   *  - expDataLength in scsiCmnd since this field is read by sataLLIOStart()
19141   */
19142  if (dmaAllocLength != 0)
19143  {
19144    satIntIo->satIntTiScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
19145
19146    OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntTiScsiXchg.agSgl1.len, 0,
19147                     satIntIo->satIntDmaMem.totalLength);
19148    satIntIo->satIntTiScsiXchg.agSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
19149    satIntIo->satIntTiScsiXchg.agSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
19150    satIntIo->satIntTiScsiXchg.agSgl1.type  = tiSgl;
19151
19152    satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
19153  }
19154  else
19155  {
19156    satIntIo->satIntTiScsiXchg.sglVirtualAddr = agNULL;
19157
19158    satIntIo->satIntTiScsiXchg.agSgl1.len   = 0;
19159    satIntIo->satIntTiScsiXchg.agSgl1.lower = 0;
19160    satIntIo->satIntTiScsiXchg.agSgl1.upper = 0;
19161    satIntIo->satIntTiScsiXchg.agSgl1.type  = tiSgl;
19162
19163    satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19164  }
19165
19166  TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
19167
19168  TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
19169
19170  TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
19171
19172  TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
19173    TI_DBG5(("satAllocIntIoResource: return satIntIo %p\n", satIntIo));
19174  return  satIntIo;
19175
19176}
19177
19178/*****************************************************************************/
19179/*! \brief  Free resource for SAT intervally generated I/O.
19180 *
19181 *  Free resource for SAT intervally generated I/O that was previously
19182 *  allocated in satAllocIntIoResource().
19183 *
19184 *  \param   tiRoot:      Pointer to TISA driver/port instance.
19185 *  \param   satDevData:  Pointer to SAT specific device data.
19186 *  \param   satIntIo:    Pointer to context for SAT internal I/O that was
19187 *                        previously allocated in satAllocIntIoResource().
19188 *
19189 *  \return  None
19190 */
19191/*****************************************************************************/
19192GLOBAL void  satFreeIntIoResource(
19193                    tiRoot_t              *tiRoot,
19194                    satDeviceData_t       *satDevData,
19195                    satInternalIo_t       *satIntIo)
19196{
19197  TI_DBG6(("satFreeIntIoResource: start\n"));
19198
19199  if (satIntIo == agNULL)
19200  {
19201    TI_DBG6(("satFreeIntIoResource: allowed call\n"));
19202    return;
19203  }
19204
19205  /* sets the original tiIOrequest to agNULL for internally generated ATA cmnd */
19206  satIntIo->satOrgTiIORequest = agNULL;
19207
19208  /*
19209   * Free DMA memory if previosly alocated
19210   */
19211  if (satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength != 0)
19212  {
19213    TI_DBG1(("satFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
19214    TI_DBG6(("satFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
19215
19216    ostiFreeMemory( tiRoot,
19217                    satIntIo->satIntDmaMem.osHandle,
19218                    satIntIo->satIntDmaMem.totalLength);
19219    satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19220  }
19221
19222  if (satIntIo->satIntReqBodyMem.totalLength != 0)
19223  {
19224    TI_DBG1(("satFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
19225    /*
19226     * Free mem allocated for Req body
19227     */
19228    ostiFreeMemory( tiRoot,
19229                    satIntIo->satIntReqBodyMem.osHandle,
19230                    satIntIo->satIntReqBodyMem.totalLength);
19231
19232    satIntIo->satIntReqBodyMem.totalLength = 0;
19233  }
19234
19235  TI_DBG6(("satFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19236  /*
19237   * Return satIntIo to the free list
19238   */
19239  tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19240  TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
19241  TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
19242  tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19243
19244}
19245
19246
19247/*****************************************************************************/
19248/*! \brief SAT implementation for SCSI INQUIRY.
19249 *
19250 *  SAT implementation for SCSI INQUIRY.
19251 *  This function sends ATA Identify Device data command for SCSI INQUIRY
19252 *
19253 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
19254 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
19255 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
19256 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
19257 *  \param   satIOContext_t:   Pointer to the SAT IO Context
19258 *
19259 *  \return If command is started successfully
19260 *    - \e tiSuccess:     I/O request successfully initiated.
19261 *    - \e tiBusy:        No resources available, try again later.
19262 *    - \e tiIONoDevice:  Invalid device handle.
19263 *    - \e tiError:       Other errors.
19264 */
19265/*****************************************************************************/
19266GLOBAL bit32  satSendIDDev(
19267                           tiRoot_t                  *tiRoot,
19268                           tiIORequest_t             *tiIORequest,
19269                           tiDeviceHandle_t          *tiDeviceHandle,
19270                           tiScsiInitiatorRequest_t *tiScsiRequest,
19271                           satIOContext_t            *satIOContext)
19272
19273{
19274  bit32                     status;
19275  bit32                     agRequestType;
19276  satDeviceData_t           *pSatDevData;
19277  agsaFisRegHostToDevice_t  *fis;
19278#ifdef  TD_DEBUG_ENABLE
19279  satInternalIo_t           *satIntIoContext;
19280  tdsaDeviceData_t          *oneDeviceData;
19281  tdIORequestBody_t         *tdIORequestBody;
19282#endif
19283
19284  pSatDevData   = satIOContext->pSatDevData;
19285  fis           = satIOContext->pFis;
19286
19287  TI_DBG5(("satSendIDDev: start\n"));
19288#ifdef  TD_DEBUG_ENABLE
19289  oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
19290#endif
19291  TI_DBG5(("satSendIDDev: did %d\n", oneDeviceData->id));
19292
19293
19294#ifdef  TD_DEBUG_ENABLE
19295  satIntIoContext = satIOContext->satIntIoContext;
19296  tdIORequestBody = satIntIoContext->satIntRequestBody;
19297#endif
19298
19299  TI_DBG5(("satSendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
19300
19301  fis->h.fisType        = 0x27;                   /* Reg host to device */
19302  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
19303  if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
19304      fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
19305  else
19306      fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
19307  fis->h.features       = 0;                      /* FIS reserve */
19308  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
19309  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
19310  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
19311  fis->d.device         = 0;                      /* FIS LBA mode  */
19312  fis->d.lbaLowExp      = 0;
19313  fis->d.lbaMidExp      = 0;
19314  fis->d.lbaHighExp     = 0;
19315  fis->d.featuresExp    = 0;
19316  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
19317  fis->d.sectorCountExp = 0;
19318  fis->d.reserved4      = 0;
19319  fis->d.control        = 0;                      /* FIS HOB bit clear */
19320  fis->d.reserved5      = 0;
19321
19322  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19323
19324  /* Initialize CB for SATA completion.
19325   */
19326  satIOContext->satCompleteCB = &satInquiryCB;
19327
19328  /*
19329   * Prepare SGL and send FIS to LL layer.
19330   */
19331  satIOContext->reqType = agRequestType;       /* Save it */
19332
19333#ifdef TD_INTERNAL_DEBUG
19334  tdhexdump("satSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19335#ifdef  TD_DEBUG_ENABLE
19336  tdhexdump("satSendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19337#endif
19338#endif
19339
19340  status = sataLLIOStart( tiRoot,
19341                          tiIORequest,
19342                          tiDeviceHandle,
19343                          tiScsiRequest,
19344                          satIOContext);
19345
19346  TI_DBG6(("satSendIDDev: end status %d\n", status));
19347  return status;
19348}
19349
19350
19351/*****************************************************************************/
19352/*! \brief SAT implementation for SCSI INQUIRY.
19353 *
19354 *  SAT implementation for SCSI INQUIRY.
19355 *  This function prepares TD layer internal resource to send ATA
19356 *  Identify Device data command for SCSI INQUIRY
19357 *
19358 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
19359 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
19360 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
19361 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
19362 *  \param   satIOContext_t:   Pointer to the SAT IO Context
19363 *
19364 *  \return If command is started successfully
19365 *    - \e tiSuccess:     I/O request successfully initiated.
19366 *    - \e tiBusy:        No resources available, try again later.
19367 *    - \e tiIONoDevice:  Invalid device handle.
19368 *    - \e tiError:       Other errors.
19369 */
19370/*****************************************************************************/
19371/* prerequsite: tdsaDeviceData and agdevhandle must exist; in other words, LL discovered the device
19372   already */
19373/*
19374  convert OS generated IO to TD generated IO due to difference in sgl
19375*/
19376GLOBAL bit32  satStartIDDev(
19377                               tiRoot_t                  *tiRoot,
19378                               tiIORequest_t             *tiIORequest,
19379                               tiDeviceHandle_t          *tiDeviceHandle,
19380                               tiScsiInitiatorRequest_t *tiScsiRequest,
19381                               satIOContext_t            *satIOContext
19382                            )
19383{
19384  satInternalIo_t           *satIntIo = agNULL;
19385  satDeviceData_t           *satDevData = agNULL;
19386  tdIORequestBody_t         *tdIORequestBody;
19387  satIOContext_t            *satNewIOContext;
19388  bit32                     status;
19389
19390  TI_DBG6(("satStartIDDev: start\n"));
19391
19392  satDevData = satIOContext->pSatDevData;
19393
19394  TI_DBG6(("satStartIDDev: before alloc\n"));
19395
19396  /* allocate identify device command */
19397  satIntIo = satAllocIntIoResource( tiRoot,
19398                                    tiIORequest,
19399                                    satDevData,
19400                                    sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
19401                                    satIntIo);
19402
19403  TI_DBG6(("satStartIDDev: before after\n"));
19404
19405  if (satIntIo == agNULL)
19406  {
19407    TI_DBG1(("satStartIDDev: can't alloacate\n"));
19408
19409#if 0
19410    ostiInitiatorIOCompleted (
19411                              tiRoot,
19412                              tiIORequest,
19413                              tiIOFailed,
19414                              tiDetailOtherError,
19415                              agNULL,
19416                              satIOContext->interruptContext
19417                              );
19418#endif
19419
19420    return tiError;
19421  }
19422
19423  /* fill in fields */
19424  /* real ttttttthe one worked and the same; 5/21/07/ */
19425  satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
19426  tdIORequestBody = satIntIo->satIntRequestBody;
19427  satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
19428
19429  satNewIOContext->pSatDevData   = satDevData;
19430  satNewIOContext->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
19431  satNewIOContext->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
19432  satNewIOContext->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
19433  satNewIOContext->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
19434  satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
19435  satNewIOContext->interruptContext = tiInterruptContext;
19436  satNewIOContext->satIntIoContext  = satIntIo;
19437
19438  satNewIOContext->ptiDeviceHandle = agNULL;
19439  satNewIOContext->satOrgIOContext = satIOContext; /* changed */
19440
19441  /* this is valid only for TD layer generated (not triggered by OS at all) IO */
19442  satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
19443
19444
19445  TI_DBG6(("satStartIDDev: OS satIOContext %p \n", satIOContext));
19446  TI_DBG6(("satStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
19447  TI_DBG6(("satStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
19448  TI_DBG6(("satStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
19449
19450
19451
19452  TI_DBG1(("satStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
19453
19454  status = satSendIDDev( tiRoot,
19455                         &satIntIo->satIntTiIORequest, /* New tiIORequest */
19456                         tiDeviceHandle,
19457                         satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
19458                         satNewIOContext);
19459
19460  if (status != tiSuccess)
19461  {
19462    TI_DBG1(("satStartIDDev: failed in sending\n"));
19463
19464    satFreeIntIoResource( tiRoot,
19465                          satDevData,
19466                          satIntIo);
19467
19468#if 0
19469    ostiInitiatorIOCompleted (
19470                              tiRoot,
19471                              tiIORequest,
19472                              tiIOFailed,
19473                              tiDetailOtherError,
19474                              agNULL,
19475                              satIOContext->interruptContext
19476                              );
19477#endif
19478
19479    return tiError;
19480  }
19481
19482
19483  TI_DBG6(("satStartIDDev: end\n"));
19484
19485  return status;
19486
19487
19488}
19489
19490/*****************************************************************************/
19491/*! \brief satComputeCDB10LBA.
19492 *
19493 *  This fuctions computes LBA of CDB10.
19494 *
19495 *  \param   satIOContext_t:   Pointer to the SAT IO Context
19496 *
19497 *  \return
19498 *    - \e LBA
19499 */
19500/*****************************************************************************/
19501bit32 satComputeCDB10LBA(satIOContext_t            *satIOContext)
19502{
19503  tiIniScsiCmnd_t           *scsiCmnd;
19504  tiScsiInitiatorRequest_t *tiScsiRequest;
19505  bit32                     lba = 0;
19506
19507  TI_DBG5(("satComputeCDB10LBA: start\n"));
19508  tiScsiRequest = satIOContext->tiScsiXchg;
19509  scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19510
19511  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19512    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19513
19514  return lba;
19515}
19516
19517/*****************************************************************************/
19518/*! \brief satComputeCDB10TL.
19519 *
19520 *  This fuctions computes transfer length of CDB10.
19521 *
19522 *  \param   satIOContext_t:   Pointer to the SAT IO Context
19523 *
19524 *  \return
19525 *    - \e TL
19526 */
19527/*****************************************************************************/
19528bit32 satComputeCDB10TL(satIOContext_t            *satIOContext)
19529{
19530
19531  tiIniScsiCmnd_t           *scsiCmnd;
19532  tiScsiInitiatorRequest_t *tiScsiRequest;
19533  bit32                     tl = 0;
19534
19535  TI_DBG5(("satComputeCDB10TL: start\n"));
19536  tiScsiRequest = satIOContext->tiScsiXchg;
19537  scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19538
19539  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
19540  return tl;
19541}
19542
19543/*****************************************************************************/
19544/*! \brief satComputeCDB12LBA.
19545 *
19546 *  This fuctions computes LBA of CDB12.
19547 *
19548 *  \param   satIOContext_t:   Pointer to the SAT IO Context
19549 *
19550 *  \return
19551 *    - \e LBA
19552 */
19553/*****************************************************************************/
19554bit32 satComputeCDB12LBA(satIOContext_t            *satIOContext)
19555{
19556  tiIniScsiCmnd_t           *scsiCmnd;
19557  tiScsiInitiatorRequest_t *tiScsiRequest;
19558  bit32                     lba = 0;
19559
19560  TI_DBG5(("satComputeCDB10LBA: start\n"));
19561  tiScsiRequest = satIOContext->tiScsiXchg;
19562  scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19563
19564  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19565    + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19566
19567  return lba;
19568}
19569
19570/*****************************************************************************/
19571/*! \brief satComputeCDB12TL.
19572 *
19573 *  This fuctions computes transfer length of CDB12.
19574 *
19575 *  \param   satIOContext_t:   Pointer to the SAT IO Context
19576 *
19577 *  \return
19578 *    - \e TL
19579 */
19580/*****************************************************************************/
19581bit32 satComputeCDB12TL(satIOContext_t            *satIOContext)
19582{
19583
19584  tiIniScsiCmnd_t           *scsiCmnd;
19585  tiScsiInitiatorRequest_t *tiScsiRequest;
19586  bit32                     tl = 0;
19587
19588  TI_DBG5(("satComputeCDB10TL: start\n"));
19589  tiScsiRequest = satIOContext->tiScsiXchg;
19590  scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19591
19592  tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19593    + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19594  return tl;
19595}
19596
19597
19598/*****************************************************************************/
19599/*! \brief satComputeCDB16LBA.
19600 *
19601 *  This fuctions computes LBA of CDB16.
19602 *
19603 *  \param   satIOContext_t:   Pointer to the SAT IO Context
19604 *
19605 *  \return
19606 *    - \e LBA
19607 */
19608/*****************************************************************************/
19609/*
19610  CBD16 has bit64 LBA
19611  But it has to be less than (2^28 - 1)
19612  Therefore, use last four bytes to compute LBA is OK
19613*/
19614bit32 satComputeCDB16LBA(satIOContext_t            *satIOContext)
19615{
19616  tiIniScsiCmnd_t           *scsiCmnd;
19617  tiScsiInitiatorRequest_t *tiScsiRequest;
19618  bit32                     lba = 0;
19619
19620  TI_DBG5(("satComputeCDB10LBA: start\n"));
19621  tiScsiRequest = satIOContext->tiScsiXchg;
19622  scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19623
19624  lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19625    + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19626
19627  return lba;
19628}
19629
19630/*****************************************************************************/
19631/*! \brief satComputeCDB16TL.
19632 *
19633 *  This fuctions computes transfer length of CDB16.
19634 *
19635 *  \param   satIOContext_t:   Pointer to the SAT IO Context
19636 *
19637 *  \return
19638 *    - \e TL
19639 */
19640/*****************************************************************************/
19641bit32 satComputeCDB16TL(satIOContext_t            *satIOContext)
19642{
19643
19644  tiIniScsiCmnd_t           *scsiCmnd;
19645  tiScsiInitiatorRequest_t *tiScsiRequest;
19646  bit32                     tl = 0;
19647
19648  TI_DBG5(("satComputeCDB10TL: start\n"));
19649  tiScsiRequest = satIOContext->tiScsiXchg;
19650  scsiCmnd      = &(tiScsiRequest->scsiCmnd);
19651
19652  tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
19653    + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
19654  return tl;
19655}
19656
19657/*****************************************************************************/
19658/*! \brief satComputeLoopNum.
19659 *
19660 *  This fuctions computes the number of interation needed for a transfer
19661 *  length with a specific number.
19662 *
19663 *  \param   a:   a numerator
19664 *  \param   b:   a denominator
19665 *
19666 *  \return
19667 *    - \e number of interation
19668 */
19669/*****************************************************************************/
19670/*
19671  (tl, denom)
19672  tl can be upto bit32 because CDB16 has bit32 tl
19673  Therefore, fine
19674  either (tl, 0xFF) or (tl, 0xFFFF)
19675*/
19676bit32 satComputeLoopNum(bit32 a, bit32 b)
19677{
19678
19679  bit32 quo = 0, rem = 0;
19680  bit32 LoopNum = 0;
19681
19682  TI_DBG5(("satComputeLoopNum: start\n"));
19683
19684  quo = a/b;
19685
19686  if (quo == 0)
19687  {
19688    LoopNum = 1;
19689  }
19690  else
19691  {
19692    rem = a % b;
19693    if (rem == 0)
19694    {
19695      LoopNum = quo;
19696    }
19697    else
19698    {
19699      LoopNum = quo + 1;
19700    }
19701  }
19702
19703  return LoopNum;
19704}
19705
19706/*****************************************************************************/
19707/*! \brief satAddNComparebit64.
19708 *
19709 *
19710 *
19711 *
19712 *  \param   a:   lba
19713 *  \param   b:   tl
19714 *
19715 *  \return
19716 *    - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19717 *    - \e FALSE otherwise
19718 *  \note: a and b must be in the same length
19719 */
19720/*****************************************************************************/
19721/*
19722  input: bit8 a[8], bit8 b[8] (lba, tl) must be in same length
19723  if (lba + tl > SAT_TR_LBA_LIMIT)
19724  then returns true
19725  else returns false
19726  (LBA,TL)
19727*/
19728bit32 satAddNComparebit64(bit8 *a, bit8 *b)
19729{
19730  bit16 ans[8];       // 0 MSB, 8 LSB
19731  bit8  final_ans[9]; // 0 MSB, 9 LSB
19732  bit8  max[9];
19733  int i;
19734
19735  TI_DBG5(("satAddNComparebit64: start\n"));
19736
19737  osti_memset(ans, 0, sizeof(ans));
19738  osti_memset(final_ans, 0, sizeof(final_ans));
19739  osti_memset(max, 0, sizeof(max));
19740
19741  max[0] = 0x1; //max = 0x1 0000 0000 0000 0000
19742
19743  // adding from LSB to MSB
19744  for(i=7;i>=0;i--)
19745  {
19746    ans[i] = (bit16)(a[i] + b[i]);
19747    if (i != 7)
19748    {
19749      ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19750    }
19751  }
19752
19753  /*
19754    filling in the final answer
19755   */
19756  final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19757  final_ans[1] = (bit8)(ans[0] & 0xFF);
19758
19759  for(i=2;i<=8;i++)
19760  {
19761    final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19762  }
19763
19764  //compare final_ans to max
19765  for(i=0;i<=8;i++)
19766  {
19767    if (final_ans[i] > max[i])
19768    {
19769      TI_DBG5(("satAddNComparebit64: yes at %d\n", i));
19770      return agTRUE;
19771    }
19772    else if (final_ans[i] < max[i])
19773    {
19774      TI_DBG5(("satAddNComparebit64: no at %d\n", i));
19775      return agFALSE;
19776    }
19777    else
19778    {
19779      continue;
19780    }
19781  }
19782
19783
19784  return agFALSE;
19785}
19786
19787/*****************************************************************************/
19788/*! \brief satAddNComparebit32.
19789 *
19790 *
19791 *
19792 *
19793 *  \param   a:   lba
19794 *  \param   b:   tl
19795 *
19796 *  \return
19797 *    - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19798 *    - \e FALSE otherwise
19799 *  \note: a and b must be in the same length
19800 */
19801/*****************************************************************************/
19802/*
19803  input: bit8 a[4], bit8 b[4] (lba, tl) must be in same length
19804  if (lba + tl > SAT_TR_LBA_LIMIT)
19805  then returns true
19806  else returns false
19807  (LBA,TL)
19808*/
19809bit32 satAddNComparebit32(bit8 *a, bit8 *b)
19810{
19811  bit16 ans[4];       // 0 MSB, 4 LSB
19812  bit8  final_ans[5]; // 0 MSB, 5 LSB
19813  bit8   max[4];
19814  int i;
19815
19816  TI_DBG5(("satAddNComparebit32: start\n"));
19817
19818  osti_memset(ans, 0, sizeof(ans));
19819  osti_memset(final_ans, 0, sizeof(final_ans));
19820  osti_memset(max, 0, sizeof(max));
19821
19822  max[0] = 0x10; // max =0x1000 0000
19823
19824  // adding from LSB to MSB
19825  for(i=3;i>=0;i--)
19826  {
19827    ans[i] = (bit16)(a[i] + b[i]);
19828    if (i != 3)
19829    {
19830      ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19831    }
19832  }
19833
19834
19835  /*
19836    filling in the final answer
19837   */
19838  final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19839  final_ans[1] = (bit8)(ans[0] & 0xFF);
19840
19841  for(i=2;i<=4;i++)
19842  {
19843    final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19844  }
19845
19846  //compare final_ans to max
19847  if (final_ans[0] != 0)
19848  {
19849    TI_DBG5(("satAddNComparebit32: yes bigger and out of range\n"));
19850    return agTRUE;
19851  }
19852  for(i=1;i<=4;i++)
19853  {
19854    if (final_ans[i] > max[i-1])
19855    {
19856      TI_DBG5(("satAddNComparebit32: yes at %d\n", i));
19857      return agTRUE;
19858    }
19859    else if (final_ans[i] < max[i-1])
19860    {
19861      TI_DBG5(("satAddNComparebit32: no at %d\n", i));
19862      return agFALSE;
19863    }
19864    else
19865    {
19866      continue;
19867    }
19868  }
19869
19870
19871  return agFALSE;
19872}
19873
19874/*****************************************************************************/
19875/*! \brief satCompareLBALimitbit.
19876 *
19877 *
19878 *
19879 *
19880 *  \param   lba:   lba
19881 *
19882 *  \return
19883 *    - \e TRUE if (lba > SAT_TR_LBA_LIMIT - 1)
19884 *    - \e FALSE otherwise
19885 *  \note: a and b must be in the same length
19886 */
19887/*****************************************************************************/
19888
19889/*
19890  lba
19891*/
19892/*
19893  input: bit8 lba[8]
19894  if (lba > SAT_TR_LBA_LIMIT - 1)
19895  then returns true
19896  else returns false
19897  (LBA,TL)
19898*/
19899bit32 satCompareLBALimitbit(bit8 *lba)
19900{
19901  bit32 i;
19902  bit8 limit[8];
19903
19904  /* limit is 0xF FF FF = 2^28 - 1 */
19905  limit[0] = 0x0;   /* MSB */
19906  limit[1] = 0x0;
19907  limit[2] = 0x0;
19908  limit[3] = 0x0;
19909  limit[4] = 0xF;
19910  limit[5] = 0xFF;
19911  limit[6] = 0xFF;
19912  limit[7] = 0xFF; /* LSB */
19913
19914  //compare lba to limit
19915  for(i=0;i<8;i++)
19916  {
19917    if (lba[i] > limit[i])
19918    {
19919      TI_DBG5(("satCompareLBALimitbit64: yes at %d\n", i));
19920      return agTRUE;
19921    }
19922    else if (lba[i] < limit[i])
19923    {
19924      TI_DBG5(("satCompareLBALimitbit64: no at %d\n", i));
19925      return agFALSE;
19926    }
19927    else
19928    {
19929      continue;
19930    }
19931  }
19932
19933
19934  return agFALSE;
19935
19936}
19937/*****************************************************************************
19938*! \brief
19939*  Purpose: bitwise set
19940*
19941*  Parameters:
19942*   data        - input output buffer
19943*   index       - bit to set
19944*
19945*  Return:
19946*   none
19947*
19948*****************************************************************************/
19949GLOBAL void
19950satBitSet(bit8 *data, bit32 index)
19951{
19952  data[index/8] |= (1 << (index%8));
19953}
19954
19955/*****************************************************************************
19956*! \brief
19957*  Purpose: bitwise clear
19958*
19959*  Parameters:
19960*   data        - input output buffer
19961*   index       - bit to clear
19962*
19963*  Return:
19964*   none
19965*
19966*****************************************************************************/
19967GLOBAL void
19968satBitClear(bit8 *data, bit32 index)
19969{
19970  data[index/8] &= ~(1 << (index%8));
19971}
19972
19973/*****************************************************************************
19974*! \brief
19975*  Purpose: bitwise test
19976*
19977*  Parameters:
19978*   data        - input output buffer
19979*   index       - bit to test
19980*
19981*  Return:
19982*   0 - not set
19983*   1 - set
19984*
19985*****************************************************************************/
19986GLOBAL agBOOLEAN
19987satBitTest(bit8 *data, bit32 index)
19988{
19989  return ( (BOOLEAN)((data[index/8] & (1 << (index%8)) ) ? 1: 0));
19990}
19991
19992
19993/******************************************************************************/
19994/*! \brief allocate an available SATA tag
19995 *
19996 *  allocate an available SATA tag
19997 *
19998 *  \param tiRoot           Pointer to TISA initiator driver/port instance.
19999 *  \param pSatDevData
20000 *  \param pTag
20001 *
20002 *  \return -Success or fail-
20003 */
20004/*******************************************************************************/
20005GLOBAL bit32 satTagAlloc(
20006                           tiRoot_t          *tiRoot,
20007                           satDeviceData_t   *pSatDevData,
20008                           bit8              *pTag
20009                           )
20010{
20011  bit32             retCode = agFALSE;
20012  bit32             i;
20013
20014  tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20015  for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
20016  {
20017    if ( 0 == satBitTest((bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
20018    {
20019      satBitSet((bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20020      *pTag = (bit8) i;
20021      retCode = agTRUE;
20022      break;
20023    }
20024  }
20025  tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20026  return retCode;
20027}
20028
20029/******************************************************************************/
20030/*! \brief release an SATA tag
20031 *
20032 *  release an available SATA tag
20033 *
20034 *  \param tiRoot           Pointer to TISA initiator driver/port instance.
20035 *  \param pSatDevData
20036 *  \param Tag
20037 *
20038 *  \return -the tag-
20039 */
20040/*******************************************************************************/
20041GLOBAL bit32 satTagRelease(
20042                              tiRoot_t          *tiRoot,
20043                              satDeviceData_t   *pSatDevData,
20044                              bit8              tag
20045                              )
20046{
20047  bit32             retCode = agFALSE;
20048
20049  tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20050  if ( tag < pSatDevData->satNCQMaxIO )
20051  {
20052    satBitClear( (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
20053    retCode = agTRUE;
20054  }
20055  tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20056  return retCode;
20057}
20058
20059/*****************************************************************************
20060 *! \brief  satSubTM
20061 *
20062 *   This routine is called to initiate a TM request to SATL.
20063 *   This routine is independent of HW/LL API.
20064 *
20065 *  \param  tiRoot:           Pointer to TISA initiator driver/port instance.
20066 *  \param  tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20067 *  \param  task:             SAM-3 task management request.
20068 *  \param  lun:              Pointer to LUN.
20069 *  \param  taskTag:          Pointer to the associated task where the TM
20070 *                            command is to be applied.
20071 *  \param  currentTaskTag:   Pointer to tag/context for this TM request.
20072 *  \param  NotifyOS          flag determines whether notify OS layer or not
20073 *
20074 *  \return:
20075 *
20076 *  \e tiSuccess:     I/O request successfully initiated.
20077 *  \e tiBusy:        No resources available, try again later.
20078 *  \e tiIONoDevice:  Invalid device handle.
20079 *  \e tiError:       Other errors that prevent the I/O request to be started.
20080 *
20081 *  \note:
20082 *        This funcion is triggered bottom up. Not yet in use.
20083 *****************************************************************************/
20084/* called for bottom up */
20085osGLOBAL bit32 satSubTM(
20086                        tiRoot_t          *tiRoot,
20087                        tiDeviceHandle_t  *tiDeviceHandle,
20088                        bit32             task,
20089                        tiLUN_t           *lun,
20090                        tiIORequest_t     *taskTag,
20091                        tiIORequest_t     *currentTaskTag,
20092                        bit32              NotifyOS
20093                        )
20094{
20095  void                        *osMemHandle;
20096  tdIORequestBody_t           *TMtdIORequestBody;
20097  bit32                       PhysUpper32;
20098  bit32                       PhysLower32;
20099  bit32                       memAllocStatus;
20100  agsaIORequest_t             *agIORequest = agNULL;
20101
20102  TI_DBG6(("satSubTM: start\n"));
20103
20104  /* allocation tdIORequestBody and pass it to satTM() */
20105  memAllocStatus = ostiAllocMemory(
20106                                   tiRoot,
20107                                   &osMemHandle,
20108                                   (void **)&TMtdIORequestBody,
20109                                   &PhysUpper32,
20110                                   &PhysLower32,
20111                                   8,
20112                                   sizeof(tdIORequestBody_t),
20113                                   agTRUE
20114                                   );
20115
20116  if (memAllocStatus != tiSuccess)
20117  {
20118    TI_DBG1(("satSubTM: ostiAllocMemory failed... \n"));
20119    return tiError;
20120  }
20121
20122  if (TMtdIORequestBody == agNULL)
20123  {
20124    TI_DBG1(("satSubTM: ostiAllocMemory returned NULL TMIORequestBody\n"));
20125    return tiError;
20126   }
20127
20128  /* setup task management structure */
20129  TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
20130  TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
20131  TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
20132
20133  /* initialize tiDevhandle */
20134  TMtdIORequestBody->tiDevHandle = tiDeviceHandle;
20135
20136  /* initialize tiIORequest */
20137  TMtdIORequestBody->tiIORequest = agNULL;
20138
20139  /* initialize agIORequest */
20140  agIORequest = &(TMtdIORequestBody->agIORequest);
20141  agIORequest->osData = (void *) TMtdIORequestBody;
20142  agIORequest->sdkData = agNULL; /* SA takes care of this */
20143  satTM(tiRoot,
20144        tiDeviceHandle,
20145        task, /* TD_INTERNAL_TM_RESET */
20146        agNULL,
20147        agNULL,
20148        agNULL,
20149        TMtdIORequestBody,
20150        agFALSE);
20151
20152  return tiSuccess;
20153}
20154
20155
20156/*****************************************************************************/
20157/*! \brief SAT implementation for satStartResetDevice.
20158 *
20159 *  SAT implementation for sending SRT and send FIS request to LL layer.
20160 *
20161 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20162 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20163 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20164 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20165 *  \param   satIOContext_t:   Pointer to the SAT IO Context
20166 *
20167 *  \return If command is started successfully
20168 *    - \e tiSuccess:     I/O request successfully initiated.
20169 *    - \e tiBusy:        No resources available, try again later.
20170 *    - \e tiIONoDevice:  Invalid device handle.
20171 *    - \e tiError:       Other errors.
20172 *  \note : triggerred by OS layer or bottom up
20173 */
20174/*****************************************************************************/
20175/* OS triggerred or bottom up */
20176GLOBAL bit32
20177satStartResetDevice(
20178                            tiRoot_t                  *tiRoot,
20179                            tiIORequest_t             *tiIORequest, /* currentTaskTag */
20180                            tiDeviceHandle_t          *tiDeviceHandle,
20181                            tiScsiInitiatorRequest_t *tiScsiRequest, /* should be NULL */
20182                            satIOContext_t            *satIOContext
20183                            )
20184{
20185  satInternalIo_t           *satIntIo = agNULL;
20186  satDeviceData_t           *satDevData = agNULL;
20187  satIOContext_t            *satNewIOContext;
20188  bit32                     status;
20189  tiIORequest_t             *currentTaskTag = agNULL;
20190
20191  TI_DBG1(("satStartResetDevice: start\n"));
20192
20193  currentTaskTag = tiIORequest;
20194
20195  satDevData = satIOContext->pSatDevData;
20196
20197  TI_DBG6(("satStartResetDevice: before alloc\n"));
20198
20199  /* allocate any fis for seting SRT bit in device control */
20200  satIntIo = satAllocIntIoResource( tiRoot,
20201                                    tiIORequest,
20202                                    satDevData,
20203                                    0,
20204                                    satIntIo);
20205
20206  TI_DBG6(("satStartResetDevice: before after\n"));
20207
20208  if (satIntIo == agNULL)
20209  {
20210    TI_DBG1(("satStartResetDevice: can't alloacate\n"));
20211    if (satIOContext->NotifyOS)
20212    {
20213      ostiInitiatorEvent( tiRoot,
20214                          NULL,
20215                          NULL,
20216                          tiIntrEventTypeTaskManagement,
20217                          tiTMFailed,
20218                          currentTaskTag );
20219    }
20220    return tiError;
20221  }
20222
20223  satNewIOContext = satPrepareNewIO(satIntIo,
20224                                    tiIORequest,
20225                                    satDevData,
20226                                    agNULL,
20227                                    satIOContext);
20228
20229  TI_DBG6(("satStartResetDevice: OS satIOContext %p \n", satIOContext));
20230  TI_DBG6(("satStartResetDevice: TD satNewIOContext %p \n", satNewIOContext));
20231  TI_DBG6(("satStartResetDevice: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
20232  TI_DBG6(("satStartResetDevice: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
20233
20234
20235
20236  TI_DBG6(("satStartResetDevice: satNewIOContext %p \n", satNewIOContext));
20237
20238  if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
20239  {
20240    status = satDeviceReset(tiRoot,
20241                          &satIntIo->satIntTiIORequest, /* New tiIORequest */
20242                          tiDeviceHandle,
20243                          satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20244                          satNewIOContext);
20245  }
20246  else
20247  {
20248    status = satResetDevice(tiRoot,
20249                          &satIntIo->satIntTiIORequest, /* New tiIORequest */
20250                          tiDeviceHandle,
20251                          satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20252                          satNewIOContext);
20253  }
20254
20255  if (status != tiSuccess)
20256  {
20257    TI_DBG1(("satStartResetDevice: failed in sending\n"));
20258
20259    satFreeIntIoResource( tiRoot,
20260                          satDevData,
20261                          satIntIo);
20262    if (satIOContext->NotifyOS)
20263    {
20264      ostiInitiatorEvent( tiRoot,
20265                          NULL,
20266                          NULL,
20267                          tiIntrEventTypeTaskManagement,
20268                          tiTMFailed,
20269                          currentTaskTag );
20270    }
20271
20272    return tiError;
20273  }
20274
20275
20276  TI_DBG6(("satStartResetDevice: end\n"));
20277
20278  return status;
20279}
20280
20281/*****************************************************************************/
20282/*! \brief SAT implementation for satResetDevice.
20283 *
20284 *  SAT implementation for building SRT FIS and sends the request to LL layer.
20285 *
20286 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20287 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20288 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20289 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20290 *  \param   satIOContext_t:   Pointer to the SAT IO Context
20291 *
20292 *  \return If command is started successfully
20293 *    - \e tiSuccess:     I/O request successfully initiated.
20294 *    - \e tiBusy:        No resources available, try again later.
20295 *    - \e tiIONoDevice:  Invalid device handle.
20296 *    - \e tiError:       Other errors.
20297 */
20298/*****************************************************************************/
20299
20300/*
20301  create any fis and set SRST bit in device control
20302*/
20303GLOBAL bit32
20304satResetDevice(
20305                            tiRoot_t                  *tiRoot,
20306                            tiIORequest_t             *tiIORequest,
20307                            tiDeviceHandle_t          *tiDeviceHandle,
20308                            tiScsiInitiatorRequest_t *tiScsiRequest,
20309                            satIOContext_t            *satIOContext
20310                            )
20311{
20312  bit32                     status;
20313  bit32                     agRequestType;
20314  agsaFisRegHostToDevice_t  *fis;
20315#ifdef  TD_DEBUG_ENABLE
20316  tdIORequestBody_t         *tdIORequestBody;
20317  satInternalIo_t           *satIntIoContext;
20318#endif
20319
20320  fis           = satIOContext->pFis;
20321
20322  TI_DBG2(("satResetDevice: start\n"));
20323
20324#ifdef  TD_DEBUG_ENABLE
20325  satIntIoContext = satIOContext->satIntIoContext;
20326  tdIORequestBody = satIntIoContext->satIntRequestBody;
20327#endif
20328  TI_DBG5(("satResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20329  /* any fis should work */
20330  fis->h.fisType        = 0x27;                   /* Reg host to device */
20331  fis->h.c_pmPort       = 0;                      /* C Bit is not set */
20332  fis->h.command        = 0;                      /* any command */
20333  fis->h.features       = 0;                      /* FIS reserve */
20334  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
20335  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
20336  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
20337  fis->d.device         = 0;                      /* FIS LBA mode  */
20338  fis->d.lbaLowExp      = 0;
20339  fis->d.lbaMidExp      = 0;
20340  fis->d.lbaHighExp     = 0;
20341  fis->d.featuresExp    = 0;
20342  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
20343  fis->d.sectorCountExp = 0;
20344  fis->d.reserved4      = 0;
20345  fis->d.control        = 0x4;                    /* SRST bit is set  */
20346  fis->d.reserved5      = 0;
20347
20348  agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
20349
20350  satIOContext->satCompleteCB = &satResetDeviceCB;
20351
20352  /*
20353   * Prepare SGL and send FIS to LL layer.
20354   */
20355  satIOContext->reqType = agRequestType;       /* Save it */
20356
20357#ifdef TD_INTERNAL_DEBUG
20358  tdhexdump("satResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20359#ifdef  TD_DEBUG_ENABLE
20360  tdhexdump("satResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20361#endif
20362#endif
20363
20364  status = sataLLIOStart( tiRoot,
20365                          tiIORequest,
20366                          tiDeviceHandle,
20367                          tiScsiRequest,
20368                          satIOContext);
20369
20370  TI_DBG6(("satResetDevice: end status %d\n", status));
20371  return status;
20372}
20373
20374/*****************************************************************************
20375*! \brief  satResetDeviceCB
20376*
20377*   This routine is a callback function called from ossaSATACompleted().
20378*   This CB routine deals with SRT completion. This function send DSRT
20379*
20380*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
20381*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
20382*  \param   agIOStatus:  Status of completed I/O.
20383*  \param   agFirstDword:Pointer to the four bytes of FIS.
20384*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20385*                        length.
20386*  \param   agParam:     Additional info based on status.
20387*  \param   ioContext:   Pointer to satIOContext_t.
20388*
20389*  \return: none
20390*
20391*****************************************************************************/
20392GLOBAL void satResetDeviceCB(
20393                   agsaRoot_t        *agRoot,
20394                   agsaIORequest_t   *agIORequest,
20395                   bit32             agIOStatus,
20396                   agsaFisHeader_t   *agFirstDword,
20397                   bit32             agIOInfoLen,
20398                   agsaFrameHandle_t agFrameHandle,
20399                   void              *ioContext
20400                   )
20401{
20402  /* callback for satResetDevice */
20403  tdsaRootOsData_t   *osData = (tdsaRootOsData_t *)agRoot->osData;
20404  tiRoot_t           *tiRoot = (tiRoot_t *)osData->tiRoot;
20405  tdsaRoot_t         *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
20406  tdsaContext_t      *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20407  tdIORequestBody_t  *tdIORequestBody;
20408  tdIORequestBody_t  *tdOrgIORequestBody;
20409  satIOContext_t     *satIOContext;
20410  satIOContext_t     *satOrgIOContext;
20411  satIOContext_t     *satNewIOContext;
20412  satInternalIo_t    *satIntIo;
20413  satInternalIo_t    *satNewIntIo = agNULL;
20414  satDeviceData_t    *satDevData;
20415  tiIORequest_t      *tiOrgIORequest;
20416#ifdef  TD_DEBUG_ENABLE
20417  bit32                     ataStatus = 0;
20418  bit32                     ataError;
20419  agsaFisPioSetupHeader_t  *satPIOSetupHeader = agNULL;
20420#endif
20421  bit32                     status;
20422
20423  TI_DBG1(("satResetDeviceCB: start\n"));
20424  TI_DBG6(("satResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20425
20426  tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
20427  satIOContext           = (satIOContext_t *) ioContext;
20428  satIntIo               = satIOContext->satIntIoContext;
20429  satDevData             = satIOContext->pSatDevData;
20430  if (satIntIo == agNULL)
20431  {
20432    TI_DBG6(("satResetDeviceCB: External, OS generated\n"));
20433    satOrgIOContext      = satIOContext;
20434    tiOrgIORequest       = tdIORequestBody->tiIORequest;
20435  }
20436  else
20437  {
20438    TI_DBG6(("satResetDeviceCB: Internal, TD generated\n"));
20439    satOrgIOContext        = satIOContext->satOrgIOContext;
20440    if (satOrgIOContext == agNULL)
20441    {
20442      TI_DBG6(("satResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20443      return;
20444    }
20445    else
20446    {
20447      TI_DBG6(("satResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20448    }
20449    tdOrgIORequestBody    = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20450    tiOrgIORequest        = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20451  }
20452
20453  tdIORequestBody->ioCompleted = agTRUE;
20454  tdIORequestBody->ioStarted = agFALSE;
20455
20456  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20457  {
20458    TI_DBG1(("satResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20459    if (satOrgIOContext->NotifyOS == agTRUE)
20460    {
20461      ostiInitiatorEvent( tiRoot,
20462                          NULL,
20463                          NULL,
20464                          tiIntrEventTypeTaskManagement,
20465                          tiTMFailed,
20466                          tiOrgIORequest );
20467    }
20468
20469    satDevData->satTmTaskTag = agNULL;
20470
20471    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20472
20473    satFreeIntIoResource( tiRoot,
20474                          satDevData,
20475                          satIntIo);
20476    return;
20477  }
20478
20479  if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20480      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20481      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20482      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20483      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20484      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20485      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20486      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20487      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20488      )
20489  {
20490    TI_DBG1(("satResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20491
20492    if (satOrgIOContext->NotifyOS == agTRUE)
20493    {
20494      ostiInitiatorEvent( tiRoot,
20495                          NULL,
20496                          NULL,
20497                          tiIntrEventTypeTaskManagement,
20498                          tiTMFailed,
20499                          tiOrgIORequest );
20500    }
20501
20502    satDevData->satTmTaskTag = agNULL;
20503
20504    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20505
20506    satFreeIntIoResource( tiRoot,
20507                         satDevData,
20508                         satIntIo);
20509    return;
20510  }
20511
20512 if (agIOStatus != OSSA_IO_SUCCESS)
20513  {
20514#ifdef  TD_DEBUG_ENABLE
20515    /* only agsaFisPioSetup_t is expected */
20516    satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20517    ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
20518    ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
20519#endif
20520    TI_DBG1(("satResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20521
20522     if (satOrgIOContext->NotifyOS == agTRUE)
20523     {
20524      ostiInitiatorEvent( tiRoot,
20525                          NULL,
20526                          NULL,
20527                          tiIntrEventTypeTaskManagement,
20528                          tiTMFailed,
20529                          tiOrgIORequest );
20530     }
20531
20532    satDevData->satTmTaskTag = agNULL;
20533
20534    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20535
20536    satFreeIntIoResource( tiRoot,
20537                          satDevData,
20538                          satIntIo);
20539    return;
20540  }
20541
20542  /* success */
20543
20544  satNewIntIo = satAllocIntIoResource( tiRoot,
20545                                       tiOrgIORequest,
20546                                       satDevData,
20547                                       0,
20548                                       satNewIntIo);
20549  if (satNewIntIo == agNULL)
20550  {
20551    satDevData->satTmTaskTag = agNULL;
20552
20553    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20554
20555    /* memory allocation failure */
20556    satFreeIntIoResource( tiRoot,
20557                          satDevData,
20558                          satNewIntIo);
20559
20560    if (satOrgIOContext->NotifyOS == agTRUE)
20561    {
20562      ostiInitiatorEvent( tiRoot,
20563                          NULL,
20564                          NULL,
20565                          tiIntrEventTypeTaskManagement,
20566                          tiTMFailed,
20567                          tiOrgIORequest );
20568    }
20569
20570
20571      TI_DBG1(("satResetDeviceCB: momory allocation fails\n"));
20572      return;
20573    } /* end of memory allocation failure */
20574
20575    /*
20576     * Need to initialize all the fields within satIOContext
20577     */
20578
20579    satNewIOContext = satPrepareNewIO(
20580                                      satNewIntIo,
20581                                      tiOrgIORequest,
20582                                      satDevData,
20583                                      agNULL,
20584                                      satOrgIOContext
20585                                      );
20586
20587
20588
20589
20590    /* send AGSA_SATA_PROTOCOL_SRST_DEASSERT */
20591    status = satDeResetDevice(tiRoot,
20592                              tiOrgIORequest,
20593                              satOrgIOContext->ptiDeviceHandle,
20594                              agNULL,
20595                              satNewIOContext
20596                              );
20597
20598    if (status != tiSuccess)
20599    {
20600      if (satOrgIOContext->NotifyOS == agTRUE)
20601      {
20602        ostiInitiatorEvent( tiRoot,
20603                            NULL,
20604                            NULL,
20605                            tiIntrEventTypeTaskManagement,
20606                            tiTMFailed,
20607                            tiOrgIORequest );
20608      }
20609
20610      /* sending AGSA_SATA_PROTOCOL_SRST_DEASSERT fails */
20611
20612      satDevData->satTmTaskTag = agNULL;
20613
20614      satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20615
20616      satFreeIntIoResource( tiRoot,
20617                          satDevData,
20618                          satNewIntIo);
20619      return;
20620
20621    }
20622
20623  satDevData->satTmTaskTag = agNULL;
20624
20625  satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20626
20627  satFreeIntIoResource( tiRoot,
20628                        satDevData,
20629                        satIntIo);
20630  TI_DBG5(("satResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20631  TI_DBG6(("satResetDeviceCB: end\n"));
20632  return;
20633
20634}
20635
20636
20637/*****************************************************************************/
20638/*! \brief SAT implementation for satDeResetDevice.
20639 *
20640 *  SAT implementation for building DSRT FIS and sends the request to LL layer.
20641 *
20642 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20643 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20644 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20645 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20646 *  \param   satIOContext_t:   Pointer to the SAT IO Context
20647 *
20648 *  \return If command is started successfully
20649 *    - \e tiSuccess:     I/O request successfully initiated.
20650 *    - \e tiBusy:        No resources available, try again later.
20651 *    - \e tiIONoDevice:  Invalid device handle.
20652 *    - \e tiError:       Other errors.
20653 */
20654/*****************************************************************************/
20655GLOBAL bit32  satDeResetDevice(
20656                            tiRoot_t                  *tiRoot,
20657                            tiIORequest_t             *tiIORequest,
20658                            tiDeviceHandle_t          *tiDeviceHandle,
20659                            tiScsiInitiatorRequest_t *tiScsiRequest,
20660                            satIOContext_t            *satIOContext
20661                            )
20662{
20663  bit32                     status;
20664  bit32                     agRequestType;
20665  agsaFisRegHostToDevice_t  *fis;
20666#ifdef  TD_DEBUG_ENABLE
20667  tdIORequestBody_t         *tdIORequestBody;
20668  satInternalIo_t           *satIntIoContext;
20669#endif
20670  fis           = satIOContext->pFis;
20671
20672  TI_DBG6(("satDeResetDevice: start\n"));
20673
20674#ifdef  TD_DEBUG_ENABLE
20675  satIntIoContext = satIOContext->satIntIoContext;
20676  tdIORequestBody = satIntIoContext->satIntRequestBody;
20677  TI_DBG5(("satDeResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20678#endif
20679  /* any fis should work */
20680  fis->h.fisType        = 0x27;                   /* Reg host to device */
20681  fis->h.c_pmPort       = 0;                      /* C Bit is not set */
20682  fis->h.command        = 0;                      /* any command */
20683  fis->h.features       = 0;                      /* FIS reserve */
20684  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
20685  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
20686  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
20687  fis->d.device         = 0;                      /* FIS LBA mode  */
20688  fis->d.lbaLowExp      = 0;
20689  fis->d.lbaMidExp      = 0;
20690  fis->d.lbaHighExp     = 0;
20691  fis->d.featuresExp    = 0;
20692  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
20693  fis->d.sectorCountExp = 0;
20694  fis->d.reserved4      = 0;
20695  fis->d.control        = 0;                    /* SRST bit is not set  */
20696  fis->d.reserved5      = 0;
20697
20698  agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT;
20699
20700  satIOContext->satCompleteCB = &satDeResetDeviceCB;
20701
20702  /*
20703   * Prepare SGL and send FIS to LL layer.
20704   */
20705  satIOContext->reqType = agRequestType;       /* Save it */
20706
20707#ifdef TD_INTERNAL_DEBUG
20708  tdhexdump("satDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20709#ifdef  TD_DEBUG_ENABLE
20710  tdhexdump("satDeResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20711#endif
20712#endif
20713
20714  status = sataLLIOStart( tiRoot,
20715                          tiIORequest,
20716                          tiDeviceHandle,
20717                          tiScsiRequest,
20718                          satIOContext);
20719
20720  TI_DBG6(("satDeResetDevice: end status %d\n", status));
20721  return status;
20722
20723}
20724
20725/*****************************************************************************
20726*! \brief  satDeResetDeviceCB
20727*
20728*   This routine is a callback function called from ossaSATACompleted().
20729*   This CB routine deals with DSRT completion.
20730*
20731*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
20732*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
20733*  \param   agIOStatus:  Status of completed I/O.
20734*  \param   agFirstDword:Pointer to the four bytes of FIS.
20735*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20736*                        length.
20737*  \param   agParam:     Additional info based on status.
20738*  \param   ioContext:   Pointer to satIOContext_t.
20739*
20740*  \return: none
20741*
20742*****************************************************************************/
20743GLOBAL void satDeResetDeviceCB(
20744                   agsaRoot_t        *agRoot,
20745                   agsaIORequest_t   *agIORequest,
20746                   bit32             agIOStatus,
20747                   agsaFisHeader_t   *agFirstDword,
20748                   bit32             agIOInfoLen,
20749                   agsaFrameHandle_t agFrameHandle,
20750                   void              *ioContext
20751                   )
20752{
20753  /* callback for satDeResetDevice */
20754  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
20755  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
20756  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
20757  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20758  tdIORequestBody_t       *tdIORequestBody;
20759  tdIORequestBody_t       *tdOrgIORequestBody = agNULL;
20760  satIOContext_t          *satIOContext;
20761  satIOContext_t          *satOrgIOContext;
20762  satInternalIo_t         *satIntIo;
20763  satDeviceData_t         *satDevData;
20764  tiIORequest_t           *tiOrgIORequest;
20765#ifdef  TD_DEBUG_ENABLE
20766  bit32                    ataStatus = 0;
20767  bit32                    ataError;
20768  agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
20769#endif
20770  bit32                     report = agFALSE;
20771  bit32                     AbortTM = agFALSE;
20772
20773  TI_DBG1(("satDeResetDeviceCB: start\n"));
20774  TI_DBG6(("satDeResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20775  tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
20776  satIOContext           = (satIOContext_t *) ioContext;
20777  satIntIo               = satIOContext->satIntIoContext;
20778  satDevData             = satIOContext->pSatDevData;
20779  if (satIntIo == agNULL)
20780  {
20781    TI_DBG6(("satDeResetDeviceCB: External, OS generated\n"));
20782    satOrgIOContext      = satIOContext;
20783    tiOrgIORequest       = tdIORequestBody->tiIORequest;
20784  }
20785  else
20786  {
20787    TI_DBG6(("satDeResetDeviceCB: Internal, TD generated\n"));
20788    satOrgIOContext        = satIOContext->satOrgIOContext;
20789    if (satOrgIOContext == agNULL)
20790    {
20791      TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20792      return;
20793    }
20794    else
20795    {
20796      TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20797    }
20798    tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20799    tiOrgIORequest         = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20800  }
20801
20802  tdIORequestBody->ioCompleted = agTRUE;
20803  tdIORequestBody->ioStarted = agFALSE;
20804
20805  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20806  {
20807    TI_DBG1(("satDeResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20808    if (satOrgIOContext->NotifyOS == agTRUE)
20809    {
20810      ostiInitiatorEvent( tiRoot,
20811                          NULL,
20812                          NULL,
20813                          tiIntrEventTypeTaskManagement,
20814                          tiTMFailed,
20815                          tiOrgIORequest );
20816    }
20817
20818    satDevData->satTmTaskTag = agNULL;
20819    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20820
20821    satFreeIntIoResource( tiRoot,
20822                          satDevData,
20823                          satIntIo);
20824    return;
20825  }
20826
20827  if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20828      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20829      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20830      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20831      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20832      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20833      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20834      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20835      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20836      )
20837  {
20838    TI_DBG1(("satDeResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20839
20840    if (satOrgIOContext->NotifyOS == agTRUE)
20841    {
20842      ostiInitiatorEvent( tiRoot,
20843                          NULL,
20844                          NULL,
20845                          tiIntrEventTypeTaskManagement,
20846                          tiTMFailed,
20847                          tiOrgIORequest );
20848    }
20849
20850    satDevData->satTmTaskTag = agNULL;
20851
20852    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20853
20854    satFreeIntIoResource( tiRoot,
20855                         satDevData,
20856                         satIntIo);
20857    return;
20858  }
20859
20860 if (agIOStatus != OSSA_IO_SUCCESS)
20861  {
20862#ifdef  TD_DEBUG_ENABLE
20863    /* only agsaFisPioSetup_t is expected */
20864    satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20865    ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
20866    ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
20867#endif
20868    TI_DBG1(("satDeResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20869
20870     if (satOrgIOContext->NotifyOS == agTRUE)
20871     {
20872      ostiInitiatorEvent( tiRoot,
20873                          NULL,
20874                          NULL,
20875                          tiIntrEventTypeTaskManagement,
20876                          tiTMFailed,
20877                          tiOrgIORequest );
20878     }
20879
20880    satDevData->satTmTaskTag = agNULL;
20881
20882    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20883
20884    satFreeIntIoResource( tiRoot,
20885                          satDevData,
20886                          satIntIo);
20887    return;
20888  }
20889
20890  /* success */
20891  TI_DBG1(("satDeResetDeviceCB: success \n"));
20892  TI_DBG1(("satDeResetDeviceCB: TMF %d\n", satOrgIOContext->TMF));
20893
20894  if (satOrgIOContext->TMF == AG_ABORT_TASK)
20895  {
20896    AbortTM = agTRUE;
20897  }
20898
20899  if (satOrgIOContext->NotifyOS == agTRUE)
20900  {
20901    report = agTRUE;
20902  }
20903
20904  if (AbortTM == agTRUE)
20905  {
20906    TI_DBG1(("satDeResetDeviceCB: calling satAbort\n"));
20907    satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
20908  }
20909  satDevData->satTmTaskTag = agNULL;
20910
20911  satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
20912
20913  satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20914
20915  TI_DBG1(("satDeResetDeviceCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
20916  TI_DBG1(("satDeResetDeviceCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
20917
20918  satFreeIntIoResource( tiRoot,
20919                        satDevData,
20920                        satIntIo);
20921
20922  /* clean up TD layer's IORequestBody */
20923  if (tdOrgIORequestBody != agNULL)
20924  {
20925    ostiFreeMemory(
20926                   tiRoot,
20927                   tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
20928                   sizeof(tdIORequestBody_t)
20929                   );
20930  }
20931  else
20932  {
20933    TI_DBG1(("satDeResetDeviceCB: tdOrgIORequestBody is NULL, wrong\n"));
20934  }
20935
20936
20937  if (report)
20938  {
20939    ostiInitiatorEvent( tiRoot,
20940                        NULL,
20941                        NULL,
20942                        tiIntrEventTypeTaskManagement,
20943                        tiTMOK,
20944                        tiOrgIORequest );
20945  }
20946
20947
20948  TI_DBG5(("satDeResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20949  TI_DBG6(("satDeResetDeviceCB: end\n"));
20950  return;
20951
20952}
20953
20954/*****************************************************************************/
20955/*! \brief SAT implementation for satStartCheckPowerMode.
20956 *
20957 *  SAT implementation for abort task management for non-ncq sata disk.
20958 *  This function sends CHECK POWER MODE
20959 *
20960 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
20961 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
20962 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
20963 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
20964 *  \param   satIOContext_t:   Pointer to the SAT IO Context
20965 *
20966 *  \return If command is started successfully
20967 *    - \e tiSuccess:     I/O request successfully initiated.
20968 *    - \e tiBusy:        No resources available, try again later.
20969 *    - \e tiIONoDevice:  Invalid device handle.
20970 *    - \e tiError:       Other errors.
20971 */
20972/*****************************************************************************/
20973GLOBAL bit32  satStartCheckPowerMode(
20974                            tiRoot_t                  *tiRoot,
20975                            tiIORequest_t             *tiIORequest,
20976                            tiDeviceHandle_t          *tiDeviceHandle,
20977                            tiScsiInitiatorRequest_t  *tiScsiRequest, /* NULL */
20978                            satIOContext_t            *satIOContext
20979                            )
20980{
20981  satInternalIo_t           *satIntIo = agNULL;
20982  satDeviceData_t           *satDevData = agNULL;
20983  satIOContext_t            *satNewIOContext;
20984  bit32                     status;
20985  tiIORequest_t             *currentTaskTag = agNULL;
20986
20987  TI_DBG6(("satStartCheckPowerMode: start\n"));
20988
20989  currentTaskTag = tiIORequest;
20990
20991  satDevData = satIOContext->pSatDevData;
20992
20993  TI_DBG6(("satStartCheckPowerMode: before alloc\n"));
20994
20995  /* allocate any fis for seting SRT bit in device control */
20996  satIntIo = satAllocIntIoResource( tiRoot,
20997                                    tiIORequest,
20998                                    satDevData,
20999                                    0,
21000                                    satIntIo);
21001
21002  TI_DBG6(("satStartCheckPowerMode: before after\n"));
21003
21004  if (satIntIo == agNULL)
21005  {
21006    TI_DBG1(("satStartCheckPowerMode: can't alloacate\n"));
21007    if (satIOContext->NotifyOS)
21008    {
21009      ostiInitiatorEvent( tiRoot,
21010                          NULL,
21011                          NULL,
21012                          tiIntrEventTypeTaskManagement,
21013                          tiTMFailed,
21014                          currentTaskTag );
21015    }
21016    return tiError;
21017  }
21018
21019  satNewIOContext = satPrepareNewIO(satIntIo,
21020                                    tiIORequest,
21021                                    satDevData,
21022                                    agNULL,
21023                                    satIOContext);
21024
21025  TI_DBG6(("satStartCheckPowerMode: OS satIOContext %p \n", satIOContext));
21026  TI_DBG6(("satStartCheckPowerMode: TD satNewIOContext %p \n", satNewIOContext));
21027  TI_DBG6(("satStartCheckPowerMode: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21028  TI_DBG6(("satStartCheckPowerMode: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21029
21030
21031
21032  TI_DBG1(("satStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
21033
21034  status = satCheckPowerMode(tiRoot,
21035                             &satIntIo->satIntTiIORequest, /* New tiIORequest */
21036                             tiDeviceHandle,
21037                             satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21038                             satNewIOContext);
21039
21040  if (status != tiSuccess)
21041  {
21042    TI_DBG1(("satStartCheckPowerMode: failed in sending\n"));
21043
21044    satFreeIntIoResource( tiRoot,
21045                          satDevData,
21046                          satIntIo);
21047    if (satIOContext->NotifyOS)
21048    {
21049      ostiInitiatorEvent( tiRoot,
21050                          NULL,
21051                          NULL,
21052                          tiIntrEventTypeTaskManagement,
21053                          tiTMFailed,
21054                          currentTaskTag );
21055    }
21056
21057    return tiError;
21058  }
21059
21060
21061  TI_DBG6(("satStartCheckPowerMode: end\n"));
21062
21063  return status;
21064}
21065
21066/*****************************************************************************/
21067/*! \brief SAT implementation for satCheckPowerMode.
21068 *
21069 *  This function creates CHECK POWER MODE fis and sends the request to LL layer
21070 *
21071 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
21072 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
21073 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
21074 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
21075 *  \param   satIOContext_t:   Pointer to the SAT IO Context
21076 *
21077 *  \return If command is started successfully
21078 *    - \e tiSuccess:     I/O request successfully initiated.
21079 *    - \e tiBusy:        No resources available, try again later.
21080 *    - \e tiIONoDevice:  Invalid device handle.
21081 *    - \e tiError:       Other errors.
21082 */
21083/*****************************************************************************/
21084GLOBAL bit32  satCheckPowerMode(
21085                            tiRoot_t                  *tiRoot,
21086                            tiIORequest_t             *tiIORequest,
21087                            tiDeviceHandle_t          *tiDeviceHandle,
21088                            tiScsiInitiatorRequest_t *tiScsiRequest,
21089                            satIOContext_t            *satIOContext
21090                            )
21091{
21092  /*
21093    sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands
21094    internally generated - no directly corresponding scsi
21095  */
21096  bit32                     status;
21097  bit32                     agRequestType;
21098  agsaFisRegHostToDevice_t  *fis;
21099
21100  fis           = satIOContext->pFis;
21101  TI_DBG5(("satCheckPowerMode: start\n"));
21102  /*
21103   * Send the ATA CHECK POWER MODE command.
21104   */
21105  fis->h.fisType        = 0x27;                   /* Reg host to device */
21106  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
21107  fis->h.command        = SAT_CHECK_POWER_MODE;   /* 0xE5 */
21108  fis->h.features       = 0;
21109  fis->d.lbaLow         = 0;
21110  fis->d.lbaMid         = 0;
21111  fis->d.lbaHigh        = 0;
21112  fis->d.device         = 0;
21113  fis->d.lbaLowExp      = 0;
21114  fis->d.lbaMidExp      = 0;
21115  fis->d.lbaHighExp     = 0;
21116  fis->d.featuresExp    = 0;
21117  fis->d.sectorCount    = 0;
21118  fis->d.sectorCountExp = 0;
21119  fis->d.reserved4      = 0;
21120  fis->d.control        = 0;                      /* FIS HOB bit clear */
21121  fis->d.reserved5      = 0;
21122
21123  agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
21124
21125  /* Initialize CB for SATA completion.
21126   */
21127  satIOContext->satCompleteCB = &satCheckPowerModeCB;
21128
21129  /*
21130   * Prepare SGL and send FIS to LL layer.
21131   */
21132  satIOContext->reqType = agRequestType;       /* Save it */
21133
21134  status = sataLLIOStart( tiRoot,
21135                          tiIORequest,
21136                          tiDeviceHandle,
21137                          tiScsiRequest,
21138                          satIOContext);
21139
21140  TI_DBG5(("satCheckPowerMode: return\n"));
21141
21142  return status;
21143}
21144
21145/*****************************************************************************
21146*! \brief  satCheckPowerModeCB
21147*
21148*   This routine is a callback function called from ossaSATACompleted().
21149*   This CB routine deals with CHECK POWER MODE completion as abort task
21150*   management.
21151*
21152*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
21153*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
21154*  \param   agIOStatus:  Status of completed I/O.
21155*  \param   agFirstDword:Pointer to the four bytes of FIS.
21156*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21157*                        length.
21158*  \param   agParam:     Additional info based on status.
21159*  \param   ioContext:   Pointer to satIOContext_t.
21160*
21161*  \return: none
21162*
21163*****************************************************************************/
21164GLOBAL void satCheckPowerModeCB(
21165                   agsaRoot_t        *agRoot,
21166                   agsaIORequest_t   *agIORequest,
21167                   bit32             agIOStatus,
21168                   agsaFisHeader_t   *agFirstDword,
21169                   bit32             agIOInfoLen,
21170                   agsaFrameHandle_t agFrameHandle,
21171                   void              *ioContext
21172                   )
21173{
21174  /* callback for satDeResetDevice */
21175  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
21176  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
21177  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
21178  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21179  tdIORequestBody_t       *tdIORequestBody;
21180  tdIORequestBody_t       *tdOrgIORequestBody = agNULL;
21181  satIOContext_t          *satIOContext;
21182  satIOContext_t          *satOrgIOContext;
21183  satInternalIo_t         *satIntIo;
21184  satDeviceData_t         *satDevData;
21185
21186  tiIORequest_t             *tiOrgIORequest;
21187#ifdef  TD_DEBUG_ENABLE
21188  bit32                     ataStatus = 0;
21189  bit32                     ataError;
21190  agsaFisPioSetupHeader_t   *satPIOSetupHeader = agNULL;
21191#endif
21192  bit32                     report = agFALSE;
21193  bit32                     AbortTM = agFALSE;
21194
21195
21196  TI_DBG1(("satCheckPowerModeCB: start\n"));
21197
21198  TI_DBG1(("satCheckPowerModeCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21199
21200  tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
21201  satIOContext           = (satIOContext_t *) ioContext;
21202  satIntIo               = satIOContext->satIntIoContext;
21203  satDevData             = satIOContext->pSatDevData;
21204  if (satIntIo == agNULL)
21205  {
21206    TI_DBG6(("satCheckPowerModeCB: External, OS generated\n"));
21207    satOrgIOContext      = satIOContext;
21208    tiOrgIORequest       = tdIORequestBody->tiIORequest;
21209  }
21210  else
21211  {
21212    TI_DBG6(("satCheckPowerModeCB: Internal, TD generated\n"));
21213    satOrgIOContext        = satIOContext->satOrgIOContext;
21214    if (satOrgIOContext == agNULL)
21215    {
21216      TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NULL, wrong\n"));
21217      return;
21218    }
21219    else
21220    {
21221      TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NOT NULL\n"));
21222    }
21223    tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21224    tiOrgIORequest         = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
21225  }
21226
21227
21228  tdIORequestBody->ioCompleted = agTRUE;
21229  tdIORequestBody->ioStarted = agFALSE;
21230
21231  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21232  {
21233    TI_DBG1(("satCheckPowerModeCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21234
21235    if (satOrgIOContext->NotifyOS == agTRUE)
21236    {
21237      ostiInitiatorEvent( tiRoot,
21238                          NULL,
21239                          NULL,
21240                          tiIntrEventTypeTaskManagement,
21241                          tiTMFailed,
21242                          tiOrgIORequest );
21243    }
21244
21245    satDevData->satTmTaskTag = agNULL;
21246
21247    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21248
21249    satFreeIntIoResource( tiRoot,
21250                          satDevData,
21251                          satIntIo);
21252    return;
21253  }
21254
21255  if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21256      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21257      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21258      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21259      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21260      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21261      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21262      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21263      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21264      )
21265  {
21266    TI_DBG1(("satCheckPowerModeCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21267
21268    if (satOrgIOContext->NotifyOS == agTRUE)
21269    {
21270      ostiInitiatorEvent( tiRoot,
21271                          NULL,
21272                          NULL,
21273                          tiIntrEventTypeTaskManagement,
21274                          tiTMFailed,
21275                          tiOrgIORequest );
21276    }
21277
21278    satDevData->satTmTaskTag = agNULL;
21279
21280    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21281
21282    satFreeIntIoResource( tiRoot,
21283                         satDevData,
21284                         satIntIo);
21285    return;
21286  }
21287
21288 if (agIOStatus != OSSA_IO_SUCCESS)
21289  {
21290#ifdef  TD_DEBUG_ENABLE
21291    /* only agsaFisPioSetup_t is expected */
21292    satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
21293    ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
21294    ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
21295#endif
21296    TI_DBG1(("satCheckPowerModeCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
21297
21298     if (satOrgIOContext->NotifyOS == agTRUE)
21299     {
21300      ostiInitiatorEvent( tiRoot,
21301                          NULL,
21302                          NULL,
21303                          tiIntrEventTypeTaskManagement,
21304                          tiTMFailed,
21305                          tiOrgIORequest );
21306     }
21307
21308    satDevData->satTmTaskTag = agNULL;
21309
21310    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21311
21312    satFreeIntIoResource( tiRoot,
21313                          satDevData,
21314                          satIntIo);
21315    return;
21316  }
21317
21318  /* success */
21319  TI_DBG1(("satCheckPowerModeCB: success\n"));
21320  TI_DBG1(("satCheckPowerModeCB: TMF %d\n", satOrgIOContext->TMF));
21321
21322  if (satOrgIOContext->TMF == AG_ABORT_TASK)
21323  {
21324    AbortTM = agTRUE;
21325  }
21326
21327  if (satOrgIOContext->NotifyOS == agTRUE)
21328  {
21329    report = agTRUE;
21330  }
21331  if (AbortTM == agTRUE)
21332  {
21333    TI_DBG1(("satCheckPowerModeCB: calling satAbort\n"));
21334    satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
21335  }
21336  satDevData->satTmTaskTag = agNULL;
21337
21338  satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
21339
21340  satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21341
21342  TI_DBG1(("satCheckPowerModeCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
21343  TI_DBG1(("satCheckPowerModeCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
21344
21345  satFreeIntIoResource( tiRoot,
21346                        satDevData,
21347                        satIntIo);
21348
21349  /* clean up TD layer's IORequestBody */
21350  if (tdOrgIORequestBody != agNULL)
21351  {
21352    ostiFreeMemory(
21353                   tiRoot,
21354                   tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21355                   sizeof(tdIORequestBody_t)
21356                   );
21357  }
21358  else
21359  {
21360    TI_DBG1(("satCheckPowerModeCB: tdOrgIORequestBody is NULL, wrong\n"));
21361  }
21362  if (report)
21363  {
21364    ostiInitiatorEvent( tiRoot,
21365                        NULL,
21366                        NULL,
21367                        tiIntrEventTypeTaskManagement,
21368                        tiTMOK,
21369                        tiOrgIORequest );
21370  }
21371
21372  TI_DBG5(("satCheckPowerModeCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
21373  TI_DBG2(("satCheckPowerModeCB: end\n"));
21374  return;
21375
21376}
21377
21378/*****************************************************************************/
21379/*! \brief SAT implementation for satAddSATAStartIDDev.
21380 *
21381 *  This function sends identify device data to find out the uniqueness
21382 *  of device.
21383 *
21384 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
21385 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
21386 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
21387 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
21388 *  \param   satIOContext_t:   Pointer to the SAT IO Context
21389 *
21390 *  \return If command is started successfully
21391 *    - \e tiSuccess:     I/O request successfully initiated.
21392 *    - \e tiBusy:        No resources available, try again later.
21393 *    - \e tiIONoDevice:  Invalid device handle.
21394 *    - \e tiError:       Other errors.
21395 */
21396/*****************************************************************************/
21397GLOBAL bit32  satAddSATAStartIDDev(
21398                               tiRoot_t                  *tiRoot,
21399                               tiIORequest_t             *tiIORequest,
21400                               tiDeviceHandle_t          *tiDeviceHandle,
21401                               tiScsiInitiatorRequest_t  *tiScsiRequest, // NULL
21402                               satIOContext_t            *satIOContext
21403                            )
21404{
21405  satInternalIo_t           *satIntIo = agNULL;
21406  satDeviceData_t           *satDevData = agNULL;
21407  tdIORequestBody_t         *tdIORequestBody;
21408  satIOContext_t            *satNewIOContext;
21409  bit32                     status;
21410
21411  TI_DBG2(("satAddSATAStartIDDev: start\n"));
21412
21413  satDevData = satIOContext->pSatDevData;
21414
21415  TI_DBG2(("satAddSATAStartIDDev: before alloc\n"));
21416
21417  /* allocate identify device command */
21418  satIntIo = satAllocIntIoResource( tiRoot,
21419                                    tiIORequest,
21420                                    satDevData,
21421                                    sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
21422                                    satIntIo);
21423
21424  TI_DBG2(("satAddSATAStartIDDev: after alloc\n"));
21425
21426  if (satIntIo == agNULL)
21427  {
21428    TI_DBG1(("satAddSATAStartIDDev: can't alloacate\n"));
21429
21430    return tiError;
21431  }
21432
21433  /* fill in fields */
21434  /* real ttttttthe one worked and the same; 5/21/07/ */
21435  satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
21436  tdIORequestBody = satIntIo->satIntRequestBody;
21437  satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
21438
21439  satNewIOContext->pSatDevData   = satDevData;
21440  satNewIOContext->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
21441  satNewIOContext->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
21442  satNewIOContext->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
21443  satNewIOContext->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
21444  satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
21445  satNewIOContext->interruptContext = tiInterruptContext;
21446  satNewIOContext->satIntIoContext  = satIntIo;
21447
21448  satNewIOContext->ptiDeviceHandle = agNULL;
21449  satNewIOContext->satOrgIOContext = satIOContext; /* changed */
21450
21451  /* this is valid only for TD layer generated (not triggered by OS at all) IO */
21452  satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
21453
21454
21455  TI_DBG6(("satAddSATAStartIDDev: OS satIOContext %p \n", satIOContext));
21456  TI_DBG6(("satAddSATAStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
21457  TI_DBG6(("satAddSATAStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21458  TI_DBG6(("satAddSATAStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21459
21460
21461
21462  TI_DBG2(("satAddSATAStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
21463
21464  status = satAddSATASendIDDev( tiRoot,
21465                                &satIntIo->satIntTiIORequest, /* New tiIORequest */
21466                                tiDeviceHandle,
21467                                satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21468                                satNewIOContext);
21469
21470  if (status != tiSuccess)
21471  {
21472    TI_DBG1(("satAddSATAStartIDDev: failed in sending\n"));
21473
21474    satFreeIntIoResource( tiRoot,
21475                          satDevData,
21476                          satIntIo);
21477
21478    return tiError;
21479  }
21480
21481
21482  TI_DBG6(("satAddSATAStartIDDev: end\n"));
21483
21484  return status;
21485
21486
21487}
21488
21489/*****************************************************************************/
21490/*! \brief SAT implementation for satAddSATASendIDDev.
21491 *
21492 *  This function creates identify device data fis and send it to LL
21493 *
21494 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
21495 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
21496 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
21497 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
21498 *  \param   satIOContext_t:   Pointer to the SAT IO Context
21499 *
21500 *  \return If command is started successfully
21501 *    - \e tiSuccess:     I/O request successfully initiated.
21502 *    - \e tiBusy:        No resources available, try again later.
21503 *    - \e tiIONoDevice:  Invalid device handle.
21504 *    - \e tiError:       Other errors.
21505 */
21506/*****************************************************************************/
21507GLOBAL bit32  satAddSATASendIDDev(
21508                           tiRoot_t                  *tiRoot,
21509                           tiIORequest_t             *tiIORequest,
21510                           tiDeviceHandle_t          *tiDeviceHandle,
21511                           tiScsiInitiatorRequest_t  *tiScsiRequest,
21512                           satIOContext_t            *satIOContext)
21513{
21514  bit32                     status;
21515  bit32                     agRequestType;
21516  satDeviceData_t           *pSatDevData;
21517  agsaFisRegHostToDevice_t  *fis;
21518#ifdef  TD_DEBUG_ENABLE
21519  tdIORequestBody_t         *tdIORequestBody;
21520  satInternalIo_t           *satIntIoContext;
21521#endif
21522
21523  pSatDevData   = satIOContext->pSatDevData;
21524  fis           = satIOContext->pFis;
21525  TI_DBG2(("satAddSATASendIDDev: start\n"));
21526#ifdef  TD_DEBUG_ENABLE
21527  satIntIoContext = satIOContext->satIntIoContext;
21528  tdIORequestBody = satIntIoContext->satIntRequestBody;
21529#endif
21530  TI_DBG5(("satAddSATASendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
21531
21532  fis->h.fisType        = 0x27;                   /* Reg host to device */
21533  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
21534  if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
21535      fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0x40 */
21536  else
21537      fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
21538  fis->h.features       = 0;                      /* FIS reserve */
21539  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
21540  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
21541  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
21542  fis->d.device         = 0;                      /* FIS LBA mode  */
21543  fis->d.lbaLowExp      = 0;
21544  fis->d.lbaMidExp      = 0;
21545  fis->d.lbaHighExp     = 0;
21546  fis->d.featuresExp    = 0;
21547  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
21548  fis->d.sectorCountExp = 0;
21549  fis->d.reserved4      = 0;
21550  fis->d.control        = 0;                      /* FIS HOB bit clear */
21551  fis->d.reserved5      = 0;
21552
21553  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
21554
21555  /* Initialize CB for SATA completion.
21556   */
21557  satIOContext->satCompleteCB = &satAddSATAIDDevCB;
21558
21559  /*
21560   * Prepare SGL and send FIS to LL layer.
21561   */
21562  satIOContext->reqType = agRequestType;       /* Save it */
21563
21564#ifdef TD_INTERNAL_DEBUG
21565  tdhexdump("satAddSATASendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
21566#ifdef  TD_DEBUG_ENABLE
21567  tdhexdump("satAddSATASendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
21568#endif
21569#endif
21570
21571  status = sataLLIOStart( tiRoot,
21572                          tiIORequest,
21573                          tiDeviceHandle,
21574                          tiScsiRequest,
21575                          satIOContext);
21576
21577  TI_DBG2(("satAddSATASendIDDev: end status %d\n", status));
21578  return status;
21579}
21580
21581/*****************************************************************************
21582*! \brief  satAddSATAIDDevCB
21583*
21584*   This routine is a callback function for satAddSATASendIDDev()
21585*   Using Identify Device Data, this function finds whether devicedata is
21586*   new or old. If new, add it to the devicelist.
21587*
21588*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
21589*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
21590*  \param   agIOStatus:  Status of completed I/O.
21591*  \param   agFirstDword:Pointer to the four bytes of FIS.
21592*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21593*                        length.
21594*  \param   agParam:     Additional info based on status.
21595*  \param   ioContext:   Pointer to satIOContext_t.
21596*
21597*  \return: none
21598*
21599*****************************************************************************/
21600void satAddSATAIDDevCB(
21601                   agsaRoot_t        *agRoot,
21602                   agsaIORequest_t   *agIORequest,
21603                   bit32             agIOStatus,
21604                   agsaFisHeader_t   *agFirstDword,
21605                   bit32             agIOInfoLen,
21606                   void              *agParam,
21607                   void              *ioContext
21608                   )
21609{
21610
21611  /*
21612    In the process of Inquiry
21613    Process SAT_IDENTIFY_DEVICE
21614  */
21615  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
21616  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
21617  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
21618  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21619  tdIORequestBody_t       *tdIORequestBody;
21620  tdIORequestBody_t       *tdOrgIORequestBody;
21621  satIOContext_t          *satIOContext;
21622  satIOContext_t          *satOrgIOContext;
21623  satIOContext_t          *satNewIOContext;
21624  satInternalIo_t         *satIntIo;
21625  satInternalIo_t         *satNewIntIo = agNULL;
21626  satDeviceData_t         *satDevData;
21627  tiIORequest_t           *tiOrgIORequest = agNULL;
21628  agsaSATAIdentifyData_t    *pSATAIdData;
21629  bit16                     *tmpptr, tmpptr_tmp;
21630  bit32                     x;
21631  tdsaDeviceData_t          *NewOneDeviceData = agNULL;
21632  tdsaDeviceData_t          *oneDeviceData = agNULL;
21633  tdList_t                  *DeviceListList;
21634  int                       new_device = agTRUE;
21635  bit8                      PhyID;
21636  void                      *sglVirtualAddr;
21637  bit32                     retry_status;
21638  agsaContext_t             *agContext;
21639  tdsaPortContext_t         *onePortContext;
21640  bit32                     status = 0;
21641
21642  TI_DBG2(("satAddSATAIDDevCB: start\n"));
21643  TI_DBG6(("satAddSATAIDDevCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21644  tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
21645  satIOContext           = (satIOContext_t *) ioContext;
21646  satIntIo               = satIOContext->satIntIoContext;
21647  satDevData             = satIOContext->pSatDevData;
21648
21649  NewOneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
21650  TI_DBG2(("satAddSATAIDDevCB: NewOneDeviceData %p did %d\n", NewOneDeviceData, NewOneDeviceData->id));
21651  PhyID = NewOneDeviceData->phyID;
21652  TI_DBG2(("satAddSATAIDDevCB: phyID %d\n", PhyID));
21653  agContext = &(NewOneDeviceData->agDeviceResetContext);
21654  agContext->osData = agNULL;
21655  if (satIntIo == agNULL)
21656  {
21657    TI_DBG1(("satAddSATAIDDevCB: External, OS generated\n"));
21658    TI_DBG1(("satAddSATAIDDevCB: Not possible case\n"));
21659    satOrgIOContext      = satIOContext;
21660    tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21661    tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21662
21663    /* put onedevicedata back to free list */
21664    osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21665    TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21666    TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21667
21668    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21669
21670    satFreeIntIoResource( tiRoot,
21671                          satDevData,
21672                          satIntIo);
21673    /* clean up TD layer's IORequestBody */
21674    ostiFreeMemory(
21675                   tiRoot,
21676                   tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21677                   sizeof(tdIORequestBody_t)
21678                   );
21679
21680    /* notifying link up */
21681    ostiPortEvent (
21682                   tiRoot,
21683                   tiPortLinkUp,
21684                   tiSuccess,
21685                   (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
21686                   );
21687#ifdef INITIATOR_DRIVER
21688    /* triggers discovery */
21689    ostiPortEvent(
21690                  tiRoot,
21691                  tiPortDiscoveryReady,
21692                  tiSuccess,
21693                  (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
21694                  );
21695#endif
21696    return;
21697  }
21698  else
21699  {
21700    TI_DBG1(("satAddSATAIDDevCB: Internal, TD generated\n"));
21701    satOrgIOContext        = satIOContext->satOrgIOContext;
21702    if (satOrgIOContext == agNULL)
21703    {
21704      TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NULL\n"));
21705      return;
21706    }
21707    else
21708    {
21709      TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NOT NULL\n"));
21710      tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21711      sglVirtualAddr         = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
21712    }
21713  }
21714  tiOrgIORequest           = tdIORequestBody->tiIORequest;
21715
21716  tdIORequestBody->ioCompleted = agTRUE;
21717  tdIORequestBody->ioStarted = agFALSE;
21718  TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21719  /* protect against double completion for old port */
21720  if (satOrgIOContext->pid != tdsaAllShared->Ports[PhyID].portContext->id)
21721  {
21722    TI_DBG2(("satAddSATAIDDevCB: incorrect pid\n"));
21723    TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21724    TI_DBG2(("satAddSATAIDDevCB: tiPortalContext pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
21725    tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21726    /* put onedevicedata back to free list */
21727    osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21728    TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21729    TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21730    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21731
21732    satFreeIntIoResource( tiRoot,
21733                          satDevData,
21734                          satIntIo);
21735    /* clean up TD layer's IORequestBody */
21736    ostiFreeMemory(
21737                   tiRoot,
21738                   tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21739                   sizeof(tdIORequestBody_t)
21740                   );
21741    /* no notification to OS layer */
21742    return;
21743  }
21744  /* completion after portcontext is invalidated */
21745  onePortContext = NewOneDeviceData->tdPortContext;
21746  if (onePortContext != agNULL)
21747  {
21748    if (onePortContext->valid == agFALSE)
21749    {
21750      TI_DBG1(("satAddSATAIDDevCB: portcontext is invalid\n"));
21751      TI_DBG1(("satAddSATAIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
21752      satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21753
21754      satFreeIntIoResource( tiRoot,
21755                            satDevData,
21756                            satIntIo);
21757      /* clean up TD layer's IORequestBody */
21758      ostiFreeMemory(
21759                     tiRoot,
21760                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21761                     sizeof(tdIORequestBody_t)
21762                     );
21763      /* no notification to OS layer */
21764      return;
21765    }
21766  }
21767  else
21768  {
21769    TI_DBG1(("satAddSATAIDDevCB: onePortContext is NULL!!!\n"));
21770    return;
21771  }
21772  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21773  {
21774    TI_DBG1(("satAddSATAIDDevCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21775    if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21776    {
21777      satDevData->satPendingNONNCQIO--;
21778      satDevData->satPendingIO--;
21779      retry_status = sataLLIOStart(tiRoot,
21780                                   &satIntIo->satIntTiIORequest,
21781                                   &(NewOneDeviceData->tiDeviceHandle),
21782                                   satIOContext->tiScsiXchg,
21783                                   satIOContext);
21784      if (retry_status != tiSuccess)
21785      {
21786        /* simply give up */
21787        satDevData->ID_Retries = 0;
21788        satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21789        return;
21790      }
21791      satDevData->ID_Retries++;
21792      tdIORequestBody->ioCompleted = agFALSE;
21793      tdIORequestBody->ioStarted = agTRUE;
21794      return;
21795    }
21796    else
21797    {
21798      if (tdsaAllShared->ResetInDiscovery == 0)
21799      {
21800        satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21801      }
21802      else /* ResetInDiscovery in on */
21803      {
21804        /* RESET only one after ID retries */
21805        if (satDevData->NumOfIDRetries <= 0)
21806        {
21807          satDevData->NumOfIDRetries++;
21808          satDevData->ID_Retries = 0;
21809          satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21810          /* send link reset */
21811          saLocalPhyControl(agRoot,
21812                            agContext,
21813                            tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21814                            PhyID,
21815                            AGSA_PHY_HARD_RESET,
21816                            agNULL);
21817        }
21818        else
21819        {
21820          satDevData->ID_Retries = 0;
21821          satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21822        }
21823      }
21824      return;
21825    }
21826  }
21827  if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21828      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21829      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21830      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21831      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21832      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21833      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21834      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21835      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21836      )
21837  {
21838    TI_DBG1(("satAddSATAIDDevCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21839    if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21840    {
21841      satDevData->satPendingNONNCQIO--;
21842      satDevData->satPendingIO--;
21843      retry_status = sataLLIOStart(tiRoot,
21844                                   &satIntIo->satIntTiIORequest,
21845                                   &(NewOneDeviceData->tiDeviceHandle),
21846                                   satIOContext->tiScsiXchg,
21847                                   satIOContext);
21848      if (retry_status != tiSuccess)
21849      {
21850        /* simply give up */
21851        satDevData->ID_Retries = 0;
21852        satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21853        return;
21854      }
21855      satDevData->ID_Retries++;
21856      tdIORequestBody->ioCompleted = agFALSE;
21857      tdIORequestBody->ioStarted = agTRUE;
21858      return;
21859    }
21860    else
21861    {
21862      if (tdsaAllShared->ResetInDiscovery == 0)
21863      {
21864        satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21865      }
21866      else /* ResetInDiscovery in on */
21867      {
21868        /* RESET only one after ID retries */
21869        if (satDevData->NumOfIDRetries <= 0)
21870        {
21871          satDevData->NumOfIDRetries++;
21872          satDevData->ID_Retries = 0;
21873          satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21874          /* send link reset */
21875          saLocalPhyControl(agRoot,
21876                            agContext,
21877                            tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21878                            PhyID,
21879                            AGSA_PHY_HARD_RESET,
21880                            agNULL);
21881        }
21882        else
21883        {
21884          satDevData->ID_Retries = 0;
21885          satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21886        }
21887      }
21888      return;
21889    }
21890  }
21891
21892  if ( agIOStatus != OSSA_IO_SUCCESS ||
21893      (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
21894    )
21895  {
21896    if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21897    {
21898      satIOContext->pSatDevData->satPendingNONNCQIO--;
21899      satIOContext->pSatDevData->satPendingIO--;
21900      retry_status = sataLLIOStart(tiRoot,
21901                                   &satIntIo->satIntTiIORequest,
21902                                   &(NewOneDeviceData->tiDeviceHandle),
21903                                   satIOContext->tiScsiXchg,
21904                                   satIOContext);
21905      if (retry_status != tiSuccess)
21906      {
21907        /* simply give up */
21908        satDevData->ID_Retries = 0;
21909        satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21910        return;
21911      }
21912      satDevData->ID_Retries++;
21913      tdIORequestBody->ioCompleted = agFALSE;
21914      tdIORequestBody->ioStarted = agTRUE;
21915      return;
21916    }
21917    else
21918    {
21919      if (tdsaAllShared->ResetInDiscovery == 0)
21920      {
21921        satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21922      }
21923      else /* ResetInDiscovery in on */
21924      {
21925        /* RESET only one after ID retries */
21926        if (satDevData->NumOfIDRetries <= 0)
21927        {
21928          satDevData->NumOfIDRetries++;
21929          satDevData->ID_Retries = 0;
21930          satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21931          /* send link reset */
21932          saLocalPhyControl(agRoot,
21933                            agContext,
21934                            tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21935                            PhyID,
21936                            AGSA_PHY_HARD_RESET,
21937                            agNULL);
21938        }
21939        else
21940        {
21941          satDevData->ID_Retries = 0;
21942          satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21943        }
21944      }
21945      return;
21946    }
21947  }
21948
21949  /* success */
21950  TI_DBG2(("satAddSATAIDDevCB: Success\n"));
21951  /* Convert to host endian */
21952  tmpptr = (bit16*)sglVirtualAddr;
21953  //tdhexdump("satAddSATAIDDevCB before", (bit8 *)sglVirtualAddr, sizeof(agsaSATAIdentifyData_t));
21954  for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
21955  {
21956   OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
21957   *tmpptr = tmpptr_tmp;
21958   tmpptr++;
21959    /*Print tmpptr_tmp here for debugging purpose*/
21960  }
21961
21962  pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
21963  //tdhexdump("satAddSATAIDDevCB after", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
21964
21965  TI_DBG5(("satAddSATAIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
21966  TI_DBG5(("satAddSATAIDDevCB: TD satIOContext %p \n", satIOContext));
21967  TI_DBG5(("satAddSATAIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
21968  TI_DBG5(("satAddSATAIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21969
21970
21971  /* compare idenitfy device data to the exiting list */
21972  DeviceListList = tdsaAllShared->MainDeviceList.flink;
21973  while (DeviceListList != &(tdsaAllShared->MainDeviceList))
21974  {
21975    oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
21976    TI_DBG1(("satAddSATAIDDevCB: LOOP oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
21977    //tdhexdump("satAddSATAIDDevCB LOOP", (bit8 *)&oneDeviceData->satDevData.satIdentifyData, sizeof(agsaSATAIdentifyData_t));
21978
21979    /* what is unique ID for sata device -> response of identify devicedata; not really
21980       Let's compare serial number, firmware version, model number
21981    */
21982    if ( oneDeviceData->DeviceType == TD_SATA_DEVICE &&
21983         (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.serialNumber,
21984                       pSATAIdData->serialNumber,
21985                       20) == 0) &&
21986         (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.firmwareVersion,
21987                       pSATAIdData->firmwareVersion,
21988                       8) == 0) &&
21989         (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.modelNumber,
21990                       pSATAIdData->modelNumber,
21991                       40) == 0)
21992       )
21993    {
21994      TI_DBG2(("satAddSATAIDDevCB: did %d\n", oneDeviceData->id));
21995      new_device = agFALSE;
21996      break;
21997    }
21998    DeviceListList = DeviceListList->flink;
21999  }
22000
22001  if (new_device == agFALSE)
22002  {
22003    TI_DBG2(("satAddSATAIDDevCB: old device data\n"));
22004    oneDeviceData->valid = agTRUE;
22005    oneDeviceData->valid2 = agTRUE;
22006    /* save data field from new device data */
22007    oneDeviceData->agRoot = agRoot;
22008    oneDeviceData->agDevHandle = NewOneDeviceData->agDevHandle;
22009    oneDeviceData->agDevHandle->osData = oneDeviceData; /* TD layer */
22010    oneDeviceData->tdPortContext = NewOneDeviceData->tdPortContext;
22011    oneDeviceData->phyID = NewOneDeviceData->phyID;
22012
22013    /*
22014      one SATA directly attached device per phy;
22015      Therefore, deregister then register
22016    */
22017    saDeregisterDeviceHandle(agRoot, agNULL, NewOneDeviceData->agDevHandle, 0);
22018
22019    if (oneDeviceData->registered == agFALSE)
22020    {
22021      TI_DBG2(("satAddSATAIDDevCB: re-registering old device data\n"));
22022      /* already has old information; just register it again */
22023      saRegisterNewDevice( /* satAddSATAIDDevCB */
22024                          agRoot,
22025                          &oneDeviceData->agContext,
22026                          tdsaRotateQnumber(tiRoot, oneDeviceData),
22027                          &oneDeviceData->agDeviceInfo,
22028                          oneDeviceData->tdPortContext->agPortContext,
22029                          0
22030                          );
22031    }
22032
22033//    tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
22034    /* put onedevicedata back to free list */
22035    osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22036    TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
22037    TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22038    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22039
22040    satFreeIntIoResource( tiRoot,
22041                          satDevData,
22042                          satIntIo);
22043
22044    if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22045    {
22046      /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22047      satNewIntIo = satAllocIntIoResource( tiRoot,
22048                                       tiOrgIORequest,
22049                                       satDevData,
22050                                       0,
22051                                       satNewIntIo);
22052
22053      if (satNewIntIo == agNULL)
22054      {
22055        TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22056          /* clean up TD layer's IORequestBody */
22057        ostiFreeMemory(
22058                     tiRoot,
22059                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22060                     sizeof(tdIORequestBody_t)
22061                     );
22062        return;
22063      } /* end memory allocation */
22064
22065      satNewIOContext = satPrepareNewIO(satNewIntIo,
22066                                        tiOrgIORequest,
22067                                        satDevData,
22068                                        agNULL,
22069                                        satOrgIOContext
22070                                        );
22071      /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22072      status = satSetFeatures(tiRoot,
22073                     &satNewIntIo->satIntTiIORequest,
22074                     satNewIOContext->ptiDeviceHandle,
22075                     &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22076                     satNewIOContext,
22077                     agFALSE);
22078      if (status != tiSuccess)
22079      {
22080           satFreeIntIoResource( tiRoot,
22081                        satDevData,
22082                        satIntIo);
22083           /* clean up TD layer's IORequestBody */
22084           ostiFreeMemory(
22085                     tiRoot,
22086                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22087                     sizeof(tdIORequestBody_t)
22088                     );
22089      }
22090    }
22091    else
22092    {
22093      /* clean up TD layer's IORequestBody */
22094      ostiFreeMemory(
22095                   tiRoot,
22096                   tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22097                   sizeof(tdIORequestBody_t)
22098                   );
22099      TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22100      /* notifying link up */
22101      ostiPortEvent(
22102                   tiRoot,
22103                   tiPortLinkUp,
22104                   tiSuccess,
22105                   (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22106                   );
22107
22108
22109    #ifdef INITIATOR_DRIVER
22110        /* triggers discovery */
22111        ostiPortEvent(
22112                  tiRoot,
22113                  tiPortDiscoveryReady,
22114                  tiSuccess,
22115                  (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22116                  );
22117    #endif
22118    }
22119    return;
22120  }
22121
22122  TI_DBG2(("satAddSATAIDDevCB: new device data\n"));
22123  /* copy ID Dev data to satDevData */
22124  satDevData->satIdentifyData = *pSATAIdData;
22125
22126
22127  satDevData->IDDeviceValid = agTRUE;
22128#ifdef TD_INTERNAL_DEBUG
22129  tdhexdump("satAddSATAIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
22130  tdhexdump("satAddSATAIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
22131#endif
22132
22133  /* set satDevData fields from IndentifyData */
22134  satSetDevInfo(satDevData,pSATAIdData);
22135  satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22136
22137  satFreeIntIoResource( tiRoot,
22138                        satDevData,
22139                        satIntIo);
22140
22141  if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22142  {
22143      /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22144      satNewIntIo = satAllocIntIoResource( tiRoot,
22145                                       tiOrgIORequest,
22146                                       satDevData,
22147                                       0,
22148                                       satNewIntIo);
22149
22150      if (satNewIntIo == agNULL)
22151      {
22152        TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22153          /* clean up TD layer's IORequestBody */
22154        ostiFreeMemory(
22155                     tiRoot,
22156                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22157                     sizeof(tdIORequestBody_t)
22158                     );
22159        return;
22160      } /* end memory allocation */
22161
22162      satNewIOContext = satPrepareNewIO(satNewIntIo,
22163                                        tiOrgIORequest,
22164                                        satDevData,
22165                                        agNULL,
22166                                        satOrgIOContext
22167                                        );
22168      /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22169      status = satSetFeatures(tiRoot,
22170                     &satNewIntIo->satIntTiIORequest,
22171                     satNewIOContext->ptiDeviceHandle,
22172                     &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22173                     satNewIOContext,
22174                     agFALSE);
22175      if (status != tiSuccess)
22176      {
22177           satFreeIntIoResource( tiRoot,
22178                        satDevData,
22179                        satIntIo);
22180           /* clean up TD layer's IORequestBody */
22181           ostiFreeMemory(
22182                     tiRoot,
22183                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22184                     sizeof(tdIORequestBody_t)
22185                     );
22186      }
22187
22188  }
22189  else
22190  {
22191       /* clean up TD layer's IORequestBody */
22192      ostiFreeMemory(
22193                     tiRoot,
22194                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22195                     sizeof(tdIORequestBody_t)
22196                     );
22197
22198      TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22199      /* notifying link up */
22200      ostiPortEvent (
22201                     tiRoot,
22202                     tiPortLinkUp,
22203                     tiSuccess,
22204                     (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22205                     );
22206    #ifdef INITIATOR_DRIVER
22207      /* triggers discovery */
22208      ostiPortEvent(
22209                    tiRoot,
22210                    tiPortDiscoveryReady,
22211                    tiSuccess,
22212                    (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22213                    );
22214    #endif
22215  }
22216
22217 TI_DBG2(("satAddSATAIDDevCB: end\n"));
22218 return;
22219
22220}
22221
22222/*****************************************************************************
22223*! \brief  satAddSATAIDDevCBReset
22224*
22225*   This routine cleans up IOs for failed Identify device data
22226*
22227*  \param   agRoot:           Handles for this instance of SAS/SATA hardware
22228*  \param   oneDeviceData:    Pointer to the device data.
22229*  \param   ioContext:        Pointer to satIOContext_t.
22230*  \param   tdIORequestBody:  Pointer to the request body
22231*  \param   flag:             Decrement pending io or not
22232*
22233*  \return: none
22234*
22235*****************************************************************************/
22236void satAddSATAIDDevCBReset(
22237                   agsaRoot_t        *agRoot,
22238                   tdsaDeviceData_t  *oneDeviceData,
22239                   satIOContext_t    *satIOContext,
22240                   tdIORequestBody_t *tdIORequestBody
22241                   )
22242{
22243  tdsaRootOsData_t   *osData = (tdsaRootOsData_t *)agRoot->osData;
22244  tiRoot_t           *tiRoot = (tiRoot_t *)osData->tiRoot;
22245  tdsaRoot_t         *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
22246  tdsaContext_t      *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22247  satInternalIo_t    *satIntIo;
22248  satDeviceData_t    *satDevData;
22249
22250  TI_DBG2(("satAddSATAIDDevCBReset: start\n"));
22251  satIntIo           = satIOContext->satIntIoContext;
22252  satDevData         = satIOContext->pSatDevData;
22253  satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22254
22255  satFreeIntIoResource( tiRoot,
22256                        satDevData,
22257                        satIntIo);
22258  /* clean up TD layer's IORequestBody */
22259  ostiFreeMemory(
22260                 tiRoot,
22261                 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22262                 sizeof(tdIORequestBody_t)
22263                );
22264  return;
22265}
22266
22267
22268/*****************************************************************************
22269*! \brief  satAddSATAIDDevCBCleanup
22270*
22271*   This routine cleans up IOs for failed Identify device data
22272*
22273*  \param   agRoot:           Handles for this instance of SAS/SATA hardware
22274*  \param   oneDeviceData:    Pointer to the device data.
22275*  \param   ioContext:        Pointer to satIOContext_t.
22276*  \param   tdIORequestBody:  Pointer to the request body
22277*
22278*  \return: none
22279*
22280*****************************************************************************/
22281void satAddSATAIDDevCBCleanup(
22282                   agsaRoot_t        *agRoot,
22283                   tdsaDeviceData_t  *oneDeviceData,
22284                   satIOContext_t    *satIOContext,
22285                   tdIORequestBody_t *tdIORequestBody
22286                   )
22287{
22288  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
22289  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
22290  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
22291  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22292  satInternalIo_t         *satIntIo;
22293  satDeviceData_t         *satDevData;
22294  bit8                    PhyID;
22295
22296  TI_DBG2(("satAddSATAIDDevCBCleanup: start\n"));
22297  satIntIo               = satIOContext->satIntIoContext;
22298  satDevData             = satIOContext->pSatDevData;
22299  PhyID                  = oneDeviceData->phyID;
22300  tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
22301  /* put onedevicedata back to free list */
22302  osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22303  TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
22304  TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22305
22306  satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22307
22308
22309  satFreeIntIoResource( tiRoot,
22310                        satDevData,
22311                        satIntIo);
22312
22313  /* clean up TD layer's IORequestBody */
22314  ostiFreeMemory(
22315                 tiRoot,
22316                 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22317                 sizeof(tdIORequestBody_t)
22318                );
22319
22320  /* notifying link up */
22321  ostiPortEvent (
22322                 tiRoot,
22323                 tiPortLinkUp,
22324                 tiSuccess,
22325                 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22326                );
22327#ifdef INITIATOR_DRIVER
22328  /* triggers discovery */
22329  ostiPortEvent(
22330                tiRoot,
22331                tiPortDiscoveryReady,
22332                tiSuccess,
22333                (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22334                );
22335#endif
22336
22337  return;
22338}
22339
22340/*****************************************************************************/
22341/*! \brief SAT implementation for tdsaDiscoveryStartIDDev.
22342 *
22343 *  This function sends identify device data to SATA device in discovery
22344 *
22345 *
22346 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
22347 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
22348 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
22349 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
22350 *  \param   oneDeviceData :   Pointer to the device data.
22351 *
22352 *  \return If command is started successfully
22353 *    - \e tiSuccess:     I/O request successfully initiated.
22354 *    - \e tiBusy:        No resources available, try again later.
22355 *    - \e tiIONoDevice:  Invalid device handle.
22356 *    - \e tiError:       Other errors.
22357 */
22358/*****************************************************************************/
22359GLOBAL bit32
22360tdsaDiscoveryStartIDDev(tiRoot_t                  *tiRoot,
22361                        tiIORequest_t             *tiIORequest, /* agNULL */
22362                        tiDeviceHandle_t          *tiDeviceHandle,
22363                        tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */
22364                        tdsaDeviceData_t          *oneDeviceData
22365                        )
22366{
22367  void                        *osMemHandle;
22368  tdIORequestBody_t           *tdIORequestBody;
22369  bit32                       PhysUpper32;
22370  bit32                       PhysLower32;
22371  bit32                       memAllocStatus;
22372  agsaIORequest_t             *agIORequest = agNULL; /* identify device data itself */
22373  satIOContext_t              *satIOContext = agNULL;
22374  bit32                       status;
22375
22376  /* allocate tdiorequestbody and call tdsaDiscoveryIntStartIDDev
22377  tdsaDiscoveryIntStartIDDev(tiRoot, agNULL, tiDeviceHandle, satIOContext);
22378
22379  */
22380
22381  TI_DBG3(("tdsaDiscoveryStartIDDev: start\n"));
22382  TI_DBG3(("tdsaDiscoveryStartIDDev: did %d\n", oneDeviceData->id));
22383
22384  /* allocation tdIORequestBody and pass it to satTM() */
22385  memAllocStatus = ostiAllocMemory(
22386                                   tiRoot,
22387                                   &osMemHandle,
22388                                   (void **)&tdIORequestBody,
22389                                   &PhysUpper32,
22390                                   &PhysLower32,
22391                                   8,
22392                                   sizeof(tdIORequestBody_t),
22393                                   agTRUE
22394                                   );
22395
22396  if (memAllocStatus != tiSuccess)
22397  {
22398    TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory failed... loc 1\n"));
22399    return tiError;
22400  }
22401  if (tdIORequestBody == agNULL)
22402  {
22403    TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory returned NULL tdIORequestBody loc 2\n"));
22404    return tiError;
22405  }
22406
22407  /* setup identify device data IO structure */
22408  tdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
22409  tdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
22410  tdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
22411
22412  /* initialize tiDevhandle */
22413  tdIORequestBody->tiDevHandle = &(oneDeviceData->tiDeviceHandle);
22414  tdIORequestBody->tiDevHandle->tdData = oneDeviceData;
22415
22416  /* initialize tiIORequest */
22417  tdIORequestBody->tiIORequest = agNULL;
22418
22419  /* initialize agIORequest */
22420  agIORequest = &(tdIORequestBody->agIORequest);
22421  agIORequest->osData = (void *) tdIORequestBody;
22422  agIORequest->sdkData = agNULL; /* SA takes care of this */
22423
22424  /* set up satIOContext */
22425  satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22426  satIOContext->pSatDevData   = &(oneDeviceData->satDevData);
22427  satIOContext->pFis          =
22428    &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22429
22430  satIOContext->tiRequestBody = tdIORequestBody;
22431  satIOContext->ptiDeviceHandle = &(oneDeviceData->tiDeviceHandle);
22432  satIOContext->tiScsiXchg = agNULL;
22433  satIOContext->satIntIoContext  = agNULL;
22434  satIOContext->satOrgIOContext  = agNULL;
22435  /* followings are used only for internal IO */
22436  satIOContext->currentLBA = 0;
22437  satIOContext->OrgTL = 0;
22438  satIOContext->satToBeAbortedIOContext = agNULL;
22439  satIOContext->NotifyOS = agFALSE;
22440
22441  /* saving port ID just in case of full discovery to full discovery transition */
22442  satIOContext->pid = oneDeviceData->tdPortContext->id;
22443  osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0x0, sizeof(agsaSATAIdentifyData_t));
22444  status = tdsaDiscoveryIntStartIDDev(tiRoot,
22445                                      tiIORequest, /* agNULL */
22446                                      tiDeviceHandle, /* &(oneDeviceData->tiDeviceHandle)*/
22447                                      agNULL,
22448                                      satIOContext
22449                                      );
22450  if (status != tiSuccess)
22451  {
22452    TI_DBG1(("tdsaDiscoveryStartIDDev: failed in sending %d\n", status));
22453    ostiFreeMemory(tiRoot, osMemHandle, sizeof(tdIORequestBody_t));
22454  }
22455  return status;
22456}
22457
22458/*****************************************************************************/
22459/*! \brief SAT implementation for tdsaDiscoveryIntStartIDDev.
22460 *
22461 *  This function sends identify device data to SATA device.
22462 *
22463 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
22464 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
22465 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
22466 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
22467 *  \param   satIOContext_t:   Pointer to the SAT IO Context
22468 *
22469 *  \return If command is started successfully
22470 *    - \e tiSuccess:     I/O request successfully initiated.
22471 *    - \e tiBusy:        No resources available, try again later.
22472 *    - \e tiIONoDevice:  Invalid device handle.
22473 *    - \e tiError:       Other errors.
22474 */
22475/*****************************************************************************/
22476GLOBAL bit32
22477tdsaDiscoveryIntStartIDDev(tiRoot_t                  *tiRoot,
22478                           tiIORequest_t             *tiIORequest, /* agNULL */
22479                           tiDeviceHandle_t          *tiDeviceHandle,
22480                           tiScsiInitiatorRequest_t  *tiScsiRequest, /* agNULL */
22481                           satIOContext_t            *satIOContext
22482                           )
22483{
22484  satInternalIo_t           *satIntIo = agNULL;
22485  satDeviceData_t           *satDevData = agNULL;
22486  tdIORequestBody_t         *tdIORequestBody;
22487  satIOContext_t            *satNewIOContext;
22488  bit32                     status;
22489
22490  TI_DBG3(("tdsaDiscoveryIntStartIDDev: start\n"));
22491
22492  satDevData = satIOContext->pSatDevData;
22493
22494  /* allocate identify device command */
22495  satIntIo = satAllocIntIoResource( tiRoot,
22496                                    tiIORequest,
22497                                    satDevData,
22498                                    sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
22499                                    satIntIo);
22500
22501  if (satIntIo == agNULL)
22502  {
22503    TI_DBG2(("tdsaDiscoveryIntStartIDDev: can't alloacate\n"));
22504
22505    return tiError;
22506  }
22507
22508  /* fill in fields */
22509  /* real ttttttthe one worked and the same; 5/21/07/ */
22510  satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
22511  tdIORequestBody = satIntIo->satIntRequestBody;
22512  satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22513
22514  satNewIOContext->pSatDevData   = satDevData;
22515  satNewIOContext->pFis          = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22516  satNewIOContext->pScsiCmnd     = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
22517  satNewIOContext->pSense        = &(tdIORequestBody->transport.SATA.sensePayload);
22518  satNewIOContext->pTiSenseData  = &(tdIORequestBody->transport.SATA.tiSenseData);
22519  satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
22520  satNewIOContext->interruptContext = tiInterruptContext;
22521  satNewIOContext->satIntIoContext  = satIntIo;
22522
22523  satNewIOContext->ptiDeviceHandle = agNULL;
22524  satNewIOContext->satOrgIOContext = satIOContext; /* changed */
22525
22526  /* this is valid only for TD layer generated (not triggered by OS at all) IO */
22527  satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
22528
22529
22530  TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS satIOContext %p \n", satIOContext));
22531  TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
22532  TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
22533  TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
22534
22535
22536
22537  TI_DBG3(("tdsaDiscoveryIntStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
22538
22539  status = tdsaDiscoverySendIDDev(tiRoot,
22540                                  &satIntIo->satIntTiIORequest, /* New tiIORequest */
22541                                  tiDeviceHandle,
22542                                  satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
22543                                  satNewIOContext);
22544
22545  if (status != tiSuccess)
22546  {
22547    TI_DBG1(("tdsaDiscoveryIntStartIDDev: failed in sending %d\n", status));
22548
22549    satFreeIntIoResource( tiRoot,
22550                          satDevData,
22551                          satIntIo);
22552
22553    return tiError;
22554  }
22555
22556
22557  TI_DBG6(("tdsaDiscoveryIntStartIDDev: end\n"));
22558
22559  return status;
22560}
22561
22562
22563/*****************************************************************************/
22564/*! \brief SAT implementation for tdsaDiscoverySendIDDev.
22565 *
22566 *  This function prepares identify device data FIS and sends it to SATA device.
22567 *
22568 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
22569 *  \param   tiIORequest:      Pointer to TISA I/O request context for this I/O.
22570 *  \param   tiDeviceHandle:   Pointer to TISA device handle for this I/O.
22571 *  \param   tiScsiRequest:    Pointer to TISA SCSI I/O request and SGL list.
22572 *  \param   satIOContext_t:   Pointer to the SAT IO Context
22573 *
22574 *  \return If command is started successfully
22575 *    - \e tiSuccess:     I/O request successfully initiated.
22576 *    - \e tiBusy:        No resources available, try again later.
22577 *    - \e tiIONoDevice:  Invalid device handle.
22578 *    - \e tiError:       Other errors.
22579 */
22580/*****************************************************************************/
22581GLOBAL bit32
22582tdsaDiscoverySendIDDev(tiRoot_t                  *tiRoot,
22583                       tiIORequest_t             *tiIORequest,
22584                       tiDeviceHandle_t          *tiDeviceHandle,
22585                       tiScsiInitiatorRequest_t  *tiScsiRequest,
22586                       satIOContext_t            *satIOContext
22587                       )
22588{
22589  bit32                     status;
22590  bit32                     agRequestType;
22591  satDeviceData_t           *pSatDevData;
22592  agsaFisRegHostToDevice_t  *fis;
22593#ifdef  TD_DEBUG_ENABLE
22594  tdIORequestBody_t         *tdIORequestBody;
22595  satInternalIo_t           *satIntIoContext;
22596#endif
22597
22598  pSatDevData   = satIOContext->pSatDevData;
22599  fis           = satIOContext->pFis;
22600  TI_DBG3(("tdsaDiscoverySendIDDev: start\n"));
22601#ifdef  TD_DEBUG_ENABLE
22602  satIntIoContext = satIOContext->satIntIoContext;
22603  tdIORequestBody = satIntIoContext->satIntRequestBody;
22604#endif
22605  TI_DBG5(("tdsaDiscoverySendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
22606
22607  fis->h.fisType        = 0x27;                   /* Reg host to device */
22608  fis->h.c_pmPort       = 0x80;                   /* C Bit is set */
22609  if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
22610      fis->h.command    = SAT_IDENTIFY_PACKET_DEVICE;  /* 0xA1 */
22611  else
22612      fis->h.command    = SAT_IDENTIFY_DEVICE;    /* 0xEC */
22613  fis->h.features       = 0;                      /* FIS reserve */
22614  fis->d.lbaLow         = 0;                      /* FIS LBA (7 :0 ) */
22615  fis->d.lbaMid         = 0;                      /* FIS LBA (15:8 ) */
22616  fis->d.lbaHigh        = 0;                      /* FIS LBA (23:16) */
22617  fis->d.device         = 0;                      /* FIS LBA mode  */
22618  fis->d.lbaLowExp      = 0;
22619  fis->d.lbaMidExp      = 0;
22620  fis->d.lbaHighExp     = 0;
22621  fis->d.featuresExp    = 0;
22622  fis->d.sectorCount    = 0;                      /* FIS sector count (7:0) */
22623  fis->d.sectorCountExp = 0;
22624  fis->d.reserved4      = 0;
22625  fis->d.control        = 0;                      /* FIS HOB bit clear */
22626  fis->d.reserved5      = 0;
22627
22628  agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
22629
22630  /* Initialize CB for SATA completion.
22631   */
22632  satIOContext->satCompleteCB = &tdsaDiscoveryStartIDDevCB;
22633
22634  /*
22635   * Prepare SGL and send FIS to LL layer.
22636   */
22637  satIOContext->reqType = agRequestType;       /* Save it */
22638
22639#ifdef TD_INTERNAL_DEBUG
22640  tdhexdump("tdsaDiscoverySendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
22641#ifdef  TD_DEBUG_ENABLE
22642  tdhexdump("tdsaDiscoverySendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
22643#endif
22644#endif
22645  status = sataLLIOStart( tiRoot,
22646                          tiIORequest,
22647                          tiDeviceHandle,
22648                          tiScsiRequest,
22649                          satIOContext);
22650  TI_DBG3(("tdsaDiscoverySendIDDev: end status %d\n", status));
22651  return status;
22652}
22653
22654
22655/*****************************************************************************
22656*! \brief  tdsaDiscoveryStartIDDevCB
22657*
22658*   This routine is a callback function for tdsaDiscoverySendIDDev()
22659*   Using Identify Device Data, this function finds whether devicedata is
22660*   new or old. If new, add it to the devicelist. This is done as a part
22661*   of discovery.
22662*
22663*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
22664*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
22665*  \param   agIOStatus:  Status of completed I/O.
22666*  \param   agFirstDword:Pointer to the four bytes of FIS.
22667*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
22668*                        length.
22669*  \param   agParam:     Additional info based on status.
22670*  \param   ioContext:   Pointer to satIOContext_t.
22671*
22672*  \return: none
22673*
22674*****************************************************************************/
22675void tdsaDiscoveryStartIDDevCB(
22676                               agsaRoot_t        *agRoot,
22677                               agsaIORequest_t   *agIORequest,
22678                                bit32             agIOStatus,
22679                                agsaFisHeader_t   *agFirstDword,
22680                                bit32             agIOInfoLen,
22681                                void              *agParam,
22682                                void              *ioContext
22683                                )
22684{
22685 /*
22686    In the process of SAT_IDENTIFY_DEVICE during discovery
22687  */
22688  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
22689  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
22690  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
22691  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22692  tdIORequestBody_t       *tdIORequestBody;
22693  tdIORequestBody_t       *tdOrgIORequestBody;
22694  satIOContext_t          *satIOContext;
22695  satIOContext_t          *satOrgIOContext;
22696  satIOContext_t          *satNewIOContext;
22697  satInternalIo_t         *satIntIo;
22698  satInternalIo_t         *satNewIntIo = agNULL;
22699  satDeviceData_t         *satDevData;
22700  tiIORequest_t           *tiOrgIORequest = agNULL;
22701
22702#ifdef  TD_DEBUG_ENABLE
22703  bit32                     ataStatus = 0;
22704  bit32                     ataError;
22705  agsaFisPioSetupHeader_t   *satPIOSetupHeader = agNULL;
22706#endif
22707  agsaSATAIdentifyData_t    *pSATAIdData;
22708  bit16                     *tmpptr, tmpptr_tmp;
22709  bit32                     x;
22710  tdsaDeviceData_t          *oneDeviceData = agNULL;
22711  void                      *sglVirtualAddr;
22712  tdsaPortContext_t         *onePortContext = agNULL;
22713  tiPortalContext_t         *tiPortalContext = agNULL;
22714  bit32                     retry_status;
22715
22716  TI_DBG3(("tdsaDiscoveryStartIDDevCB: start\n"));
22717
22718  tdIORequestBody        = (tdIORequestBody_t *)agIORequest->osData;
22719  satIOContext           = (satIOContext_t *) ioContext;
22720  satIntIo               = satIOContext->satIntIoContext;
22721  satDevData             = satIOContext->pSatDevData;
22722  oneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
22723  TI_DBG3(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22724  onePortContext = oneDeviceData->tdPortContext;
22725  if (onePortContext == agNULL)
22726  {
22727      TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL\n"));
22728      return;
22729  }
22730  tiPortalContext= onePortContext->tiPortalContext;
22731
22732  satDevData->IDDeviceValid = agFALSE;
22733
22734  if (satIntIo == agNULL)
22735  {
22736    TI_DBG1(("tdsaDiscoveryStartIDDevCB: External, OS generated\n"));
22737    TI_DBG1(("tdsaDiscoveryStartIDDevCB: Not possible case\n"));
22738    satOrgIOContext      = satIOContext;
22739    tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22740
22741    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22742
22743    satFreeIntIoResource( tiRoot,
22744                          satDevData,
22745                          satIntIo);
22746
22747    /* clean up TD layer's IORequestBody */
22748    ostiFreeMemory(
22749                   tiRoot,
22750                   tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22751                   sizeof(tdIORequestBody_t)
22752                   );
22753    return;
22754  }
22755  else
22756  {
22757    TI_DBG3(("tdsaDiscoveryStartIDDevCB: Internal, TD generated\n"));
22758    satOrgIOContext        = satIOContext->satOrgIOContext;
22759    if (satOrgIOContext == agNULL)
22760    {
22761      TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NULL\n"));
22762      return;
22763    }
22764    else
22765    {
22766      TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NOT NULL\n"));
22767      tdOrgIORequestBody     = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22768      sglVirtualAddr         = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
22769    }
22770  }
22771
22772  tiOrgIORequest           = tdIORequestBody->tiIORequest;
22773  tdIORequestBody->ioCompleted = agTRUE;
22774  tdIORequestBody->ioStarted = agFALSE;
22775
22776  TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22777
22778  /* protect against double completion for old port */
22779  if (satOrgIOContext->pid != oneDeviceData->tdPortContext->id)
22780  {
22781    TI_DBG3(("tdsaDiscoveryStartIDDevCB: incorrect pid\n"));
22782    TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22783    TI_DBG3(("tdsaDiscoveryStartIDDevCB: tiPortalContext pid %d\n", oneDeviceData->tdPortContext->id));
22784
22785    satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22786
22787    satFreeIntIoResource( tiRoot,
22788                          satDevData,
22789                          satIntIo);
22790
22791    /* clean up TD layer's IORequestBody */
22792    ostiFreeMemory(
22793                   tiRoot,
22794                   tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22795                   sizeof(tdIORequestBody_t)
22796                   );
22797
22798    return;
22799  }
22800
22801  /* completion after portcontext is invalidated */
22802  if (onePortContext != agNULL)
22803  {
22804    if (onePortContext->valid == agFALSE)
22805    {
22806      TI_DBG1(("tdsaDiscoveryStartIDDevCB: portcontext is invalid\n"));
22807      TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
22808      satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22809
22810      satFreeIntIoResource( tiRoot,
22811                            satDevData,
22812                            satIntIo);
22813
22814      /* clean up TD layer's IORequestBody */
22815      ostiFreeMemory(
22816                     tiRoot,
22817                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22818                     sizeof(tdIORequestBody_t)
22819                     );
22820
22821      /* no notification to OS layer */
22822      return;
22823    }
22824  }
22825
22826  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
22827  {
22828    TI_DBG1(("tdsaDiscoveryStartIDDevCB: agFirstDword is NULL when error, status %d\n", agIOStatus));
22829    TI_DBG1(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22830
22831    if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22832    {
22833      satIOContext->pSatDevData->satPendingNONNCQIO--;
22834      satIOContext->pSatDevData->satPendingIO--;
22835      retry_status = sataLLIOStart(tiRoot,
22836                                   &satIntIo->satIntTiIORequest,
22837           &(oneDeviceData->tiDeviceHandle),
22838           satIOContext->tiScsiXchg,
22839           satIOContext);
22840      if (retry_status != tiSuccess)
22841      {
22842        /* simply give up */
22843        satDevData->ID_Retries = 0;
22844        satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22845
22846        satFreeIntIoResource( tiRoot,
22847                              satDevData,
22848                              satIntIo);
22849
22850        /* clean up TD layer's IORequestBody */
22851        ostiFreeMemory(
22852                       tiRoot,
22853                       tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22854                       sizeof(tdIORequestBody_t)
22855                       );
22856        return;
22857      }
22858      satDevData->ID_Retries++;
22859      tdIORequestBody->ioCompleted = agFALSE;
22860      tdIORequestBody->ioStarted = agTRUE;
22861      return;
22862    }
22863    else
22864    {
22865      satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22866      satFreeIntIoResource( tiRoot,
22867                            satDevData,
22868                            satIntIo);
22869
22870      /* clean up TD layer's IORequestBody */
22871      ostiFreeMemory(
22872                     tiRoot,
22873                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22874                     sizeof(tdIORequestBody_t)
22875                     );
22876      if (tdsaAllShared->ResetInDiscovery != 0)
22877      {
22878        /* ResetInDiscovery in on */
22879        if (satDevData->NumOfIDRetries <= 0)
22880        {
22881          satDevData->NumOfIDRetries++;
22882          satDevData->ID_Retries = 0;
22883          /* send link reset */
22884          tdsaPhyControlSend(tiRoot,
22885                             oneDeviceData,
22886                             SMP_PHY_CONTROL_HARD_RESET,
22887                             agNULL,
22888                             tdsaRotateQnumber(tiRoot, oneDeviceData)
22889                            );
22890        }
22891      }
22892      return;
22893    }
22894  }
22895
22896  if (agIOStatus == OSSA_IO_ABORTED ||
22897      agIOStatus == OSSA_IO_UNDERFLOW ||
22898      agIOStatus == OSSA_IO_XFER_ERROR_BREAK ||
22899      agIOStatus == OSSA_IO_XFER_ERROR_PHY_NOT_READY ||
22900      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
22901      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
22902      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
22903      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
22904      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
22905      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY ||
22906      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
22907      agIOStatus == OSSA_IO_XFER_ERROR_NAK_RECEIVED ||
22908      agIOStatus == OSSA_IO_XFER_ERROR_DMA ||
22909      agIOStatus == OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT ||
22910      agIOStatus == OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE ||
22911      agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT ||
22912      agIOStatus == OSSA_IO_NO_DEVICE ||
22913      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
22914      agIOStatus == OSSA_IO_PORT_IN_RESET ||
22915      agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
22916      agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
22917      agIOStatus == OSSA_IO_DS_IN_ERROR
22918      )
22919  {
22920    TI_DBG1(("tdsaDiscoveryStartIDDevCB: OSSA_IO_OPEN_CNX_ERROR 0x%x\n", agIOStatus));
22921    if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22922    {
22923      satIOContext->pSatDevData->satPendingNONNCQIO--;
22924      satIOContext->pSatDevData->satPendingIO--;
22925      retry_status = sataLLIOStart(tiRoot,
22926                                   &satIntIo->satIntTiIORequest,
22927           &(oneDeviceData->tiDeviceHandle),
22928           satIOContext->tiScsiXchg,
22929           satIOContext);
22930      if (retry_status != tiSuccess)
22931      {
22932        /* simply give up */
22933        satDevData->ID_Retries = 0;
22934        satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22935
22936        satFreeIntIoResource( tiRoot,
22937                              satDevData,
22938                              satIntIo);
22939
22940        /* clean up TD layer's IORequestBody */
22941        ostiFreeMemory(
22942                       tiRoot,
22943                       tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22944                       sizeof(tdIORequestBody_t)
22945                       );
22946        return;
22947      }
22948      satDevData->ID_Retries++;
22949      tdIORequestBody->ioCompleted = agFALSE;
22950      tdIORequestBody->ioStarted = agTRUE;
22951      return;
22952    }
22953    else
22954    {
22955      satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22956      satFreeIntIoResource( tiRoot,
22957                            satDevData,
22958                            satIntIo);
22959
22960      /* clean up TD layer's IORequestBody */
22961      ostiFreeMemory(
22962                     tiRoot,
22963                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22964                     sizeof(tdIORequestBody_t)
22965                     );
22966      if (tdsaAllShared->ResetInDiscovery != 0)
22967      {
22968        /* ResetInDiscovery in on */
22969        if (satDevData->NumOfIDRetries <= 0)
22970        {
22971          satDevData->NumOfIDRetries++;
22972          satDevData->ID_Retries = 0;
22973          /* send link reset */
22974          tdsaPhyControlSend(tiRoot,
22975                             oneDeviceData,
22976                             SMP_PHY_CONTROL_HARD_RESET,
22977                             agNULL,
22978                             tdsaRotateQnumber(tiRoot, oneDeviceData)
22979                            );
22980        }
22981      }
22982      return;
22983    }
22984  }
22985
22986  if ( agIOStatus != OSSA_IO_SUCCESS ||
22987       (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
22988     )
22989  {
22990#ifdef  TD_DEBUG_ENABLE
22991    /* only agsaFisPioSetup_t is expected */
22992    satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
22993    ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
22994    ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
22995#endif
22996    TI_DBG1(("tdsaDiscoveryStartIDDevCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
22997
22998    if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22999    {
23000      satIOContext->pSatDevData->satPendingNONNCQIO--;
23001      satIOContext->pSatDevData->satPendingIO--;
23002      retry_status = sataLLIOStart(tiRoot,
23003                                   &satIntIo->satIntTiIORequest,
23004           &(oneDeviceData->tiDeviceHandle),
23005           satIOContext->tiScsiXchg,
23006           satIOContext);
23007      if (retry_status != tiSuccess)
23008      {
23009        /* simply give up */
23010        satDevData->ID_Retries = 0;
23011        satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23012
23013        satFreeIntIoResource( tiRoot,
23014                              satDevData,
23015                              satIntIo);
23016
23017        /* clean up TD layer's IORequestBody */
23018        ostiFreeMemory(
23019                       tiRoot,
23020                       tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23021                       sizeof(tdIORequestBody_t)
23022                       );
23023        return;
23024      }
23025      satDevData->ID_Retries++;
23026      tdIORequestBody->ioCompleted = agFALSE;
23027      tdIORequestBody->ioStarted = agTRUE;
23028      return;
23029    }
23030    else
23031    {
23032      satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23033      satFreeIntIoResource( tiRoot,
23034                            satDevData,
23035                            satIntIo);
23036
23037      /* clean up TD layer's IORequestBody */
23038      ostiFreeMemory(
23039                     tiRoot,
23040                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23041                     sizeof(tdIORequestBody_t)
23042                     );
23043      if (tdsaAllShared->ResetInDiscovery != 0)
23044      {
23045        /* ResetInDiscovery in on */
23046        if (satDevData->NumOfIDRetries <= 0)
23047        {
23048          satDevData->NumOfIDRetries++;
23049          satDevData->ID_Retries = 0;
23050          /* send link reset */
23051          tdsaPhyControlSend(tiRoot,
23052                             oneDeviceData,
23053                             SMP_PHY_CONTROL_HARD_RESET,
23054                             agNULL,
23055                             tdsaRotateQnumber(tiRoot, oneDeviceData)
23056                            );
23057        }
23058      }
23059      return;
23060    }
23061  }
23062
23063
23064  /* success */
23065  TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success\n"));
23066  TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success did %d\n", oneDeviceData->id));
23067
23068  /* Convert to host endian */
23069  tmpptr = (bit16*)sglVirtualAddr;
23070  for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
23071  {
23072    OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
23073    *tmpptr = tmpptr_tmp;
23074    tmpptr++;
23075  }
23076
23077  pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
23078  //tdhexdump("satAddSATAIDDevCB before", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23079
23080  TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
23081  TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD satIOContext %p \n", satIOContext));
23082  TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
23083  TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
23084
23085
23086   /* copy ID Dev data to satDevData */
23087  satDevData->satIdentifyData = *pSATAIdData;
23088  satDevData->IDDeviceValid = agTRUE;
23089
23090#ifdef TD_INTERNAL_DEBUG
23091  tdhexdump("tdsaDiscoveryStartIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23092  tdhexdump("tdsaDiscoveryStartIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
23093#endif
23094
23095  /* set satDevData fields from IndentifyData */
23096  satSetDevInfo(satDevData,pSATAIdData);
23097  satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23098
23099  satFreeIntIoResource( tiRoot,
23100                        satDevData,
23101                        satIntIo);
23102
23103  if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
23104  {
23105      /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
23106      satNewIntIo = satAllocIntIoResource( tiRoot,
23107                                       tiOrgIORequest,
23108                                       satDevData,
23109                                       0,
23110                                       satNewIntIo);
23111
23112      if (satNewIntIo == agNULL)
23113      {
23114        TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
23115          /* clean up TD layer's IORequestBody */
23116        ostiFreeMemory(
23117                     tiRoot,
23118                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23119                     sizeof(tdIORequestBody_t)
23120                     );
23121        return;
23122      } /* end memory allocation */
23123
23124      satNewIOContext = satPrepareNewIO(satNewIntIo,
23125                                        tiOrgIORequest,
23126                                        satDevData,
23127                                        agNULL,
23128                                        satOrgIOContext
23129                                        );
23130      /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
23131      retry_status = satSetFeatures(tiRoot,
23132                                 &satNewIntIo->satIntTiIORequest,
23133                                 satNewIOContext->ptiDeviceHandle,
23134                                 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
23135                                 satNewIOContext,
23136                                 agFALSE);
23137      if (retry_status != tiSuccess)
23138      {
23139          satFreeIntIoResource(tiRoot, satDevData, satIntIo);
23140          /* clean up TD layer's IORequestBody */
23141          ostiFreeMemory(
23142                 tiRoot,
23143                 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23144                 sizeof(tdIORequestBody_t)
23145                 );
23146      }
23147  }
23148  else
23149  {
23150      /* clean up TD layer's IORequestBody */
23151      ostiFreeMemory(
23152                     tiRoot,
23153                     tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23154                     sizeof(tdIORequestBody_t)
23155                     );
23156      if (onePortContext != agNULL)
23157      {
23158        if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED)
23159        {
23160          TI_DBG1(("tdsaDiscoveryStartIDDevCB: ID completed after discovery is done; tiDeviceArrival\n"));
23161          /* in case registration is finished after discovery is finished */
23162          ostiInitiatorEvent(
23163                             tiRoot,
23164                             tiPortalContext,
23165                             agNULL,
23166                             tiIntrEventTypeDeviceChange,
23167                             tiDeviceArrival,
23168                             agNULL
23169                             );
23170        }
23171      }
23172      else
23173      {
23174        TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL, wrong\n"));
23175      }
23176  }
23177  TI_DBG3(("tdsaDiscoveryStartIDDevCB: end\n"));
23178  return;
23179}
23180/*****************************************************************************
23181*! \brief  satAbort
23182*
23183*   This routine does local abort for outstanding FIS.
23184*
23185*  \param   agRoot:         Handles for this instance of SAS/SATA hardware
23186*  \param   satIOContext:   Pointer to satIOContext_t.
23187*
23188*  \return: none
23189*
23190*****************************************************************************/
23191GLOBAL void satAbort(agsaRoot_t        *agRoot,
23192                     satIOContext_t    *satIOContext)
23193{
23194  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
23195  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
23196  tdIORequestBody_t       *tdIORequestBody; /* io to be aborted */
23197  tdIORequestBody_t       *tdAbortIORequestBody; /* abort io itself */
23198  agsaIORequest_t         *agToBeAbortedIORequest; /* io to be aborted */
23199  agsaIORequest_t         *agAbortIORequest;  /* abort io itself */
23200  bit32                   PhysUpper32;
23201  bit32                   PhysLower32;
23202  bit32                   memAllocStatus;
23203  void                    *osMemHandle;
23204
23205  TI_DBG1(("satAbort: start\n"));
23206
23207  if (satIOContext == agNULL)
23208  {
23209    TI_DBG1(("satAbort: satIOContext is NULL, wrong\n"));
23210    return;
23211  }
23212  tdIORequestBody = (tdIORequestBody_t *)satIOContext->tiRequestBody;
23213  agToBeAbortedIORequest = (agsaIORequest_t *)&(tdIORequestBody->agIORequest);
23214  /* allocating agIORequest for abort itself */
23215  memAllocStatus = ostiAllocMemory(
23216                                   tiRoot,
23217                                   &osMemHandle,
23218                                   (void **)&tdAbortIORequestBody,
23219                                   &PhysUpper32,
23220                                   &PhysLower32,
23221                                   8,
23222                                   sizeof(tdIORequestBody_t),
23223                                   agTRUE
23224                                   );
23225
23226  if (memAllocStatus != tiSuccess)
23227  {
23228    /* let os process IO */
23229    TI_DBG1(("satAbort: ostiAllocMemory failed...\n"));
23230    return;
23231  }
23232
23233  if (tdAbortIORequestBody == agNULL)
23234  {
23235    /* let os process IO */
23236    TI_DBG1(("satAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
23237    return;
23238  }
23239  /* setup task management structure */
23240  tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
23241  tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
23242
23243  /* initialize agIORequest */
23244  agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
23245  agAbortIORequest->osData = (void *) tdAbortIORequestBody;
23246  agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
23247
23248
23249  /*
23250   * Issue abort
23251   */
23252  saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, agNULL );
23253
23254
23255  TI_DBG1(("satAbort: end\n"));
23256  return;
23257}
23258
23259/*****************************************************************************
23260 *! \brief  satSATADeviceReset
23261 *
23262 *   This routine is called to reset all phys of port which a device belongs to
23263 *
23264 *  \param   tiRoot:           Pointer to TISA initiator driver/port instance.
23265 *  \param   oneDeviceData:    Pointer to the device data.
23266 *  \param   flag:             reset flag
23267 *
23268 *  \return:
23269 *
23270 *  none
23271 *
23272 *****************************************************************************/
23273osGLOBAL void
23274satSATADeviceReset(                                                                                                  tiRoot_t            *tiRoot,
23275                tdsaDeviceData_t    *oneDeviceData,
23276                bit32               flag)
23277{
23278  agsaRoot_t              *agRoot;
23279  tdsaPortContext_t       *onePortContext;
23280  bit32                   i;
23281
23282  TI_DBG1(("satSATADeviceReset: start\n"));
23283  agRoot         = oneDeviceData->agRoot;
23284  onePortContext = oneDeviceData->tdPortContext;
23285
23286  if (agRoot == agNULL)
23287  {
23288    TI_DBG1(("satSATADeviceReset: Error!!! agRoot is NULL\n"));
23289    return;
23290  }
23291  if (onePortContext == agNULL)
23292  {
23293    TI_DBG1(("satSATADeviceReset: Error!!! onePortContext is NULL\n"));
23294    return;
23295  }
23296
23297   for(i=0;i<TD_MAX_NUM_PHYS;i++)
23298  {
23299    if (onePortContext->PhyIDList[i] == agTRUE)
23300    {
23301      saLocalPhyControl(agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, flag, agNULL);
23302    }
23303  }
23304
23305  return;
23306}
23307
23308#endif  /* #ifdef SATA_ENABLE */
23309