/*******************************************************************************
*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved. 
*
*Redistribution and use in source and binary forms, with or without modification, are permitted provided 
*that the following conditions are met: 
*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
*following disclaimer. 
*2. Redistributions in binary form must reproduce the above copyright notice, 
*this list of conditions and the following disclaimer in the documentation and/or other materials provided
*with the distribution. 
*
*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED 
*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE

********************************************************************************/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <dev/pms/config.h>

#include <dev/pms/freebsd/driver/common/osenv.h>
#include <dev/pms/freebsd/driver/common/ostypes.h>
#include <dev/pms/freebsd/driver/common/osdebug.h>

#include <dev/pms/RefTisa/tisa/api/titypes.h>

#include <dev/pms/RefTisa/sallsdk/api/sa.h>
#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>

#include <dev/pms/RefTisa/sat/api/sm.h>
#include <dev/pms/RefTisa/sat/api/smapi.h>
#include <dev/pms/RefTisa/sat/api/tdsmapi.h>

#include <dev/pms/RefTisa/sat/src/smdefs.h>
#include <dev/pms/RefTisa/sat/src/smproto.h>
#include <dev/pms/RefTisa/sat/src/smtypes.h>

extern smRoot_t *gsmRoot;

/******************************** completion ***********************************************************/

FORCEINLINE void
smllSATACompleted(
                  agsaRoot_t        *agRoot,
                  agsaIORequest_t   *agIORequest,
                  bit32             agIOStatus,
                  void              *agFirstDword,
                  bit32             agIOInfoLen,
                  void              *agParam
                 )
{
  smRoot_t             *smRoot = agNULL;
//  smIntRoot_t          *smIntRoot = agNULL;
//  smIntContext_t       *smAllShared = agNULL;
  smIORequestBody_t    *smIORequestBody;
  smSatIOContext_t       *satIOContext;
  smDeviceData_t       *pSatDevData;
  smDeviceHandle_t     *smDeviceHandle = agNULL;
  smDeviceData_t       *oneDeviceData = agNULL;

  SM_DBG2(("smllSATACompleted: start\n"));

  if (agIORequest == agNULL)
  {
    SM_DBG1(("smllSATACompleted: agIORequest is NULL!!!\n"));
    return;
  }

  smIORequestBody = (smIORequestBody_t *)agIORequest->osData;

  if (smIORequestBody == agNULL)
  {
    SM_DBG1(("smllSATACompleted: smIORequestBody is NULL!!!\n"));
    return;
  }

  /* for debugging */
  if (smIORequestBody->ioCompleted == agTRUE)
  {
    smDeviceHandle = smIORequestBody->smDevHandle;
    if (smDeviceHandle == agNULL)
    {
      SM_DBG1(("smllSATACompleted: smDeviceHandle is NULL!!!\n"));
      return;
    }
    oneDeviceData  = (smDeviceData_t *)smDeviceHandle->smData;
    SM_DBG1(("smllSATACompleted: Error!!!!!! double completion!!!, ID %d!!!\n", smIORequestBody->id));
    if (oneDeviceData == agNULL)
    {
      SM_DBG1(("smllSATACompleted: oneDeviceData is NULL!!!\n"));
      return;
    }
    SM_DBG1(("smllSATACompleted: did %d!!!\n", oneDeviceData->id));
    return;
  }

  smIORequestBody->ioCompleted = agTRUE;
  satIOContext    = &(smIORequestBody->transport.SATA.satIOContext);

  if (satIOContext == agNULL)
  {
    SM_DBG1(("smllSATACompleted: satIOContext is NULL!!!\n"));
    return;
  }

  pSatDevData     = satIOContext->pSatDevData;

  if (pSatDevData == agNULL)
  {
    SM_DBG1(("smllSATACompleted: pSatDevData is NULL loc 1, wrong!!!\n"));
    if (satIOContext->satIntIoContext == agNULL)
    {
      SM_DBG1(("smllSATACompleted: external command!!!\n"));
    }
    else
    {
      SM_DBG1(("smllSATACompleted: internal command!!!\n"));
    }
    return;
  }

  smDeviceHandle = smIORequestBody->smDevHandle;

  if (smDeviceHandle == agNULL)
  {
    SM_DBG1(("smllSATACompleted: smDeviceHandle is NULL!!!!\n"));
    return;
  }

  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;

  if (oneDeviceData != pSatDevData)
  {
    SM_DBG1(("smllSATACompleted: diff device handle!!!\n"));
    if (satIOContext->satIntIoContext == agNULL)
    {
      SM_DBG1(("smllSATACompleted: external command!!!\n"));
    }
    else
    {
      SM_DBG1(("smllSATACompleted: internal command!!!\n"));
    }
    return;
  }

  if (oneDeviceData == agNULL)
  {
    SM_DBG1(("smllSATACompleted: oneDeviceData is NULL!!!!\n"));
    if (satIOContext->satIntIoContext == agNULL)
    {
      SM_DBG1(("smllSATACompleted: external command!!!\n"));
    }
    else
    {
      SM_DBG1(("smllSATACompleted: internal command!!!\n"));
    }
    return;
  }

  smRoot = oneDeviceData->smRoot;

  /* release tag value for SATA */
  if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
       (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
  {
    smsatTagRelease(smRoot, pSatDevData, satIOContext->sataTag);
    SM_DBG3(("smllSATACompleted: ncq tag 0x%x\n",satIOContext->sataTag));
  }

  /* just for debugging */
  if (agIOStatus == OSSA_IO_DS_NON_OPERATIONAL)
  {
    SM_DBG1(("smllSATACompleted: agIOStatus is OSSA_IO_DS_NON_OPERATIONAL!!!\n"));
  }
  if (agIOStatus == OSSA_IO_DS_IN_RECOVERY)
  {
    SM_DBG1(("smllSATACompleted: agIOStatus is OSSA_IO_DS_IN_RECOVERY!!!\n"));
  }
  if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS)
  {
    SM_DBG1(("smllSATACompleted: agIOStatus is OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS!!!\n"));
  }

  satIOContext->satCompleteCB( agRoot,
                               agIORequest,
                               agIOStatus,
                               agFirstDword,
                               agIOInfoLen,
                               agParam,
                               satIOContext);



  return;
}
/*****************************************************************************
*! \brief  smsatPacketCB
*
*   This routine is a callback function called from smllSATACompleted().
*   This CB routine deals with normal Packet command I/O SATA request.
*
*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
*  \param   agIOStatus:  Status of completed I/O.
*  \param   agFirstDword:Pointer to the four bytes of FIS.
*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
*                        length.
*  \param   agParam:     Additional info based on status.
*  \param   ioContext:   Pointer to smSatIOContext_t.
*
*  \return: none
*
*****************************************************************************/

osGLOBAL void
smsatPacketCB(
   agsaRoot_t        *agRoot,
   agsaIORequest_t   *agIORequest,
   bit32             agIOStatus,
   agsaFisHeader_t   *agFirstDword,
   bit32             agIOInfoLen,
   void              *agParam,
   void              *ioContext
   )
{
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL;
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatIOContext_t         *satNewIOContext;
  smSatInternalIo_t        *satIntIo;
  smSatInternalIo_t        *satNewIntIo = agNULL;
  smDeviceData_t           *oneDeviceData;
  bit32                     interruptContext;
  smScsiRspSense_t         *pSense;
  smIniScsiCmnd_t          *scsiCmnd;
  smIORequest_t            *smOrgIORequest;
//  bit32                     ataStatus = 0;
//  bit32                     ataError;

  bit32                     status = SM_RC_SUCCESS;
//  agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
//  bit32                     dataLength;
  bit8                      bSenseKey = 0;
  bit16                     bSenseCodeInfo = 0;

  SM_DBG3(("smsatPacketCB: start\n"));
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  if (satIOContext == agNULL)
  {
    SM_DBG1(("smsatPacketCB: satIOContext is NULL\n"));
    return;
  }
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  interruptContext       = satIOContext->interruptContext;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG5(("smsatPacketCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satIOContext->pSense;
    scsiCmnd        = satIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG5(("smsatPacketCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    pSense        = satOrgIOContext->pSense;
    scsiCmnd      = satOrgIOContext->pScsiCmnd;
  }

  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted   = agFALSE;

  /* interal structure free */
  smsatFreeIntIoResource( smRoot, oneDeviceData, satIntIo);
  if( agIOStatus == OSSA_IO_SUCCESS && agIOInfoLen == 0 && agFirstDword == agNULL)
  {
    SM_DBG3(("smsatPacketCB: First, agIOStatus == OSSA_IO_SUCCESS, agFirstDword == agNULL, agIOInfoLen = %d\n", agIOInfoLen));
    tdsmIOCompletedCB(smRoot,
                      smOrgIORequest,
                      smIOSuccess,
                      SCSI_STAT_GOOD,
                      agNULL,
                      interruptContext);
  }
  else if (agIOStatus == OSSA_IO_SUCCESS &&  !(agIOInfoLen == 0 && agFirstDword == agNULL))
  {
      SM_DBG2(("smsatPacketCB: Second, agIOStatus == OSSA_IO_SUCCESS , agFirstDword %p agIOInfoLen = %d\n", agFirstDword, agIOInfoLen));
      /*The SCSI command status is error, need to send REQUEST SENSE for getting more sense information*/
      satNewIntIo = smsatAllocIntIoResource( smRoot,
                                       smOrgIORequest,
                                       oneDeviceData,
                                       SENSE_DATA_LENGTH,
                                       satNewIntIo);
      if (satNewIntIo == agNULL)
      {
          /* memory allocation failure */
          /* just translate the ATAPI error register to sense information */
          smsatTranslateATAPIErrorsToSCSIErrors(
                          scsiCmnd->cdb[0],
                          agFirstDword->D2H.status,
                          agFirstDword->D2H.error,
                          &bSenseKey,
                          &bSenseCodeInfo
                          );
          smsatSetSensePayload(pSense, bSenseKey, 0, bSenseCodeInfo, satOrgIOContext);
          tdsmIOCompletedCB( smRoot,
                             smOrgIORequest,
                             smIOSuccess,
                             SCSI_STAT_CHECK_CONDITION,
                             satOrgIOContext->pSmSenseData,
                             interruptContext);
          SM_DBG1(("smsatPacketCB: momory allocation fails\n"));
          return;
      } /* end memory allocation */

      satNewIOContext = smsatPrepareNewIO(satNewIntIo,
                                        smOrgIORequest,
                                        oneDeviceData,
                                        scsiCmnd,
                                        satOrgIOContext
                                        );
      /* sends request sense to ATAPI device for acquiring sense information */
      status = smsatRequestSenseForATAPI(smRoot,
                              &satNewIntIo->satIntSmIORequest,
                              satNewIOContext->psmDeviceHandle,
                              &satNewIntIo->satIntSmScsiXchg,
                              satNewIOContext
                              );
      if (status != SM_RC_SUCCESS)
      {
          smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satNewIntIo);
          /* just translate the ATAPI error register to sense information */
          smsatTranslateATAPIErrorsToSCSIErrors(
                          scsiCmnd->cdb[0],
                          agFirstDword->D2H.status,
                          agFirstDword->D2H.error,
                          &bSenseKey,
                          &bSenseCodeInfo
                          );
          smsatSetSensePayload(pSense, bSenseKey, 0, bSenseCodeInfo, satOrgIOContext);
          tdsmIOCompletedCB(smRoot,
                            smOrgIORequest,
                            smIOSuccess,
                            SCSI_STAT_CHECK_CONDITION,
                            satOrgIOContext->pSmSenseData,
                            interruptContext);
          SM_DBG1(("smsatPacketCB: failed to call satRequestSenseForATAPI()\n"));
      }
  }
  else if (agIOStatus != OSSA_IO_SUCCESS )
  {
      SM_DBG2(("smsatPacketCB: agIOStatus != OSSA_IO_SUCCESS, status %d\n", agIOStatus));
      smsatProcessAbnormalCompletion(
                    agRoot,
                    agIORequest,
                    agIOStatus,
                    agFirstDword,
                    agIOInfoLen,
                    agParam,
                    satIOContext);
  }
  else
  {
    SM_DBG1(("smsatPacketCB: Unknown error \n"));
    tdsmIOCompletedCB(smRoot,
                      smOrgIORequest,
                      smIOFailed,
                      smDetailOtherError,
                      agNULL,
                      interruptContext);
  }
}
/*****************************************************************************
*! \brief  smsatRequestSenseForATAPICB
*
*   This routine is a callback function called from smllSATACompleted().
*   This CB routine deals with normal non-chained data I/O SATA request.
*
*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
*  \param   agIOStatus:  Status of completed I/O.
*  \param   agFirstDword:Pointer to the four bytes of FIS.
*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
*                        length.
*  \param   agParam:     Additional info based on status.
*  \param   ioContext:   Pointer to smSatIOContext_t.
*
*  \return: none
*
*****************************************************************************/
osGLOBAL void
smsatRequestSenseForATAPICB(
   agsaRoot_t        *agRoot,
   agsaIORequest_t   *agIORequest,
   bit32             agIOStatus,
   agsaFisHeader_t   *agFirstDword,
   bit32             agIOInfoLen,
   void              *agParam,
   void              *ioContext
   )
{
   smRoot_t                  *smRoot = agNULL;
   smIntRoot_t               *smIntRoot = agNULL;
   smIntContext_t            *smAllShared = agNULL;
   smIORequestBody_t         *smIORequestBody;
   smIORequestBody_t         *smOrgIORequestBody;
   smSatIOContext_t            *satIOContext;
   smSatIOContext_t            *satOrgIOContext;
//   smSatIOContext_t            *satNewIOContext;
   smSatInternalIo_t           *satIntIo;
//   smSatInternalIo_t           *satNewIntIo = agNULL;
   smDeviceData_t            *oneDeviceData;
   bit32                     interruptContext;
   bit8                      dataLength;
   smIniScsiCmnd_t           *scsiCmnd;
   smIORequest_t             *smOrgIORequest;

   SM_DBG3(("smsatRequestSenseForATAPICB: start\n"));
   smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
   satIOContext           = (smSatIOContext_t *) ioContext;
   if (satIOContext == agNULL)
   {
     SM_DBG1(("smsatRequestSenseForATAPICB: satIOContext is NULL\n"));
     return;
   }
   satIntIo               = satIOContext->satIntIoContext;
   oneDeviceData          = satIOContext->pSatDevData;
   interruptContext = satIOContext->interruptContext;
   smRoot                 = oneDeviceData->smRoot;
   smIntRoot              = (smIntRoot_t *)smRoot->smData;
   smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
   if (satIntIo == agNULL)
   {
     SM_DBG5(("smsatRequestSenseForATAPICB: External smSatInternalIo_t satIntIoContext\n"));
     satOrgIOContext = satIOContext;
     smOrgIORequest  = smIORequestBody->smIORequest;
     scsiCmnd        = satIOContext->pScsiCmnd;
   }
   else
   {
     SM_DBG5(("smsatRequestSenseForATAPICB: Internal smSatInternalIo_t satIntIoContext\n"));
     satOrgIOContext        = satIOContext->satOrgIOContext;
     smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
     smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
     scsiCmnd      = satOrgIOContext->pScsiCmnd;
   }

   smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
   smIORequestBody->ioCompleted = agTRUE;
   smIORequestBody->ioStarted   = agFALSE;
   if ( (agIOStatus == OSSA_IO_SUCCESS && agIOInfoLen == 0 && agFirstDword == agNULL))
   {
      /* copy the request sense buffer to original IO buffer*/
      if (satIntIo)
      {
        sm_memcpy(satOrgIOContext->pSmSenseData->senseData, satIntIo->satIntDmaMem.virtPtr, SENSE_DATA_LENGTH);
      }
      satOrgIOContext->pSmSenseData->senseLen = SENSE_DATA_LENGTH;
      /* interal structure free */
      smsatFreeIntIoResource( smRoot, oneDeviceData, satIntIo);

      /* notify the OS to complete this SRB */
      tdsmIOCompletedCB( smRoot,
                  smOrgIORequest,
                  smIOSuccess,
                  SCSI_STAT_CHECK_CONDITION,
                  satOrgIOContext->pSmSenseData,
                  interruptContext);
   }
   else if (agIOStatus == OSSA_IO_UNDERFLOW )
   {
      /* copy the request sense buffer to original IO buffer*/
      SM_DBG1(("smsatRequestSenseForATAPICB: OSSA_IO_UNDERFLOW agIOInfoLen = %d\n", agIOInfoLen));
      dataLength = (bit8)(scsiCmnd->expDataLength - agIOInfoLen);
      if (satIntIo)
      {
        sm_memcpy(satOrgIOContext->pSmSenseData->senseData, satIntIo->satIntDmaMem.virtPtr, dataLength);
      }
      satOrgIOContext->pSmSenseData->senseLen = dataLength;
      /* interal structure free */
      smsatFreeIntIoResource( smRoot, oneDeviceData, satIntIo);

      /* notify the OS to complete this SRB */
      tdsmIOCompletedCB( smRoot,
                  smOrgIORequest,
                  smIOSuccess,
                  SCSI_STAT_CHECK_CONDITION,
                  satOrgIOContext->pSmSenseData,
                  interruptContext);
   }
   else
   {
      SM_DBG1(("smsatRequestSenseForATAPICB: failed, agIOStatus error = 0x%x agIOInfoLen = %d\n", agIOStatus, agIOInfoLen));
      /* interal structure free */
      smsatFreeIntIoResource( smRoot, oneDeviceData, satIntIo);

      /* notify the OS to complete this SRB */
      tdsmIOCompletedCB( smRoot,
                  smOrgIORequest,
                  smIOFailed,
                  smDetailOtherError,
                  agNULL,
                  interruptContext);
   }
   SM_DBG3(("smsatRequestSenseForATAPICB: end\n"));
}

/*****************************************************************************
*! \brief  smsatSetFeaturesPIOCB
*
*   This routine is a callback function called from smllSATACompleted().
*   This CB routine deals with normal non-chained data I/O SATA request.
*
*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
*  \param   agIOStatus:  Status of completed I/O.
*  \param   agFirstDword:Pointer to the four bytes of FIS.
*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
*                        length.
*  \param   agParam:     Additional info based on status.
*  \param   ioContext:   Pointer to smSatIOContext_t.
*
*  \return: none
*
*****************************************************************************/
osGLOBAL void
smsatSetFeaturesPIOCB(
    agsaRoot_t        *agRoot,
    agsaIORequest_t   *agIORequest,
    bit32             agIOStatus,
    agsaFisHeader_t   *agFirstDword,
    bit32             agIOInfoLen,
    void              *agParam,
    void              *ioContext
    )
{
    smRoot_t                  *smRoot = agNULL;
    smIntRoot_t               *smIntRoot = agNULL;
    smIntContext_t            *smAllShared = agNULL;
    smIORequestBody_t         *smIORequestBody;
    smIORequestBody_t         *smOrgIORequestBody = agNULL;
    smSatIOContext_t          *satIOContext;
    smSatIOContext_t          *satOrgIOContext;
    smSatIOContext_t          *satNewIOContext;
    smSatInternalIo_t         *satIntIo;
    smSatInternalIo_t         *satNewIntIo = agNULL;
    smDeviceData_t            *oneDeviceData;
    smIniScsiCmnd_t           *scsiCmnd;
    smIORequest_t             *smOrgIORequest;
    smDeviceHandle_t          *smDeviceHandle;
    bit32                      status = SM_RC_FAILURE;
    smIORequest_t             *smIORequest;

    SM_DBG2(("smsatSetFeaturesPIOCB: start\n"));
    smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
    satIOContext           = (smSatIOContext_t *) ioContext;
    if (satIOContext == agNULL)
    {
      SM_DBG1(("smsatSetFeaturesPIOCB: satIOContext is NULL\n"));
      return;
    }
    satIntIo               = satIOContext->satIntIoContext;
    oneDeviceData          = satIOContext->pSatDevData;
    smDeviceHandle         = satIOContext->psmDeviceHandle;
    smRoot                 = oneDeviceData->smRoot;
    smIntRoot              = (smIntRoot_t *)smRoot->smData;
    smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
    if (satIntIo == agNULL)
    {
      SM_DBG2(("smsatSetFeaturesPIOCB: External smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext = satIOContext;
      smOrgIORequest  = smIORequestBody->smIORequest;
      scsiCmnd        = satIOContext->pScsiCmnd;
    }
    else
    {
      SM_DBG2(("smsatSetFeaturesPIOCB: Internal smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext        = satIOContext->satOrgIOContext;
      smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
      smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
      scsiCmnd      = satOrgIOContext->pScsiCmnd;
    }
    smIORequest  = smOrgIORequestBody->smIORequest;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smIORequestBody->ioCompleted = agTRUE;
    smIORequestBody->ioStarted   = agFALSE;
    /* interal structure free */
    smsatFreeIntIoResource(smRoot,
                           oneDeviceData,
                           satIntIo);
    if (smIORequest->tdData == smIORequest->smData)
    {
      SM_DBG1(("smsatSetFeaturesPIOCB: the same tdData and smData error!\n"));
    }
    /* check the agIOStatus */
    if (agIOStatus == OSSA_IO_ABORTED ||
        agIOStatus == OSSA_IO_NO_DEVICE ||
        agIOStatus == OSSA_IO_PORT_IN_RESET ||
        agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
        agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
        agIOStatus == OSSA_IO_DS_IN_ERROR ||
        agIOStatus == OSSA_IO_DS_INVALID
       )
    {
      SM_DBG1(("smsatSetFeaturesPIOCB: error status 0x%x\n", agIOStatus));
      SM_DBG1(("smsatSetFeaturesPIOCB: did %d!!!\n", oneDeviceData->id));
      tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
      return;
    }
    /*if the ATAPI device support DMA, then enble this feature*/
    if (oneDeviceData->satDMASupport)
    {
        satNewIntIo = smsatAllocIntIoResource(smRoot,
                                           smOrgIORequest,
                                           oneDeviceData,
                                           0,
                                           satNewIntIo);
        if (satNewIntIo == agNULL)
        {
            SM_DBG1(("smsatSetFeaturesPIOCB: memory allocation fails\n"));
            /*Complete this identify packet device IO */
            tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
            return;
        } /* end memory allocation */

        satNewIOContext = smsatPrepareNewIO(satNewIntIo,
                                          smOrgIORequest,
                                          oneDeviceData,
                                          scsiCmnd,
                                          satOrgIOContext
                                          );
        /* sends another ATA SET FEATURES based on DMA bit */
        status = smsatSetFeaturesDMA(smRoot,
                                &satNewIntIo->satIntSmIORequest,
                                satNewIOContext->psmDeviceHandle,
                                &satNewIntIo->satIntSmScsiXchg,
                                satNewIOContext
                                );
        if (status != SM_RC_SUCCESS)
        {
            smsatFreeIntIoResource(smRoot, oneDeviceData, satNewIntIo);
            SM_DBG2(("satSetFeaturesPIOCB: failed to call smsatSetFeatures()\n"));
            /*Complete this identify packet device IO */
            tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
        }
    }
    else
    {
        /*Complete this identify packet device IO */
        tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
    }
    SM_DBG2(("smsatSetFeaturesPIOCB: exit, agIOStatus 0x%x\n", agIOStatus));
}

/*****************************************************************************
*! \brief  smsatDeviceResetCB
*
*   This routine is a callback function called from smllSATACompleted().
*   This CB routine deals with normal non-chained data I/O SATA request.
*
*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
*  \param   agIOStatus:  Status of completed I/O.
*  \param   agFirstDword:Pointer to the four bytes of FIS.
*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
*                        length.
*  \param   agParam:     Additional info based on status.
*  \param   ioContext:   Pointer to smSatIOContext_t.
*
*  \return: none
*
*****************************************************************************/
osGLOBAL void
smsatDeviceResetCB(
    agsaRoot_t        *agRoot,
    agsaIORequest_t   *agIORequest,
    bit32             agIOStatus,
    agsaFisHeader_t   *agFirstDword,
    bit32             agIOInfoLen,
    void              *agParam,
    void              *ioContext
    )
{
    smRoot_t                 *smRoot = agNULL;
    smIntRoot_t              *smIntRoot = agNULL;
    smIntContext_t           *smAllShared = agNULL;
    smIORequestBody_t        *smIORequestBody;
    smSatIOContext_t         *satIOContext;
    smSatIOContext_t         *satOrgIOContext;
//    smSatIOContext_t          *satNewIOContext;
    smSatInternalIo_t        *satIntIo;
//    smSatInternalIo_t         *satNewIntIo = agNULL;
    smDeviceData_t           *oneDeviceData;
#ifdef  TD_DEBUG_ENABLE
    agsaFisPioSetupHeader_t  *satPIOSetupHeader = agNULL;
    bit32                     ataStatus = 0;
    bit32                     ataError;
#endif
//    bit32                     status;
    bit32                     AbortTM = agFALSE;
    smDeviceHandle_t         *smDeviceHandle;

    SM_DBG1(("smsatDeviceResetCB: start\n"));
    smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
    satIOContext           = (smSatIOContext_t *) ioContext;
    satIntIo               = satIOContext->satIntIoContext;
    oneDeviceData          = satIOContext->pSatDevData;
    smRoot                 = oneDeviceData->smRoot;
    smIntRoot              = (smIntRoot_t *)smRoot->smData;
    smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
    smDeviceHandle         = oneDeviceData->smDevHandle;
    if (satIntIo == agNULL)
    {
      SM_DBG6(("smsatDeviceResetCB: External, OS generated\n"));
      satOrgIOContext      = satIOContext;
    }
    else
    {
      SM_DBG6(("smsatDeviceResetCB: Internal, TD generated\n"));
      satOrgIOContext        = satIOContext->satOrgIOContext;
      if (satOrgIOContext == agNULL)
      {
        SM_DBG6(("smsatDeviceResetCB: satOrgIOContext is NULL, wrong\n"));
        return;
      }
      else
      {
        SM_DBG6(("smsatDeviceResetCB: satOrgIOContext is NOT NULL\n"));
      }
    }
    smIORequestBody->ioCompleted = agTRUE;
    smIORequestBody->ioStarted = agFALSE;
    if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatDeviceResetCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
      /* TM completed */
      tdsmEventCB( smRoot,
                   smDeviceHandle,
                   smIntrEventTypeTaskManagement,
                   smTMFailed,
                   oneDeviceData->satTmTaskTag);
      oneDeviceData->satTmTaskTag = agNULL;
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }
    if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
        )
    {
      SM_DBG1(("smsatDeviceResetCB: OSSA_IO_OPEN_CNX_ERROR!!!\n"));
      /* TM completed */
      tdsmEventCB( smRoot,
                   smDeviceHandle,
                   smIntrEventTypeTaskManagement,
                   smTMFailed,
                   oneDeviceData->satTmTaskTag);
      oneDeviceData->satTmTaskTag = agNULL;
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }
    if (agIOStatus != OSSA_IO_SUCCESS)
    {
#ifdef  TD_DEBUG_ENABLE
       /* only agsaFisPioSetup_t is expected */
       satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
       ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
       ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
#endif
       SM_DBG1(("smsatDeviceResetCB: ataStatus 0x%x ataError 0x%x!!!\n", ataStatus, ataError));
       /* TM completed */
       tdsmEventCB( smRoot,
                    smDeviceHandle,
                    smIntrEventTypeTaskManagement,
                    smTMFailed,
                    oneDeviceData->satTmTaskTag);
       oneDeviceData->satTmTaskTag = agNULL;
       smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
       smsatFreeIntIoResource( smRoot,
                               oneDeviceData,
                               satIntIo);
       return;
    }
    /*success */
    if (satOrgIOContext->TMF == AG_ABORT_TASK)
    {
      AbortTM = agTRUE;
    }
    if (AbortTM == agTRUE)
    {
      SM_DBG1(("smsatDeviceResetCB: calling satAbort!!!\n"));
      smsatAbort(smRoot, agRoot, satOrgIOContext->satToBeAbortedIOContext);
    }
    oneDeviceData->satTmTaskTag = agNULL;
    oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    SM_DBG1(("smsatDeviceResetCB: satPendingIO %d satNCQMaxIO %d!!!\n", oneDeviceData->satPendingIO, oneDeviceData->satNCQMaxIO ));
    SM_DBG1(("smsatDeviceResetCB: satPendingNCQIO %d satPendingNONNCQIO %d!!!\n", oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMOK,
                 oneDeviceData->satTmTaskTag);


    SM_DBG3(("smsatDeviceResetCB: return\n"));
}


/*****************************************************************************
*! \brief  smsatExecuteDeviceDiagnosticCB
*
*   This routine is a callback function called from smllSATACompleted().
*   This CB routine deals with normal non-chained data I/O SATA request.
*
*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
*  \param   agIOStatus:  Status of completed I/O.
*  \param   agFirstDword:Pointer to the four bytes of FIS.
*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
*                        length.
*  \param   agParam:     Additional info based on status.
*  \param   ioContext:   Pointer to smSatIOContext_t.
*
*  \return: none
*
*****************************************************************************/
osGLOBAL void
smsatExecuteDeviceDiagnosticCB(
    agsaRoot_t        *agRoot,
    agsaIORequest_t   *agIORequest,
    bit32             agIOStatus,
    agsaFisHeader_t   *agFirstDword,
    bit32             agIOInfoLen,
    void              *agParam,
    void              *ioContext
    )
{
    smRoot_t                  *smRoot = agNULL;
    smIntRoot_t               *smIntRoot = agNULL;
    smIntContext_t            *smAllShared = agNULL;
    smIORequestBody_t         *smIORequestBody;
    smSatIOContext_t          *satIOContext;
    smSatIOContext_t          *satOrgIOContext;
//    smSatIOContext_t            *satNewIOContext;
    smSatInternalIo_t         *satIntIo;
//    smSatInternalIo_t           *satNewIntIo = agNULL;
    smDeviceData_t            *oneDeviceData;

    SM_DBG6(("smsatSetFeaturesDMACB: start\n"));
    smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
    satIOContext           = (smSatIOContext_t *) ioContext;
    satIntIo               = satIOContext->satIntIoContext;
    oneDeviceData          = satIOContext->pSatDevData;
    smRoot                 = oneDeviceData->smRoot;
    smIntRoot              = (smIntRoot_t *)smRoot->smData;
    smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
    if (satIntIo == agNULL)
    {
      SM_DBG5(("smsatExecuteDeviceDiagnosticCB: External smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext = satIOContext;
    }
    else
    {
      SM_DBG5(("smsatExecuteDeviceDiagnosticCB: Internal smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext        = satIOContext->satOrgIOContext;
      if (satOrgIOContext == agNULL)
      {
        SM_DBG5(("smsatExecuteDeviceDiagnosticCB: satOrgIOContext is NULL\n"));
      }
      else
      {
        SM_DBG5(("smsatExecuteDeviceDiagnosticCB: satOrgIOContext is NOT NULL\n"));
      }
    }
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smIORequestBody->ioCompleted = agTRUE;
    smIORequestBody->ioStarted   = agFALSE;
     /* interal structure free */
    smsatFreeIntIoResource(smRoot,oneDeviceData, satIntIo);
}

GLOBAL void
smsatTranslateATAPIErrorsToSCSIErrors(
    bit8   bCommand,
    bit8   bATAStatus,
    bit8   bATAError,
    bit8   *pSenseKey,
    bit16  *pSenseCodeInfo
    )
{
    if (pSenseKey == agNULL || pSenseCodeInfo == agNULL)
    {
        SM_DBG1(("TranslateATAErrorsToSCSIErros: pSenseKey == agNULL || pSenseCodeInfo == agNULL\n"));
        return;
    }
    if (bATAStatus & ERR_ATA_STATUS_MASK )
    {
        if(bATAError & NM_ATA_ERROR_MASK)
        {
          *pSenseKey = SCSI_SNSKEY_NOT_READY;
          *pSenseCodeInfo = 0x3a00;
        }
        else if(bATAError & ABRT_ATA_ERROR_MASK)
        {
          *pSenseKey = SCSI_SNSKEY_ABORTED_COMMAND;
          *pSenseCodeInfo = 0;
        }
        else if(bATAError & MCR_ATA_ERROR_MASK)
        {
          *pSenseKey = SCSI_SNSKEY_UNIT_ATTENTION;
          *pSenseCodeInfo = 0x5a01;
        }
        else if(bATAError & IDNF_ATA_ERROR_MASK)
        {
          *pSenseKey = SCSI_SNSKEY_MEDIUM_ERROR;
          *pSenseCodeInfo = 0x1401;
        }
        else if(bATAError & MC_ATA_ERROR_MASK)
        {
          *pSenseKey = SCSI_SNSKEY_UNIT_ATTENTION;
          *pSenseCodeInfo = 0x2800;
        }
        else if(bATAError & UNC_ATA_ERROR_MASK)
        {
          /*READ*/
          *pSenseKey = SCSI_SNSKEY_MEDIUM_ERROR;
          *pSenseCodeInfo = 0x1100;

          /*add WRITE here */
        }
        else if(bATAError & ICRC_ATA_ERROR_MASK)
        {
          *pSenseKey = SCSI_SNSKEY_ABORTED_COMMAND;
          *pSenseCodeInfo = 0x4703;
        }
    }
    else if((bATAStatus & DF_ATA_STATUS_MASK))
    {
        *pSenseKey = SCSI_SNSKEY_HARDWARE_ERROR;
        *pSenseCodeInfo = 0x4400;
    }
    else
    {
        SM_DBG1(("unhandled ata error: bATAStatus = 0x%x, bATAError = 0x%x\n", bATAStatus, bATAError));
    }
}

GLOBAL void 
smsatTranslateATAErrorsToSCSIErrors(
    bit8   bATAStatus,
    bit8   bATAError,
    bit8   *pSenseKey,
    bit16  *pSenseCodeInfo
    )
{

  SM_DBG1(("TranslateATAErrorsToSCSIErros: bATAStatus=%d  bATAError= %d \n",bATAStatus,bATAError));

  if (pSenseKey == agNULL || pSenseCodeInfo == agNULL)
  {
    SM_DBG1(("TranslateATAErrorsToSCSIErros: pSenseKey == agNULL || pSenseCodeInfo == agNULL\n"));
    return;
  }
	
  if (bATAStatus & ERR_ATA_STATUS_MASK) 
  {
    if(bATAError & NM_ATA_ERROR_MASK)
    {
      *pSenseKey = SCSI_SNSKEY_NOT_READY;
      *pSenseCodeInfo = SCSI_SNSCODE_MEDIUM_NOT_PRESENT;
    }
    else if(bATAError & UNC_ATA_ERROR_MASK)
    {
      *pSenseKey = SCSI_SNSKEY_MEDIUM_ERROR;
      *pSenseCodeInfo = SCSI_SNSCODE_UNRECOVERED_READ_ERROR;
    }
    else if(bATAError & IDNF_ATA_ERROR_MASK)
    {
      *pSenseKey = SCSI_SNSKEY_ILLEGAL_REQUEST;
      *pSenseCodeInfo = SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
    }
    else if(bATAError & ABRT_ATA_ERROR_MASK)
    {
      *pSenseKey = SCSI_SNSKEY_ABORTED_COMMAND;
      *pSenseCodeInfo = SCSI_SNSCODE_NO_ADDITIONAL_INFO;
    }
    else if(bATAError & MC_ATA_ERROR_MASK)
    {
      *pSenseKey = SCSI_SNSKEY_UNIT_ATTENTION;
      *pSenseCodeInfo = SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE;
    }
    else if(bATAError & MCR_ATA_ERROR_MASK)
    {
      *pSenseKey = SCSI_SNSKEY_UNIT_ATTENTION;
      *pSenseCodeInfo = SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST;
    }
    else if(bATAError & ICRC_ATA_ERROR_MASK)
    {
      *pSenseKey = SCSI_SNSKEY_ABORTED_COMMAND;
      *pSenseCodeInfo = SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR;
    }
    else
    {
      *pSenseKey = SCSI_SNSKEY_NO_SENSE;
      *pSenseCodeInfo = SCSI_SNSCODE_NO_ADDITIONAL_INFO;

    }
  }
  else if (bATAStatus & DF_ATA_STATUS_MASK) /* INTERNAL TARGET FAILURE */
  {
    *pSenseKey = SCSI_SNSKEY_HARDWARE_ERROR;
    *pSenseCodeInfo = SCSI_SNSCODE_INTERNAL_TARGET_FAILURE; 
  }
	
	
}


FORCEINLINE void
smsatNonChainedDataIOCB(
                        agsaRoot_t        *agRoot,
                        agsaIORequest_t   *agIORequest,
                        bit32             agIOStatus,
                        agsaFisHeader_t   *agFirstDword,
                        bit32             agIOInfoLen,
                        void              *agParam,
                        void              *ioContext
                       )
{
  smIORequestBody_t    *smIORequestBody = (smIORequestBody_t *)agIORequest->osData;
  smSatIOContext_t       *satIOContext    = (smSatIOContext_t *) ioContext;
  smSatInternalIo_t      *SatIntIo        = satIOContext->satIntIoContext;
  smDeviceData_t       *oneDeviceData   = satIOContext->pSatDevData;
  smRoot_t             *smRoot          = oneDeviceData->smRoot;
  smIntRoot_t          *smIntRoot       = (smIntRoot_t *)smRoot->smData;
  smIntContext_t       *smAllShared     = (smIntContext_t *)&smIntRoot->smAllShared;
  bit32                interruptContext = satIOContext->interruptContext;

  SM_DBG2(("smsatNonChainedDataIOCB: start\n"));

  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted   = agFALSE;

  /* interal structure free */
  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          SatIntIo);

  /* Process completion */
  if( (agIOStatus == OSSA_IO_SUCCESS) && (agIOInfoLen == 0))
  {
    SM_DBG5(("smsatNonChainedDataIOCB: success\n"));
    SM_DBG5(("smsatNonChainedDataIOCB: success agIORequest %p\n", agIORequest));
    /*
     * Command was completed OK, this is the normal path.
     * Now call the OS-App Specific layer about this completion.
     */
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       interruptContext);
  }
  else
  {
    SM_DBG1(("smsatNonChainedDataIOCB: calling smsatProcessAbnormalCompletion!!!\n"));
    /* More checking needed */
    smsatProcessAbnormalCompletion( agRoot,
                                    agIORequest,
                                    agIOStatus,
                                    agFirstDword,
                                    agIOInfoLen,
                                    agParam,
                                    satIOContext);
  }

  return;
}

FORCEINLINE void
smsatChainedDataIOCB(
                     agsaRoot_t        *agRoot,
                     agsaIORequest_t   *agIORequest,
                     bit32             agIOStatus,
                     agsaFisHeader_t   *agFirstDword,
                     bit32             agIOInfoLen,
                     void              *agParam,
                     void              *ioContext
                    )
{

  smRoot_t                  *smRoot = agNULL;
  smIntRoot_t               *smIntRoot = agNULL;
  smIntContext_t            *smAllShared = agNULL;
  smIORequestBody_t         *smIORequestBody;
  smIORequestBody_t         *smOrgIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatIOContext_t          *satNewIOContext;
  smSatInternalIo_t         *satIntIo;
  smSatInternalIo_t         *satNewIntIo = agNULL;
//  smDeviceData_t             *satDevData;
  smDeviceData_t            *oneDeviceData;
  smScsiRspSense_t          *pSense;
  smIniScsiCmnd_t           *scsiCmnd;
  smIORequest_t             *smOrgIORequest;
  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
  bit32                      ataStatus = 0;
  bit32                      status = tiError;
  agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
  bit32                      dataLength;

  SM_DBG6(("smsatChainedDataIOCB: start\n"));
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  if (satIOContext == agNULL)
  {
    SM_DBG1(("smsatChainedDataIOCB: satIOContext is NULL\n"));
    return;
  }
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  if (satIntIo == agNULL)
  {
    SM_DBG5(("smsatChainedDataIOCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satIOContext->pSense;
    scsiCmnd        = satIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG5(("smsatChainedDataIOCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    pSense        = satOrgIOContext->pSense;
    scsiCmnd      = satOrgIOContext->pScsiCmnd;
  }
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
     SM_DBG1(("smsatChainedDataIOCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
     smsatSetSensePayload( pSense,
                           SCSI_SNSKEY_NO_SENSE,
                           0,
                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                           satOrgIOContext);

     tdsmIOCompletedCB( smRoot,
                        smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                        smIOSuccess,
                        SCSI_STAT_CHECK_CONDITION,
                        satOrgIOContext->pSmSenseData,
                        satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);
    return;
  }

  /*
    checking IO status, FIS type and error status
  */
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* agsaFisPioSetup_t or agsaFisRegDeviceToHost_t or agsaFisSetDevBits_t for read
       agsaFisRegDeviceToHost_t or agsaFisSetDevBits_t for write
       first, assumed to be Reg Device to Host FIS
       This is OK to just find fis type
    */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
    /* for debugging */
    if( (statDevToHostFisHeader->fisType != PIO_SETUP_DEV_TO_HOST_FIS) &&
        (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) &&
        (statDevToHostFisHeader->fisType != SET_DEV_BITS_FIS)
        )
    {
      SM_DBG1(("smsatChainedDataIOCB: FAILED, Wrong FIS type 0x%x!!!\n", statDevToHostFisHeader->fisType));
    }

    /* for debugging */
    if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
         (ataStatus & DF_ATA_STATUS_MASK)
         )
    {
      SM_DBG1(("smsatChainedDataIOCB: FAILED, error status and command 0x%x!!!\n", hostToDevFis->h.command));
    }

    /* the function below handles abort case */
    smsatDelayedProcessAbnormalCompletion(agRoot,
                                          agIORequest,
                                          agIOStatus,
                                          agFirstDword,
                                          agIOInfoLen,
                                          agParam,
                                          satIOContext);

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  } /* end of error */

  switch (hostToDevFis->h.command)
  {
  case SAT_READ_DMA: /* fall through */
  case SAT_READ_SECTORS: /* fall through */
  case SAT_READ_DMA_EXT: /* fall through */
  case SAT_READ_SECTORS_EXT: /* fall through */
  case SAT_READ_FPDMA_QUEUED: /* fall through */
  case SAT_WRITE_DMA: /* fall through */
  case SAT_WRITE_SECTORS:/* fall through */
  case SAT_WRITE_DMA_FUA_EXT: /* fall through */
  case SAT_WRITE_DMA_EXT: /* fall through */
  case SAT_WRITE_SECTORS_EXT: /* fall through */
  case SAT_WRITE_FPDMA_QUEUED:

    SM_DBG5(("smsatChainedDataIOCB: READ/WRITE success case\n"));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* done with internally genereated SAT_SMART_RETURN_STATUS */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    /* let's loop till TL */

    /* lba = lba + tl
       loopnum--;
       if (loopnum == 0) done
     */
    (satOrgIOContext->LoopNum)--;
    if (satOrgIOContext->LoopNum == 0)
    {
      /* done with read */
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext );
      return;
    }
    
    /* don't need to allocate payload memory here. Use the one allocated by OS layer */
    dataLength = 0;

    satNewIntIo = smsatAllocIntIoResource( smRoot,
                                           smOrgIORequest,
                                           oneDeviceData,
                                           dataLength,
                                           satNewIntIo);
    if (satNewIntIo == agNULL)
    {
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         satOrgIOContext->interruptContext );

      SM_DBG1(("smsatChainedDataIOCB: momory allocation fails!!!\n"));
      return;
    } /* end of memory allocation failure */

       /*
     * Need to initialize all the fields within satIOContext
     */

    satNewIOContext = smsatPrepareNewIO(
                                        satNewIntIo,
                                        smOrgIORequest,
                                        oneDeviceData,
                                        scsiCmnd,
                                        satOrgIOContext
                                        );

    /* sending another ATA command */
    switch (scsiCmnd->cdb[0])
    {
    case SCSIOPC_READ_6:
      /* no loop should occur with READ6 since it fits in one ATA command */
      break;
    case SCSIOPC_READ_10: /* fall through */
    case SCSIOPC_READ_12: /* fall through */
    case SCSIOPC_READ_16: /* fall through */
      status = smsatRead_1( smRoot,
                            &satNewIntIo->satIntSmIORequest,
                            satNewIOContext->psmDeviceHandle,
                            &satNewIntIo->satIntSmScsiXchg,
                            satNewIOContext);
      break;
    case SCSIOPC_WRITE_6:
      /* no loop should occur with WRITE6 since it fits in one ATA command */
      break;
    case SCSIOPC_WRITE_10: /* fall through */
    case SCSIOPC_WRITE_12: /* fall through */
    case SCSIOPC_WRITE_16: /* fall through */
      status = smsatWrite_1( smRoot,
                             &satNewIntIo->satIntSmIORequest,
                             satNewIOContext->psmDeviceHandle,
                             &satNewIntIo->satIntSmScsiXchg,
                             satNewIOContext);
      break;
    default:
      SM_DBG1(("smsatChainedDataIOCB: success but default case scsi cmd 0x%x ata cmd 0x%x!!!\n",scsiCmnd->cdb[0], hostToDevFis->h.command));
      status = tiError;
      break;
    }



    if (status != SM_RC_SUCCESS)
    {
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satNewIntIo);
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         satOrgIOContext->interruptContext );
      SM_DBG1(("smsatChainedDataIOCB: calling satRead10_1 fails!!!\n"));
      return;
    }

    break;


  default:
    SM_DBG1(("smsatChainedDataIOCB: success but default case command 0x%x!!!\n",hostToDevFis->h.command));
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);

    break;
  }


  return;
}

osGLOBAL void
smsatNonChainedVerifyCB(
                        agsaRoot_t        *agRoot,
                        agsaIORequest_t   *agIORequest,
                        bit32             agIOStatus,
                        agsaFisHeader_t   *agFirstDword,
                        bit32             agIOInfoLen,
                        agsaFrameHandle_t agFrameHandle,
                        void              *ioContext
                       )
{
 
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                *smRoot = agNULL;
  smIntRoot_t             *smIntRoot = agNULL;
  smIntContext_t          *smAllShared = agNULL;
  smIORequestBody_t       *smIORequestBody;
  smIORequestBody_t       *smOrgIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatInternalIo_t         *satIntIo;
//  satDeviceData_t         *satDevData;
  smDeviceData_t          *oneDeviceData;
  smScsiRspSense_t          *pSense;
  smIORequest_t             *smOrgIORequest;
  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;
  agsaFisRegD2HHeader_t    *statDevToHostFisHeader = agNULL;

  SM_DBG2(("smsatNonChainedVerifyCB: start\n"));
  SM_DBG5(("smsatNonChainedVerifyCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatNonChainedVerifyCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satIOContext->pSense;
  }
  else
  {
    SM_DBG4(("smsatNonChainedVerifyCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatNonChainedVerifyCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatNonChainedVerifyCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    pSense                 = satOrgIOContext->pSense;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;
  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
     SM_DBG1(("smsatNonChainedVerifyCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
     smsatSetSensePayload( pSense,
                           SCSI_SNSKEY_NO_SENSE,
                           0,
                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                           satOrgIOContext);
     tdsmIOCompletedCB( smRoot,
                        smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                        smIOSuccess,
                        SCSI_STAT_CHECK_CONDITION,
                        satOrgIOContext->pSmSenseData,
                        satOrgIOContext->interruptContext );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisRegDeviceToHost_t is expected */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  }

  if( agIOStatus != OSSA_IO_SUCCESS)
  {
    if ( (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) ||
         ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
         )
    {
      /* for debugging */
      if( agIOStatus != OSSA_IO_SUCCESS)
      {
        SM_DBG1(("smsatNonChainedVerifyCB: FAILED, NOT IO_SUCCESS!!!\n"));
      }
      else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
      {
        SM_DBG1(("smsatNonChainedVerifyCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
      }
      else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
                (ataStatus & DF_ATA_STATUS_MASK)
                )
      {
        SM_DBG1(("smsatNonChainedVerifyCB: FAILED, FAILED, error status!!!\n"));
      }

      /* Process abort case */
      if (agIOStatus == OSSA_IO_ABORTED)
      {
        smsatProcessAbort(smRoot,
                          smOrgIORequest,
                          satOrgIOContext
                          );

        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
        return;
      }

      /* for debugging */
      switch (hostToDevFis->h.command)
      {
      case SAT_READ_VERIFY_SECTORS:
        SM_DBG1(("smsatNonChainedVerifyCB: SAT_READ_VERIFY_SECTORS!!!\n"));
        break;
      case SAT_READ_VERIFY_SECTORS_EXT:
        SM_DBG1(("smsatNonChainedVerifyCB: SAT_READ_VERIFY_SECTORS_EXT!!!\n"));
        break;
      default:
        SM_DBG1(("smsatNonChainedVerifyCB: error default case command 0x%x!!!\n", hostToDevFis->h.command));
        break;
      }

      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    } /* end error checking */
  }

  /* process success from this point on */
  switch (hostToDevFis->h.command)
  {
  case SAT_READ_VERIFY_SECTORS: /* fall through */
  case SAT_READ_VERIFY_SECTORS_EXT:
    SM_DBG5(("smsatNonChainedVerifyCB: SAT_WRITE_DMA_EXT success \n"));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       satOrgIOContext->interruptContext);
    break;
  default:
    SM_DBG1(("smsatNonChainedVerifyCB: success but error default case command 0x%x!!!\n", hostToDevFis->h.command));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    break;
  }

  return;
}

osGLOBAL void
smsatChainedVerifyCB(
                     agsaRoot_t        *agRoot,
                     agsaIORequest_t   *agIORequest,
                     bit32             agIOStatus,
                     agsaFisHeader_t   *agFirstDword,
                     bit32             agIOInfoLen,
                     agsaFrameHandle_t agFrameHandle,
                     void              *ioContext
                    )
{
  
  smRoot_t                  *smRoot = agNULL;
  smIntRoot_t               *smIntRoot = agNULL;
  smIntContext_t            *smAllShared = agNULL;
  smIORequestBody_t         *smIORequestBody;
  smIORequestBody_t         *smOrgIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatIOContext_t          *satNewIOContext;
  smSatInternalIo_t         *satIntIo;
  smSatInternalIo_t         *satNewIntIo = agNULL;
  smDeviceData_t            *oneDeviceData;
  smScsiRspSense_t          *pSense;
  smIniScsiCmnd_t           *scsiCmnd;
  smIORequest_t             *smOrgIORequest;
  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
  bit32                      ataStatus = 0;
  agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
  bit32                      status = tiError;
  bit32                      dataLength;

  SM_DBG2(("smsatChainedVerifyCB: start\n"));
  SM_DBG5(("smsatChainedVerifyCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatChainedVerifyCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satIOContext->pSense;
    scsiCmnd        = satIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG4(("smsatChainedVerifyCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatChainedVerifyCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatChainedVerifyCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    pSense        = satOrgIOContext->pSense;
    scsiCmnd      = satOrgIOContext->pScsiCmnd;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
     SM_DBG1(("smsatChainedVerifyCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
     smsatSetSensePayload( pSense,
                           SCSI_SNSKEY_NO_SENSE,
                           0,
                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                           satOrgIOContext);

     tdsmIOCompletedCB( smRoot,
                        smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                        smIOSuccess,
                        SCSI_STAT_CHECK_CONDITION,
                        satOrgIOContext->pSmSenseData,
                        satOrgIOContext->interruptContext );

     smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

     smsatFreeIntIoResource( smRoot,
                             oneDeviceData,
                             satIntIo);
     return;
  }

  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisRegDeviceToHost_t is expected */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  }

  if( agIOStatus != OSSA_IO_SUCCESS)
  {
    if ( (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) ||
         ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
         )
    {
      /* for debugging */
      if( agIOStatus != OSSA_IO_SUCCESS)
      {
        SM_DBG1(("smsatChainedVerifyCB: FAILED, NOT IO_SUCCESS!!!\n"));
      }
      else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
      {
        SM_DBG1(("smsatChainedVerifyCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
      }
      else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
                (ataStatus & DF_ATA_STATUS_MASK)
                )
      {
        SM_DBG1(("smsatChainedVerifyCB: FAILED, FAILED, error status!!!\n"));
      }

      /* Process abort case */
      if (agIOStatus == OSSA_IO_ABORTED)
      {
        smsatProcessAbort(smRoot,
                          smOrgIORequest,
                          satOrgIOContext
                          );

        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
        return;
      }

      /* for debugging */
      switch (hostToDevFis->h.command)
      {
      case SAT_READ_VERIFY_SECTORS:
        SM_DBG1(("smsatChainedVerifyCB: SAT_READ_VERIFY_SECTORS!!!\n"));
        break;
      case SAT_READ_VERIFY_SECTORS_EXT:
        SM_DBG1(("smsatChainedVerifyCB: SAT_READ_VERIFY_SECTORS_EXT!!!\n"));
        break;
      default:
        SM_DBG1(("smsatChainedVerifyCB: error default case command 0x%x!!!\n", hostToDevFis->h.command));
        break;
      }

      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                            satOrgIOContext);

     tdsmIOCompletedCB( smRoot,
                        smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                        smIOSuccess,
                        SCSI_STAT_CHECK_CONDITION,
                        satOrgIOContext->pSmSenseData,
                        satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    } /* end error checking */
  }

  /* process success from this point on */
  switch (hostToDevFis->h.command)
  {
  case SAT_READ_VERIFY_SECTORS: /* fall through */
  case SAT_READ_VERIFY_SECTORS_EXT:
    SM_DBG5(("smsatChainedVerifyCB: SAT_WRITE_DMA_EXT success \n"));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    /* let's loop till TL */

    /* lba = lba + tl
       loopnum--;
       if (loopnum == 0) done
     */
    (satOrgIOContext->LoopNum)--;
    if (satOrgIOContext->LoopNum == 0)
    {
      /*
        done with write and verify
      */
     tdsmIOCompletedCB( smRoot,
                        smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                        smIOSuccess,
                        SCSI_STAT_GOOD,
                        agNULL,
                        satOrgIOContext->interruptContext );
      return;
    }

    if (satOrgIOContext->superIOFlag)
    {
      dataLength = ((tiSuperScsiInitiatorRequest_t *) satOrgIOContext->smScsiXchg)->scsiCmnd.expDataLength;
    }
    else
    {
      dataLength = ((tiScsiInitiatorRequest_t *) satOrgIOContext->smScsiXchg)->scsiCmnd.expDataLength;
    }

    satNewIntIo = smsatAllocIntIoResource( smRoot,
                                           smOrgIORequest,
                                           oneDeviceData,
                                           dataLength,
                                           satNewIntIo);
    if (satNewIntIo == agNULL)
    {
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         satOrgIOContext->interruptContext );

      SM_DBG1(("smsatChainedVerifyCB: momory allocation fails!!!\n"));
      return;
    } /* end of memory allocation failure */

    /*
     * Need to initialize all the fields within satIOContext
     */

    satNewIOContext = smsatPrepareNewIO(
                                        satNewIntIo,
                                        smOrgIORequest,
                                        oneDeviceData,
                                        scsiCmnd,
                                        satOrgIOContext
                                       );
    status = smsatChainedVerify(smRoot,
                                &satNewIntIo->satIntSmIORequest,
                                satNewIOContext->psmDeviceHandle,
                                &satNewIntIo->satIntSmScsiXchg,
                                satNewIOContext);

    if (status != SM_RC_SUCCESS)
    {
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satNewIntIo);
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         satOrgIOContext->interruptContext );
      SM_DBG1(("smsatChainedVerifyCB: calling satChainedVerify fails!!!\n"));
      return;
    }

    break;
  default:
    SM_DBG1(("smsatChainedVerifyCB: success but error default case command 0x%x!!!\n", hostToDevFis->h.command));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    break;
  }
  return;
}


osGLOBAL void
smsatTestUnitReadyCB(
                     agsaRoot_t        *agRoot,
                     agsaIORequest_t   *agIORequest,
                     bit32             agIOStatus,
                     agsaFisHeader_t   *agFirstDword,
                     bit32             agIOInfoLen,
                     agsaFrameHandle_t agFrameHandle,
                     void              *ioContext
                    )
{
  /*
    In the process of TestUnitReady
    Process SAT_GET_MEDIA_STATUS
    Process SAT_CHECK_POWER_MODE
  */
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                *smRoot = agNULL;
  smIntRoot_t             *smIntRoot = agNULL;
  smIntContext_t          *smAllShared = agNULL;
  smIORequestBody_t       *smIORequestBody;
  smIORequestBody_t       *smOrgIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatIOContext_t          *satNewIOContext;
  smSatInternalIo_t         *satIntIo;
  smSatInternalIo_t         *satNewIntIo = agNULL;
//  satDeviceData_t         *satDevData;
  smDeviceData_t          *oneDeviceData;

  smScsiRspSense_t          *pSense;
  smIniScsiCmnd_t           *scsiCmnd;
  smIORequest_t             *smOrgIORequest;

  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;
  bit32                     ataError;

  bit32                     status;
  agsaFisRegD2HHeader_t    *statDevToHostFisHeader = agNULL;

  SM_DBG2(("smsatTestUnitReadyCB: start\n"));
  SM_DBG6(("smsatTestUnitReadyCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG5(("smsatTestUnitReadyCB: no internal smSatInternalIo_t satIntIoContext\n"));
    pSense        = satIOContext->pSense;
    scsiCmnd      = satIOContext->pScsiCmnd;
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
  }
  else
  {
    SM_DBG5(("smsatTestUnitReadyCB: yes internal smSatInternalIo_t satIntIoContext\n"));

    /* orginal smIOContext */
    smOrgIORequest         = (smIORequest_t *)satIOContext->satIntIoContext->satOrgSmIORequest;
    smOrgIORequestBody     = (smIORequestBody_t *)smOrgIORequest->tdData;
    satOrgIOContext        = &(smOrgIORequestBody->transport.SATA.satIOContext);

    pSense        = satOrgIOContext->pSense;
    scsiCmnd      = satOrgIOContext->pScsiCmnd;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agIOStatus == OSSA_IO_ABORTED)
  {
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailAborted,
                       agNULL,
                       satIOContext->interruptContext);

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    return;
  }

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatTestUnitReadyCB: agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NOT_READY,
                          0,
                          SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    return;
  }
  /*
    HW checks an error for us and the results is agIOStatus
  */
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisRegDeviceToHost_t is expected */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
    ataError      = statDevToHostFisHeader->error;    /* ATA Eror register   */
    if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
    {
      SM_DBG1(("smsatTestUnitReadyCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
    }
    else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
              (ataStatus & DF_ATA_STATUS_MASK)
            )
    {
      SM_DBG1(("smsatTestUnitReadyCB: FAILED, FAILED, error status!!!\n"));
    }

    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }

    switch (hostToDevFis->h.command)
    {
    case SAT_GET_MEDIA_STATUS:
      SM_DBG1(("smsatTestUnitReadyCB: SAT_GET_MEDIA_STATUS failed!!! \n"));

      /* checking NM bit */
      if (ataError & SCSI_NM_MASK)
      {
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_NOT_READY,
                              0,
                              SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
                              satOrgIOContext);
      }
      else
      {
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_NOT_READY,
                              0,
                              SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE,
                              satOrgIOContext);
      }

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      break;
    case SAT_CHECK_POWER_MODE:
      SM_DBG1(("smsatTestUnitReadyCB: SAT_CHECK_POWER_MODE failed!!! \n"));
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NOT_READY,
                            0,
                            SCSI_SNSCODE_LOGICAL_UNIT_DOES_NOT_RESPOND_TO_SELECTION,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      break;
    default:
      SM_DBG1(("smsatTestUnitReadyCB: default failed command %d!!!\n", hostToDevFis->h.command));

      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NOT_READY,
                            0,
                            SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      break;

    }
    return;
  }/* end error */

  /* ATA command completes sucessfully */
  switch (hostToDevFis->h.command)
  {
  case SAT_GET_MEDIA_STATUS:

    SM_DBG5(("smsatTestUnitReadyCB: SAT_GET_MEDIA_STATUS success\n"));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    satNewIntIo = smsatAllocIntIoResource( smRoot,
                                           smOrgIORequest,
                                           oneDeviceData,
                                           0,
                                           satNewIntIo);
    if (satNewIntIo == agNULL)
    {
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NOT_READY,
                            0,
                            SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      SM_DBG1(("smsatTestUnitReadyCB: momory allocation fails!!!\n"));
      return;
    }

    /*
     * Need to initialize all the fields within satIOContext
     */

    satNewIOContext = smsatPrepareNewIO(
                                        satNewIntIo,
                                        smOrgIORequest,
                                        oneDeviceData,
                                        scsiCmnd,
                                        satOrgIOContext
                                        );

    /* sends SAT_CHECK_POWER_MODE */
    status = smsatTestUnitReady_1( smRoot,
                                   &satNewIntIo->satIntSmIORequest,
                                   satNewIOContext->psmDeviceHandle,
                                   &satNewIntIo->satIntSmScsiXchg,
                                   satNewIOContext);

    if (status != SM_RC_SUCCESS)
    {
      /* sending SAT_CHECK_POWER_MODE fails */
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satNewIntIo);
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NOT_READY,
                            0,
                            SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                        smOrgIORequest,
                        smIOSuccess,
                        SCSI_STAT_CHECK_CONDITION,
                        satOrgIOContext->pSmSenseData,
                        satOrgIOContext->interruptContext );

       SM_DBG1(("smsatTestUnitReadyCB: calling satTestUnitReady_1 fails!!!\n"));
       return;
    }

    break;
  case SAT_CHECK_POWER_MODE:
    SM_DBG5(("smsatTestUnitReadyCB: SAT_CHECK_POWER_MODE success\n"));


    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    /* returns good status */
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       satOrgIOContext->interruptContext );

    break;
  default:
    SM_DBG1(("smsatTestUnitReadyCB: default success command %d!!!\n", hostToDevFis->h.command));
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NOT_READY,
                          0,
                          SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_CAUSE_NOT_REPORTABLE,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );


    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    break;
  }

  return;
}

osGLOBAL void
smsatRequestSenseCB(
                    agsaRoot_t        *agRoot,
                    agsaIORequest_t   *agIORequest,
                    bit32             agIOStatus,
                    agsaFisHeader_t   *agFirstDword,
                    bit32             agIOInfoLen,
                    void              *agParam,
                    void              *ioContext
                   )
{
  /* ATA Vol 1, p299 SAT_SMART_RETURN_STATUS */
  /*
    if threshold exceeds, return SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE
    else call satRequestSense_1 to send CHECK_POWER_MODE
  */

//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                *smRoot = agNULL;
  smIntRoot_t             *smIntRoot = agNULL;
  smIntContext_t          *smAllShared = agNULL;
  smIORequestBody_t       *smIORequestBody;
  smIORequestBody_t       *smOrgIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatIOContext_t          *satNewIOContext;
  smSatInternalIo_t         *satIntIo;
  smSatInternalIo_t         *satNewIntIo = agNULL;
//  satDeviceData_t         *satDevData;
  smDeviceData_t          *oneDeviceData;
  smScsiRspSense_t          *pSense;
  smIniScsiCmnd_t           *scsiCmnd;
  smIORequest_t             *smOrgIORequest;
  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;
  bit32                     status;
  agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
  agsaFisRegD2HData_t       statDevToHostFisData;
  bit32                     allocationLen = 0;
  bit32                     dataLength;
  bit8                      *pDataBuffer = agNULL;

  SM_DBG2(("smsatRequestSenseCB: start\n"));
  SM_DBG4(("smsatRequestSenseCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  /*ttttttthe one */
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatRequestSenseCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    if (satOrgIOContext->superIOFlag)
    {
        pDataBuffer = (bit8 *)(((tiSuperScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg)->sglVirtualAddr);//satOrgIOContext->pSense;
    }
    else
    {
        pDataBuffer = (bit8 *)(((tiScsiInitiatorRequest_t *) satOrgIOContext->smScsiXchg)->sglVirtualAddr);//satOrgIOContext->pSense;

    }
    scsiCmnd        = satOrgIOContext->pScsiCmnd;
    pSense          = satOrgIOContext->pSense;
  }
  else
  {
    SM_DBG4(("smsatRequestSenseCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatRequestSenseCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatRequestSenseCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;

    if (satOrgIOContext->superIOFlag)
    {
      pDataBuffer = (bit8 *)(((tiSuperScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg)->sglVirtualAddr);//satOrgIOContext->pSense;
    }
    else
    {
      pDataBuffer = (bit8 *)(((tiScsiInitiatorRequest_t *) satOrgIOContext->smScsiXchg)->sglVirtualAddr);//satOrgIOContext->pSense;

    }
    scsiCmnd               = satOrgIOContext->pScsiCmnd;
    pSense                 = satOrgIOContext->pSense;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  SM_DBG4(("smsatRequestSenseCB: fis command 0x%x\n", hostToDevFis->h.command));
  
  allocationLen = scsiCmnd->cdb[4];
  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
  SM_DBG1(("smsatRequestSenseCB: allocationLen in CDB %d 0x%x!!!\n", allocationLen,allocationLen));

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatRequestSenseCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                       smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext
                      );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    return;
  }

  /*
    checking IO status, FIS type and error status
  */
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisRegDeviceToHost_t is expected */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */

    /* for debugging */
    if( statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
    {
      if (hostToDevFis->h.command == SAT_SMART && hostToDevFis->h.features == SAT_SMART_RETURN_STATUS)
      {
        SM_DBG1(("smsatRequestSenseCB: FAILED, Wrong FIS type 0x%x and SAT_SMART_RETURN_STATU!!!\n", statDevToHostFisHeader->fisType));
      }
      else
      {
        SM_DBG1(("smsatRequestSenseCB: FAILED, Wrong FIS type 0x%x and SAT_CHECK_POWER_MODE!!!\n",statDevToHostFisHeader->fisType));
      }
    }

    /* for debugging */
    if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
         (ataStatus & DF_ATA_STATUS_MASK)
         )
    {
      if (hostToDevFis->h.command == SAT_SMART && hostToDevFis->h.features == SAT_SMART_RETURN_STATUS)
      {
        SM_DBG1(("smsatRequestSenseCB: FAILED, error status and SAT_SMART_RETURN_STATU!!!\n"));
      }
      else
      {
        SM_DBG1(("smsatRequestSenseCB: FAILED, error status and SAT_CHECK_POWER_MODE!!!\n"));
      }
    }

    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }
    if (hostToDevFis->h.command == SAT_SMART && hostToDevFis->h.features == SAT_SMART_RETURN_STATUS)
    {
      /* report using the original tiIOrequst */
      /* failed during sending SMART RETURN STATUS */
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
                            satOrgIOContext);
      sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
      if (SENSE_DATA_LENGTH < allocationLen)
      {
        /* underrun */
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOUnderRun,
                           allocationLen - SENSE_DATA_LENGTH,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }
      else
      {
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }
    }
    else
    {
      /* report using the original tiIOrequst */
      /* failed during sending SAT_CHECK_POWER_MODE */
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_LOW_POWER_CONDITION_ON,
                            satOrgIOContext);
      sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));

      if (SENSE_DATA_LENGTH < allocationLen)
      {
        /* underrun */
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOUnderRun,
                           allocationLen - SENSE_DATA_LENGTH,
                           agNULL,
                           satOrgIOContext->interruptContext );
       }
       else
       {
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext );
       }
    }


    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  saFrameReadBlock(agRoot, agParam, 0, &statDevToHostFisData, sizeof(agsaFisRegD2HData_t));

  switch (hostToDevFis->h.command)
  {
  case SAT_SMART:
    SM_DBG4(("smsatRequestSenseCB: SAT_SMART_RETURN_STATUS case\n"));
    if (statDevToHostFisData.lbaMid == 0xF4 || statDevToHostFisData.lbaHigh == 0x2C)
    {
      /* threshold exceeds */
      SM_DBG1(("smsatRequestSenseCB: threshold exceeds!!!\n"));


      /* report using the original tiIOrequst */
      /* failed during sending SMART RETURN STATUS */
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
                            satOrgIOContext);
      sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));

      if (SENSE_DATA_LENGTH < allocationLen)
      {
        /* underrun */
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOUnderRun,
                           allocationLen - SENSE_DATA_LENGTH,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }
      else
      {
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }


      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }


    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* done with internally genereated SAT_SMART_RETURN_STATUS */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    /* at this point, successful SMART_RETURN_STATUS
       xmit SAT_CHECK_POWER_MODE
    */
    if (satOrgIOContext->superIOFlag)
    {
        dataLength = ((tiSuperScsiInitiatorRequest_t *) satOrgIOContext->smScsiXchg)->scsiCmnd.expDataLength;
    }
    else
    {
        dataLength = ((tiScsiInitiatorRequest_t *) satOrgIOContext->smScsiXchg)->scsiCmnd.expDataLength;
    }

    satNewIntIo = smsatAllocIntIoResource( smRoot,
                                           smOrgIORequest,
                                           oneDeviceData,
                                           dataLength,
                                           satNewIntIo);
    if (satNewIntIo == agNULL)
    {
      /* failed as a part of sending SMART RETURN STATUS */
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
                            satOrgIOContext);
      sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));

      if (SENSE_DATA_LENGTH < allocationLen)
      {
        /* underrun */
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest,
                           smIOUnderRun,
                           allocationLen - SENSE_DATA_LENGTH,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }
      else
      {
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest,
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }

      SM_DBG1(("smsatRequestSenseCB: momory allocation fails!!!\n"));
      return;
    } /* end of memory allocation failure */


    /*
     * Need to initialize all the fields within satIOContext
     */

    satNewIOContext = smsatPrepareNewIO(
                                        satNewIntIo,
                                        smOrgIORequest,
                                        oneDeviceData,
                                        scsiCmnd,
                                        satOrgIOContext
                                        );

    /* sending SAT_CHECK_POWER_MODE */
    status = smsatRequestSense_1( smRoot,
                                  &satNewIntIo->satIntSmIORequest,
                                  satNewIOContext->psmDeviceHandle,
                                  &satNewIntIo->satIntSmScsiXchg,
                                  satNewIOContext);

    if (status != SM_RC_SUCCESS)
    {
      /* sending SAT_CHECK_POWER_MODE fails */
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satNewIntIo);

      /* failed during sending SAT_CHECK_POWER_MODE */
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_LOW_POWER_CONDITION_ON,
                            satOrgIOContext);
      sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));

      if (SENSE_DATA_LENGTH < allocationLen)
      {
        /* underrun */
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest,
                           smIOUnderRun,
                           allocationLen - SENSE_DATA_LENGTH,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }
      else
      {
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest,
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }

      SM_DBG1(("smsatRequestSenseCB: calling satRequestSense_1 fails!!!\n"));
      return;
    }

    break;
  case SAT_CHECK_POWER_MODE:
    SM_DBG4(("smsatRequestSenseCB: SAT_CHECK_POWER_MODE case\n"));

    /* check ATA STANDBY state */
    if (statDevToHostFisData.sectorCount == 0x00)
    {
      /* in STANDBY */
      SM_DBG1(("smsatRequestSenseCB: in standby!!!\n"));


      /* report using the original tiIOrequst */
      /* failed during sending SAT_CHECK_POWER_MODE */
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_LOW_POWER_CONDITION_ON,
                            satOrgIOContext);
      sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));

      if (SENSE_DATA_LENGTH < allocationLen)
      {
        /* underrun */
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOUnderRun,
                           allocationLen - SENSE_DATA_LENGTH,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }
      else
      {
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* done with internnaly generated SAT_CHECK_POWER_MODE */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    if (oneDeviceData->satFormatState == agTRUE)
    {
      SM_DBG1(("smsatRequestSenseCB: in format!!!\n"));


      /* report using the original tiIOrequst */
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NOT_READY,
                            0,
                            SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
                            satOrgIOContext);
      sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));

      if (SENSE_DATA_LENGTH < allocationLen)
      {
        /* underrun */
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOUnderRun,
                           allocationLen - SENSE_DATA_LENGTH,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }
      else
      {
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext );
      }

      return;
    }

    /* normal: returns good status for requestsense */
    /* report using the original tiIOrequst */
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);
    sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
    SM_DBG4(("smsatRequestSenseCB: returning good status for requestsense\n"));
    if (SENSE_DATA_LENGTH < allocationLen)
    {
      /* underrun */
      SM_DBG6(("smsatRequestSenseCB reporting underrun lenNeeded=0x%x lenReceived=0x%x smIORequest=%p\n",
        SENSE_DATA_LENGTH, allocationLen, smOrgIORequest));      
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOUnderRun,
                         allocationLen - SENSE_DATA_LENGTH,
                         agNULL,
                         satOrgIOContext->interruptContext );

    }
    else
    {
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext );
    }

    break;
  default:
     SM_DBG1(("smsatRequestSenseCB: success but error default case command 0x%x!!!\n", hostToDevFis->h.command));
     /* pSense here is a part of satOrgIOContext */
     pSense = satOrgIOContext->pSmSenseData->senseData;
     satOrgIOContext->pSmSenseData->senseLen = SENSE_DATA_LENGTH;
     /* unspecified case, return no sense and no addition info */
     smsatSetSensePayload( pSense,
                           SCSI_SNSKEY_NO_SENSE,
                           0,
                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                           satOrgIOContext);
     sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));

     tdsmIOCompletedCB( smRoot,
                        smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                        smIOSuccess,
                        SCSI_STAT_CHECK_CONDITION,
                        satOrgIOContext->pSmSenseData,
                        satOrgIOContext->interruptContext );

     smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

     smsatFreeIntIoResource( smRoot,
                             oneDeviceData,
                             satIntIo);
    break;
  } /* switch */

  return;

}

osGLOBAL void
smsatSendDiagnosticCB(
                       agsaRoot_t        *agRoot,
                       agsaIORequest_t   *agIORequest,
                       bit32             agIOStatus,
                       agsaFisHeader_t   *agFirstDword,
                       bit32             agIOInfoLen,
                       agsaFrameHandle_t agFrameHandle,
                       void              *ioContext
                     )
{
  /*
    In the process of SendDiagnotic
    Process READ VERIFY SECTOR(S) EXT two time
    Process SMART ECECUTE OFF-LINE IMMEDIATE
  */
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL;
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatIOContext_t         *satNewIOContext;
  smSatInternalIo_t        *satIntIo;
  smSatInternalIo_t        *satNewIntIo = agNULL;
//  satDeviceData_t         *satDevData;
  smDeviceData_t           *oneDeviceData;
  smScsiRspSense_t         *pSense;
  smIniScsiCmnd_t          *scsiCmnd;
  smIORequest_t            *smOrgIORequest;
  agsaFisRegHostToDevice_t *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;

  bit32                     status;
  agsaFisRegD2HHeader_t    *statDevToHostFisHeader = agNULL;

  SM_DBG2(("smsatSendDiagnosticCB: start\n"));
  SM_DBG5(("smsatSendDiagnosticCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatSendDiagnosticCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satOrgIOContext->pSense;
    scsiCmnd        = satOrgIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG4(("smsatSendDiagnosticCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatSendDiagnosticCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatSendDiagnosticCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    pSense                 = satOrgIOContext->pSense;
    scsiCmnd               = satOrgIOContext->pScsiCmnd;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
     SM_DBG1(("smsatSendDiagnosticCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
     oneDeviceData->satVerifyState = 0;
     oneDeviceData->satBGPendingDiag = agFALSE;

    if (hostToDevFis->d.lbaLow != 0x01 && hostToDevFis->d.lbaLow != 0x02)
    {
      /* no completion for background send diagnotic. It is done in satSendDiagnostic() */
      tdsmIOCompletedCB(
                         smRoot,
                         smOrgIORequest,
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         satOrgIOContext->interruptContext
                        );
     }
     smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

     smsatFreeIntIoResource( smRoot,
                             oneDeviceData,
                              satIntIo);
    return;

  }

  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisRegDeviceToHost_t is expected */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  }

  SM_DBG5(("smsatSendDiagnosticCB: fis command 0x%x\n", hostToDevFis->h.command));

  if( agIOStatus != OSSA_IO_SUCCESS)
  {
  /*
    checking IO status, FIS type and error status
  */
  oneDeviceData->satVerifyState = 0;
  oneDeviceData->satBGPendingDiag = agFALSE;

  if( (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) ||
      ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
      )
  {

    /* for debugging */
    if( agIOStatus != OSSA_IO_SUCCESS)
    {
      if ( hostToDevFis->h.command == SAT_READ_VERIFY_SECTORS_EXT )
      {
        SM_DBG1(("smsatSendDiagnosticCB: FAILED, NOT IO_SUCCESS and SAT_READ_VERIFY_SECTORS(_EXT)!!!\n"));
      }
      else
      {
        SM_DBG1(("smsatSendDiagnosticCB: FAILED, NOT IO_SUCCESS and SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE!!!\n"));
      }
    }

    /* for debugging */
    if( statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
    {
      if ( hostToDevFis->h.command == SAT_READ_VERIFY_SECTORS_EXT )
      {
        SM_DBG1(("smsatSendDiagnosticCB: FAILED, Wrong FIS type 0x%x and SAT_READ_VERIFY_SECTORS(_EXT)!!!\n", statDevToHostFisHeader->fisType));
      }
      else
      {
        SM_DBG1(("smsatSendDiagnosticCB: FAILED, Wrong FIS type 0x%x and SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE!!!\n",statDevToHostFisHeader->fisType));
      }
    }

    /* for debugging */
    if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
         (ataStatus & DF_ATA_STATUS_MASK)
         )
    {
      if ( hostToDevFis->h.command == SAT_READ_VERIFY_SECTORS_EXT )
      {
        SM_DBG1(("smsatSendDiagnosticCB: FAILED, error status and SAT_READ_VERIFY_SECTORS(_EXT)!!!\n"));
      }
      else
      {
        SM_DBG1(("smsatSendDiagnosticCB: FAILED, error status and SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE!!!\n"));
      }
    }

    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }

    if ( (hostToDevFis->h.command == SAT_READ_VERIFY_SECTORS) ||
         (hostToDevFis->h.command == SAT_READ_VERIFY_SECTORS_EXT) )
    {
      /* report using the original tiIOrequst */
      /* failed during sending SAT_READ_VERIFY_SECTORS(_EXT) */
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_HARDWARE_ERROR,
                            0,
                            SCSI_SNSCODE_LOGICAL_UNIT_FAILED_SELF_TEST,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }
    else
    {
      /* report using the original tiIOrequst */
      /* failed during sending SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE */
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_HARDWARE_ERROR,
                            0,
                            SCSI_SNSCODE_LOGICAL_UNIT_FAILED_SELF_TEST,
                            satOrgIOContext);

      if (hostToDevFis->d.lbaLow != 0x01 && hostToDevFis->d.lbaLow != 0x02)
      {
        /* no completion for background send diagnotic. It is done in satSendDiagnostic() */
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );

      }
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }
  }
  }

  /* processing success case */
  switch (hostToDevFis->h.command)
  {
  case SAT_READ_VERIFY_SECTORS:     /* fall through */
  case SAT_READ_VERIFY_SECTORS_EXT:
    SM_DBG5(("smsatSendDiagnosticCB: SAT_READ_VERIFY_SECTORS(_EXT) case\n"));
    tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
    oneDeviceData->satVerifyState++;
    tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
    SM_DBG5(("smsatSendDiagnosticCB: satVerifyState %d\n",oneDeviceData->satVerifyState));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* done with internally genereated AT_READ_VERIFY_SECTORS(_EXT) */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    if (oneDeviceData->satVerifyState == 3)
    {
      /* reset satVerifyState */
      oneDeviceData->satVerifyState = 0;
      /* return GOOD status */
      SM_DBG5(("smsatSendDiagnosticCB: return GOOD status\n"));
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext );
     return;
    }
    else
    {
      /* prepare SAT_READ_VERIFY_SECTORS(_EXT) */
      satNewIntIo = smsatAllocIntIoResource( smRoot,
                                             smOrgIORequest,
                                             oneDeviceData,
                                             0,
                                             satNewIntIo);
      if (satNewIntIo == agNULL)
      {
        /* reset satVerifyState */
        oneDeviceData->satVerifyState = 0;

        /* failed as a part of sending SAT_READ_VERIFY_SECTORS(_EXT) */
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_HARDWARE_ERROR,
                              0,
                              SCSI_SNSCODE_LOGICAL_UNIT_FAILED_SELF_TEST,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest,
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );

        SM_DBG1(("smsatSendDiagnosticCB: momory allocation fails!!!\n"));
        return;
      } /* end of memory allocation failure */

      /*
       * Need to initialize all the fields within satIOContext
       */

      satNewIOContext = smsatPrepareNewIO(
                                          satNewIntIo,
                                          smOrgIORequest,
                                          oneDeviceData,
                                          scsiCmnd,
                                          satOrgIOContext
                                          );

      if (oneDeviceData->satVerifyState == 1)
      {
        /* sending SAT_CHECK_POWER_MODE */
        status = smsatSendDiagnostic_1( smRoot,
                                        &satNewIntIo->satIntSmIORequest,
                                        satNewIOContext->psmDeviceHandle,
                                        &satNewIntIo->satIntSmScsiXchg,
                                        satNewIOContext);
      }
      else
      {
        /* oneDeviceData->satVerifyState == 2 */
        status = smsatSendDiagnostic_2( smRoot,
                                        &satNewIntIo->satIntSmIORequest,
                                        satNewIOContext->psmDeviceHandle,
                                        &satNewIntIo->satIntSmScsiXchg,
                                        satNewIOContext);
      }

      if (status != SM_RC_SUCCESS)
      {
        /* sending SAT_READ_VERIFY_SECTORS(_EXT) fails */
        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satNewIntIo);

        /* failed during sending SAT_READ_VERIFY_SECTORS(_EXT) */
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_HARDWARE_ERROR,
                              0,
                              SCSI_SNSCODE_LOGICAL_UNIT_FAILED_SELF_TEST,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest,
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );

        /* reset satVerifyState */
        oneDeviceData->satVerifyState = 0;
        SM_DBG1(("smsatSendDiagnosticCB: calling satSendDiagnostic_1 or _2 fails!!!\n"));
        return;
      }
    } /* oneDeviceData->satVerifyState == 1 or 2 */

    break;
  case SAT_SMART:
    if (hostToDevFis->h.features == SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE)
    {
      SM_DBG5(("smsatSendDiagnosticCB: SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case\n"));

      oneDeviceData->satBGPendingDiag = agFALSE;

      if (hostToDevFis->d.lbaLow == 0x01 || hostToDevFis->d.lbaLow == 0x02)
      {
        /* for background send diagnostic, no completion here. It is done already. */
        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        /* done with AT_SMART_EXEUTE_OFF_LINE_IMMEDIATE */
        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
        SM_DBG5(("smsatSendDiagnosticCB: returning but no IOCompleted\n"));
      }
      else
      {
        SM_DBG5(("smsatSendDiagnosticCB: returning good status for senddiagnostic\n"));
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext );


        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        /* done with AT_SMART_EXEUTE_OFF_LINE_IMMEDIATE */
        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
      }
    }
    break;
  default:
    SM_DBG1(("smsatSendDiagnosticCB: success but error default case command 0x%x!!!\n", hostToDevFis->h.command));
    /* unspecified case, return no sense and no addition info */
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    break;
  }
  return;

}

osGLOBAL void
smsatStartStopUnitCB(
                     agsaRoot_t        *agRoot,
                     agsaIORequest_t   *agIORequest,
                     bit32             agIOStatus,
                     agsaFisHeader_t   *agFirstDword,
                     bit32             agIOInfoLen,
                     agsaFrameHandle_t agFrameHandle,
                     void              *ioContext
                    )
{
  /*
    In the process of StartStopUnit
    Process FLUSH CACHE (EXT)
    Process STANDBY
    Process READ VERIFY SECTOR(S) EXT
    Process MEDIA EJECT
  */
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL;
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatIOContext_t         *satNewIOContext;
  smSatInternalIo_t        *satIntIo;
  smSatInternalIo_t        *satNewIntIo = agNULL;
//  satDeviceData_t         *satDevData;
  smDeviceData_t           *oneDeviceData;
  smScsiRspSense_t         *pSense;
  smIniScsiCmnd_t          *scsiCmnd;
  smIORequest_t            *smOrgIORequest;
  agsaFisRegHostToDevice_t *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;
  bit32                     status;
  agsaFisRegD2HHeader_t    *statDevToHostFisHeader = agNULL;

  SM_DBG2(("smsatStartStopUnitCB: start\n"));
  SM_DBG5(("smsatStartStopUnitCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatStartStopUnitCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satIOContext->pSense;
    scsiCmnd        = satIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG4(("smsatStartStopUnitCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatStartStopUnitCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatStartStopUnitCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;

    pSense        = satOrgIOContext->pSense;
    scsiCmnd      = satOrgIOContext->pScsiCmnd;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
     SM_DBG1(("smsatStartStopUnitCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));

      /* IMMED == 0 */
      if (!( scsiCmnd->cdb[1] & SCSI_IMMED_MASK))
      {
        SM_DBG1(("smsatStartStopUnitCB: immed bit 0!!!\n"));
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_ABORTED_COMMAND,
                              0,
                              SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );


        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
      }
      /* IMMED == 1 */
      if ( scsiCmnd->cdb[1] & SCSI_IMMED_MASK)
      {
        SM_DBG1(("smsatStartStopUnitCB: immed bit 1!!!\n"));
        smsatSetDeferredSensePayload( pSense,
                                      SCSI_SNSKEY_ABORTED_COMMAND,
                                      0,
                                      SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                                      satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );


        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
     }



    return;
  }

  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisRegDeviceToHost_t is expected */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  }
  /*
    checking IO status, FIS type and error status
  */
  if( agIOStatus != OSSA_IO_SUCCESS)
  {
  if( (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) ||
      ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
      )
  {
    /* for debugging */
    if( agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatStartStopUnitCB: FAILED, NOT IO_SUCCESS!!!\n"));
    }
    else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
    {
      SM_DBG1(("smsatStartStopUnitCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
    }
    else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
         (ataStatus & DF_ATA_STATUS_MASK)
         )
    {
      SM_DBG1(("smsatStartStopUnitCB: FAILED, FAILED, error status!!!\n"));
    }


    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );


      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }

    switch (hostToDevFis->h.command)
    {
    case SAT_FLUSH_CACHE: /* fall through */
    case SAT_FLUSH_CACHE_EXT:
      SM_DBG1(("smsatStartStopUnitCB: SAT_FLUSH_CACHE(_EXT)!!!\n"));
      /* check immed bit in scsi command */
      /* IMMED == 0 */
      if (!( scsiCmnd->cdb[1] & SCSI_IMMED_MASK))
      {
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_ABORTED_COMMAND,
                              0,
                              SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );


        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
      }
      /* IMMED == 1 */
      if ( scsiCmnd->cdb[1] & SCSI_IMMED_MASK)
      {
        smsatSetDeferredSensePayload( pSense,
                                      SCSI_SNSKEY_ABORTED_COMMAND,
                                      0,
                                      SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                                      satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );


        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
      }
      break;
    case SAT_STANDBY:
      SM_DBG5(("smsatStartStopUnitCB: SAT_STANDBY\n"));
      /* check immed bit in scsi command */
      /* IMMED == 0 */
      if (!( scsiCmnd->cdb[1] & SCSI_IMMED_MASK))
      {
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_ABORTED_COMMAND,
                              0,
                              SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );


        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
      }
      /* IMMED == 1 */
      if ( scsiCmnd->cdb[1] & SCSI_IMMED_MASK)
      {
        smsatSetDeferredSensePayload( pSense,
                                      SCSI_SNSKEY_ABORTED_COMMAND,
                                      0,
                                      SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                                      satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );


        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
      }
      break;
    case SAT_READ_VERIFY_SECTORS:     /* fall through */
    case SAT_READ_VERIFY_SECTORS_EXT:
      SM_DBG5(("smsatStartStopUnitCB: SAT_READ_VERIFY_SECTORS(_EXT)\n"));
       /* IMMED == 0 */
      if (!( scsiCmnd->cdb[1] & SCSI_IMMED_MASK))
      {
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_ABORTED_COMMAND,
                              0,
                              SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );


        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
      }
      /* IMMED == 1 */
      if ( scsiCmnd->cdb[1] & SCSI_IMMED_MASK)
      {
        smsatSetDeferredSensePayload( pSense,
                                      SCSI_SNSKEY_ABORTED_COMMAND,
                                      0,
                                      SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                                      satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );


        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
      }
      break;
    case SAT_MEDIA_EJECT:
      SM_DBG5(("smsatStartStopUnitCB: SAT_MEDIA_EJECT\n"));
       /* IMMED == 0 */
      if (!( scsiCmnd->cdb[1] & SCSI_IMMED_MASK))
      {
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_ABORTED_COMMAND,
                              0,
                              SCSI_SNSCODE_MEDIA_LOAD_OR_EJECT_FAILED,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );


        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
      }
      /* IMMED == 1 */
      if ( scsiCmnd->cdb[1] & SCSI_IMMED_MASK)
      {
        smsatSetDeferredSensePayload( pSense,
                                      SCSI_SNSKEY_ABORTED_COMMAND,
                                      0,
                                      SCSI_SNSCODE_MEDIA_LOAD_OR_EJECT_FAILED,
                                      satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );

        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
      }
      break;
    default:
      /* unspecified case, return no sense and no addition info */
      SM_DBG5(("smsatStartStopUnitCB: default command %d\n", hostToDevFis->h.command));
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );


      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      break;
    } /* switch */

    return;
  } /* error check */
  }

  /* ATA command completes sucessfully */
  switch (hostToDevFis->h.command)
  {
  case SAT_FLUSH_CACHE: /* fall through */
  case SAT_FLUSH_CACHE_EXT:
    SM_DBG5(("smsatStartStopUnitCB: SAT_READ_VERIFY_SECTORS(_EXT) success case\n"));


    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* done with SAT_FLUSH_CACHE(_EXT) */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    /* at this point, successful SAT_READ_VERIFY_SECTORS(_EXT)
       send SAT_SATNDBY
    */
    satNewIntIo = smsatAllocIntIoResource( smRoot,
                                           smOrgIORequest,
                                           oneDeviceData,
                                           0,
                                           satNewIntIo);
    if (satNewIntIo == agNULL)
    {
      /* IMMED == 0 */
      if (!( scsiCmnd->cdb[1] & SCSI_IMMED_MASK))
      {
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_ABORTED_COMMAND,
                              0,
                              SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                              satOrgIOContext);
      }
      else   /* IMMED == 1 */
      {
        smsatSetDeferredSensePayload( pSense,
                                      SCSI_SNSKEY_ABORTED_COMMAND,
                                      0,
                                      SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                                      satOrgIOContext);
      }
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      SM_DBG1(("smsatStartStopUnitCB: momory allocation fails!!!\n"));
      return;
    } /* end of memory allocation failure */

    /*
     * Need to initialize all the fields within satIOContext
     */

    satNewIOContext = smsatPrepareNewIO(
                                        satNewIntIo,
                                        smOrgIORequest,
                                        oneDeviceData,
                                        scsiCmnd,
                                        satOrgIOContext
                                        );

    /* sending SAT_STANDBY */
    status = smsatStartStopUnit_1( smRoot,
                                   &satNewIntIo->satIntSmIORequest,
                                   satNewIOContext->psmDeviceHandle,
                                   &satNewIntIo->satIntSmScsiXchg,
                                   satNewIOContext);

    if (status != SM_RC_SUCCESS)
    {
      /* sending SAT_CHECK_POWER_MODE fails */
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satNewIntIo);

      /* IMMED == 0 */
      if (!( scsiCmnd->cdb[1] & SCSI_IMMED_MASK))
      {
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_ABORTED_COMMAND,
                              0,
                              SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                              satOrgIOContext);
      }
      else   /* IMMED == 1 */
      {
        smsatSetDeferredSensePayload( pSense,
                                      SCSI_SNSKEY_ABORTED_COMMAND,
                                      0,
                                      SCSI_SNSCODE_COMMAND_SEQUENCE_ERROR,
                                      satOrgIOContext);
      }
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      SM_DBG1(("smsatStartStopUnitCB: calling satStartStopUnit_1 fails!!!\n"));
      return;
    }
    break;
  case SAT_STANDBY:
    SM_DBG5(("smsatStartStopUnitCB: SAT_STANDBY success case\n"));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* done with SAT_STANDBY */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    /*
      if immed == 0, return good status
     */
    /* IMMED == 0 */
    if (!( scsiCmnd->cdb[1] & SCSI_IMMED_MASK))
    {
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest,
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext );
    }
    oneDeviceData->satStopState = agTRUE;
    break;
  case SAT_READ_VERIFY_SECTORS:     /* fall through */
  case SAT_READ_VERIFY_SECTORS_EXT:
    SM_DBG5(("smsatStartStopUnitCB: SAT_READ_VERIFY_SECTORS(_EXT) success case\n"));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* done with SAT_READ_VERIFY_SECTORS(_EXT) */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    /*
      if immed == 0, return good status
     */
    if (!( scsiCmnd->cdb[1] & SCSI_IMMED_MASK))
    {
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest,
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext );
    }
    /*
      if immed == 0, return good status
     */
    /*
      don't forget to check and set driver state; Active power state
    */
    oneDeviceData->satStopState = agFALSE;
    break;
  case SAT_MEDIA_EJECT:
    SM_DBG5(("smsatStartStopUnitCB: SAT_MEDIA_EJECT success case\n"));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* done with SAT_READ_VERIFY_SECTORS(_EXT) */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    /*
      if immed == 0, return good status
     */
    if (!( scsiCmnd->cdb[1] & SCSI_IMMED_MASK))
    {
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext );
    }
    break;
  default:
    SM_DBG1(("smsatStartStopUnitCB:success but  error default case command 0x%x!!!\n", hostToDevFis->h.command));

    /* unspecified case, return no sense and no addition info */
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    break;
  }
  return;

}

osGLOBAL void
smsatWriteSame10CB(
                   agsaRoot_t        *agRoot,
                   agsaIORequest_t   *agIORequest,
                   bit32             agIOStatus,
                   agsaFisHeader_t   *agFirstDword,
                   bit32             agIOInfoLen,
                   agsaFrameHandle_t agFrameHandle,
                   void              *ioContext
                  )
{
  smRoot_t                *smRoot = agNULL;
  smIntRoot_t             *smIntRoot = agNULL;
  smIntContext_t          *smAllShared = agNULL;
  smIORequestBody_t       *smIORequestBody;
  smIORequestBody_t       *smOrgIORequestBody;
  smIORequestBody_t       *smNewIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatIOContext_t          *satNewIOContext;
  smSatInternalIo_t         *satIntIo;
  smSatInternalIo_t         *satNewIntIo = agNULL;
  smDeviceData_t          *oneDeviceData;
  smScsiRspSense_t          *pSense;
  smIniScsiCmnd_t           *scsiCmnd;
  smIORequest_t             *smOrgIORequest;
  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;
  bit32                     status;
  bit32                     sectorcount = 0;
  bit32                     lba = 0, tl = 0;
  agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
  agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL;

  SM_DBG2(("smsatWriteSame10CB: start\n"));
  SM_DBG5(("smsatWriteSame10CB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatWriteSame10CB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satIOContext->pSense;
    scsiCmnd        = satIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG4(("smsatWriteSame10CB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatWriteSame10CB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatWriteSame10CB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;

    pSense        = satOrgIOContext->pSense;
    scsiCmnd      = satOrgIOContext->pScsiCmnd;
  }


  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
     SM_DBG1(("smsatWriteSame10CB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
     smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

     tdsmIOCompletedCB( smRoot,
                        smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                        smIOSuccess,
                        SCSI_STAT_CHECK_CONDITION,
                        satOrgIOContext->pSmSenseData,
                        satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* FP, DMA and PIO write */
    /* First, assumed to be Reg Device to Host FIS */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  }

  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS)
    {
      statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H);

      /* Get ATA Status register */
      ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70);               /* bits 4,5,6 */
      ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07);   /* bits 0,1,2 */
    }
  }

  if( agIOStatus != OSSA_IO_SUCCESS)
  {
  /*
    checking IO status, FIS type and error status
    FIS type should be either REG_DEV_TO_HOST_FIS or SET_DEV_BITS_FIS
  */
  if (  ((statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) &&
        (statDevToHostFisHeader->fisType != SET_DEV_BITS_FIS)) ||
       ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
       )
  {
    /* for debugging */
    if( agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatWriteSame10CB: FAILED, NOT IO_SUCCESS!!!\n"));
    }
    else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
    {
      SM_DBG1(("smsatWriteSame10CB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
    }
    else if (statDevToHostFisHeader->fisType != SET_DEV_BITS_FIS)
    {
      SM_DBG1(("smsatWriteSame10CB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
    }
    else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
              (ataStatus & DF_ATA_STATUS_MASK)
              )
    {
      SM_DBG1(("smsatWriteSame10CB: FAILED, FAILED, error status!!!\n"));
    }

    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );


      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }

    /* for debugging */
    switch (hostToDevFis->h.command)
    {
    case SAT_WRITE_DMA_EXT:
      SM_DBG1(("smsatWriteSame10CB: SAT_WRITE_DMA_EXT!!!\n"));
      break;
    case SAT_WRITE_SECTORS_EXT:
      SM_DBG1(("smsatWriteSame10CB: SAT_WRITE_SECTORS_EXT!!!\n"));
      break;
    case SAT_WRITE_FPDMA_QUEUED:
      SM_DBG1(("smsatWriteSame10CB: SAT_WRITE_FPDMA_QUEUED!!!\n"));
      break;
    default:
      SM_DBG1(("smsatWriteSame10CB: error default case command 0x%x!!!\n", hostToDevFis->h.command));
      break;
    }

    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );


    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  } /* end error */
  }

  /* process success from this point on */
  /*
    note: inefficient implementation until a single block can be manipulated
  */

  if (hostToDevFis->h.command == SAT_WRITE_DMA_EXT)
  {
    SM_DBG5(("smsatWriteSame10CB: SAT_WRITE_DMA_EXT success\n"));
  }
  else if (hostToDevFis->h.command == SAT_WRITE_SECTORS_EXT)
  {
    SM_DBG5(("smsatWriteSame10CB: SAT_WRITE_SECTORS_EXT success\n"));
  }
  else if (hostToDevFis->h.command == SAT_WRITE_FPDMA_QUEUED)
  {
    SM_DBG5(("smsatWriteSame10CB: SAT_WRITE_FPDMA_QUEUED success\n"));
  }
  else
  {
    SM_DBG1(("smsatWriteSame10CB: error case command 0x%x success!!!\n", hostToDevFis->h.command));
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );


    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }


  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

  /* free */
  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);

  /*
    increment LBA by one, keeping the same sector count(1)
    sends another ATA command with the changed parameters
  */

  tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
  oneDeviceData->satSectorDone++;
  tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);

  SM_DBG1(("smsatWriteSame10CB: sectordone %d!!!\n", oneDeviceData->satSectorDone));

  lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
      + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
  tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];

  SM_DBG5(("smsatWriteSame10CB: lba 0x%x tl 0x%x\n", lba, tl));

  if (tl == 0)
  {
    /* (oneDeviceData->satMaxUserAddrSectors - 1) - lba*/
    sectorcount = (0x0FFFFFFF - 1) - lba;
  }
  else
  {
    sectorcount = tl;
  }

  if (sectorcount <= 0)
  {
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );
    SM_DBG1(("smsatWriteSame10CB: incorrect sectorcount 0x%x!!!\n", sectorcount));
    return;
  }

  if (sectorcount == oneDeviceData->satSectorDone)
  {
    /*
      done with writesame
    */
    SM_DBG1(("smsatWriteSame10CB: return writesame done!!!\n"));
    oneDeviceData->satSectorDone = 0;

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       satOrgIOContext->interruptContext );
  }
  else
  {
    /* sends another ATA command */
    if (hostToDevFis->h.command == SAT_WRITE_DMA_EXT)
    {
      SM_DBG1(("smsatWriteSame10CB: sends another SAT_WRITE_DMA_EXT!!!\n"));
    }
    else if (hostToDevFis->h.command == SAT_WRITE_SECTORS_EXT)
    {
      SM_DBG1(("smsatWriteSame10CB: sends another SAT_WRITE_SECTORS_EXT!!!\n"));
    }
    else if (hostToDevFis->h.command == SAT_WRITE_FPDMA_QUEUED)
    {
      SM_DBG1(("smsatWriteSame10CB: sends another SAT_WRITE_FPDMA_QUEUED!!!\n"));
    }

    satNewIntIo = smsatAllocIntIoResource( smRoot,
                                           smOrgIORequest,
                                           oneDeviceData,
                                           0,
                                           satNewIntIo);
    if (satNewIntIo == agNULL)
    {
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );
      SM_DBG1(("smsatWriteSame10CB: momory allocation fails!!!\n"));
      return;
    } /* end memory allocation */

    /* the one to be used */
    smNewIORequestBody = satNewIntIo->satIntRequestBody;
    satNewIOContext = &smNewIORequestBody->transport.SATA.satIOContext;

    satNewIOContext->pSatDevData   = oneDeviceData;
    satNewIOContext->pFis          = &smNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
    satNewIOContext->pScsiCmnd     = &satNewIntIo->satIntSmScsiXchg.scsiCmnd;
    /* saves scsi command for LBA and number of blocks */
    sm_memcpy(satNewIOContext->pScsiCmnd, scsiCmnd, sizeof(smIniScsiCmnd_t));
    satNewIOContext->pSense        = &smNewIORequestBody->transport.SATA.sensePayload;
    satNewIOContext->pSmSenseData  = &smNewIORequestBody->transport.SATA.smSenseData;
    satNewIOContext->pSmSenseData->senseData = satNewIOContext->pSense;
    satNewIOContext->smRequestBody = satNewIntIo->satIntRequestBody;
    satNewIOContext->interruptContext = satNewIOContext->interruptContext;
    satNewIOContext->satIntIoContext  = satNewIntIo;
    satNewIOContext->psmDeviceHandle = satIOContext->psmDeviceHandle;
    /* saves smScsiXchg; only for writesame10() */
    satNewIOContext->smScsiXchg = satOrgIOContext->smScsiXchg;

    if (hostToDevFis->h.command == SAT_WRITE_DMA_EXT)
    {
      status = smsatWriteSame10_1( smRoot,
                                   &satNewIntIo->satIntSmIORequest,
                                   satNewIOContext->psmDeviceHandle,
                                   &satNewIntIo->satIntSmScsiXchg,
                                   satNewIOContext,
                                   lba + oneDeviceData->satSectorDone
                                   );
    }
    else if (hostToDevFis->h.command == SAT_WRITE_SECTORS_EXT)
    {
      status = smsatWriteSame10_2( smRoot,
                                   &satNewIntIo->satIntSmIORequest,
                                   satNewIOContext->psmDeviceHandle,
                                   &satNewIntIo->satIntSmScsiXchg,
                                   satNewIOContext,
                                   lba + oneDeviceData->satSectorDone
                                  );
    }
    else if (hostToDevFis->h.command == SAT_WRITE_FPDMA_QUEUED)
    {
      status = smsatWriteSame10_3( smRoot,
                                   &satNewIntIo->satIntSmIORequest,
                                   satNewIOContext->psmDeviceHandle,
                                   &satNewIntIo->satIntSmScsiXchg,
                                   satNewIOContext,
                                   lba + oneDeviceData->satSectorDone
                                  );
    }
    else
    {
      status = tiError;
      SM_DBG1(("smsatWriteSame10CB: sucess but error in command 0x%x!!!\n", hostToDevFis->h.command));
    }

    if (status != SM_RC_SUCCESS)
    {
      /* sending ATA command fails */
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satNewIntIo);
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );
      SM_DBG1(("smsatWriteSame10CB:calling satWriteSame10_1 fails!!!\n"));
      return;
    } /* end send fails */

  } /* end sends another ATA command */

  return;

}

osGLOBAL void
smsatLogSenseCB(
                agsaRoot_t        *agRoot,
                agsaIORequest_t   *agIORequest,
                bit32             agIOStatus,
                agsaFisHeader_t   *agFirstDword,
                bit32             agIOInfoLen,
                void              *agParam,
                void              *ioContext
               )
{
  smRoot_t                  *smRoot = agNULL;
  smIntRoot_t               *smIntRoot = agNULL;
  smIntContext_t            *smAllShared = agNULL;
  smIORequestBody_t         *smIORequestBody;
  smIORequestBody_t         *smOrgIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatInternalIo_t         *satIntIo;
//  satDeviceData_t          *satDevData;
  smDeviceData_t            *oneDeviceData;

  smScsiRspSense_t          *pSense;
  smIORequest_t             *smOrgIORequest;

  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
  bit32                      ataStatus = 0;
  smScsiInitiatorRequest_t  *smScsiRequest; /* tiScsiXchg */
  smScsiInitiatorRequest_t  *smOrgScsiRequest; /* tiScsiXchg */
  satReadLogExtSelfTest_t   *virtAddr1;
  satSmartReadLogSelfTest_t *virtAddr2;
  bit8                      *pLogPage;
  bit8                      LogPage[SELFTEST_RESULTS_LOG_PAGE_LENGTH];
  bit8                       SelfTestExecutionStatus = 0;
  bit32                      i = 0;

  agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
  agsaFisRegD2HData_t        statDevToHostFisData;
  smIniScsiCmnd_t           *scsiCmnd;
  bit32                      allocationLen = 0;

  SM_DBG2(("smsatLogSenseCB: start\n"));
  SM_DBG5(("smsatLogSenseCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  if (satIOContext == agNULL)
  {
    SM_DBG1(("smsatLogSenseCB: satIOContext is NULL\n"));
    return;
  }
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatLogSenseCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satOrgIOContext->pSense;
    smOrgScsiRequest   = satOrgIOContext->smScsiXchg;
    /* SCSI command response payload to OS layer */
    pLogPage        = (bit8 *) smOrgScsiRequest->sglVirtualAddr;
    /* ATA command response payload */
    smScsiRequest   = satOrgIOContext->smScsiXchg;
    scsiCmnd        = satOrgIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG4(("smsatLogSenseCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;

    pSense        = satOrgIOContext->pSense;
    smOrgScsiRequest   = satOrgIOContext->smScsiXchg;
    /* SCSI command response payload to OS layer */
    pLogPage        = (bit8 *) smOrgScsiRequest->sglVirtualAddr;
    /* ATA command response payload */
    smScsiRequest   =  (smScsiInitiatorRequest_t *)&(satIntIo->satIntSmScsiXchg);
    scsiCmnd        = satOrgIOContext->pScsiCmnd;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatLogSenseCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                       smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext
                      );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* non-data and pio read -> device to host and pio setup fis are expected */
    /*
      first, assumed to be Reg Device to Host FIS
      This is OK to just find fis type
    */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  }

  if( agIOStatus != OSSA_IO_SUCCESS)
  {
  if ( ((statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) &&
        (statDevToHostFisHeader->fisType != PIO_SETUP_DEV_TO_HOST_FIS)) ||
       ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
       )
  {
    /* for debugging */
    if( agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatLogSenseCB: FAILED, NOT IO_SUCCESS!!!\n"));
    }
    else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
    {
      SM_DBG1(("smsatLogSenseCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
    }
    else if (statDevToHostFisHeader->fisType != PIO_SETUP_DEV_TO_HOST_FIS)
    {
      SM_DBG1(("smsatLogSenseCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
    }
    else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
              (ataStatus & DF_ATA_STATUS_MASK)
              )
    {
      SM_DBG1(("smsatLogSenseCB: FAILED, FAILED, error status!!!\n"));
    }

    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }

    /* for debugging */
    if (hostToDevFis->h.command == SAT_READ_LOG_EXT)
    {
      SM_DBG1(("smsatLogSenseCB: SAT_READ_LOG_EXT failed!!!\n"));
    }
    else if (hostToDevFis->h.command == SAT_SMART)
    {
      if (hostToDevFis->h.features == SAT_SMART_READ_LOG)
      {
        SM_DBG1(("smsatLogSenseCB: SAT_SMART_READ_LOG failed!!!\n"));
      }
      else if (hostToDevFis->h.features == SAT_SMART_RETURN_STATUS)
      {
        SM_DBG1(("smsatLogSenseCB: SAT_SMART_RETURN_STATUS failed!!!\n"));
      }
      else
      {
        SM_DBG1(("smsatLogSenseCB: error unknown command 0x%x feature 0x%x!!!\n", hostToDevFis->h.command, hostToDevFis->h.features));
      }
    }
    else
    {
      SM_DBG1(("smsatLogSenseCB: error default case command 0x%x!!!\n", hostToDevFis->h.command));
    }

    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;

  } /* error checking */
  }

  /* prcessing the success case */
  saFrameReadBlock(agRoot, agParam, 0, &statDevToHostFisData, sizeof(agsaFisRegD2HData_t));

  allocationLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
  SM_DBG5(("smsatLogSenseCB: allocationLen in CDB %d 0x%x\n", allocationLen,allocationLen));


  if (hostToDevFis->h.command == SAT_READ_LOG_EXT)
  {
    SM_DBG5(("smsatLogSenseCB: SAT_READ_LOG_EXT success\n"));

    /* process log data and sends it to upper */

    /* ATA: Extended Self-Test Log */
    virtAddr1  = (satReadLogExtSelfTest_t *)(smScsiRequest->sglVirtualAddr);
    /*
      ATA/ATAPI VOLII, p197, 287
      self-test execution status (4 bits); ((virtAddr1->byte[5] & 0xF0) >> 4)
    */
    SelfTestExecutionStatus  = (bit8)(((virtAddr1->byte[5] & 0xF0) >> 4));

    /* fills in the log page from ATA log page */
    /* SPC-4, 7.2.10, Table 216, 217, p 259 - 260 */
    LogPage[0] = 0x10; /* page code */
    LogPage[1] = 0;
    LogPage[2] = 0x01;    /* 0x190, page length */
    LogPage[3] = 0x90;

    /* SPC-4, Table 217 */
    LogPage[4] = 0;    /* Parameter Code */
    LogPage[5] = 0x01; /* Parameter Code,  unspecfied but ... */
    LogPage[6] = 3;    /* unspecified but ... */
    LogPage[7] = 0x10; /* Parameter Length */
    LogPage[8] = (bit8)(0 | ((virtAddr1->byte[5] & 0xF0) >> 4)); /* Self Test Code and Self-Test Result */
    LogPage[9] = 0;    /* self test number */
    LogPage[10] = virtAddr1->byte[7];    /* time stamp, MSB */
    LogPage[11] = virtAddr1->byte[6];    /* time stamp, LSB */

    LogPage[12] = 0;    /* address of first failure MSB*/
    LogPage[13] = 0;    /* address of first failure */
    LogPage[14] = virtAddr1->byte[14];    /* address of first failure */
    LogPage[15] = virtAddr1->byte[13];    /* address of first failure */
    LogPage[16] = virtAddr1->byte[12];    /* address of first failure */
    LogPage[17] = virtAddr1->byte[11];    /* address of first failure */
    LogPage[18] = virtAddr1->byte[10];    /* address of first failure */
    LogPage[19] = virtAddr1->byte[9];    /* address of first failure LSB */

    /* SAT rev8 Table75, p 76 */
    switch (SelfTestExecutionStatus)
    {
    case 0:
      LogPage[20] = 0 | SCSI_SNSKEY_NO_SENSE;
      LogPage[21] = (SCSI_SNSCODE_NO_ADDITIONAL_INFO >> 8) & 0xFF;
      LogPage[22] = SCSI_SNSCODE_NO_ADDITIONAL_INFO & 0xFF;
      break;
    case 1:
      LogPage[20] = 0 | SCSI_SNSKEY_ABORTED_COMMAND;
      LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
      LogPage[22] = 0x81;
      break;
    case 2:
      LogPage[20] = 0 | SCSI_SNSKEY_ABORTED_COMMAND;
      LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
      LogPage[22] = 0x82;
      break;
    case 3:
      LogPage[20] = 0 | SCSI_SNSKEY_ABORTED_COMMAND;
      LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
      LogPage[22] = 0x83;
      break;
    case 4:
      LogPage[20] = 0 | SCSI_SNSKEY_HARDWARE_ERROR;
      LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
      LogPage[22] = 0x84;
    break;
    case 5:
      LogPage[20] = 0 | SCSI_SNSKEY_HARDWARE_ERROR;
      LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
      LogPage[22] = 0x85;
      break;
    case 6:
      LogPage[20] = 0 | SCSI_SNSKEY_HARDWARE_ERROR;
      LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
      LogPage[22] = 0x86;
      break;
    case 7:
      LogPage[20] = 0 | SCSI_SNSKEY_MEDIUM_ERROR;
      LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
      LogPage[22] = 0x87;
      break;
    case 8:
      LogPage[20] = 0 | SCSI_SNSKEY_HARDWARE_ERROR;
      LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
      LogPage[22] = 0x88;
      break;
    case 9: /* fall through */
    case 10:/* fall through */
    case 11:/* fall through */
    case 12:/* fall through */
    case 13:/* fall through */
    case 14:
      LogPage[20] = 0 | SCSI_SNSKEY_NO_SENSE;
      LogPage[21] = (SCSI_SNSCODE_NO_ADDITIONAL_INFO >> 8) & 0xFF;
      LogPage[22] = SCSI_SNSCODE_NO_ADDITIONAL_INFO & 0xFF;
      break;
    case 15:
      LogPage[20] = 0 | SCSI_SNSKEY_NO_SENSE;
      LogPage[21] = (SCSI_SNSCODE_NO_ADDITIONAL_INFO >> 8) & 0xFF;
      LogPage[22] = SCSI_SNSCODE_NO_ADDITIONAL_INFO & 0xFF;
      break;
    default:
      SM_DBG1(("smsatLogSenseCB: Error, incorrect SelfTestExecutionStatus 0x%x!!!\n", SelfTestExecutionStatus));

      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);

      return;
    }

    LogPage[23] = 0;    /* vendor specific */

    /* the rest of Self-test results log */
    /* 403 is from SPC-4, 7.2.10, Table 216, p 259*/
    for (i=24;i<=403;i++)
    {
      LogPage[i] = 0;    /* vendor specific */
    }

    sm_memcpy(pLogPage, LogPage, MIN(allocationLen, SELFTEST_RESULTS_LOG_PAGE_LENGTH));
    if (SELFTEST_RESULTS_LOG_PAGE_LENGTH < allocationLen)
    {
      SM_DBG6(("smsatLogSenseCB: 1st underrun allocationLen %d len %d \n", allocationLen, SELFTEST_RESULTS_LOG_PAGE_LENGTH));

      /* underrun */
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                         smIOUnderRun,
                         allocationLen - SELFTEST_RESULTS_LOG_PAGE_LENGTH,
                         agNULL,
                         satOrgIOContext->interruptContext );

    }
    else
    {
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext);
    }

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    return;
  }
  else if (hostToDevFis->h.command == SAT_SMART)
  {
    if (hostToDevFis->h.features == SAT_SMART_READ_LOG)
    {
      SM_DBG5(("smsatLogSenseCB: SAT_SMART_READ_LOG success\n"));
      /* process log data and sends it to upper */

      /* ATA: Extended Self-Test Log */
      virtAddr2  = (satSmartReadLogSelfTest_t *)(smScsiRequest->sglVirtualAddr);
      /*
        SPC-4, p197, 287
        self-test execution status (4 bits); ((virtAddr2->byte[3] & 0xF0) >> 4)
      */
      SelfTestExecutionStatus  = (bit8)(((virtAddr2->byte[3] & 0xF0) >> 4));

      /* fills in the log page from ATA log page */
      /* SPC-4, 7.2.10, Table 216, 217, p 259 - 260 */
      LogPage[0] = 0x10;    /* page code */
      LogPage[1] = 0;
      LogPage[2] = 0x01;    /* 0x190, page length */
      LogPage[3] = 0x90;    /* 0x190, page length */

      /* SPC-4, Table 217 */
      LogPage[4] = 0;    /* Parameter Code */
      LogPage[5] = 0x01; /* Parameter Code unspecfied but ... */
      LogPage[6] = 3;    /* unspecified but ... */
      LogPage[7] = 0x10; /* Parameter Length */
      LogPage[8] = (bit8)(0 | ((virtAddr2->byte[3] & 0xF0) >> 4)); /* Self Test Code and Self-Test Result */
      LogPage[9] = 0;    /* self test number */
      LogPage[10] = virtAddr2->byte[5];    /* time stamp, MSB */
      LogPage[11] = virtAddr2->byte[4];    /* time stamp, LSB */

      LogPage[12] = 0;    /* address of first failure MSB*/
      LogPage[13] = 0;    /* address of first failure */
      LogPage[14] = 0;    /* address of first failure */
      LogPage[15] = 0;    /* address of first failure */
      LogPage[16] = virtAddr2->byte[10];    /* address of first failure */
      LogPage[17] = virtAddr2->byte[9];    /* address of first failure */
      LogPage[18] = virtAddr2->byte[8];    /* address of first failure */
      LogPage[19] = virtAddr2->byte[7];    /* address of first failure LSB */

      /* SAT rev8 Table75, p 76 */
      switch (SelfTestExecutionStatus)
      {
      case 0:
        LogPage[20] = 0 | SCSI_SNSKEY_NO_SENSE;
        LogPage[21] = (SCSI_SNSCODE_NO_ADDITIONAL_INFO >> 8) & 0xFF;
        LogPage[22] = SCSI_SNSCODE_NO_ADDITIONAL_INFO & 0xFF;
        break;
      case 1:
        LogPage[20] = 0 | SCSI_SNSKEY_ABORTED_COMMAND;
        LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
        LogPage[22] = 0x81;
        break;
      case 2:
        LogPage[20] = 0 | SCSI_SNSKEY_ABORTED_COMMAND;
        LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
        LogPage[22] = 0x82;
        break;
      case 3:
        LogPage[20] = 0 | SCSI_SNSKEY_ABORTED_COMMAND;
        LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
        LogPage[22] = 0x83;
        break;
      case 4:
        LogPage[20] = 0 | SCSI_SNSKEY_HARDWARE_ERROR;
        LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
        LogPage[22] = 0x84;
        break;
      case 5:
        LogPage[20] = 0 | SCSI_SNSKEY_HARDWARE_ERROR;
        LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
        LogPage[22] = 0x85;
        break;
      case 6:
        LogPage[20] = 0 | SCSI_SNSKEY_HARDWARE_ERROR;
        LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
        LogPage[22] = 0x86;
        break;
      case 7:
        LogPage[20] = 0 | SCSI_SNSKEY_MEDIUM_ERROR;
        LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
        LogPage[22] = 0x87;
        break;
      case 8:
        LogPage[20] = 0 | SCSI_SNSKEY_HARDWARE_ERROR;
        LogPage[21] = (SCSI_SNSCODE_DIAGNOSTIC_FAILURE_ON_COMPONENT_NN >> 8) & 0xFF;
        LogPage[22] = 0x88;
        break;
      case 9: /* fall through */
      case 10:/* fall through */
      case 11:/* fall through */
      case 12:/* fall through */
      case 13:/* fall through */
      case 14:
        /* unspecified */
        LogPage[20] = 0 | SCSI_SNSKEY_NO_SENSE;
        LogPage[21] = (SCSI_SNSCODE_NO_ADDITIONAL_INFO >> 8) & 0xFF;
        LogPage[22] = SCSI_SNSCODE_NO_ADDITIONAL_INFO & 0xFF;
        break;
      case 15:
        LogPage[20] = 0 | SCSI_SNSKEY_NO_SENSE;
        LogPage[21] = (SCSI_SNSCODE_NO_ADDITIONAL_INFO >> 8) & 0xFF;
        LogPage[22] = SCSI_SNSCODE_NO_ADDITIONAL_INFO & 0xFF;
        break;
      default:
        SM_DBG1(("smsatLogSenseCB: Error, incorrect SelfTestExecutionStatus 0x%x!!!\n", SelfTestExecutionStatus));

        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_NO_SENSE,
                              0,
                              SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );

        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);

        return;
      }

      LogPage[23] = 0;    /* vendor specific */

      /* the rest of Self-test results log */
      /* 403 is from SPC-4, 7.2.10, Table 216, p 259*/
      for (i=24;i<=403;i++)
      {
        LogPage[i] = 0;    /* vendor specific */
      }

      sm_memcpy(pLogPage, LogPage, MIN(allocationLen, SELFTEST_RESULTS_LOG_PAGE_LENGTH));
      if (SELFTEST_RESULTS_LOG_PAGE_LENGTH < allocationLen)
      {
        SM_DBG6(("smsatLogSenseCB: 2nd underrun allocationLen %d len %d \n", allocationLen, SELFTEST_RESULTS_LOG_PAGE_LENGTH));

        /* underrun */
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOUnderRun,
                           allocationLen - SELFTEST_RESULTS_LOG_PAGE_LENGTH,
                           agNULL,
                           satOrgIOContext->interruptContext );

      }
      else
      {
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest,
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext);
      }
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);

      return;
    }
    else if (hostToDevFis->h.features == SAT_SMART_RETURN_STATUS)
    {
      SM_DBG5(("smsatLogSenseCB: SAT_SMART_RETURN_STATUS success\n"));

      /* fills in the log page from ATA output */
      /* SPC-4, 7.2.5, Table 209, 211, p 255 */
      LogPage[0] = 0x2F;    /* page code unspecified */
      LogPage[1] = 0;       /* reserved */
      LogPage[2] = 0;       /* page length */
      LogPage[3] = 0x07;    /* page length */

      /*
        SPC-4, 7.2.5, Table 211, p 255
        no vendor specific field
       */
      LogPage[4] = 0;    /* Parameter Code */
      LogPage[5] = 0;    /* Parameter Code unspecfied but to do: */
      LogPage[6] = 0;    /* unspecified */
      LogPage[7] = 0x03; /* Parameter length, unspecified */

      /* SAT rev8, 10.2.3.1 Table 72, p 73 */
      if (statDevToHostFisData.lbaMid == 0x4F || statDevToHostFisData.lbaHigh == 0xC2)
      {
        LogPage[8] = 0;   /* Sense code */ 
        LogPage[9] = 0;   /* Sense code qualifier */ 
      }
      else if (statDevToHostFisData.lbaMid == 0xF4 || statDevToHostFisData.lbaHigh == 0x2C)
      {
        LogPage[8] = 0x5D;   /* Sense code */ 
        LogPage[9] = 0x10;   /* Sense code qualifier */ 
      }

      /* Assumption: No support for SCT */
      LogPage[10] = 0xFF; /* Most Recent Temperature Reading */

      sm_memcpy(pLogPage, LogPage, MIN(allocationLen, INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH));
      if (INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH < allocationLen)
      {
        SM_DBG6(("smsatLogSenseCB: 3rd underrun allocationLen %d len %d \n", allocationLen, INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH));

        /* underrun */
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                           smIOUnderRun,
                           allocationLen - INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH,
                           agNULL,
                           satOrgIOContext->interruptContext );

      }
      else
      {
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest,
                           smIOSuccess,
                           SCSI_STAT_GOOD,
                           agNULL,
                           satOrgIOContext->interruptContext);
      }

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);


      return;
    }
    else
    {
      SM_DBG1(("smsatLogSenseCB: error unknown command success 0x%x feature 0x%x!!!\n", hostToDevFis->h.command, hostToDevFis->h.features));
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);

      return;
    }
  }
  else
  {
    SM_DBG1(("smsatLogSenseCB: error unknown command success 0x%x!!!\n", hostToDevFis->h.command));
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    return;
  }

  return;
}

osGLOBAL void
smsatSMARTEnableCB(
                   agsaRoot_t        *agRoot,
                   agsaIORequest_t   *agIORequest,
                   bit32             agIOStatus,
                   agsaFisHeader_t   *agFirstDword,
                   bit32             agIOInfoLen,
                   agsaFrameHandle_t agFrameHandle,
                   void              *ioContext
                  )
{
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL;
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatIOContext_t         *satNewIOContext;
  smSatInternalIo_t        *satIntIo;
  smSatInternalIo_t        *satNewIntIo = agNULL;
//  satDeviceData_t           *satDevData;
  smDeviceData_t           *oneDeviceData;
  smIniScsiCmnd_t          *scsiCmnd;
  smIORequest_t            *smOrgIORequest;
  bit32                     status;

  SM_DBG2(("smsatSMARTEnableCB: start\n"));
  SM_DBG4(("smsatSMARTEnableCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate tiIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  /*ttttttthe one */
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatSMARTEnableCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    scsiCmnd        = satOrgIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG4(("smsatSMARTEnableCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatSMARTEnableCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatSMARTEnableCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    scsiCmnd               = satOrgIOContext->pScsiCmnd;
  }
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatSMARTEnableCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                      smRoot,
                      smOrgIORequest,
                      smIOFailed,
                      smDetailOtherError,
                      agNULL,
                      satOrgIOContext->interruptContext
                     );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  /*
    checking IO status, FIS type and error status
  */
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatSMARTEnableCB: not success status, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                       smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext
                      );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  /* process success case */
  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);
  satNewIntIo = smsatAllocIntIoResource( smRoot,
                                         smOrgIORequest,
                                         oneDeviceData,
                                         512,
                                         satNewIntIo);
  if (satNewIntIo == agNULL)
  {
    tdsmIOCompletedCB(
                       smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext
                      );
    return;
  }
  satNewIOContext = smsatPrepareNewIO(
                                      satNewIntIo,
                                      smOrgIORequest,
                                      oneDeviceData,
                                      scsiCmnd,
                                      satOrgIOContext
                                      );
  status = smsatLogSense_1(smRoot,
                           &satNewIntIo->satIntSmIORequest,
                           satNewIOContext->psmDeviceHandle,
                           &satNewIntIo->satIntSmScsiXchg,
                           satNewIOContext);
  if (status != SM_RC_SUCCESS)
  {
    /* sending SAT_CHECK_POWER_MODE fails */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satNewIntIo);
    tdsmIOCompletedCB(
                      smRoot,
                      smOrgIORequest,
                      smIOFailed,
                      smDetailOtherError,
                      agNULL,
                      satOrgIOContext->interruptContext
                     );
    return;
  }
  return;
}

osGLOBAL void
smsatModeSelect6n10CB(
                      agsaRoot_t        *agRoot,
                      agsaIORequest_t   *agIORequest,
                      bit32             agIOStatus,
                      agsaFisHeader_t   *agFirstDword,
                      bit32             agIOInfoLen,
                      agsaFrameHandle_t agFrameHandle,
                      void              *ioContext
                     )
{
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL;
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatIOContext_t         *satNewIOContext;
  smSatInternalIo_t        *satIntIo;
  smSatInternalIo_t        *satNewIntIo = agNULL;
//  satDeviceData_t         *satDevData;
  smDeviceData_t           *oneDeviceData;

  smScsiRspSense_t         *pSense;
  smIniScsiCmnd_t          *scsiCmnd;
  smIORequest_t            *smOrgIORequest;

  agsaFisRegHostToDevice_t *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;
  bit32                     status;
  smScsiInitiatorRequest_t *smScsiRequest; /* smScsiXchg */
  agsaFisRegD2HHeader_t    *statDevToHostFisHeader = agNULL;

  SM_DBG2(("smsatModeSelect6n10CB: start\n"));
  SM_DBG5(("smsatModeSelect6n10CB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatModeSelect6n10CB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    smScsiRequest   = satOrgIOContext->smScsiXchg;
    pSense          = satOrgIOContext->pSense;
    scsiCmnd        = satOrgIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG4(("smsatModeSelect6n10CB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatModeSelect6n10CB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatModeSelect6n10CB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;

    smScsiRequest = satOrgIOContext->smScsiXchg;
    pSense        = satOrgIOContext->pSense;
    scsiCmnd      = satOrgIOContext->pScsiCmnd;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatModeSelect6n10CB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                       smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext
                      );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisRegDeviceToHost_t is expected */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  }

  if (agIOStatus != OSSA_IO_SUCCESS)
  {
  if ( (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) ||
       ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
       )
  {
    /* for debugging */
    if( agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatModeSelect6n10CB: FAILED, NOT IO_SUCCESS!!!\n"));
    }
    else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
    {
      SM_DBG1(("smsatModeSelect6n10CB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
    }
    else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
              (ataStatus & DF_ATA_STATUS_MASK)
              )
    {
      SM_DBG1(("smsatModeSelect6n10CB: FAILED, FAILED, error status!!!\n"));
    }

    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }

    /* for debugging */
    if (hostToDevFis->h.command == SAT_SET_FEATURES)
    {
      if ((hostToDevFis->h.features == 0x82) || (hostToDevFis->h.features == 0x02))
      {
        SM_DBG1(("smsatModeSelect6n10CB: 1 SAT_SET_FEATURES failed, feature 0x%x!!!\n", hostToDevFis->h.features));
      }
      else if ((hostToDevFis->h.features == 0xAA) || (hostToDevFis->h.features == 0x55))
      {
        SM_DBG1(("smsatModeSelect6n10CB: 2 SAT_SET_FEATURES failed, feature 0x%x!!!\n", hostToDevFis->h.features));
      }
      else
      {
        SM_DBG1(("smsatModeSelect6n10CB: error unknown command 0x%x feature 0x%x!!!\n", hostToDevFis->h.command, hostToDevFis->h.features));
      }
    }
    else if (hostToDevFis->h.command == SAT_SMART)
    {
      if ((hostToDevFis->h.features == SAT_SMART_ENABLE_OPERATIONS) || (hostToDevFis->h.features == SAT_SMART_DISABLE_OPERATIONS))
      {
        SM_DBG1(("smsatModeSelect6n10CB: SAT_SMART_ENABLE/DISABLE_OPERATIONS failed, feature 0x%x!!!\n", hostToDevFis->h.features));
      }
      else
      {
        SM_DBG1(("smsatModeSelect6n10CB: error unknown command 0x%x feature 0x%x!!!\n", hostToDevFis->h.command, hostToDevFis->h.features));
      }
    }
    else
    {
      SM_DBG1(("smsatModeSelect6n10CB: error default case command 0x%x!!!\n", hostToDevFis->h.command));
    }


    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );


    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  } /* error checking */
  }


  /* prcessing the success case */


  if (hostToDevFis->h.command == SAT_SET_FEATURES)
  {
    if ((hostToDevFis->h.features == 0x82) || (hostToDevFis->h.features == 0x02))
    {
      SM_DBG5(("smsatModeSelect6n10CB: 1 SAT_SET_FEATURES success, feature 0x%x\n", hostToDevFis->h.features));
      if (hostToDevFis->h.features == 0x02)
      {
        /* enable write cache */
        oneDeviceData->satWriteCacheEnabled = agTRUE;
      }
      else
      {
        /* disable write cache */
        oneDeviceData->satWriteCacheEnabled = agFALSE;
      }

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);

      satNewIntIo = smsatAllocIntIoResource( smRoot,
                                             smOrgIORequest,
                                             oneDeviceData,
                                             0,
                                             satNewIntIo);
      if (satNewIntIo == agNULL)
      {
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_NO_SENSE,
                              0,
                              SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );
        SM_DBG1(("smsatModeSelect6n10CB: momory allocation fails!!!\n"));
        return;
      } /* end memory allocation */

      satNewIOContext = smsatPrepareNewIO(
                                          satNewIntIo,
                                          smOrgIORequest,
                                          oneDeviceData,
                                          scsiCmnd,
                                          satOrgIOContext
                                         );
      /* sends either ATA SET FEATURES based on DRA bit */
      status = smsatModeSelect6n10_1( smRoot,
                                      &satNewIntIo->satIntSmIORequest,
                                      satNewIOContext->psmDeviceHandle,
                                      smScsiRequest, /* orginal from OS layer */
                                      satNewIOContext
                                    );

      if (status != SM_RC_SUCCESS)
      {
        /* sending ATA command fails */
        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satNewIntIo);
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_NO_SENSE,
                              0,
                              SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );
        SM_DBG1(("smsatModeSelect6n10CB: calling satModeSelect6_1 fails!!!\n"));
        return;
      } /* end send fails */
      return;
    }
    else if ((hostToDevFis->h.features == 0xAA) || (hostToDevFis->h.features == 0x55))
    {
      SM_DBG5(("smsatModeSelect6n10CB: 2 SAT_SET_FEATURES success, feature 0x%x\n", hostToDevFis->h.features));

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);

      /* return stat_good */
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext );
      return;
    }
    else
    {
      SM_DBG1(("smsatModeSelect6n10CB: error unknown command success 0x%x feature 0x%x!!!\n", hostToDevFis->h.command, hostToDevFis->h.features));

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );
      return;
    }
  }
  else if (hostToDevFis->h.command == SAT_SMART )
  {
    if ((hostToDevFis->h.features == SAT_SMART_ENABLE_OPERATIONS) || (hostToDevFis->h.features == SAT_SMART_DISABLE_OPERATIONS))
    {
      SM_DBG5(("smsatModeSelect6n10CB: SAT_SMART_ENABLE/DISABLE_OPERATIONS success, feature 0x%x\n", hostToDevFis->h.features));

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      /* return stat_good */
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext );
      return;
    }
    else
    {
      SM_DBG1(("smsatModeSelect6n10CB: error unknown command failed 0x%x feature 0x%x!!!\n", hostToDevFis->h.command, hostToDevFis->h.features));

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );
      return;
    }
  }

  else
  {
    SM_DBG1(("smsatModeSelect6n10CB: error default case command success 0x%x!!!\n", hostToDevFis->h.command));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );
    return;
  }

  return;

}

osGLOBAL void
smsatSynchronizeCache10n16CB(
                             agsaRoot_t        *agRoot,
                             agsaIORequest_t   *agIORequest,
                             bit32             agIOStatus,
                             agsaFisHeader_t   *agFirstDword,
                             bit32             agIOInfoLen,
                             agsaFrameHandle_t agFrameHandle,
                             void              *ioContext
                            )
{
  /*
    In the process of SynchronizeCache10 and SynchronizeCache16
    Process SAT_FLUSH_CACHE_EXT
    Process SAT_FLUSH_CACHE
  */


  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL;
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatInternalIo_t        *satIntIo;
  smDeviceData_t           *oneDeviceData;

  smScsiRspSense_t         *pSense;
  smIniScsiCmnd_t          *scsiCmnd;
  smIORequest_t            *smOrgIORequest;

  agsaFisRegHostToDevice_t *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;
  agsaFisRegD2HHeader_t    *statDevToHostFisHeader = agNULL;

  SM_DBG2(("smsatSynchronizeCache10n16CB: start\n"));
  SM_DBG5(("smsatSynchronizeCache10n16CB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  /* SPC: Self-Test Result Log page */
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatSynchronizeCache10n16CB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satIOContext->pSense;
    scsiCmnd        = satIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG4(("smsatSynchronizeCache10n16CB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatSynchronizeCache10n16CB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatSynchronizeCache10n16CB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;

    pSense        = satOrgIOContext->pSense;
    scsiCmnd      = satOrgIOContext->pScsiCmnd;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatSynchronizeCache10n16CB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));

    tdsmIOCompletedCB(
                       smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext
                      );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  if( agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisRegDeviceToHost_t is expected */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  }

  if( agIOStatus != OSSA_IO_SUCCESS)
  {
  if ( (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) ||
       ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
       )
  {
    /* for debugging */
    if( agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatSynchronizeCache10n16CB: FAILED, NOT IO_SUCCESS!!!\n"));
    }
    else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
    {
      SM_DBG1(("smsatSynchronizeCache10n16CB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
    }
    else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
              (ataStatus & DF_ATA_STATUS_MASK)
              )
    {
      SM_DBG1(("smsatSynchronizeCache10n16CB: FAILED, FAILED, error status!!!\n"));
    }


    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }

    switch (hostToDevFis->h.command)
    {
    case SAT_FLUSH_CACHE:
      SM_DBG1(("smsatSynchronizeCache10n16CB: SAT_FLUSH_CACHE failed!!!\n"));
      /* checking IMMED bit */
      if (scsiCmnd->cdb[1] & SCSI_FLUSH_CACHE_IMMED_MASK)
      {
        smsatSetDeferredSensePayload( pSense,
                                      SCSI_SNSKEY_NO_SENSE,
                                      0,
                                      SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                                      satOrgIOContext);
      }
      else
      {
        smsatSetDeferredSensePayload( pSense,
                                      SCSI_SNSKEY_NO_SENSE,
                                      0,
                                      SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                                      satOrgIOContext);
      }


      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
      break;
    case SAT_FLUSH_CACHE_EXT:
      SM_DBG1(("smsatSynchronizeCache10n16CB: SAT_FLUSH_CACHE_EXT failed!!!\n"));
       /* checking IMMED bit */
      if (scsiCmnd->cdb[1] & SCSI_FLUSH_CACHE_IMMED_MASK)
      {
        smsatSetDeferredSensePayload( pSense,
                                      SCSI_SNSKEY_NO_SENSE,
                                      0,
                                      SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                                      satOrgIOContext);
      }
      else
      {
        smsatSetDeferredSensePayload( pSense,
                                      SCSI_SNSKEY_NO_SENSE,
                                      0,
                                      SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                                      satOrgIOContext);
      }


      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
      break;
    default:
      SM_DBG1(("smsatSynchronizeCache10n16CB: error unknown command 0x%x!!!\n", hostToDevFis->h.command));
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                            satOrgIOContext);


      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
      break;
    }

    return;
  } /* end of error checking */
  }

  /* prcessing the success case */
  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);


  switch (hostToDevFis->h.command)
  {
  case SAT_FLUSH_CACHE:
    SM_DBG5(("smsatSynchronizeCache10n16CB: SAT_FLUSH_CACHE success\n"));

    /* checking IMMED bit */
    if ( !(scsiCmnd->cdb[1] & SCSI_FLUSH_CACHE_IMMED_MASK))
    {
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext );
      return;
    }


    break;
  case SAT_FLUSH_CACHE_EXT:
    SM_DBG5(("smsatSynchronizeCache10n16CB: SAT_FLUSH_CACHE_EXT success\n"));

    /* checking IMMED bit */
    if ( !(scsiCmnd->cdb[1] & SCSI_FLUSH_CACHE_IMMED_MASK))
    {
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext );
      return;
    }

    break;
  default:
    SM_DBG5(("smsatSynchronizeCache10n16CB: error unknown command 0x%x\n", hostToDevFis->h.command));
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);


    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    return;
    break;
  }

  return;
}

//qqqqqqqq
osGLOBAL void
smsatNonChainedWriteNVerifyCB(
                              agsaRoot_t        *agRoot,
                              agsaIORequest_t   *agIORequest,
                              bit32             agIOStatus,
                              agsaFisHeader_t   *agFirstDword,
                              bit32             agIOInfoLen,
                              void              *agParam,
                              void              *ioContext
                             )
{
  /*
    In the process of WriteAndVerify10
    Process SAT_WRITE_DMA_FUA_EXT
    Process SAT_WRITE_DMA_EXT
    Process SAT_WRITE_SECTORS_EXT
    Process SAT_WRITE_FPDMA_QUEUED
    Process SAT_READ_VERIFY_SECTORS
    Process SAT_READ_VERIFY_SECTORS_EXT
    chained command
  */


  smRoot_t                *smRoot = agNULL;
  smIntRoot_t             *smIntRoot = agNULL;
  smIntContext_t          *smAllShared = agNULL;
  smIORequestBody_t       *smIORequestBody;
  smIORequestBody_t       *smOrgIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatIOContext_t          *satNewIOContext;
  smSatInternalIo_t         *satIntIo;
  smSatInternalIo_t         *satNewIntIo = agNULL;
//  satDeviceData_t         *satDevData;
  smDeviceData_t          *oneDeviceData;

  smScsiRspSense_t          *pSense;
  smIniScsiCmnd_t           *scsiCmnd;
  smIORequest_t             *smOrgIORequest;

  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;
  bit32                     status;
  smScsiInitiatorRequest_t  *smScsiRequest; /* smScsiXchg */
  agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
  agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL;

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  /* SPC: Self-Test Result Log page */
  smScsiRequest          = satIOContext->smScsiXchg;

  SM_DBG2(("smsatNonChainedWriteNVerifyCB: start\n"));
  SM_DBG5(("smsatNonChainedWriteNVerifyCB: start agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));


  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatNonChainedWriteNVerifyCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satOrgIOContext->pSense;
    scsiCmnd        = satOrgIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG4(("smsatNonChainedWriteNVerifyCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatNonChainedWriteNVerifyCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatNonChainedWriteNVerifyCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;

    pSense        = satOrgIOContext->pSense;
    scsiCmnd      = satOrgIOContext->pScsiCmnd;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;


  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatNonChainedWriteNVerifyCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext
                       );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }


  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /*
      FIS type should be either REG_DEV_TO_HOST_FIS or SET_DEV_BITS_FIS
    */
    /* First, assumed to be Reg Device to Host FIS */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  }

  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS)
    {
      statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H);

      /* Get ATA Status register */
      ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70);               /* bits 4,5,6 */
      ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07);   /* bits 0,1,2 */
   }
  }


  if( agIOStatus != OSSA_IO_SUCCESS)
  {
  /*
    checking IO status, FIS type and error status
    FIS type should be either REG_DEV_TO_HOST_FIS or SET_DEV_BITS_FIS
    Both have fisType in the same location
  */
  if ( ((statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) &&
        (statDevToHostFisHeader->fisType != SET_DEV_BITS_FIS)) ||
       ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
       )
    {
      /* for debugging */
      if( agIOStatus != OSSA_IO_SUCCESS)
      {
        SM_DBG1(("smsatNonChainedWriteNVerifyCB: FAILED, NOT IO_SUCCESS!!!\n"));
      }
      else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
      {
        SM_DBG1(("smsatNonChainedWriteNVerifyCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
      }
      else if (statDevToHostFisHeader->fisType != SET_DEV_BITS_FIS)
      {
        SM_DBG1(("smsatNonChainedWriteNVerifyCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
      }
      else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
                (ataStatus & DF_ATA_STATUS_MASK)
                )
      {
        SM_DBG1(("smsatNonChainedWriteNVerifyCB: FAILED, FAILED, error status!!!\n"));
      }


      /* Process abort case */
      if (agIOStatus == OSSA_IO_ABORTED)
      {
        smsatProcessAbort(smRoot,
                          smOrgIORequest,
                          satOrgIOContext
                          );

        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
        return;
      }

      /* for debugging */
      switch (hostToDevFis->h.command)
      {
      case SAT_WRITE_DMA_FUA_EXT:
        SM_DBG1(("smsatNonChainedWriteNVerifyCB: SAT_WRITE_DMA_FUA_EXT!!!\n"));
        break;
      case SAT_WRITE_DMA_EXT:
        SM_DBG1(("smsatNonChainedWriteNVerifyCB: SAT_WRITE_DMA_EXT!!!\n"));
        break;
      case SAT_WRITE_SECTORS_EXT:
        SM_DBG1(("smsatNonChainedWriteNVerifyCB: SAT_WRITE_SECTORS_EXT!!!\n"));
        break;
      case SAT_WRITE_FPDMA_QUEUED:
        SM_DBG1(("smsatNonChainedWriteNVerifyCB: SAT_WRITE_FPDMA_QUEUED!!!\n"));
        break;
      case SAT_READ_VERIFY_SECTORS:
        SM_DBG1(("smsatNonChainedWriteNVerifyCB: SAT_READ_VERIFY_SECTORS!!!\n"));
        break;
      case SAT_READ_VERIFY_SECTORS_EXT:
        SM_DBG1(("smsatNonChainedWriteNVerifyCB: SAT_READ_VERIFY_SECTORS_EXT!!!\n"));
        break;
      default:
        SM_DBG1(("smsatNonChainedWriteNVerifyCB: error default case command 0x%x!!!\n", hostToDevFis->h.command));
        break;
      }

      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_NO_SENSE,
                            0,
                            SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    } /* end error checking */
  }

  /* process success from this point on */

  switch (hostToDevFis->h.command)
  {
  case SAT_WRITE_DMA_FUA_EXT:
    SM_DBG5(("smsatNonChainedWriteNVerifyCB: SAT_WRITE_DMA_FUA_EXT success\n"));
    break;
  case SAT_WRITE_DMA_EXT:
    SM_DBG5(("smsatNonChainedWriteNVerifyCB: SAT_WRITE_DMA_EXT success\n"));
    break;
  case SAT_WRITE_SECTORS_EXT:
    SM_DBG5(("smsatNonChainedWriteNVerifyCB: SAT_WRITE_SECTORS_EXT succes\n"));

    break;
  case SAT_WRITE_FPDMA_QUEUED:
    SM_DBG5(("smsatNonChainedWriteNVerifyCB: SAT_WRITE_FPDMA_QUEUED succes\n"));
    break;
  case SAT_READ_VERIFY_SECTORS:
    SM_DBG5(("smsatNonChainedWriteNVerifyCB: SAT_READ_VERIFY_SECTORS succes\n"));
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* free */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    /* return stat_good */
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       satOrgIOContext->interruptContext );
    return;
    break;
  case SAT_READ_VERIFY_SECTORS_EXT:
    SM_DBG5(("smsatNonChainedWriteNVerifyCB: SAT_READ_VERIFY_SECTORS_EXT succes\n"));
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* free */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    /* return stat_good */
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       satOrgIOContext->interruptContext );
    return;
    break;
  default:
    SM_DBG1(("smsatNonChainedWriteNVerifyCB:  error default case command 0x%x success!!!\n", hostToDevFis->h.command));

    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
    break;
  }

  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

  /* free */
  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);

  satNewIntIo = smsatAllocIntIoResource( smRoot,
                                         smOrgIORequest,
                                         oneDeviceData,
                                         0,
                                         satNewIntIo);
  if (satNewIntIo == agNULL)
  {
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );
    SM_DBG1(("smsatNonChainedWriteNVerifyCB: momory allocation fails!!!\n"));
    return;
  } /* end memory allocation */

  satNewIOContext = smsatPrepareNewIO(satNewIntIo,
                                      smOrgIORequest,
                                      oneDeviceData,
                                      scsiCmnd,
                                      satOrgIOContext
                                     );

  /* sends ATA verify command(READ_VERIFY_SECTORS or READ_VERIFY_SECTORS_EXT) */
  status = smsatNonChainedWriteNVerify_Verify(smRoot,
                                              &satNewIntIo->satIntSmIORequest,
                                              satNewIOContext->psmDeviceHandle,
                                              smScsiRequest, /* orginal from OS layer */
                                              satNewIOContext
                                             );


  if (status != SM_RC_SUCCESS)
  {
    /* sending ATA command fails */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satNewIntIo);
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );
    SM_DBG1(("smsatNonChainedWriteNVerifyCB: calling satWriteAndVerify10_1 fails!!!\n"));
    return;
  } /* end send fails */

  return;

}

osGLOBAL void
smsatChainedWriteNVerifyCB(
                           agsaRoot_t        *agRoot,
                           agsaIORequest_t   *agIORequest,
                           bit32             agIOStatus,
                           agsaFisHeader_t   *agFirstDword,
                           bit32             agIOInfoLen,
                           void              *agParam,
                           void              *ioContext
                          )
{
  /*
    send write in loop
    then, send verify in loop
  */

  smRoot_t                *smRoot = agNULL;
  smIntRoot_t             *smIntRoot = agNULL;
  smIntContext_t          *smAllShared = agNULL;
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatIOContext_t         *satNewIOContext;
  smSatInternalIo_t        *satIntIo;
  smSatInternalIo_t        *satNewIntIo = agNULL;
//  satDeviceData_t         *satDevData;
  smDeviceData_t           *oneDeviceData;

  smScsiRspSense_t         *pSense;
  smIniScsiCmnd_t          *scsiCmnd;
  smIORequest_t            *smOrgIORequest;
  agsaFisRegHostToDevice_t *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;
  bit32                     dataLength;
  bit32                     status = tiError;
  agsaFisRegD2HHeader_t    *statDevToHostFisHeader = agNULL;

  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  SM_DBG2(("smsatChainedWriteNVerifyCB: start\n"));
  SM_DBG6(("smsatChainedWriteNVerifyCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n",
           agIORequest, agIOStatus, agIOInfoLen));

  if (satIntIo == agNULL)
  {
    SM_DBG5(("smsatChainedWriteNVerifyCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satIOContext->pSense;
    scsiCmnd        = satIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG5(("smsatChainedWriteNVerifyCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG5(("smsatChainedWriteNVerifyCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG5(("smsatChainedWriteNVerifyCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;

    pSense        = satOrgIOContext->pSense;
    scsiCmnd      = satOrgIOContext->pScsiCmnd;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
     SM_DBG1(("smsatChainedWriteNVerifyCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
     smsatSetSensePayload( pSense,
                           SCSI_SNSKEY_NO_SENSE,
                           0,
                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                           satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  /*
    checking IO status, FIS type and error status
  */
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* agsaFisPioSetup_t or agsaFisRegDeviceToHost_t or agsaFisSetDevBits_t for read
       agsaFisRegDeviceToHost_t or agsaFisSetDevBits_t for write
       first, assumed to be Reg Device to Host FIS
       This is OK to just find fis type
    */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
    /* for debugging */
    if( (statDevToHostFisHeader->fisType != PIO_SETUP_DEV_TO_HOST_FIS) &&
        (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) &&
        (statDevToHostFisHeader->fisType != SET_DEV_BITS_FIS)
        )
    {
      SM_DBG1(("smsatChainedWriteNVerifyCB: FAILED, Wrong FIS type 0x%x!!!\n", statDevToHostFisHeader->fisType));
    }

    /* for debugging */
    if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
         (ataStatus & DF_ATA_STATUS_MASK)
         )
    {
      SM_DBG1(("smsatChainedWriteNVerifyCB: FAILED, error status and command 0x%x!!!\n", hostToDevFis->h.command));
    }

    /* the function below handles abort case */
    smsatDelayedProcessAbnormalCompletion(agRoot,
                                          agIORequest,
                                          agIOStatus,
                                          agFirstDword,
                                          agIOInfoLen,
                                          agParam,
                                          satIOContext);

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  } /* end of error */

  /* process the success case */
  switch (hostToDevFis->h.command)
  {
  case SAT_WRITE_DMA: /* fall through */
  case SAT_WRITE_SECTORS:/* fall through */
//  case SAT_WRITE_DMA_FUA_EXT: /* fall through */
  case SAT_WRITE_DMA_EXT: /* fall through */
  case SAT_WRITE_SECTORS_EXT: /* fall through */
  case SAT_WRITE_FPDMA_QUEUED:

    SM_DBG5(("smsatChainedWriteNVerifyCB: WRITE success case\n"));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* done with internally genereated SAT_SMART_RETURN_STATUS */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    /* let's loop till TL */

    /* lba = lba + tl
       loopnum--;
       if (loopnum == 0) done
     */
    (satOrgIOContext->LoopNum)--;
  
    if (satOrgIOContext->superIOFlag)
    {
        dataLength = ((tiSuperScsiInitiatorRequest_t *) satOrgIOContext->smScsiXchg)->scsiCmnd.expDataLength;
    }
    else
    {
        dataLength = ((tiScsiInitiatorRequest_t *) satOrgIOContext->smScsiXchg)->scsiCmnd.expDataLength;
    }

    satNewIntIo = smsatAllocIntIoResource( smRoot,
                                           smOrgIORequest,
                                           oneDeviceData,
                                           dataLength,
                                           satNewIntIo);
    if (satNewIntIo == agNULL)
    {
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         satOrgIOContext->interruptContext );

      SM_DBG1(("smsatChainedWriteNVerifyCB: momory allocation fails!!!\n"));
      return;
    } /* end of memory allocation failure */

    /*
     * Need to initialize all the fields within satIOContext
     */

    satNewIOContext = smsatPrepareNewIO(
                                        satNewIntIo,
                                        smOrgIORequest,
                                        oneDeviceData,
                                        scsiCmnd,
                                        satOrgIOContext
                                        );

    if (satOrgIOContext->LoopNum == 0)
    {
      /*
        done with write
        start with verify
      */
      satOrgIOContext->LoopNum = satOrgIOContext->LoopNum2;
      status = smsatChainedWriteNVerify_Start_Verify(smRoot,
                                                     &satNewIntIo->satIntSmIORequest,
                                                     satNewIOContext->psmDeviceHandle,
                                                     &satNewIntIo->satIntSmScsiXchg,
                                                     satNewIOContext);
    }
    else
    {
      status = smsatChainedWriteNVerify_Write(smRoot,
                                             &satNewIntIo->satIntSmIORequest,
                                             satNewIOContext->psmDeviceHandle,
                                             &satNewIntIo->satIntSmScsiXchg,
                                             satNewIOContext);
    }

    if (status != SM_RC_SUCCESS)
    {
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satNewIntIo);
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         satOrgIOContext->interruptContext );
      SM_DBG1(("smsatChainedWriteNVerifyCB: calling satChainedWriteNVerify_Write fails!!!\n"));
      return;
    }

    break;

  case SAT_READ_VERIFY_SECTORS: /* fall through */
  case SAT_READ_VERIFY_SECTORS_EXT:
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    /* done with internally genereated SAT_SMART_RETURN_STATUS */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    /* let's loop till TL */

    /* lba = lba + tl
       loopnum--;
       if (loopnum == 0) done
     */
    (satOrgIOContext->LoopNum)--;
    if (satOrgIOContext->LoopNum == 0)
    {
      /*
        done with write and verify
      */
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext );
      return;
    }

    if (satOrgIOContext->superIOFlag)
    {
        dataLength = ((tiSuperScsiInitiatorRequest_t *) satOrgIOContext->smScsiXchg)->scsiCmnd.expDataLength;
    }
    else
    {
        dataLength = ((tiScsiInitiatorRequest_t *) satOrgIOContext->smScsiXchg)->scsiCmnd.expDataLength;
    }

    satNewIntIo = smsatAllocIntIoResource( smRoot,
                                           smOrgIORequest,
                                           oneDeviceData,
                                           dataLength,
                                           satNewIntIo);
    if (satNewIntIo == agNULL)
    {
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         satOrgIOContext->interruptContext );

      SM_DBG1(("smsatChainedWriteNVerifyCB: momory allocation fails!!!\n"));
      return;
    } /* end of memory allocation failure */

    /*
     * Need to initialize all the fields within satIOContext
     */

    satNewIOContext = smsatPrepareNewIO(
                                        satNewIntIo,
                                        smOrgIORequest,
                                        oneDeviceData,
                                        scsiCmnd,
                                        satOrgIOContext
                                        );
    status = smsatChainedWriteNVerify_Verify(smRoot,
                                             &satNewIntIo->satIntSmIORequest,
                                             satNewIOContext->psmDeviceHandle,
                                             &satNewIntIo->satIntSmScsiXchg,
                                             satNewIOContext);

    if (status != SM_RC_SUCCESS)
    {
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satNewIntIo);
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         satOrgIOContext->interruptContext );
      SM_DBG1(("smsatChainedWriteNVerifyCB: calling satChainedWriteNVerify_Verify fails!!!\n"));
      return;
    }

    break;

  default:
    SM_DBG1(("smsatChainedWriteNVerifyCB: success but default case command 0x%x!!!\n",hostToDevFis->h.command));
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    break;
  }


  return;
}

osGLOBAL void
smsatReadMediaSerialNumberCB(
                             agsaRoot_t        *agRoot,
                             agsaIORequest_t   *agIORequest,
                             bit32             agIOStatus,
                             agsaFisHeader_t   *agFirstDword,
                             bit32             agIOInfoLen,
                             agsaFrameHandle_t agFrameHandle,
                             void              *ioContext
                            )
{
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL;
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatInternalIo_t        *satIntIo;
//  satDeviceData_t           *satDevData;
  smDeviceData_t           *oneDeviceData;

  smScsiRspSense_t         *pSense;
  smIORequest_t            *smOrgIORequest;

  agsaFisRegHostToDevice_t *hostToDevFis = agNULL;
  smScsiInitiatorRequest_t *smOrgScsiRequest; /* tiScsiXchg */
  bit8                     *pMediaSerialNumber;
  bit8                      MediaSerialNumber[ZERO_MEDIA_SERIAL_NUMBER_LENGTH] = {0};
  smIniScsiCmnd_t          *scsiCmnd;
  bit32                     allocationLen = 0;

  SM_DBG2(("smsatReadMediaSerialNumberCB: start\n"));
  SM_DBG4(("smsatReadMediaSerialNumberCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate tiIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatReadMediaSerialNumberCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satOrgIOContext->pSense;
    smOrgScsiRequest          = satOrgIOContext->smScsiXchg;
    /* SCSI command response payload to OS layer */
    pMediaSerialNumber        = (bit8 *) smOrgScsiRequest->sglVirtualAddr;
    /* ATA command response payload */
    scsiCmnd        = satOrgIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG4(("smsatReadMediaSerialNumberCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatReadMediaSerialNumberCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatReadMediaSerialNumberCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest     = (smIORequest_t *)smOrgIORequestBody->smIORequest;

    pSense             = satOrgIOContext->pSense;
    smOrgScsiRequest   = satOrgIOContext->smScsiXchg;
    /* SCSI command response payload to OS layer */
    pMediaSerialNumber = (bit8 *) smOrgScsiRequest->sglVirtualAddr;
    scsiCmnd           = satOrgIOContext->pScsiCmnd;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatReadMediaSerialNumberCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                       smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext
                      );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  if( agIOStatus != OSSA_IO_SUCCESS)
  {
    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NOT_READY,
                          0,
                          SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  /* process success case */
  allocationLen = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
                + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
  SM_DBG5(("smsatReadMediaSerialNumberCB: allocationLen in CDB %d 0x%x\n", allocationLen,allocationLen));

  if (hostToDevFis->h.command == SAT_READ_SECTORS ||
      hostToDevFis->h.command == SAT_READ_SECTORS_EXT
     )
  {
    MediaSerialNumber[0] = 0;
    MediaSerialNumber[1] = 0;
    MediaSerialNumber[2] = 0;
    MediaSerialNumber[3] = 4;
    MediaSerialNumber[4] = 0;
    MediaSerialNumber[5] = 0;
    MediaSerialNumber[6] = 0;
    MediaSerialNumber[7] = 0;

    sm_memcpy(pMediaSerialNumber, MediaSerialNumber, MIN(allocationLen, ZERO_MEDIA_SERIAL_NUMBER_LENGTH));
    if (ZERO_MEDIA_SERIAL_NUMBER_LENGTH < allocationLen)
    {
      SM_DBG1(("smsatReadMediaSerialNumberCB: 1st underrun allocationLen %d len %d !!!\n", allocationLen, ZERO_MEDIA_SERIAL_NUMBER_LENGTH));

      /* underrun */
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == satIntIo->satOrgSmIORequest */
                         smIOUnderRun,
                         allocationLen - ZERO_MEDIA_SERIAL_NUMBER_LENGTH,
                         agNULL,
                         satOrgIOContext->interruptContext );

    }
    else
    {
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext);
    }
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  else
  {
    SM_DBG1(("smsatReadMediaSerialNumberCB: error unknown command success 0x%x!!!\n", hostToDevFis->h.command));
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    return;
  }
  return;
}

osGLOBAL void
smsatReadBufferCB(
                  agsaRoot_t        *agRoot,
                  agsaIORequest_t   *agIORequest,
                  bit32             agIOStatus,
                  agsaFisHeader_t   *agFirstDword,
                  bit32             agIOInfoLen,
                  agsaFrameHandle_t agFrameHandle,
                  void              *ioContext
                 )
{
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL;
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatInternalIo_t        *satIntIo;
  smDeviceData_t           *oneDeviceData;
  smScsiRspSense_t         *pSense;
  smIORequest_t            *smOrgIORequest;
  agsaFisRegHostToDevice_t *hostToDevFis = agNULL;


  SM_DBG2(("smsatReadBufferCB: start\n"));
  SM_DBG4(("smsatReadBufferCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
  /* internally generate tiIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatReadBufferCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satOrgIOContext->pSense;
  }
  else
  {
    SM_DBG4(("smsatReadBufferCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatReadBufferCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatReadBufferCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    pSense        = satOrgIOContext->pSense;
  }
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;
  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatReadBufferCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                       smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext
                      );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  if( agIOStatus != OSSA_IO_SUCCESS)
  {
    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NOT_READY,
                          0,
                          SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  /* process success case */
  if (hostToDevFis->h.command == SAT_READ_BUFFER )
  {

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       satOrgIOContext->interruptContext);
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  else
  {
    SM_DBG1(("smsatReadBufferCB: error unknown command success 0x%x!!!\n", hostToDevFis->h.command));
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    return;
  }

  return;
}

osGLOBAL void
smsatWriteBufferCB(
                   agsaRoot_t        *agRoot,
                   agsaIORequest_t   *agIORequest,
                   bit32             agIOStatus,
                   agsaFisHeader_t   *agFirstDword,
                   bit32             agIOInfoLen,
                   agsaFrameHandle_t agFrameHandle,
                   void              *ioContext
                  )
{
  smRoot_t                *smRoot = agNULL;
  smIntRoot_t             *smIntRoot = agNULL;
  smIntContext_t          *smAllShared = agNULL;
  smIORequestBody_t       *smIORequestBody;
  smIORequestBody_t       *smOrgIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatInternalIo_t         *satIntIo;
  smDeviceData_t          *oneDeviceData;
  smScsiRspSense_t          *pSense;
  smIORequest_t             *smOrgIORequest;
  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;


  SM_DBG2(("smsatWriteBufferCB: start\n"));
  SM_DBG4(("smsatWriteBufferCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
  /* internally generate tiIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatWriteBufferCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satOrgIOContext->pSense;
    /* SCSI command response payload to OS layer */
//    pMediaSerialNumber        = (bit8 *) s,OrgScsiRequest->sglVirtualAddr;
  }
  else
  {
    SM_DBG4(("smsatWriteBufferCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatWriteBufferCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatWriteBufferCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    pSense        = satOrgIOContext->pSense;
  }
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;
  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatWriteBufferCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                       smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext
                      );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  if( agIOStatus != OSSA_IO_SUCCESS)
  {
    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NOT_READY,
                          0,
                          SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
                          satOrgIOContext);
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  /* process success case */
  if (hostToDevFis->h.command == SAT_WRITE_BUFFER )
  {
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       satOrgIOContext->interruptContext);
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  else
  {
    SM_DBG1(("smsatWriteBufferCB: error unknown command success 0x%x!!!\n", hostToDevFis->h.command));
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  return;
}

osGLOBAL void
smsatReassignBlocksCB(
                      agsaRoot_t        *agRoot,
                      agsaIORequest_t   *agIORequest,
                      bit32             agIOStatus,
                      agsaFisHeader_t   *agFirstDword,
                      bit32             agIOInfoLen,
                      agsaFrameHandle_t agFrameHandle,
                      void              *ioContext
                     )
{
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL;
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatIOContext_t         *satNewIOContext;
  smSatInternalIo_t        *satIntIo;
  smSatInternalIo_t        *satNewIntIo = agNULL;
  smDeviceData_t           *oneDeviceData;
  smScsiRspSense_t         *pSense;
  smIniScsiCmnd_t          *scsiCmnd;
  smIORequest_t            *smOrgIORequest;
  agsaFisRegHostToDevice_t *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;
  bit32                     status;
  smScsiInitiatorRequest_t *smScsiRequest; /* smScsiXchg */
  agsaFisRegD2HHeader_t    *statDevToHostFisHeader = agNULL;

  SM_DBG2(("smsatReassignBlocksCB: start\n"));
  SM_DBG5(("smsatReassignBlocksCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate tiIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatReassignBlocksCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    smScsiRequest   = satOrgIOContext->smScsiXchg;
    pSense          = satOrgIOContext->pSense;
    scsiCmnd        = satOrgIOContext->pScsiCmnd;
  }
  else
  {
    SM_DBG4(("smsatReassignBlocksCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatReassignBlocksCB: satOrgIOContext is NULL, Wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatReassignBlocksCB: satOrgIOContext is NOT NULL, Wrong\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    smScsiRequest = satOrgIOContext->smScsiXchg;
    pSense        = satOrgIOContext->pSense;
    scsiCmnd      = satOrgIOContext->pScsiCmnd;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatReassignBlocksCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                       smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       satOrgIOContext->interruptContext
                      );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisRegDeviceToHost_t is expected */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  }
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
  if ( (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) ||
       ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
       )
  {
    /* for debugging */
    if( agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatReassignBlocksCB FAILED, NOT IO_SUCCESS!!!\n"));
    }
    else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
    {
      SM_DBG1(("smsatReassignBlocksCB FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
    }
    else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
              (ataStatus & DF_ATA_STATUS_MASK)
              )
    {
      SM_DBG1(("smsatReassignBlocksCB FAILED, FAILED, error status!!!\n"));
    }

    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }
    /* for debugging */
    if (hostToDevFis->h.command == SAT_READ_VERIFY_SECTORS ||
        hostToDevFis->h.command == SAT_READ_VERIFY_SECTORS_EXT
       )
    {
      SM_DBG1(("smsatReassignBlocksCB SAT_READ_VERIFY_SECTORS(_EXT) failed!!!\n"));
      /* Verify failed; send Write with same LBA */
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);

      satNewIntIo = smsatAllocIntIoResource( smRoot,
                                             smOrgIORequest,
                                             oneDeviceData,
                                             512, /* writing 1 sector */
                                             satNewIntIo);
      if (satNewIntIo == agNULL)
      {
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_HARDWARE_ERROR,
                              0,
                              SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
                              satOrgIOContext);
        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );
        SM_DBG1(("smsatReassignBlocksCB: momory allocation fails!!!\n"));
        return;
      } /* end memory allocation */
      satNewIOContext = smsatPrepareNewIO(
                                          satNewIntIo,
                                          smOrgIORequest,
                                          oneDeviceData,
                                          scsiCmnd,
                                          satOrgIOContext
                                          );
      /* send Write with same LBA */
      status = smsatReassignBlocks_2(
                                     smRoot,
                                     &satNewIntIo->satIntSmIORequest,
                                     satNewIOContext->psmDeviceHandle,
                                     &satNewIntIo->satIntSmScsiXchg,
                                     satNewIOContext,
                                     satOrgIOContext->LBA
                                    );

      if (status != SM_RC_SUCCESS)
      {
        /* sending ATA command fails */
        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satNewIntIo);
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_HARDWARE_ERROR,
                              0,
                              SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );
        SM_DBG1(("smsatReassignBlocksCB calling fail 1!!!\n"));
        return;
      } /* end send fails */

      return;
    }
    else if (hostToDevFis->h.command == SAT_WRITE_DMA ||
             hostToDevFis->h.command == SAT_WRITE_SECTORS ||
             hostToDevFis->h.command == SAT_WRITE_DMA_EXT ||
             hostToDevFis->h.command == SAT_WRITE_SECTORS_EXT ||
             hostToDevFis->h.command == SAT_WRITE_FPDMA_QUEUED
             )
    {
      SM_DBG1(("smsatReassignBlocksCB SAT_WRITE failed!!!\n"));
      /* fall through */
    }
    else
    {
      SM_DBG1(("smsatReassignBlocksCB error default case unexpected command 0x%x!!!\n", hostToDevFis->h.command));
    }


    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_HARDWARE_ERROR,
                          0,
                          SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );


    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  } /* error checking */
  }


  /* prcessing the success case */
  if (hostToDevFis->h.command == SAT_READ_VERIFY_SECTORS ||
      hostToDevFis->h.command == SAT_READ_VERIFY_SECTORS_EXT ||
      hostToDevFis->h.command == SAT_WRITE_DMA ||
      hostToDevFis->h.command == SAT_WRITE_SECTORS ||
      hostToDevFis->h.command == SAT_WRITE_DMA_EXT ||
      hostToDevFis->h.command == SAT_WRITE_SECTORS_EXT ||
      hostToDevFis->h.command == SAT_WRITE_FPDMA_QUEUED
      )
  {
    /* next LBA; verify */
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    if (satOrgIOContext->ParmIndex >= satOrgIOContext->ParmLen)
    {
      SM_DBG5(("smsatReassignBlocksCB: GOOD status\n"));
      /* return stat_good */
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOSuccess,
                         SCSI_STAT_GOOD,
                         agNULL,
                         satOrgIOContext->interruptContext );
      return;
    }
    else
    {
      SM_DBG5(("smsatReassignBlocksCB: processing next LBA\n"));
      satNewIntIo = smsatAllocIntIoResource( smRoot,
                                             smOrgIORequest,
                                             oneDeviceData,
                                             0,
                                             satNewIntIo);
      if (satNewIntIo == agNULL)
      {
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_HARDWARE_ERROR,
                              0,
                              SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );
        SM_DBG1(("smsatReassignBlocksCB: momory allocation fails!!!\n"));
        return;
      } /* end memory allocation */

      satNewIOContext = smsatPrepareNewIO(
                                          satNewIntIo,
                                          smOrgIORequest,
                                          oneDeviceData,
                                          scsiCmnd,
                                          satOrgIOContext
                                          );

      /* send Verify with the next LBA */
      status = smsatReassignBlocks_1(
                                     smRoot,
                                     &satNewIntIo->satIntSmIORequest,
                                     satNewIOContext->psmDeviceHandle,
                                     smScsiRequest, /* orginal from OS layer */
                                     satNewIOContext,
                                     satOrgIOContext
                                     );

      if (status != SM_RC_SUCCESS)
      {
        /* sending ATA command fails */
        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satNewIntIo);
        smsatSetSensePayload( pSense,
                              SCSI_SNSKEY_HARDWARE_ERROR,
                              0,
                              SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
                              satOrgIOContext);

        tdsmIOCompletedCB( smRoot,
                           smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                           smIOSuccess,
                           SCSI_STAT_CHECK_CONDITION,
                           satOrgIOContext->pSmSenseData,
                           satOrgIOContext->interruptContext );
        SM_DBG1(("smsatReassignBlocksCB calling satModeSelect6_1 fails!!!\n"));
        return;
      } /* end send fails */
    } /* else */
    return;

  }
  else if (hostToDevFis->h.command == SAT_WRITE_DMA ||
           hostToDevFis->h.command == SAT_WRITE_SECTORS ||
           hostToDevFis->h.command == SAT_WRITE_DMA_EXT ||
           hostToDevFis->h.command == SAT_WRITE_SECTORS_EXT ||
           hostToDevFis->h.command == SAT_WRITE_FPDMA_QUEUED
           )
  {
    /* next LBA; verify */
  }
  else
  {
      SM_DBG1(("smsatReassignBlocksCB error unknown command success 0x%x !!!\n", hostToDevFis->h.command));

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_HARDWARE_ERROR,
                            0,
                            SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );
      return;
  }
  return;
}


osGLOBAL FORCEINLINE void
smsatDecrementPendingIO(
                        smRoot_t                *smRoot,
                        smIntContext_t          *smAllShared,
                        smSatIOContext_t        *satIOContext
                        )
{
#ifdef CCFLAG_OPTIMIZE_SAT_LOCK
  bit32 volatile satPendingNCQIO = 0;
  bit32 volatile satPendingNONNCQIO = 0;
  bit32 volatile satPendingIO = 0;
#endif /* CCFLAG_OPTIMIZE_SAT_LOCK */
  smDeviceData_t       *oneDeviceData   = satIOContext->pSatDevData;
  smSatInternalIo_t    *satIntIo        = satIOContext->satIntIoContext;
  smSatIOContext_t     *satOrgIOContext = satIOContext->satOrgIOContext;
#ifdef  TD_DEBUG_ENABLE
  smIORequestBody_t    *smIORequestBody = agNULL;
  smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
#endif

  SM_DBG3(("smsatDecrementPendingIO: start\n"));

#ifdef CCFLAG_OPTIMIZE_SAT_LOCK
  if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
       (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
  {
    tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNCQIO);
  }
  else
  {
    tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingNONNCQIO);
  }
  tdsmInterlockedDecrement(smRoot,&oneDeviceData->satPendingIO);
  /* temp */
  tdsmInterlockedExchange(smRoot, &satPendingNCQIO, oneDeviceData->satPendingNCQIO);
  tdsmInterlockedExchange(smRoot, &satPendingNONNCQIO, oneDeviceData->satPendingNONNCQIO);
  tdsmInterlockedExchange(smRoot, &satPendingIO, oneDeviceData->satPendingIO);
  if (satPendingNCQIO == -1)
  {
    SM_DBG1(("smsatDecrementPendingIO: satPendingNCQIO adjustment!!!\n"));
    oneDeviceData->satPendingNCQIO = 0;
  }
  if (satPendingNONNCQIO == -1)
  {
    SM_DBG1(("smsatDecrementPendingIO: satPendingNONNCQIO adjustment!!!\n"));
    oneDeviceData->satPendingNONNCQIO = 0;
  }
  if (satPendingIO == -1)
  {
    SM_DBG1(("smsatDecrementPendingIO: satPendingIO adjustment!!!\n"));
    oneDeviceData->satPendingIO = 0;
  }

#else

  if ( (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
       (satIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ) )
  {
    tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
    oneDeviceData->satPendingNCQIO--;
    oneDeviceData->satPendingIO--;
    SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink);
    /* temp */
    if (oneDeviceData->satPendingNCQIO == -1)
    {
      SM_DBG1(("smsatDecrementPendingIO: satPendingNCQIO adjustment!!!\n"));
      oneDeviceData->satPendingNCQIO = 0;
    }
    if (oneDeviceData->satPendingIO == -1)
    {
      SM_DBG1(("smsatDecrementPendingIO: satPendingIO adjustment!!!\n"));
      oneDeviceData->satPendingIO = 0;
    }
    tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
  }
  else
  {
    tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
    oneDeviceData->satPendingNONNCQIO--;
    oneDeviceData->satPendingIO--;
    SMLIST_DEQUEUE_THIS (&satIOContext->satIoContextLink);
    /* temp */
    if (oneDeviceData->satPendingNONNCQIO == -1)
    {
      SM_DBG1(("smsatDecrementPendingIO: satPendingNONNCQIO adjustment!!!\n"));
      oneDeviceData->satPendingNONNCQIO = 0;
    }
    if (oneDeviceData->satPendingIO == -1)
    {
      SM_DBG1(("smsatDecrementPendingIO: satPendingIO adjustment!!!\n"));
      oneDeviceData->satPendingIO = 0;
    }
    tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
  }

#endif /* CCFLAG_OPTIMIZE_SAT_LOCK */

  if (satIntIo == agNULL)
  {
    SM_DBG3(("smsatDecrementPendingIO: external command!!!\n"));
    /*smEnqueueIO(smRoot, satIOContext);*/
  }
  else
  {
    SM_DBG3(("smsatDecrementPendingIO: internal command!!!\n"));
    if (satOrgIOContext == agNULL)
    {
      /* No smEnqueueIO since only alloc used */
      SM_DBG3(("smsatDecrementPendingIO: internal only command!!!, ID %d!!!\n", smIORequestBody->id));
      return;
    }
    else
    {
      /* smDequeueIO used */
      /*smEnqueueIO(smRoot, satOrgIOContext);*/
    }
  }

  return;
}


osGLOBAL void
smsatProcessAbnormalCompletion(
                               agsaRoot_t        *agRoot,
                               agsaIORequest_t   *agIORequest,
                               bit32             agIOStatus,
                               agsaFisHeader_t   *agFirstDword,
                               bit32             agIOInfoLen,
                               void              *agParam,
                               smSatIOContext_t    *satIOContext
                              )
{

  smRoot_t             *smRoot = agNULL;
//  tdsaRootOsData_t     *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t             *tiRoot = (tiRoot_t *)osData->tiRoot;
  bit32                interruptContext;
  smIORequestBody_t    *smIORequestBody;
//  satDeviceData_t      *pSatDevData;
  smDeviceHandle_t     *smDeviceHandle;
  smDeviceData_t       *oneDeviceData = agNULL;
  agsaDevHandle_t      *agDevHandle = agNULL;

  smIORequestBody = (smIORequestBody_t *)agIORequest->osData;
  oneDeviceData   = satIOContext->pSatDevData;
  if (oneDeviceData == agNULL)
  {
    SM_DBG1(("smsatProcessAbnormalCompletion: oneDeviceData is NULL\n"));
    return;
  }
  smDeviceHandle  = satIOContext->psmDeviceHandle;
  smRoot          = oneDeviceData->smRoot;
  interruptContext = satIOContext->interruptContext;

  SM_DBG5(("smsatProcessAbnormalCompletion: start\n"));

  /* Get into the detail */
  switch(agIOStatus)
  {
  case OSSA_IO_SUCCESS:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_SUCCESS agIOInfoLen 0x%x calling smsatIOCompleted!!!\n", agIOInfoLen));
    /*
     * At this point agIOInfoLen should be non-zero and there is valid FIS
     * to read. Pass this info to the SAT layer in order to do the ATA status
     * to SCSI status translation.
     */
      smsatIOCompleted( smRoot,
                        smIORequestBody->smIORequest,
                        agFirstDword,
                        agIOInfoLen,
                        agParam,
                        satIOContext,
                        interruptContext);
    break;


  case OSSA_IO_ABORTED:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_ABORTED!!!\n"));

    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailAborted,
                       agNULL,
                       interruptContext);

#ifdef REMOVED
    if ( oneDeviceData->satTmTaskTag != agNULL )
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: TM callback!!!\n"));
      if (smDeviceHandle == agNULL)
      {
        SM_DBG1(("smsatProcessAbnormalCompletion: wrong, smDeviceHandle is NULL!!!\n"));
      }
      /* TM completed */
      tdsmEventCB( smRoot,
                   smDeviceHandle,
                   smIntrEventTypeTaskManagement,
                   smTMOK,
                   oneDeviceData->satTmTaskTag);
      /*
       * Reset flag
       */
      oneDeviceData->satTmTaskTag = agNULL;
    }
#endif

    /*
     * Check if we are in recovery mode and need to update the recovery flag
     */
    if ((oneDeviceData->satDriveState == SAT_DEV_STATE_IN_RECOVERY ) &&
        (oneDeviceData->satPendingIO == 0 ))
    {
      oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
      SM_DBG1(("smsatProcessAbnormalCompletion: STATE NORMAL!!!\n"));
    }

    SM_DBG1(("smsatProcessAbnormalCompletion: did %d satDriveState %d!!!\n", oneDeviceData->id, oneDeviceData->satDriveState));
    SM_DBG1(("smsatProcessAbnormalCompletion: satPendingIO %d satNCQMaxIO %d!!!\n", oneDeviceData->satPendingIO, oneDeviceData->satNCQMaxIO ));
    SM_DBG1(("smsatProcessAbnormalCompletion: satPendingNCQIO %d satPendingNONNCQIO %d!!!\n", oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));

    break;
#ifdef REMOVED
  case OSSA_IO_OVERFLOW:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_OVERFLOW!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOOverRun,
                       agIOInfoLen,
                       agNULL,
                       interruptContext);
    break;
#endif
  case OSSA_IO_UNDERFLOW:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_UNDERFLOW!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOUnderRun,
                       agIOInfoLen,
                       agNULL,
                       interruptContext);
    break;


  case OSSA_IO_FAILED:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_FAILED!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_ABORT_RESET:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_ABORT_RESET!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailAbortReset,
                       agNULL,
                       interruptContext);
    /*
     * Check if we are in recovery mode and need to update the recovery flag
     */
    if ((oneDeviceData->satDriveState == SAT_DEV_STATE_IN_RECOVERY ) &&
        (oneDeviceData->satPendingIO == 0 ))
    {
      oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
      SM_DBG1(("smsatProcessAbnormalCompletion: STATE NORMAL!!!\n"));
    }

    SM_DBG1(("smsatProcessAbnormalCompletion: satDriveState %d!!!\n", oneDeviceData->satDriveState));
    SM_DBG1(("smsatProcessAbnormalCompletion: satPendingIO %d satNCQMaxIO %d!!!\n", oneDeviceData->satPendingIO, oneDeviceData->satNCQMaxIO ));
    SM_DBG1(("smsatProcessAbnormalCompletion: satPendingNCQIO %d satPendingNONNCQIO %d!!!\n", oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));

    break;

#ifdef REMOVED
  case OSSA_IO_NOT_VALID:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_NOT_VALID!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailNotValid,
                       agNULL,
                       interruptContext);
    break;
#endif

  case OSSA_IO_NO_DEVICE:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_NO_DEVICE!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailNoLogin,
                       agNULL,
                       interruptContext);
    break;

#ifdef REMOVED /* removed from spec */
  case OSSA_IO_ILLEGAL_PARAMETER:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_ILLEGAL_PARAMETER!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_LINK_FAILURE:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_LINK_FAILURE!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_PROG_ERROR:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_PROG_ERROR!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;
#endif
  case OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_BREAK: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_OPEN_PREEMPTED: /* fall through */
#ifdef REMOVED /* removed from spec */
  case OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR: /* fall through */
#endif
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_OPEN_CNX_ERROR_* 0x%x!!!\n", agIOStatus));
    if (smDeviceHandle == agNULL)
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: wrong, smDeviceHandle is NULL!!!\n"));
      tdsmIOCompletedCB( smRoot,
                         smIORequestBody->smIORequest,
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         interruptContext);
      return;
    }
    if (oneDeviceData == agNULL)
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: wrong, oneDeviceData is NULL!!!\n"));
    }
    else
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: did %d!!!\n", oneDeviceData->id));
    }

    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;
  case OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailBusy,
                       agNULL,
                       interruptContext);
    break;
#ifdef REMOVED
  case OSSA_IO_XFER_ERROR_BREAK: /* fall throuth */
#endif

  case OSSA_IO_XFER_ERROR_PHY_NOT_READY: /* fall throuth */
  case OSSA_IO_XFER_ERROR_NAK_RECEIVED: /* fall throuth */

#ifdef REMOVED
  case OSSA_IO_XFER_ERROR_ACK_NAK_TIMEOUT: /* fall throuth */
  case OSSA_IO_XFER_ERROR_PEER_ABORTED: /* fall throuth */
#endif
  case OSSA_IO_XFER_ERROR_DMA: /* fall throuth */
#ifdef REMOVED
  case OSSA_IO_XFER_ERROR_RX_FRAME: /* fall throuth */
  case OSSA_IO_XFER_ERROR_CREDIT_TIMEOUT: /* fall throuth */
  case OSSA_IO_XFER_ERROR_SATA: /* fall throuth */
#endif
  case OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT: /* fall throuth */
  case OSSA_IO_XFER_ERROR_ABORTED_DUE_TO_SRST: /* fall throuth */
  case OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE: /* fall throuth */
#ifdef REMOVED
  case OSSA_IO_XFER_ERR_EOB_DATA_OVERRUN:
  case OSSA_IO_XFER_ERROR_ABORTED_NCQ_MODE: /* fall throuth */
  case OSSA_IO_XFER_ERROR_DISRUPTED_PHY_DOWN: /* fall throuth */
  case OSSA_IO_XFER_ERROR_OFFSET_MISMATCH: /* fall throuth */
  case OSSA_IO_XFER_ERROR_XFER_ZERO_DATA_LEN: /* fall throuth */
#endif
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_XFER_ERROR_* 0x%x!!!\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;
#ifdef REMOVED
  case OSSA_IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT: /* fall throuth */
  case OSSA_IO_XFER_ERROR_CMD_ISSUE_BREAK_BEFORE_ACK_NAK: /* fall throuth */
  case OSSA_IO_XFER_ERROR_CMD_ISSUE_PHY_DOWN_BEFORE_ACK_NAK: /* fall throuth */
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_XFER_ERROR_CMD_ISSUE_* 0x%x!!!\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;
  case OSSA_IO_XFER_PIO_SETUP_ERROR:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_XFER_PIO_SETUP_ERROR!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;
#endif
  case OSSA_IO_DS_IN_ERROR:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_DS_IN_ERROR!!!\n"));
    if (smDeviceHandle == agNULL)
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: wrong, smDeviceHandle is NULL!!!\n"));
      tdsmIOCompletedCB( smRoot,
                         smIORequestBody->smIORequest,
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         interruptContext);
      return;
    }
    if (oneDeviceData == agNULL)
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: wrong, oneDeviceData is NULL!!!\n"));
    }
    else
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: did %d!!!\n", oneDeviceData->id));
    }
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;
  case OSSA_IO_DS_NON_OPERATIONAL:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_IO_DS_NON_OPERATIONAL!!!\n"));
    if (smDeviceHandle == agNULL)
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: wrong, smDeviceHandle is NULL!!!\n"));
      tdsmIOCompletedCB( smRoot,
                         smIORequestBody->smIORequest,
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         interruptContext);
      return;
    }
    if (oneDeviceData == agNULL)
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: wrong, oneDeviceData is NULL!!!\n"));
    }
    else
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: did %d!!!\n", oneDeviceData->id));
      agDevHandle = oneDeviceData->agDevHandle;
      if (oneDeviceData->valid == agTRUE)
      {
        saSetDeviceState(agRoot, agNULL, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, SA_DS_OPERATIONAL);
      }
    }

    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_PORT_IN_RESET:
  case OSSA_IO_DS_IN_RECOVERY:
    SM_DBG1(("smsatProcessAbnormalCompletion: OSSA_IO_DS_IN_RECOVERY or OSSA_IO_PORT_IN_RESET status %x\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
    SM_DBG1(("smsatProcessAbnormalCompletion: SSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_XX status %x\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                      smIORequestBody->smIORequest,
                      smIOFailed,
                      smDetailOtherError,
                      agNULL,
                      interruptContext);
    break;

  case OSSA_MPI_IO_RQE_BUSY_FULL:
  case OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE:
  case OSSA_MPI_ERR_ATAPI_DEVICE_BUSY:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = OSSA_MPI_%x!!!\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailBusy,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS: /* fall through */
#ifdef REMOVED
  case OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH:
#endif
  case OSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID: /* fall through */
  case OSSA_IO_XFR_ERROR_DEK_IV_MISMATCH: /* fall through */
  case OSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR: /* fall through */
  case OSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS:
  case OSSA_IO_XFR_ERROR_DEK_ILLEGAL_TABLE:

    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = ENCRYPTION ERROR 0x%x!!!\n", agIOStatus));
    smsatEncryptionHandler(smRoot,
                           agIORequest,
                           agIOStatus,
                           agIOInfoLen,
                           agParam,
                           0,
                           interruptContext);
    break;

#ifdef REMOVED
  case OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH: /* fall through */
  case OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH: /* fall through */
  case OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = DIF ERROR 0x%x!!!\n", agIOStatus));
    smsatDifHandler(smRoot,
                    agIORequest,
                    agIOStatus,
                    agIOInfoLen,
                    agParam,
                    0,
                    interruptContext);
    break;
#endif

  default:
    SM_DBG1(("smsatProcessAbnormalCompletion: agIOStatus = unknown 0x%x!!!\n", agIOStatus));
    if (oneDeviceData != agNULL)
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: did %d!!!\n", oneDeviceData->id));
    }
    else
    {
      SM_DBG1(("smsatProcessAbnormalCompletion: oneDeviceData is NULL!!!\n"));
    }

    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  } /* switch */

  return;
}

osGLOBAL void
smsatDelayedProcessAbnormalCompletion(
                                      agsaRoot_t        *agRoot,
                                      agsaIORequest_t   *agIORequest,
                                      bit32             agIOStatus,
                                      agsaFisHeader_t   *agFirstDword,
                                      bit32             agIOInfoLen,
                                      void              *agParam,
                                      smSatIOContext_t    *satIOContext
                                     )
{
  smRoot_t             *smRoot = agNULL;
//  tdsaRootOsData_t     *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t             *tiRoot = (tiRoot_t *)osData->tiRoot;
//  bit32                interruptContext = osData->IntContext;
  bit32                interruptContext;
  smIORequestBody_t    *smIORequestBody;
//  satDeviceData_t      *pSatDevData;
  smDeviceHandle_t     *smDeviceHandle;
  smDeviceData_t       *oneDeviceData = agNULL;
  agsaDevHandle_t      *agDevHandle = agNULL;

  smIORequestBody = (smIORequestBody_t *)agIORequest->osData;
  oneDeviceData     = satIOContext->pSatDevData;
  if (oneDeviceData == agNULL)
  {
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: oneDeviceData is NULL\n"));
    return;
  }
  smDeviceHandle  = satIOContext->psmDeviceHandle;
  smRoot          = oneDeviceData->smRoot;
  interruptContext = satIOContext->interruptContext;

  SM_DBG5(("smsatDelayedProcessAbnormalCompletion: start\n"));

  /* Get into the detail */
  switch(agIOStatus)
  {
  case OSSA_IO_SUCCESS:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_SUCCESS calling smsatIOCompleted!!!\n"));
    /* do nothing */
    break;


  case OSSA_IO_ABORTED:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_ABORTED!!!\n"));

    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailAborted,
                       agNULL,
                       interruptContext);

    if ( oneDeviceData->satTmTaskTag != agNULL )
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: TM callback!!!\n"));
      if (smDeviceHandle == agNULL)
      {
        SM_DBG1(("smsatDelayedProcessAbnormalCompletion: wrong, smDeviceHandle is NULL!!!\n"));
      }
      else
      {
        /* TM completed */
        tdsmEventCB( smRoot,
                     smDeviceHandle,
                     smIntrEventTypeTaskManagement,
                     smTMOK,
                     oneDeviceData->satTmTaskTag);
        /*
         * Reset flag
         */
        oneDeviceData->satTmTaskTag = agNULL;
      }
    }

    /*
     * Check if we are in recovery mode and need to update the recovery flag
     */
    if ((oneDeviceData->satDriveState == SAT_DEV_STATE_IN_RECOVERY ) &&
        (oneDeviceData->satPendingIO == 0 ))
    {
      oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: STATE NORMAL.!!!\n"));
    }

    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: satDriveState %d!!!\n", oneDeviceData->satDriveState));
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: satPendingIO %d satNCQMaxIO %d!!!\n", oneDeviceData->satPendingIO, oneDeviceData->satNCQMaxIO ));
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: satPendingNCQIO %d satPendingNONNCQIO %d!!!\n", oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));

    break;
#ifdef REMOVED
  case OSSA_IO_OVERFLOW:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_OVERFLOW!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOOverRun,
                       agIOInfoLen,
                       agNULL,
                       interruptContext);
    break;
#endif
  case OSSA_IO_UNDERFLOW:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_UNDERFLOW!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOUnderRun,
                       agIOInfoLen,
                       agNULL,
                       interruptContext);
    break;


  case OSSA_IO_FAILED:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_FAILED!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_ABORT_RESET:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_ABORT_RESET!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailAbortReset,
                       agNULL,
                       interruptContext);
    /*
     * Check if we are in recovery mode and need to update the recovery flag
     */
    if ((oneDeviceData->satDriveState == SAT_DEV_STATE_IN_RECOVERY ) &&
        (oneDeviceData->satPendingIO == 0 ))
    {
      oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: STATE NORMAL.!!!\n"));
    }

    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: satDriveState %d!!!\n", oneDeviceData->satDriveState));
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: satPendingIO %d satNCQMaxIO %d!!!\n", oneDeviceData->satPendingIO, oneDeviceData->satNCQMaxIO ));
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: satPendingNCQIO %d satPendingNONNCQIO %d!!!\n", oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));

    break;

#ifdef REMOVED
  case OSSA_IO_NOT_VALID:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_NOT_VALID!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailNotValid,
                       agNULL,
                       interruptContext);
    break;
#endif

  case OSSA_IO_NO_DEVICE:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_NO_DEVICE!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailNoLogin,
                       agNULL,
                       interruptContext);
    break;

#ifdef REMOVED /* removed from spec */
  case OSSA_IO_ILLEGAL_PARAMETER:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_ILLEGAL_PARAMETER!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_LINK_FAILURE:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_LINK_FAILURE!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_PROG_ERROR:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_PROG_ERROR!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;
#endif
  case OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_BREAK: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION: /* fall through */
  case OSSA_IO_OPEN_CNX_ERROR_OPEN_PREEMPTED: /* fall through */
#ifdef REMOVED /* removed from spec */
  case OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR: /* fall through */
#endif
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_OPEN_CNX_ERROR_* 0x%x!!!\n", agIOStatus));
    if (smDeviceHandle == agNULL)
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: wrong, smDeviceHandle is NULL!!!\n"));
      tdsmIOCompletedCB( smRoot,
                         smIORequestBody->smIORequest,
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         interruptContext);
      return;
    }
    if (oneDeviceData == agNULL)
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: wrong, oneDeviceData is NULL!!!\n"));
    }
    else
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: did %d!!!\n", oneDeviceData->id));
    }
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailBusy,
                       agNULL,
                       interruptContext);
    break;
#ifdef REMOVED
  case OSSA_IO_XFER_ERROR_BREAK: /* fall throuth */
#endif

  case OSSA_IO_XFER_ERROR_PHY_NOT_READY: /* fall throuth */
  case OSSA_IO_XFER_ERROR_NAK_RECEIVED: /* fall throuth */

#ifdef REMOVED
  case OSSA_IO_XFER_ERROR_ACK_NAK_TIMEOUT: /* fall throuth */
  case OSSA_IO_XFER_ERROR_PEER_ABORTED: /* fall throuth */
#endif

  case OSSA_IO_XFER_ERROR_DMA: /* fall throuth */

#ifdef REMOVED
  case OSSA_IO_XFER_ERROR_RX_FRAME: /* fall throuth */
  case OSSA_IO_XFER_ERROR_CREDIT_TIMEOUT: /* fall throuth */
  case OSSA_IO_XFER_ERROR_SATA: /* fall throuth */
#endif
  case OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT: /* fall throuth */
  case OSSA_IO_XFER_ERROR_ABORTED_DUE_TO_SRST: /* fall throuth */
  case OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE: /* fall throuth */
#ifdef REMOVED
  case OSSA_IO_XFER_ERROR_ABORTED_NCQ_MODE: /* fall throuth */
  case OSSA_IO_XFER_ERROR_DISRUPTED_PHY_DOWN: /* fall throuth */
  case OSSA_IO_XFER_ERROR_OFFSET_MISMATCH: /* fall throuth */
  case OSSA_IO_XFER_ERROR_XFER_ZERO_DATA_LEN: /* fall throuth */
#endif
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_XFER_ERROR_* 0x%x!!!\n", agIOStatus));

    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;
#ifdef REMOVED
  case OSSA_IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT: /* fall throuth */
  case OSSA_IO_XFER_ERROR_CMD_ISSUE_BREAK_BEFORE_ACK_NAK: /* fall throuth */
  case OSSA_IO_XFER_ERROR_CMD_ISSUE_PHY_DOWN_BEFORE_ACK_NAK: /* fall throuth */
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_XFER_ERROR_CMD_ISSUE_* 0x%x!!!\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;
  case OSSA_IO_XFER_PIO_SETUP_ERROR:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_XFER_PIO_SETUP_ERROR!!!\n"));
    if (smDeviceHandle == agNULL)
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: wrong, smDeviceHandle is NULL!!!\n"));
    }
    if (oneDeviceData == agNULL)
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: wrong, oneDeviceData is NULL!!!\n"));
    }
    else
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: did %d!!!\n", oneDeviceData->id));
    }
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;
#endif
  case OSSA_IO_DS_IN_ERROR:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_DS_IN_ERROR!!!\n"));
    if (smDeviceHandle == agNULL)
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: wrong, smDeviceHandle is NULL!!!\n"));
      tdsmIOCompletedCB( smRoot,
                         smIORequestBody->smIORequest,
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         interruptContext);
      return;
    }
    if (oneDeviceData == agNULL)
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: wrong, oneDeviceData is NULL!!!\n"));
    }
    else
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: did %d!!!\n", oneDeviceData->id));
    }
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;
  case OSSA_IO_DS_NON_OPERATIONAL:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_IO_DS_NON_OPERATIONAL!!!\n"));
    if (smDeviceHandle == agNULL)
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: wrong, smDeviceHandle is NULL!!!\n"));
      tdsmIOCompletedCB( smRoot,
                         smIORequestBody->smIORequest,
                         smIOFailed,
                         smDetailOtherError,
                         agNULL,
                         interruptContext);
      return;
    }
    if (oneDeviceData == agNULL)
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: wrong, oneDeviceData is NULL!!!\n"));
    }
    else
    {
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: did %d!!!\n", oneDeviceData->id));
      agDevHandle = oneDeviceData->agDevHandle;
      if (oneDeviceData->valid == agTRUE)
      {
        saSetDeviceState(agRoot, agNULL, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, SA_DS_OPERATIONAL);
      }
    }
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_PORT_IN_RESET:
  case OSSA_IO_DS_IN_RECOVERY:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: OSSA_IO_DS_IN_RECOVERY or OSSA_IO_PORT_IN_RESET status %x\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED:
  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO:
  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST:
  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE:
  case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: SSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_XX status %x\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                      smIORequestBody->smIORequest,
                      smIOFailed,
                      smDetailOtherError,
                      agNULL,
                      interruptContext);
    break;
  case OSSA_IO_DS_INVALID:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: OSSA_IO_DS_INVALID status %x\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                      smIORequestBody->smIORequest,
                      smIOFailed,
                      smDetailOtherError,
                      agNULL,
                      interruptContext);
    break;

  case OSSA_MPI_IO_RQE_BUSY_FULL:
  case OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE:
  case OSSA_MPI_ERR_ATAPI_DEVICE_BUSY:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = OSSA_MPI_%x!!!\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailBusy,
                       agNULL,
                       interruptContext);
    break;

  case OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS: /* fall through */
#ifdef REMOVED
  case OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH:
#endif
  case OSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID: /* fall through */
  case OSSA_IO_XFR_ERROR_DEK_IV_MISMATCH: /* fall through */
  case OSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR: /* fall through */
  case OSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS:
  case OSSA_IO_XFR_ERROR_DEK_ILLEGAL_TABLE:

      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = ENCRYPTION ERROR 0x%x!!!\n", agIOStatus));
      smsatEncryptionHandler(smRoot,
                             agIORequest,
                             agIOStatus,
                             agIOInfoLen,
                             agParam,
                             0,
           interruptContext);
      break;

#ifdef REMOVED
  case OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH: /* fall through */
  case OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH: /* fall through */
  case OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH:
      SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = DIF ERROR 0x%x!!!\n", agIOStatus));
      smsatDifHandler(smRoot,
                      agIORequest,
                      agIOStatus,
                      agIOInfoLen,
                      agParam,
                      0,
                      interruptContext);
      break;
#endif

  default:
    SM_DBG1(("smsatDelayedProcessAbnormalCompletion: agIOStatus = unknown!!!\n"));
    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
    break;

  } /* switch */
  return;
}

osGLOBAL void
smsatIDStartCB(
                agsaRoot_t        *agRoot,
                agsaIORequest_t   *agIORequest,
                bit32             agIOStatus,
                agsaFisHeader_t   *agFirstDword,
                bit32             agIOInfoLen,
                void              *agParam,
                void              *ioContext
               )
{
 /*
    In the process of SAT_IDENTIFY_DEVICE during discovery
  */
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                  *smRoot = agNULL;
  smIntRoot_t               *smIntRoot = agNULL;
  smIntContext_t            *smAllShared = agNULL;
  smIORequestBody_t         *smIORequestBody;
  smIORequestBody_t         *smOrgIORequestBody = agNULL;
  smDeviceHandle_t          *smDeviceHandle;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatIOContext_t          *satNewIOContext;
  smSatInternalIo_t         *satIntIo;
  smSatInternalIo_t         *satNewIntIo = agNULL;
  smDeviceData_t            *oneDeviceData;
  smIORequest_t             *smOrgIORequest = agNULL;
//  agsaFisRegD2HData_t       *deviceToHostFisData = agNULL;
//  bit8                      signature[8];
#ifdef  TD_DEBUG_ENABLE
  agsaFisPioSetupHeader_t   *satPIOSetupHeader = agNULL;
  bit32                      ataStatus = 0;
  bit32                      ataError;
#endif
  agsaSATAIdentifyData_t    *pSATAIdData;
  bit16                     *tmpptr, tmpptr_tmp;
  bit32                      x;
  void                      *sglVirtualAddr;
  bit32                      status = 0;
//  tdsaPortContext_t         *onePortContext = agNULL;
//  tiPortalContext_t         *tiPortalContext = agNULL;
//  bit32                     retry_status;
  smIORequest_t             *smIORequest;
  agsaDevHandle_t           *agDevHandle = agNULL;

  SM_DBG1(("smsatIDStartCB: start\n"));
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  smDeviceHandle         = satIOContext->psmDeviceHandle;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  SM_DBG1(("smsatIDStartCB: did %d\n", oneDeviceData->id));
//  onePortContext = oneDeviceData->tdPortContext;
//  tiPortalContext= onePortContext->tiPortalContext;
  oneDeviceData->IDDeviceValid = agFALSE;
  if (satIntIo == agNULL)
  {
    SM_DBG1(("smsatIDStartCB: External, OS generated!!!\n"));
    SM_DBG1(("smsatIDStartCB: Not possible case!!!\n"));
    satOrgIOContext      = satIOContext;
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  else
  {
    SM_DBG3(("smsatIDStartCB: Internal, SM generated\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG5(("smsatIDStartCB: satOrgIOContext is NULL\n"));
    }
    else
    {
      SM_DBG5(("smsatIDStartCB: satOrgIOContext is NOT NULL\n"));
      smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
      if (smOrgIORequestBody == agNULL)
      {
        SM_DBG1(("smsatIDStartCB: smOrgIORequestBody is NULL!!!\n"));
        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource(smRoot, oneDeviceData, satIntIo);
        return;
      }
    }
    sglVirtualAddr         = satIntIo->satIntSmScsiXchg.sglVirtualAddr;
  }
  smOrgIORequest           = smIORequestBody->smIORequest;
  smIORequest              = smOrgIORequestBody->smIORequest;
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;


  if ( agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT ||
       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY ||
       agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED ||
       agIOStatus == OSSA_IO_DS_NON_OPERATIONAL )
  {
    SM_DBG1(("smsatIDStartCB: OPEN_RETRY_TIMEOUT or STP_RESOURCES_BUSY or OPEN_RETRY_BACKOFF_THRESHOLD_REACHED or OSSA_IO_DS_NON_OPERATIONAL!!! 0x%x\n", agIOStatus));
    SM_DBG1(("smsatIDStartCB: did %d!!!\n", oneDeviceData->id));
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    SM_DBG2(("smsatIDStartCB: smOrgIORequestBody %p smIORequest %p\n", smOrgIORequestBody, smIORequest));
    SM_DBG2(("smsatIDStartCB: smOrgIORequestBody->id %d\n", smOrgIORequestBody->id));
    if (agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT)
    {
      tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIORetry, &(oneDeviceData->satIdentifyData));
    }
    else if ( agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED ||
              agIOStatus == OSSA_IO_DS_NON_OPERATIONAL )
    {
      /* set device to operational */
      agDevHandle = oneDeviceData->agDevHandle;
      if (oneDeviceData->valid == agTRUE)
      {
        saSetDeviceState(agRoot, agNULL, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, SA_DS_OPERATIONAL);
      }
      tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIORetry, &(oneDeviceData->satIdentifyData));
    }
    else
    {
      tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSTPResourceBusy, &(oneDeviceData->satIdentifyData));
    }
    return;
  }

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatIDStartCB: agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    SM_DBG1(("smsatIDStartCB: did %d!!!\n", oneDeviceData->id));
    SM_DBG1(("smsatIDStartCB: before pending IO %d NCQ pending IO %d NONNCQ pending IO %d\n",
    oneDeviceData->satPendingIO, oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    SM_DBG1(("smsatIDStartCB: after pending IO %d NCQ pending IO %d NONNCQ pending IO %d\n",
    oneDeviceData->satPendingIO, oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    SM_DBG2(("smsatIDStartCB: smOrgIORequestBody %p smIORequest %p\n", smOrgIORequestBody, smIORequest));
    SM_DBG2(("smsatIDStartCB: smOrgIORequestBody->id %d\n", smOrgIORequestBody->id));
    tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOFailed, &(oneDeviceData->satIdentifyData));
    return;
  }

  if (agIOStatus == OSSA_IO_ABORTED ||
      agIOStatus == OSSA_IO_UNDERFLOW ||
      agIOStatus == OSSA_IO_XFER_ERROR_BREAK ||
      agIOStatus == OSSA_IO_XFER_ERROR_PHY_NOT_READY ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
      agIOStatus == OSSA_IO_XFER_ERROR_NAK_RECEIVED ||
      agIOStatus == OSSA_IO_XFER_ERROR_DMA ||
      agIOStatus == OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT ||
      agIOStatus == OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE ||
      agIOStatus == OSSA_IO_NO_DEVICE ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
      agIOStatus == OSSA_IO_PORT_IN_RESET ||
      agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
      agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
      agIOStatus == OSSA_IO_DS_IN_ERROR ||
      agIOStatus == OSSA_IO_DS_INVALID
      )
  {
    SM_DBG1(("smsatIDStartCB: OSSA_IO_OPEN_CNX_ERROR 0x%x!!!\n", agIOStatus));
    SM_DBG1(("smsatIDStartCB: did %d!!!\n", oneDeviceData->id));
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);


    SM_DBG2(("smsatIDStartCB: smOrgIORequestBody %p smIORequest %p\n", smOrgIORequestBody, smIORequest));
    SM_DBG2(("smsatIDStartCB: smOrgIORequestBody->id %d\n", smOrgIORequestBody->id));
    tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOFailed, &(oneDeviceData->satIdentifyData));
    return;
  }

  if ( agIOStatus != OSSA_IO_SUCCESS ||
       (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
     )
  {
#ifdef  TD_DEBUG_ENABLE
    /* only agsaFisPioSetup_t is expected */
    satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
    ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
    ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
#endif
    SM_DBG1(("smsatIDStartCB: ataStatus 0x%x ataError 0x%x!!!\n", ataStatus, ataError));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    SM_DBG2(("smsatIDStartCB: smOrgIORequestBody %p smIORequest %p\n", smOrgIORequestBody, smIORequest));
    SM_DBG2(("smsatIDStartCB: smOrgIORequestBody->id %d\n", smOrgIORequestBody->id));

    {
       tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOFailed, &(oneDeviceData->satIdentifyData));
    }
    return;
  }


  /* success */
  SM_DBG3(("smsatIDStartCB: Success\n"));
  SM_DBG3(("smsatIDStartCB: Success did %d\n", oneDeviceData->id));

  /* Convert to host endian */
  tmpptr = (bit16*)sglVirtualAddr;
  for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
  {
    OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
    *tmpptr = tmpptr_tmp;
    tmpptr++;
  }

  pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
  //smhexdump("satAddSATAIDDevCB before", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));

  SM_DBG5(("smsatIDStartCB: OS satOrgIOContext %p \n", satOrgIOContext));
  SM_DBG5(("smsatIDStartCB: TD satIOContext %p \n", satIOContext));
  SM_DBG5(("smsatIDStartCB: OS tiScsiXchg %p \n", satOrgIOContext->smScsiXchg));
  SM_DBG5(("smsatIDStartCB: TD tiScsiXchg %p \n", satIOContext->smScsiXchg));


   /* copy ID Dev data to oneDeviceData */
  oneDeviceData->satIdentifyData = *pSATAIdData;
  oneDeviceData->IDDeviceValid = agTRUE;

#ifdef SM_INTERNAL_DEBUG
  smhexdump("smsatIDStartCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
  smhexdump("smsatIDStartCB Device ID Dev data",(bit8 *)&oneDeviceData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
#endif

  /* set oneDeviceData fields from IndentifyData */
  smsatSetDevInfo(oneDeviceData,pSATAIdData);
  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);

  if (smIORequest->tdData == smIORequest->smData)
  {
    SM_DBG1(("smsatIDStartCB: the same tdData and smData error!\n"));
  }

  /* send the Set Feature ATA command to SATA device for enbling PIO and DMA transfer mode*/
  satNewIntIo = smsatAllocIntIoResource( smRoot,
                                   smOrgIORequest,
                                   oneDeviceData,
                                   0,
                                   satNewIntIo);

  if (satNewIntIo == agNULL)
  {
    SM_DBG1(("smsatIDStartCB: momory allocation fails\n"));
    tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOFailed, &(oneDeviceData->satIdentifyData));
    return;
  } /* end memory allocation */

  satNewIOContext = smsatPrepareNewIO(satNewIntIo,
                                    smOrgIORequest,
                                    oneDeviceData,
                                    agNULL,
                                    satOrgIOContext
                                    );
  /*enable PIO mode*/
  status = smsatSetFeaturesPIO(smRoot,
                     &satNewIntIo->satIntSmIORequest,
                     satNewIOContext->psmDeviceHandle,
                     &satNewIntIo->satIntSmScsiXchg, /* orginal from OS layer */
                     satNewIOContext
                     );

  if (status != SM_RC_SUCCESS)
  {
      smsatFreeIntIoResource(smRoot,
                             oneDeviceData,
                             satNewIntIo);
      /* clean up TD layer's IORequestBody */
      tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOFailed, &(oneDeviceData->satIdentifyData));
  }

  SM_DBG2(("smsatIDStartCB: End device id %d\n", oneDeviceData->id));
  return;
}


osGLOBAL void
smsatIOCompleted(
                 smRoot_t           *smRoot,
                 smIORequest_t      *smIORequest,
                 agsaFisHeader_t    *agFirstDword,
                 bit32              respFisLen,
                 agsaFrameHandle_t  agFrameHandle,
                 smSatIOContext_t     *satIOContext,
                 bit32              interruptContext
    )
{
//  satDeviceData_t           *pSatDevData;
  smDeviceData_t            *oneDeviceData;
  smScsiRspSense_t          *pSense;
#ifdef  TD_DEBUG_ENABLE
  smIniScsiCmnd_t           *pScsiCmnd;
#endif
  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
  bit32                      ataStatus = 0;
  bit32                      ataError;
  smSatInternalIo_t         *satIntIo = agNULL;
  bit32                      status;
//  agsaRoot_t                *agRoot;
//  agsaDevHandle_t           *agDevHandle;
  smDeviceHandle_t          *smDeviceHandle;
  smSatIOContext_t          *satIOContext2;
  smIORequestBody_t         *smIORequestBody;
  agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
  agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL;
  smIORequest_t              smIORequestTMP;

  pSense          = satIOContext->pSense;
  oneDeviceData   = satIOContext->pSatDevData;
#ifdef  TD_DEBUG_ENABLE
  pScsiCmnd       = satIOContext->pScsiCmnd;
#endif
  hostToDevFis    = satIOContext->pFis;


//  agRoot          = ((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->agRoot;
//  agDevHandle     = ((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->agDevHandle;
//  tiDeviceHandle  = &((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->tiDeviceHandle;
  smDeviceHandle    = satIOContext->psmDeviceHandle;
  /*
   * Find out the type of response FIS:
   * Set Device Bit FIS or Reg Device To Host FIS.
   */

  /* First assume it is Reg Device to Host FIS */
  statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
  ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  ataError      = statDevToHostFisHeader->error;    /* ATA Eror register   */

  SM_DBG5(("smsatIOCompleted: start\n"));

  /* for debugging */
  SM_DBG1(("smsatIOCompleted: H to D command 0x%x!!!\n", hostToDevFis->h.command));
  SM_DBG1(("smsatIOCompleted: D to H fistype 0x%x!!!\n", statDevToHostFisHeader->fisType));


  if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS)
  {
    /* It is Set Device Bits FIS */
    statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H);
    /* Get ATA Status register */
    ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70);               /* bits 4,5,6 */
    ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07);   /* bits 0,1,2 */

    /* ATA Eror register   */
    ataError  = statSetDevBitFisHeader->error;

    statDevToHostFisHeader = agNULL;
  }

  else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
  {
    SM_DBG1(("smsatIOCompleted: *** UNEXPECTED RESP FIS TYPE 0x%x *** smIORequest=%p!!!\n",
                 statDevToHostFisHeader->fisType, smIORequest));

    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_HARDWARE_ERROR,
                          0,
                          SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
                          satIOContext);

    tdsmIOCompletedCB( smRoot,
                       smIORequest,
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satIOContext->pSmSenseData,
                       interruptContext );
    return;

  }

  if ( ataStatus & DF_ATA_STATUS_MASK )
  {
    oneDeviceData->satDeviceFaultState = agTRUE;
  }
  else
  {
    oneDeviceData->satDeviceFaultState = agFALSE;
  }

  SM_DBG5(("smsatIOCompleted: smIORequest=%p  CDB=0x%x ATA CMD =0x%x\n",
    smIORequest, pScsiCmnd->cdb[0], hostToDevFis->h.command));

  /*
   * Decide which ATA command is the translation needed
   */
  switch(hostToDevFis->h.command)
  {
    case SAT_READ_FPDMA_QUEUED:
    case SAT_WRITE_FPDMA_QUEUED:

      /************************************************************************
       *
       * !!!! See Section 13.5.2.4 of SATA 2.5 specs.                      !!!!
       * !!!! If the NCQ error ends up here, it means that the device sent !!!!
       * !!!! Set Device Bit FIS (which has SActive register) instead of   !!!!
       * !!!! Register Device To Host FIS (which does not have SActive     !!!!
       * !!!! register). The callback ossaSATAEvent() deals with the case  !!!!
       * !!!! where Register Device To Host FIS was sent by the device.    !!!!
       *
       * For NCQ we need to issue READ LOG EXT command with log page 10h
       * to get the error and to allow other I/Os to continue.
       *
       * Here is the basic flow or sequence of error recovery, note that due
       * to the SATA HW assist that we have, this sequence is slighly different
       * from the one described in SATA 2.5:
       *
       * 1. Set SATA device flag to indicate error condition and returning busy
       *    for all new request.
       *   return SM_RC_SUCCESS;

       * 2. Because the HW/LL layer received Set Device Bit FIS, it can get the
       *    tag or I/O context for NCQ request, SATL would translate the ATA error
       *    to SCSI status and return the original NCQ I/O with the appopriate
       *    SCSI status.
       *
       * 3. Prepare READ LOG EXT page 10h command. Set flag to indicate that
       *    the failed I/O has been returned to the OS Layer. Send command.
       *
       * 4. When the device receives READ LOG EXT page 10h request all other
       *    pending I/O are implicitly aborted. No completion (aborted) status
       *    will be sent to the host for these aborted commands.
       *
       * 5. SATL receives the completion for READ LOG EXT command in
       *    smsatReadLogExtCB(). Steps 6,7,8,9 below are the step 1,2,3,4 in
       *    smsatReadLogExtCB().
       *
       * 6. Check flag that indicates whether the failed I/O has been returned
       *    to the OS Layer. If not, search the I/O context in device data
       *    looking for a matched tag. Then return the completion of the failed
       *    NCQ command with the appopriate/trasnlated SCSI status.
       *
       * 7. Issue abort to LL layer to all other pending I/Os for the same SATA
       *    drive.
       *
       * 8. Free resource allocated for the internally generated READ LOG EXT.
       *
       * 9. At the completion of abort, in the context of ossaSATACompleted(),
       *    return the I/O with error status to the OS-App Specific layer.
       *    When all I/O aborts are completed, clear SATA device flag to
       *    indicate ready to process new request.
       *
       ***********************************************************************/

      SM_DBG1(("smsatIOCompleted: NCQ ERROR smIORequest=%p ataStatus=0x%x ataError=0x%x!!!\n",
          smIORequest, ataStatus, ataError ));

      /* Set flag to indicate we are in recovery */
      oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;

      /* Return the failed NCQ I/O to OS-Apps Specifiic layer */
      smsatDefaultTranslation( smRoot,
                               smIORequest,
                               satIOContext,
                               pSense,
                               (bit8)ataStatus,
                               (bit8)ataError,
                               interruptContext );

      /*
       * Allocate resource for READ LOG EXT page 10h
       */
      satIntIo = smsatAllocIntIoResource( smRoot,
                                          &(smIORequestTMP), /* anything but NULL */
                                          oneDeviceData,
                                          sizeof (satReadLogExtPage10h_t),
                                          satIntIo);

      /*
       * If we cannot allocate resource for READ LOG EXT 10 in order to do
       * the normal NCQ recovery, we will do SATA device reset.
       */
      if (satIntIo == agNULL)
      {
        SM_DBG1(("smsatIOCompleted: can't send RLE due to resource lack!!!\n"));

        /* Abort I/O after completion of device reset */
        oneDeviceData->satAbortAfterReset = agTRUE;
#ifdef NOT_YET
        /* needs further investigation */
        /* no report to OS layer */
        satSubTM(smRoot,
                 smDeviceHandle,
                 SM_INTERNAL_TM_RESET,
                 agNULL,
                 agNULL,
                 agNULL,
                 agFALSE);
#endif


        SM_DBG1(("smsatIOCompleted: calling saSATADeviceReset 1!!!\n"));
        return;
      }


      /*
       * Set flag to indicate that the failed I/O has been returned to the
       * OS-App specific Layer.
       */
      satIntIo->satIntFlag = AG_SAT_INT_IO_FLAG_ORG_IO_COMPLETED;

      /* compare to satPrepareNewIO() */
      /* Send READ LOG EXIT page 10h command */

      /*
       * Need to initialize all the fields within satIOContext except
       * reqType and satCompleteCB which will be set depending on cmd.
       */

      smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
      satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);

      satIOContext2->pSatDevData   = oneDeviceData;
      satIOContext2->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
      satIOContext2->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
      satIOContext2->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
      satIOContext2->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
      satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;

      satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
      satIOContext2->interruptContext = interruptContext;
      satIOContext2->satIntIoContext  = satIntIo;

      satIOContext2->psmDeviceHandle = smDeviceHandle;
      satIOContext2->satOrgIOContext = agNULL;
      satIOContext2->smScsiXchg = agNULL;

      status = smsatSendReadLogExt( smRoot,
                                    &satIntIo->satIntSmIORequest,
                                    smDeviceHandle,
                                    &satIntIo->satIntSmScsiXchg,
                                    satIOContext2);

      if (status != SM_RC_SUCCESS)
      {
        SM_DBG1(("smsatIOCompleted: can't send RLE due to LL api failure!!!\n"));
        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);

        /* Abort I/O after completion of device reset */
        oneDeviceData->satAbortAfterReset = agTRUE;
#ifdef NOT_YET
        /* needs further investigation */
        /* no report to OS layer */
        satSubTM(smRoot,
                 smDeviceHandle,
                 SM_INTERNAL_TM_RESET,
                 agNULL,
                 agNULL,
                 agNULL,
                 agFALSE);
#endif

        SM_DBG1(("smsatIOCompleted: calling saSATADeviceReset 2!!!\n"));
        return;
      }

      break;

    case SAT_READ_DMA_EXT:
      /* fall through */
      /* Use default status/error translation */

    case SAT_READ_DMA:
      /* fall through */
      /* Use default status/error translation */

    default:
      smsatDefaultTranslation( smRoot,
                               smIORequest,
                               satIOContext,
                               pSense,
                               (bit8)ataStatus,
                               (bit8)ataError,
                               interruptContext );
      break;

  }  /* end switch  */
  return;
}


osGLOBAL void
smsatEncryptionHandler(
                       smRoot_t                *smRoot,
                       agsaIORequest_t         *agIORequest,
                       bit32                   agIOStatus,
                       bit32                   agIOInfoLen,
                       void                    *agParam,
                       bit32                   agOtherInfo,
                       bit32                   interruptContext
                      )
{
  smIORequestBody_t      *smIORequestBody;
  bit32                  errorDetail = smDetailOtherError;

  SM_DBG1(("smsatEncryptionHandler: start\n"));
  SM_DBG1(("smsatEncryptionHandler: agIOStatus 0x%x\n", agIOStatus));

  smIORequestBody = (smIORequestBody_t *)agIORequest->osData;

  switch (agIOStatus)
  {
  case OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS:
      SM_DBG1(("smsatEncryptionHandler: OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS\n"));
      errorDetail = smDetailDekKeyCacheMiss;
      break;
  case OSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID:
      SM_DBG1(("smsatEncryptionHandler: OSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID\n"));
      errorDetail = smDetailCipherModeInvalid;
      break;
  case OSSA_IO_XFR_ERROR_DEK_IV_MISMATCH:
      SM_DBG1(("smsatEncryptionHandler: OSSA_IO_XFR_ERROR_DEK_IV_MISMATCH\n"));
      errorDetail = smDetailDekIVMismatch;
      break;
  case OSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR:
      SM_DBG1(("smsatEncryptionHandler: OSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR\n"));
      errorDetail = smDetailDekRamInterfaceError;
      break;
  case OSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS:
      SM_DBG1(("smsatEncryptionHandler: OSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS\n"));
      errorDetail = smDetailDekIndexOutofBounds;
      break;
  case OSSA_IO_XFR_ERROR_DEK_ILLEGAL_TABLE:
      SM_DBG1(("smsatEncryptionHandler:OSSA_IO_XFR_ERROR_DEK_ILLEGAL_TABLE\n"));
      errorDetail = smDetailOtherError;
      break;
  default:
      SM_DBG1(("smsatEncryptionHandler: other error!!! 0x%x\n", agIOStatus));
      errorDetail = smDetailOtherError;
      break;
  }

  tdsmIOCompletedCB( smRoot,
                     smIORequestBody->smIORequest,
                     smIOEncryptError,
                     errorDetail,
                     agNULL,
                     interruptContext
                   );
  return;
}

osGLOBAL void
smsatDifHandler(
                smRoot_t                *smRoot,
                agsaIORequest_t         *agIORequest,
                bit32                   agIOStatus,
                bit32                   agIOInfoLen,
                void                    *agParam,
                bit32                   agOtherInfo,
                bit32                   interruptContext
               )
{
  smIORequestBody_t      *smIORequestBody;
  bit32                  errorDetail = smDetailOtherError;
#ifdef  TD_DEBUG_ENABLE
  agsaDifDetails_t       *DifDetail;
#endif

  SM_DBG1(("smsatDifHandler: start\n"));
  SM_DBG1(("smsatDifHandler: agIOStatus 0x%x\n", agIOStatus));
  smIORequestBody = (smIORequestBody_t *)agIORequest->osData;
#ifdef  TD_DEBUG_ENABLE
  DifDetail = (agsaDifDetails_t *)agParam;
#endif

  switch (agIOStatus)
  {
  case OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH:
      SM_DBG1(("smsatDifHandler: OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH\n"));
      errorDetail = smDetailDifAppTagMismatch;
      break;
  case OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH:
      SM_DBG1(("smsatDifHandler: OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH\n"));
      errorDetail = smDetailDifRefTagMismatch;
      break;
  case OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH:
      SM_DBG1(("smsatDifHandler: OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH\n"));
      errorDetail = smDetailDifCrcMismatch;
      break;
  default:
      SM_DBG1(("smsatDifHandler: other error!!! 0x%x\n", agIOStatus));
      errorDetail = smDetailOtherError;
      break;
  }

  SM_DBG1(("smsatDifHandler: DIF detail UpperLBA 0x%08x LowerLBA 0x%08x\n", DifDetail->UpperLBA, DifDetail->LowerLBA));

  tdsmIOCompletedCB( smRoot,
                     smIORequestBody->smIORequest,
                     smIODifError,
                     errorDetail,
                     agNULL,
                     interruptContext
                   );
  return;
}

osGLOBAL void
smsatProcessAbort(
                  smRoot_t           *smRoot,
                  smIORequest_t      *smIORequest,
                  smSatIOContext_t     *satIOContext
                 )
{
  smDeviceData_t            *oneDeviceData;
#ifdef REMOVED
  smDeviceHandle_t          *smDeviceHandle;
#endif
  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;

  SM_DBG5(("smsatProcessAbort: start\n"));

  oneDeviceData   = satIOContext->pSatDevData;
#ifdef REMOVED
  smDeviceHandle  = satIOContext->psmDeviceHandle;
#endif
  hostToDevFis    = satIOContext->pFis;

  if ( (hostToDevFis->h.command == SAT_SMART && hostToDevFis->h.features == SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE) &&
       (hostToDevFis->d.lbaLow != 0x01 && hostToDevFis->d.lbaLow != 0x02)
      )
  {
    /* no completion for send diagnotic in background. It is done in satSendDiagnostic() */
    tdsmIOCompletedCB( smRoot,
                       smIORequest,
                       smIOFailed,
                       smDetailAborted,
                       agNULL,
                       satIOContext->interruptContext);
  }

  if ( oneDeviceData->satTmTaskTag != agNULL )
  {
    SM_DBG1(("smsatProcessAbort: TM callback!!!\n"));
#ifdef REMOVED
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMOK,
                 oneDeviceData->satTmTaskTag);
#endif
    /*
     * Reset flag
     */
    oneDeviceData->satTmTaskTag = agNULL;
  }

  /*
   * Check if we are in recovery mode and need to update the recovery flag
   */
  if ((oneDeviceData->satDriveState == SAT_DEV_STATE_IN_RECOVERY ) &&
      (oneDeviceData->satPendingIO == 0 ))
  {
    oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
    SM_DBG1(("smsatProcessAbort: STATE NORMAL.!!!\n"));
  }
  SM_DBG1(("smsatProcessAbort: satDriveState %d!!!\n", oneDeviceData->satDriveState));
  SM_DBG1(("smsatProcessAbort: satPendingIO %d satNCQMaxIO %d!!!\n", oneDeviceData->satPendingIO, oneDeviceData->satNCQMaxIO ));
  SM_DBG1(("smsatProcessAbort: satPendingNCQIO %d satPendingNONNCQIO %d!!!\n", oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));

  return;
}


osGLOBAL void
smsatNonDataIOCB(
                  agsaRoot_t        *agRoot,
                  agsaIORequest_t   *agIORequest,
                  bit32             agIOStatus,
                  agsaFisHeader_t   *agFirstDword,
                  bit32             agIOInfoLen,
                  void              *agParam,
                  void              *ioContext
                 )
{
  smRoot_t             *smRoot = agNULL;
  smIntRoot_t          *smIntRoot = agNULL;
  smIntContext_t       *smAllShared = agNULL;
  smIORequestBody_t    *smIORequestBody;
  bit32                interruptContext;
  smSatIOContext_t       *satIOContext;
  smDeviceData_t       *oneDeviceData;

  SM_DBG2(("smsatNonDataIOCB: start\n"));
  SM_DBG5(("satNonDataIOCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n",
    agIORequest, agIOStatus, agIOInfoLen));

  smIORequestBody = (smIORequestBody_t *)agIORequest->osData;
  satIOContext    = (smSatIOContext_t *) ioContext;
  oneDeviceData   = satIOContext->pSatDevData;
  smRoot          = oneDeviceData->smRoot;
  smIntRoot       = (smIntRoot_t *)smRoot->smData;
  smAllShared     = (smIntContext_t *)&smIntRoot->smAllShared;
  interruptContext = satIOContext->interruptContext;

  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);


  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  /* Process completion */
  if( (agIOStatus == OSSA_IO_SUCCESS) && (agIOInfoLen==0))
  {
   
    SM_DBG1(("satNonDataIOCB: *** ERROR***  agIORequest=%p agIOStatus=0x%x agIOInfoLen %d!!!\n",
      agIORequest, agIOStatus, agIOInfoLen));

    tdsmIOCompletedCB( smRoot,
                       smIORequestBody->smIORequest,
                       smIOFailed,
                       smDetailOtherError,
                       agNULL,
                       interruptContext);
  }
  else
  {
    /* More checking needed, for non-data IO this should be the normal case */
    smsatProcessAbnormalCompletion( agRoot,
                                    agIORequest,
                                    agIOStatus,
                                    agFirstDword,
                                    agIOInfoLen,
                                    agParam,
                                    satIOContext);
  }
  return;
}

osGLOBAL void
smsatInquiryCB(
               agsaRoot_t        *agRoot,
               agsaIORequest_t   *agIORequest,
               bit32             agIOStatus,
               agsaFisHeader_t   *agFirstDword,
               bit32             agIOInfoLen,
               void              *agParam,
               void              *ioContext
              )
{
  /*
    In the process of Inquiry
    Process SAT_IDENTIFY_DEVICE
  */
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL;
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatInternalIo_t        *satIntIo;
//  satDeviceData_t         *satDevData;
  smDeviceData_t           *oneDeviceData;
  smScsiRspSense_t         *pSense;
  smIniScsiCmnd_t          *scsiCmnd;
  smIORequest_t            *smOrgIORequest;
#ifdef  TD_DEBUG_ENABLE
  agsaFisPioSetupHeader_t  *satPIOSetupHeader = agNULL;
  bit32                     ataStatus = 0;
  bit32                     ataError;
#endif
  smScsiInitiatorRequest_t *smScsiRequest; /* TD's smScsiXchg */
  smScsiInitiatorRequest_t *smOrgScsiRequest; /* OS's smScsiXchg */
  agsaSATAIdentifyData_t   *pSATAIdData;
  bit8                     *pInquiry;
  bit8                      page = 0xFF;
  bit16                    *tmpptr,tmpptr_tmp;
  bit32                     x;
  bit32                     lenReceived = 0;
  bit32                     allocationLen = 0;
  bit32                     lenNeeded = 0;
  bit8                      dataBuffer[SATA_PAGE89_INQUIRY_SIZE] = {0};


  SM_DBG6(("smsatInquiryCB: start\n"));
  SM_DBG6(("smsatInquiryCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  smScsiRequest          = satIOContext->smScsiXchg;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG6(("smsatInquiryCB: External, OS generated\n"));
    pSense               = satIOContext->pSense;
    scsiCmnd             = satIOContext->pScsiCmnd;
    satOrgIOContext      = satIOContext;
    smOrgIORequest       = smIORequestBody->smIORequest;
  }
  else
  {
    SM_DBG6(("smsatInquiryCB: Internal, TD generated\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG1(("smsatInquiryCB: satOrgIOContext is NULL, wrong!!!\n"));
      return;
    }
    else
    {
      SM_DBG6(("smsatInquiryCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    pSense                 = satOrgIOContext->pSense;
    scsiCmnd               = satOrgIOContext->pScsiCmnd;
  }

  smOrgScsiRequest         = satOrgIOContext->smScsiXchg;
  pInquiry                 = dataBuffer;

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  SM_DBG3(("smsatInquiryCB: did %d\n", oneDeviceData->id));

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatInquiryCB: agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY)
    {
      SM_DBG1(("smsatInquiryCB: OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY!!!\n"));
      /* should NOT be retried */
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOFailed,
                         smDetailNoLogin,
                         agNULL,
                         satOrgIOContext->interruptContext
                       );
    }
    else
    {
      SM_DBG1(("smsatInquiryCB: NOT OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY!!!\n"));
      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOFailed,
                         smDetailNoLogin,
                         agNULL,
                         satOrgIOContext->interruptContext
                        );
    }
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
      )
  {
    SM_DBG1(("smsatInquiryCB: OSSA_IO_OPEN_CNX_ERROR!!!\n"));

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOFailed,
                       smDetailNoLogin,
                       agNULL,
                       satOrgIOContext->interruptContext
                     );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

 if ( agIOStatus != OSSA_IO_SUCCESS ||
      (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
    )
 {
#ifdef  TD_DEBUG_ENABLE
   /* only agsaFisPioSetup_t is expected */
   satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
   ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
   ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
#endif
   SM_DBG1(("smsatInquiryCB: ataStatus 0x%x ataError 0x%x!!!\n", ataStatus, ataError));

   /* Process abort case */
   if (agIOStatus == OSSA_IO_ABORTED)
   {
     smsatProcessAbort(smRoot,
                       smOrgIORequest,
                       satOrgIOContext
                      );

     smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

     smsatFreeIntIoResource( smRoot,
                             oneDeviceData,
                             satIntIo);
     return;
   }

   tdsmIOCompletedCB( smRoot,
                      smOrgIORequest,
                      smIOFailed,
                      smDetailOtherError,
                      agNULL,
                      satOrgIOContext->interruptContext
                     );

   smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

   smsatFreeIntIoResource( smRoot,
                           oneDeviceData,
                           satIntIo);
   return;
  }

 /* success */


 /* Convert to host endian */
 tmpptr = (bit16*)(smScsiRequest->sglVirtualAddr);
 for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
 {
   OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
   *tmpptr = tmpptr_tmp;
   tmpptr++;
   /*Print tmpptr_tmp here for debugging purpose*/
 }

 pSATAIdData = (agsaSATAIdentifyData_t *)(smScsiRequest->sglVirtualAddr);

 SM_DBG5(("smsatInquiryCB: OS satOrgIOContext %p \n", satOrgIOContext));
 SM_DBG5(("smsatInquiryCB: TD satIOContext %p \n", satIOContext));
 SM_DBG5(("smsatInquiryCB: OS smScsiXchg %p \n", satOrgIOContext->smScsiXchg));
 SM_DBG5(("smsatInquiryCB: TD smScsiXchg %p \n", satIOContext->smScsiXchg));

 /* copy ID Dev data to oneDeviceData */
 oneDeviceData->satIdentifyData = *pSATAIdData;
 oneDeviceData->IDDeviceValid = agTRUE;
#ifdef SM_INTERNAL_DEBUG
 smhexdump("smsatInquiryCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
 smhexdump("smsatInquiryCB Device ID Dev data",(bit8 *)&oneDeviceData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
#endif
// smhexdump("smsatInquiryCB Device ID Dev data",(bit8 *)&oneDeviceData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));

 /* set oneDeviceData fields from IndentifyData */
 smsatSetDevInfo(oneDeviceData,pSATAIdData);

  allocationLen = ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4];
  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);

  /* SPC-4, spec 6.4 p 141 */
  /* EVPD bit == 0 */
  if (!(scsiCmnd->cdb[1] & SCSI_EVPD_MASK))
  {
    /* Returns the standard INQUIRY data */
    lenNeeded = STANDARD_INQUIRY_SIZE;


    smsatInquiryStandard(pInquiry, pSATAIdData, scsiCmnd);
    //smhexdump("smsatInquiryCB ***standard***", (bit8 *)pInquiry, 36);

  }
  else
  {
    /* EVPD bit != 0 && PAGE CODE != 0 */
    /* returns the pages of vital product data information */

    /* we must support page 00h, 83h and 89h */
    page = scsiCmnd->cdb[2];
    if ((page != INQUIRY_SUPPORTED_VPD_PAGE) &&
        (page != INQUIRY_DEVICE_IDENTIFICATION_VPD_PAGE) &&
        (page != INQUIRY_ATA_INFORMATION_VPD_PAGE) &&
        (page != INQUIRY_BLOCK_DEVICE_CHARACTERISTICS_VPD_PAGE))
    {
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_ILLEGAL_REQUEST,
                            0,
                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
                            satOrgIOContext);

      tdsmIOCompletedCB( smRoot,
                         smOrgIORequest,
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satOrgIOContext->pSmSenseData,
                         satOrgIOContext->interruptContext );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      SM_DBG1(("smsatInquiryCB: invalid PAGE CODE 0x%x!!!\n", page));
      return;
    }

    /* checking length */
    switch (page)
    {
    case INQUIRY_SUPPORTED_VPD_PAGE:
      lenNeeded = SATA_PAGE0_INQUIRY_SIZE; /* 9 */
      break;
    case INQUIRY_DEVICE_IDENTIFICATION_VPD_PAGE:
      if (oneDeviceData->satWWNSupport)
      {
        lenNeeded = SATA_PAGE83_INQUIRY_WWN_SIZE; /* 16 */
      }
      else
      {
        lenNeeded = SATA_PAGE83_INQUIRY_NO_WWN_SIZE; /* 76 */
      }
      break;
    case INQUIRY_ATA_INFORMATION_VPD_PAGE:
      lenNeeded = SATA_PAGE89_INQUIRY_SIZE; /* 572 */
      break;
    case INQUIRY_BLOCK_DEVICE_CHARACTERISTICS_VPD_PAGE:
      lenNeeded = SATA_PAGEB1_INQUIRY_SIZE; /* 64 */
      break;
    default:
      SM_DBG1(("smsatInquiryCB: wrong!!! invalid PAGE CODE 0x%x!!!\n", page));
      break;
    }


    /*
     * Fill in the Inquiry data depending on what Inquiry data we are returning.
     */
    switch (page)
    {
    case INQUIRY_SUPPORTED_VPD_PAGE:
      smsatInquiryPage0(pInquiry, pSATAIdData);
      break;
    case INQUIRY_DEVICE_IDENTIFICATION_VPD_PAGE:
      smsatInquiryPage83(pInquiry, pSATAIdData, oneDeviceData);
      break;
    case INQUIRY_ATA_INFORMATION_VPD_PAGE:
      smsatInquiryPage89(pInquiry, pSATAIdData, oneDeviceData, lenReceived);
      break;
    case INQUIRY_BLOCK_DEVICE_CHARACTERISTICS_VPD_PAGE:
      smsatInquiryPageB1(pInquiry, pSATAIdData);
      break;
    default:
      SM_DBG1(("smsatInquiryCB: wrong!!! invalidinvalid PAGE CODE 0x%x!!!\n", page));
      break;
    }
  } /* else */

  SM_DBG6(("smsatInquiryCB: calling tdsmIOCompletedCB\n"));

  /* if this is a standard Inquiry command, notify Stoport to set the device queue depth to max NCQ */
  if ( (oneDeviceData->satNCQ == agTRUE) &&
       ((scsiCmnd->cdb[1] & 0x01) == 0))
  {
    if (tdsmSetDeviceQueueDepth(smRoot,
                                smOrgIORequest,
                                oneDeviceData->satNCQMaxIO-1
                                ) == agFALSE)
    {
      SM_DBG1(("smsatInquiryCB: failed to call tdsmSetDeviceQueueDepth()!!! Q=%d\n", oneDeviceData->satNCQMaxIO));
    }
  }

  sm_memcpy(smOrgScsiRequest->sglVirtualAddr, dataBuffer, MIN(allocationLen, lenNeeded));
  if (allocationLen > lenNeeded)
  {
    SM_DBG6(("smsatInquiryCB reporting underrun lenNeeded=0x%x allocationLen=0x%x smIORequest=%p\n", 
        lenNeeded, allocationLen, smOrgIORequest));      

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOUnderRun,
                       allocationLen - lenNeeded,
                       agNULL,
                       satOrgIOContext->interruptContext );
  }
  else
  {
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       satOrgIOContext->interruptContext);
  }

  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);
  SM_DBG5(("smsatInquiryCB: device %p pending IO %d\n", oneDeviceData, oneDeviceData->satPendingIO));
  SM_DBG6(("smsatInquiryCB: end\n"));
  return;
}

osGLOBAL void
smsatInquiryIntCB(
                   smRoot_t                  *smRoot,
                   smIORequest_t             *smIORequest,
                   smDeviceHandle_t          *smDeviceHandle,
                   smScsiInitiatorRequest_t  *smScsiRequest,
                   smSatIOContext_t            *satIOContext
                  )
{
  smScsiRspSense_t          *pSense;
  smIniScsiCmnd_t           *scsiCmnd;
//  satDeviceData_t           *satDevData;
  smDeviceData_t            *oneDeviceData;
  agsaSATAIdentifyData_t    *pSATAIdData;

  bit8                      *pInquiry;
  bit8                      page = 0xFF;
  bit32                     lenReceived = 0;
  bit32                     allocationLen = 0;
  bit32                     lenNeeded = 0;
  bit8                      dataBuffer[SATA_PAGE89_INQUIRY_SIZE] = {0};

  SM_DBG6(("smsatInquiryIntCB: start\n"));

  pSense      = satIOContext->pSense;
  scsiCmnd    = &smScsiRequest->scsiCmnd;
  pInquiry    = dataBuffer;
  oneDeviceData = satIOContext->pSatDevData;
  pSATAIdData = &oneDeviceData->satIdentifyData;

  allocationLen = ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4];
  allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);

  /* SPC-4, spec 6.4 p 141 */
  /* EVPD bit == 0 */
  if (!(scsiCmnd->cdb[1] & SCSI_EVPD_MASK))
  {
    /* Returns the standard INQUIRY data */
    lenNeeded = STANDARD_INQUIRY_SIZE;

     smsatInquiryStandard(pInquiry, pSATAIdData, scsiCmnd);
    //smhexdump("satInquiryIntCB ***standard***", (bit8 *)pInquiry, 36);

  }
  else
  {
    /* EVPD bit != 0 && PAGE CODE != 0 */
    /* returns the pages of vital product data information */

    /* we must support page 00h, 83h and 89h */
    page = scsiCmnd->cdb[2];
    if ((page != INQUIRY_SUPPORTED_VPD_PAGE) &&
        (page != INQUIRY_DEVICE_IDENTIFICATION_VPD_PAGE) &&
        (page != INQUIRY_ATA_INFORMATION_VPD_PAGE) &&
        (page != INQUIRY_UNIT_SERIAL_NUMBER_VPD_PAGE) &&
        (page != INQUIRY_BLOCK_DEVICE_CHARACTERISTICS_VPD_PAGE))
    {
      smsatSetSensePayload( pSense,
                            SCSI_SNSKEY_ILLEGAL_REQUEST,
                            0,
                            SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
                            satIOContext);

      tdsmIOCompletedCB( smRoot,
                         smIORequest,
                         smIOSuccess,
                         SCSI_STAT_CHECK_CONDITION,
                         satIOContext->pSmSenseData,
                         satIOContext->interruptContext );

      SM_DBG1(("smsatInquiryIntCB: invalid PAGE CODE 0x%x!!!\n", page));
      return;
    }

    /* checking length */
    switch (page)
    {
    case INQUIRY_SUPPORTED_VPD_PAGE:
      lenNeeded = SATA_PAGE0_INQUIRY_SIZE; /* 36 */
      break;
    case INQUIRY_DEVICE_IDENTIFICATION_VPD_PAGE:
      if (oneDeviceData->satWWNSupport)
      {
        lenNeeded = SATA_PAGE83_INQUIRY_WWN_SIZE; /* 16 */
      }
      else
      {
        lenNeeded = SATA_PAGE83_INQUIRY_NO_WWN_SIZE; /* 76 */
      }
      break;
    case INQUIRY_ATA_INFORMATION_VPD_PAGE:
      lenNeeded = SATA_PAGE89_INQUIRY_SIZE; /* 572 */
      break;
    case INQUIRY_UNIT_SERIAL_NUMBER_VPD_PAGE:
      lenNeeded = SATA_PAGE80_INQUIRY_SIZE; /* 24 */
      break;
    case INQUIRY_BLOCK_DEVICE_CHARACTERISTICS_VPD_PAGE:
      lenNeeded = SATA_PAGEB1_INQUIRY_SIZE; /* 64 */
      break;
    default:
      SM_DBG1(("smsatInquiryIntCB: wrong!!! invalidinvalid PAGE CODE 0x%x!!!\n", page));
      break;
    }


    /*
     * Fill in the Inquiry data depending on what Inquiry data we are returning.
     */
    switch (page)
    {
    case INQUIRY_SUPPORTED_VPD_PAGE:
      smsatInquiryPage0(pInquiry, pSATAIdData);
      break;
    case INQUIRY_DEVICE_IDENTIFICATION_VPD_PAGE:
      smsatInquiryPage83(pInquiry, pSATAIdData, oneDeviceData);
      break;
    case INQUIRY_ATA_INFORMATION_VPD_PAGE:
      smsatInquiryPage89(pInquiry, pSATAIdData, oneDeviceData, lenReceived);
      break;
    case INQUIRY_UNIT_SERIAL_NUMBER_VPD_PAGE:
      smsatInquiryPage80(pInquiry, pSATAIdData);
      break;
    case INQUIRY_BLOCK_DEVICE_CHARACTERISTICS_VPD_PAGE:
      smsatInquiryPageB1(pInquiry, pSATAIdData);
      break;
    default:
      SM_DBG1(("smsatInquiryIntCB: wrong!!! invalidinvalid PAGE CODE 0x%x!!!\n", page));
      break;
    }
  } /* else */

  SM_DBG6(("smsatInquiryIntCB: calling tdsmIOCompletedCB\n"));

  /* if this is a standard Inquiry command, notify Stoport to set the device queue depth to max NCQ */
  if ( (oneDeviceData->satNCQ == agTRUE) &&
       ((scsiCmnd->cdb[1] & 0x01) == 0))
  {
    if (tdsmSetDeviceQueueDepth(smRoot,
                                smIORequest,
                                oneDeviceData->satNCQMaxIO-1
                                ) == agFALSE)
    {
      SM_DBG1(("smsatInquiryIntCB: failed to call tdsmSetDeviceQueueDepth()!!! Q=%d\n", oneDeviceData->satNCQMaxIO));
    }
  }

  sm_memcpy(smScsiRequest->sglVirtualAddr, dataBuffer, MIN(allocationLen, lenNeeded));
  if (allocationLen > lenNeeded)
  {
    SM_DBG6(("smsatInquiryIntCB reporting underrun lenNeeded=0x%x allocationLen=0x%x smIORequest=%p\n", 
        lenNeeded, allocationLen, smIORequest));      

    tdsmIOCompletedCB( smRoot,
                       smIORequest,
                       smIOUnderRun,
                       allocationLen - lenNeeded,
                       agNULL,
                       satIOContext->interruptContext );
  }
  else
  {
    tdsmIOCompletedCB( smRoot,
                       smIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       satIOContext->interruptContext);
  }

  SM_DBG5(("smsatInquiryIntCB: device %p pending IO %d\n", oneDeviceData, oneDeviceData->satPendingIO));
  SM_DBG6(("smsatInquiryIntCB: end\n"));
  return;

}

osGLOBAL void
smsatVerify10CB(
                agsaRoot_t        *agRoot,
                agsaIORequest_t   *agIORequest,
                bit32             agIOStatus,
                agsaFisHeader_t   *agFirstDword,
                bit32             agIOInfoLen,
                void              *agParam,
                void              *ioContext
               )
{
  smRoot_t                *smRoot = agNULL;
  smIntRoot_t             *smIntRoot = agNULL;
  smIntContext_t          *smAllShared = agNULL;
  smIORequestBody_t       *smIORequestBody;
  smIORequestBody_t       *smOrgIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatInternalIo_t         *satIntIo;
  smDeviceData_t          *oneDeviceData;

  smScsiRspSense_t          *pSense;
  smIORequest_t             *smOrgIORequest;

  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
  bit32                     ataStatus = 0;
  agsaFisRegD2HHeader_t    *statDevToHostFisHeader = agNULL;

  SM_DBG5(("smsatVerify10CB: start\n"));
  SM_DBG5(("smsatVerify10CB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatVerify10CB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satIOContext->pSense;
  }
  else
  {
    SM_DBG4(("smsatVerify10CB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatVerify10CB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatVerify10CB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    pSense        = satOrgIOContext->pSense;
  }

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
     SM_DBG1(("smsatVerify10CB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
     smsatSetSensePayload( pSense,
                           SCSI_SNSKEY_NO_SENSE,
                           0,
                           SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                           satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                              satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisRegDeviceToHost_t is expected */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
  }

  if( agIOStatus != OSSA_IO_SUCCESS)
  {
  if ( (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) ||
       ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
       )
  {
    /* for debugging */
    if( agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatVerify10CB: FAILED, NOT IO_SUCCESS!!!\n"));
    }
    else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
    {
      SM_DBG1(("smsatVerify10CB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
    }
    else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
              (ataStatus & DF_ATA_STATUS_MASK)
              )
    {
      SM_DBG1(("smsatVerify10CB: FAILED, FAILED, error status!!!\n"));
    }

    /* Process abort case */
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;
    }

    /* for debugging */
    switch (hostToDevFis->h.command)
    {
    case SAT_READ_VERIFY_SECTORS_EXT:
      SM_DBG1(("smsatVerify10CB: SAT_READ_VERIFY_SECTORS_EXT!!!\n"));
      break;
    default:
      SM_DBG1(("smsatVerify10CB: error default case command 0x%x!!!\n", hostToDevFis->h.command));
      break;
    }

    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  } /* end error checking */
  }

  /* process success from this point on */
  switch (hostToDevFis->h.command)
  {
  case SAT_READ_VERIFY_SECTORS_EXT:
    SM_DBG5(("smsatVerify10CB: SAT_WRITE_DMA_EXT success \n"));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       satOrgIOContext->interruptContext);
    break;
  default:
    SM_DBG1(("smsatVerify10CB: success but error default case command 0x%x!!!\n", hostToDevFis->h.command));

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_NO_SENSE,
                          0,
                          SCSI_SNSCODE_NO_ADDITIONAL_INFO,
                          satOrgIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest, /* == &satIntIo->satOrgSmIORequest */
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satOrgIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );

    break;
  }

  return;
}

osGLOBAL void
smsatReadLogExtCB(
                   agsaRoot_t        *agRoot,
                   agsaIORequest_t   *agIORequest,
                   bit32             agIOStatus,
                   agsaFisHeader_t   *agFirstDword,
                   bit32             agIOInfoLen,
                   void              *agParam,
                   void              *ioContext
                 )
{
  smRoot_t                *smRoot = agNULL;
  smIntRoot_t             *smIntRoot = agNULL;
  smIntContext_t          *smAllShared = agNULL;
  smIORequestBody_t       *smIORequestBody;
  smSatIOContext_t          *satReadLogExtIOContext;
  smSatIOContext_t          *satIOContext;
  smSatInternalIo_t         *satIntIo;
  smDeviceData_t          *oneDeviceData;
  agsaIORequest_t         *agAbortIORequest;
  smIORequestBody_t       *smAbortIORequestBody;
  bit32                   PhysUpper32;
  bit32                   PhysLower32;
  bit32                   memAllocStatus;
  void                    *osMemHandle;
  smDeviceHandle_t        *smDeviceHandle;

  SM_DBG5(("smsatReadLogExtCB: start\n"));
  SM_DBG1(("smsatReadLogExtCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n",
    agIORequest, agIOStatus, agIOInfoLen));
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satReadLogExtIOContext = (smSatIOContext_t *) ioContext;
  satIntIo               = satReadLogExtIOContext->satIntIoContext;
  oneDeviceData          = satReadLogExtIOContext->pSatDevData;
  smDeviceHandle         = satReadLogExtIOContext->psmDeviceHandle;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  SM_DBG1(("smsatReadLogExtCB: did %d!!!\n", oneDeviceData->id));
  SM_DBG1(("smsatReadLogExtCB: smIORequestBody ID %d!!!\n", smIORequestBody->id));
  SM_DBG1(("smsatReadLogExtCB: smIORequestBody ioCompleted %d ioStarted %d\n", smIORequestBody->ioCompleted, smIORequestBody->ioStarted));
  smsatDecrementPendingIO(smRoot, smAllShared, satReadLogExtIOContext);

  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  /*
   * If READ LOG EXT failed, we issue device reset.
   */
  if ( agIOStatus != OSSA_IO_SUCCESS ||
       (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
     )
  {
    SM_DBG1(("smsatReadLogExtCB: FAILED.!!!\n"));

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    /* Abort I/O after completion of device reset */
    oneDeviceData->satAbortAfterReset = agTRUE;
#ifdef NOT_YET
    /* needs to investigate this case */
    /* no report to OS layer */
    satSubTM(smRoot,
             satReadLogExtIOContext->ptiDeviceHandle,
             TD_INTERNAL_TM_RESET,
             agNULL,
             agNULL,
             agNULL,
             agFALSE);
#endif
    return;
  }


  /***************************************************************************
   * The following steps take place when READ LOG EXT successfully completed.
   ***************************************************************************/

  /************************************************************************
   *
   * 1. Issue abort to LL layer to all other pending I/Os for the same SATA
   *    drive.
   *
   * 2. Free resource allocated for the internally generated READ LOG EXT.
   *
   * 3. At the completion of abort, in the context of ossaSATACompleted(),
   *    return the I/O with error status to the OS-App Specific layer.
   *    When all I/O aborts are completed, clear SATA device flag to
   *    indicate ready to process new request.
   *
   ***********************************************************************/

  /*
   * Issue abort to LL layer to all other pending I/Os for the same SATA drive
   */
  /*
    replace the single IO abort with device abort
  */

  SM_DBG1(("smsatReadLogExtCB: issuing saSATAAbort. Device Abort!!!\n"));
  oneDeviceData->SMAbortAll = agTRUE;
  /*
  smAbortIORequestBody = smDequeueIO(smRoot);

  if (smAbortIORequestBody == agNULL)
  {
    SM_DBG1(("smsatReadLogExtCB: empty freeIOList!!!\n"));
    return;
  }
  */
  /* allocating agIORequest for abort itself */
  memAllocStatus = tdsmAllocMemory(
                                   smRoot,
                                   &osMemHandle,
                                   (void **)&smAbortIORequestBody,
                                   &PhysUpper32,
                                   &PhysLower32,
                                   8,
                                   sizeof(smIORequestBody_t),
                                   agTRUE
                                   );

  if (memAllocStatus != tiSuccess)
  {
    /* let os process IO */
    SM_DBG1(("smsatReadLogExtCB: ostiAllocMemory failed...\n"));
    return;
  }

  if (smAbortIORequestBody == agNULL)
  {
    /* let os process IO */
    SM_DBG1(("smsatReadLogExtCB: ostiAllocMemory returned NULL smAbortIORequestBody\n"));
    return;
  }
  smIOReInit(smRoot, smAbortIORequestBody);
  /* setup task management structure */
  smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
  smAbortIORequestBody->smDevHandle = smDeviceHandle;
  /* setup task management structure */
//  smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
  satIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext);
  satIOContext->smRequestBody = smAbortIORequestBody;

  /* initialize agIORequest */
  agAbortIORequest = &(smAbortIORequestBody->agIORequest);
  agAbortIORequest->osData = (void *) smAbortIORequestBody;
  agAbortIORequest->sdkData = agNULL; /* LL takes care of this */

  /*
   * Issue abort (device abort all)
   */
  saSATAAbort( agRoot, agAbortIORequest, tdsmRotateQnumber(smRoot, smDeviceHandle), oneDeviceData->agDevHandle, 1, agNULL, smaSATAAbortCB);

  /*
   * Free resource allocated for the internally generated READ LOG EXT.
   */
  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);

  /*
   * Sequence of recovery continue at some other context:
   * At the completion of abort, in the context of ossaSATACompleted(),
   * return the I/O with error status to the OS-App Specific layer.
   * When all I/O aborts are completed, clear SATA device flag to
   * indicate ready to process new request.
   */

  oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;

  SM_DBG1(("smsatReadLogExtCB: end return!!!\n"));
  return;
}

osGLOBAL void
ossaSATAEvent(
               agsaRoot_t              *agRoot,
               agsaIORequest_t         *agIORequest,
               agsaPortContext_t       *agPortContext,
               agsaDevHandle_t         *agDevHandle,
               bit32                   event,
               bit32                   agIOInfoLen,
               void                    *agParam
         )
{
  smRoot_t                  *smRoot = gsmRoot;
  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
  smDeviceHandle_t          *smDeviceHandle = agNULL;
  smDeviceData_t            *oneDeviceData = agNULL;
  smList_t                  *DeviceListList;
  bit32                     found = agFALSE;
  smIORequestBody_t         *smIORequestBody = agNULL;
  smSatInternalIo_t           *satIntIo = agNULL;
  smSatIOContext_t            *satIOContext2;
  smIORequest_t             smIORequestTMP;
  bit32                     status;
#ifdef REMOVED
  agsaDifDetails_t          agDifDetails;
  bit8                      framePayload[256];
  bit16                     frameOffset = 0;
  bit16                     frameLen = 0;
#endif

  SM_DBG1(("ossaSATAEvent: start\n"));
  if (event == OSSA_IO_XFER_ERROR_ABORTED_NCQ_MODE)
  {
    /* agIORequest is invalid, search for smDeviceHandle from smAllShared using agDevHandle */
    /* find a device's existence */
    DeviceListList = smAllShared->MainDeviceList.flink;
    while (DeviceListList != &(smAllShared->MainDeviceList))
    {
      oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList);
      if (oneDeviceData == agNULL)
      {
        SM_DBG1(("ossaSATAEvent: oneDeviceData is NULL!!!\n"));
        return;
      }
      if (oneDeviceData->agDevHandle == agDevHandle)
      {
        SM_DBG2(("ossaSATAEvent: did %d\n", oneDeviceData->id));
        found = agTRUE;
        break;
      }
      DeviceListList = DeviceListList->flink;
    }
    if (found == agFALSE)
    {
      SM_DBG2(("ossaSATAEvent: not found!!!\n"));
      return;
    }
    if (oneDeviceData->valid == agFALSE)
    {
      SM_DBG2(("ossaSATAEvent: oneDeviceData is not valid did %d!!!\n", oneDeviceData->id));
      return;
    }
    /**************************************************************************
     *
     * !!!! See Section 13.5.2.4 of SATA 2.5 specs.                       !!!!
     * !!!! If the NCQ error ends up here, it means that the device sent  !!!!
     * !!!! Register Device To Host FIS (which does not have SActive      !!!!
     * !!!! register) instead of Set Device Bit FIS (which has SActive    !!!!
     * !!!! register). The routine osSatIOCompleted() deals with the case !!!!
     * !!!! where Set Device Bit FIS was sent by the device.              !!!!
     *
     * For NCQ we need to issue READ LOG EXT command with log page 10h
     * to get the error and to allow other I/Os to continue.
     *
     * Here is the basic flow or sequence of error recovery, this sequence is
     * similar to the one described in SATA 2.5:
     *
     * 1. Set SATA device flag to indicate error condition and returning busy
     *    for all new request.
     *
     * 2. Prepare READ LOG EXT page 10h command. Set flag to indicate that
     *    the failed I/O has NOT been returned to the OS Layer. Send command.
     *
     * 3. When the device receives READ LOG EXT page 10h request all other
     *    pending I/O are implicitly aborted. No completion (aborted) status
     *    will be sent to the host for these aborted commands.
     *
     * 4. SATL receives the completion for READ LOG EXT command in
     *    smsatReadLogExtCB(). Steps 5,6,7,8 below are the step 1,2,3,4 in
     *    smsatReadLogExtCB().
     *
     * 5. Check flag that indicates whether the failed I/O has been returned
     *    to the OS Layer. If not, search the I/O context in device data
     *    looking for a matched tag. Then return the completion of the failed
     *    NCQ command with the appopriate/trasnlated SCSI status.
     *
     * 6. Issue abort to LL layer to all other pending I/Os for the same SATA
     *    drive.
     *
     * 7. Free resource allocated for the internally generated READ LOG EXT.
     *
     * 8. At the completion of abort, in the context of ossaSATACompleted(),
     *    return the I/O with error status to the OS-App Specific layer.
     *    When all I/O aborts are completed, clear SATA device flag to
     *    indicate ready to process new request.
     *
     *************************************************************************/

    smDeviceHandle = oneDeviceData->smDevHandle;
    SM_DBG1(("ossaSATAEvent: did %d!!!\n", oneDeviceData->id));

    if (oneDeviceData->satDriveState == SAT_DEV_STATE_NORMAL)
    {
      SM_DBG1(("ossaSATAEvent: NCQ ERROR did %d!!!\n", oneDeviceData->id ));

      /* Set flag to indicate we are in recovery */
      oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;

      /*
       * Allocate resource for READ LOG EXIT page 10h
       */
      satIntIo = smsatAllocIntIoResource( smRoot,
                                          &(smIORequestTMP), /* anything but NULL */
                                          oneDeviceData,
                                          sizeof (satReadLogExtPage10h_t),
                                          satIntIo);

      /*
       * If we cannot allocate resource to do the normal NCQ recovery, we
       * will do SATA device reset.
       */
      if (satIntIo == agNULL)
      {
        /* Abort I/O after completion of device reset */
        oneDeviceData->satAbortAfterReset = agTRUE;
        SM_DBG1(("ossaSATAEvent: can't send RLE due to resource lack!!!\n"));

#ifdef NOT_YET
        /* needs to investigate this case */
        /* no report to OS layer */
        smsatSubTM(smRoot,
                   smDeviceHandle,
                   TD_INTERNAL_TM_RESET,
                   agNULL,
                   agNULL,
                   agNULL,
                   agFALSE);
#endif

        return;
      }


      /*
       * Clear flag to indicate that the failed I/O has NOT been returned to the
       * OS-App specific Layer.
       */
      satIntIo->satIntFlag = 0;

      /* compare to satPrepareNewIO() */
      /* Send READ LOG EXIT page 10h command */

      /*
       * Need to initialize all the fields within satIOContext except
       * reqType and satCompleteCB which will be set depending on cmd.
       */

      smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
      satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);

      satIOContext2->pSatDevData   = oneDeviceData;
      satIOContext2->pFis          = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
      satIOContext2->pScsiCmnd     = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
      satIOContext2->pSense        = &(smIORequestBody->transport.SATA.sensePayload);
      satIOContext2->pSmSenseData  = &(smIORequestBody->transport.SATA.smSenseData);
      satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;

      satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
      //not used
//      satIOContext2->interruptContext = interruptContext;
      satIOContext2->satIntIoContext  = satIntIo;

      satIOContext2->psmDeviceHandle = smDeviceHandle;
      satIOContext2->satOrgIOContext = agNULL;
      satIOContext2->smScsiXchg = agNULL;

      SM_DBG1(("ossaSATAEvent: smIORequestBody ID %d!!!\n", smIORequestBody->id));
      SM_DBG1(("ossaSATAEvent: smIORequestBody ioCompleted %d ioStarted %d\n", smIORequestBody->ioCompleted, smIORequestBody->ioStarted));
      status = smsatSendReadLogExt( smRoot,
                                    &satIntIo->satIntSmIORequest,
                                    smDeviceHandle,
                                    &satIntIo->satIntSmScsiXchg,
                                    satIOContext2);

      if (status != SM_RC_SUCCESS)
      {
        SM_DBG1(("ossaSATAEvent: can't send RLE due to LL api failure!!!\n"));
        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo);
        /* Abort I/O after completion of device reset */
        oneDeviceData->satAbortAfterReset = agTRUE;
#ifdef NOT_YET
        /* needs to investigate this case */
        /* no report to OS layer */
        smsatSubTM(smRoot,
                   smDeviceHandle,
                   TD_INTERNAL_TM_RESET,
                   agNULL,
                   agNULL,
                   agNULL,
                   agFALSE);
#endif

        return;
      }
    }
    else
    {
      SM_DBG1(("ossaSATAEvent: NCQ ERROR but recovery in progress!!!\n"));
    }
  }
  else if (event == OSSA_IO_XFER_CMD_FRAME_ISSUED)
  {
    SM_DBG1(("ossaSATAEvent: OSSA_IO_XFER_CMD_FRAME_ISSUED\n"));
  }
  else if (event == OSSA_IO_XFER_PIO_SETUP_ERROR)
  {
    SM_DBG1(("ossaSATAEvent: OSSA_IO_XFER_PIO_SETUP_ERROR\n"));
  }
  else if (event == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED)
  {
    SM_DBG1(("ossaSATAEvent: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED\n"));
  }
  else if (event == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO)
  {
    SM_DBG1(("ossaSATAEvent: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO\n"));
  }
  else if (event == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST)
  {
    SM_DBG1(("ossaSATAEvent: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST\n"));
  }
  else if (event == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE)
  {
    SM_DBG1(("ossaSATAEvent: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE\n"));
  }
  else if (event == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED)
  {
    SM_DBG1(("ossaSATAEvent: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED\n"));
  }
  else if (event == OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH)
  {
    SM_DBG1(("ossaSATAEvent: OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH\n"));
  }
#ifdef REMOVED
  else if (event == OSSA_IO_XFR_ERROR_DIF_MISMATCH || event == OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH ||
           event == OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH || event == OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH )
  {
    SM_DBG1(("ossaSATAEvent: DIF related, event 0x%x\n", event));
    /* process DIF detail information */
    SM_DBG2(("ossaSATAEvent: agIOInfoLen %d\n", agIOInfoLen));
    if (agParam == agNULL)
    {
      SM_DBG2(("ossaSATAEvent: agParam is NULL!!!\n"));
      return;
    }
    if (agIOInfoLen < sizeof(agsaDifDetails_t))
    {
      SM_DBG2(("ossaSATAEvent: wrong agIOInfoLen!!! agIOInfoLen %d sizeof(agsaDifDetails_t) %d\n", agIOInfoLen, (int)sizeof(agsaDifDetails_t)));
      return;
    }
    /* reads agsaDifDetails_t */
    saFrameReadBlock(agRoot, agParam, 0, &agDifDetails, sizeof(agsaDifDetails_t));
    frameOffset = (agDifDetails.ErrBoffsetEDataLen & 0xFFFF);
    frameLen = (agDifDetails.ErrBoffsetEDataLen & 0xFFFF0000) >> 16;

    SM_DBG2(("ossaSATAEvent: UpperLBA 0x%08x LowerLBA 0x%08x\n", agDifDetails.UpperLBA, agDifDetails.LowerLBA));
    SM_DBG2(("ossaSATAEvent: SASAddrHI 0x%08x SASAddrLO 0x%08x\n",
             SM_GET_SAS_ADDRESSHI(agDifDetails.sasAddressHi), SM_GET_SAS_ADDRESSLO(agDifDetails.sasAddressLo)));
    SM_DBG2(("ossaSATAEvent: DIF error mask 0x%x Device ID 0x%x\n",
             (agDifDetails.DIFErrDevID) & 0xFF, (agDifDetails.DIFErrDevID & 0xFFFF0000) >> 16));
    if (frameLen != 0 && frameLen <= 256)
    {
      saFrameReadBlock(agRoot, agParam, sizeof(agsaDifDetails_t), framePayload, frameLen);
      smhexdump("ossaSATAEvent frame", framePayload, frameLen);
    }
  }
#endif
  else if (event == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY)
  {
    smIORequestBody = (smIORequestBody_t *)agIORequest->osData;
    if (smIORequestBody == agNULL)
    {
      SM_DBG1(("ossaSATAEvent: smIORequestBody is NULL!!!\n"));
      return;
    }
    smDeviceHandle = smIORequestBody->smDevHandle;
    if (smDeviceHandle == agNULL)
    {
      SM_DBG1(("ossaSATAEvent: smDeviceHandle is NULL!!!\n"));
      return;
    }
    oneDeviceData  = (smDeviceData_t *)smDeviceHandle->smData;
    if (oneDeviceData == agNULL)
    {
      SM_DBG1(("ossaSATAEvent: oneDeviceData is NULL!!!\n"));
      return;
    }
    SM_DBG1(("ossaSATAEvent: ERROR event %d did=%d\n", event, oneDeviceData->id));


    if (smAllShared->FCA)
    {
      if (oneDeviceData->SMNumOfFCA <= 0) /* does SMP HARD RESET only upto one time */
      {
        SM_DBG1(("ossaSATAEvent: OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY; sending HARD_RESET\n"));
        oneDeviceData->SMNumOfFCA++;
        smPhyControlSend(smRoot,
                         oneDeviceData,
                         SMP_PHY_CONTROL_HARD_RESET,
                         agNULL,
                         tdsmRotateQnumber(smRoot, smDeviceHandle)
                        );
      }
      else
      {
        /* given up after one time of SMP HARD RESET; */
        SM_DBG1(("ossaSATAEvent: OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY; but giving up sending HARD_RESET!!!\n"));
      }
    }
  }
  else if (event == OSSA_IO_XFER_ERROR_NAK_RECEIVED)
  {
    SM_DBG1(("ossaSATAEvent: OSSA_IO_XFER_ERROR_NAK_RECEIVED\n"));
  }
  else if (event == OSSA_IO_XFER_ERROR_DMA_ACTIVATE_TIMEOUT)
  {
    SM_DBG1(("ossaSATAEvent: OSSA_IO_XFER_ERROR_DMA_ACTIVATE_TIMEOUT\n"));
  }
  else
  {
    SM_DBG1(("ossaSATAEvent: other event 0x%x\n", event));
  }

  return;
}

osGLOBAL void
smSMPCompletedCB(
                  agsaRoot_t            *agRoot,
                  agsaIORequest_t       *agIORequest,
                  bit32                 agIOStatus,
                  bit32                 agIOInfoLen,
                  agsaFrameHandle_t     agFrameHandle
                )
{
  smSMPRequestBody_t *smSMPRequestBody = (smSMPRequestBody_t *) agIORequest->osData;

  SM_DBG2(("smSMPCompletedCB: start\n"));

  if (smSMPRequestBody == agNULL)
  {
    SM_DBG1(("smSMPCompletedCB: smSMPRequestBody is NULL!!!\n"));
    return;
  }

  if (smSMPRequestBody->SMPCompletionFunc == agNULL)
  {
    SM_DBG1(("smSMPCompletedCB: smSMPRequestBody->SMPCompletionFunc is NULL!!!\n"));
    return;
  }

  /* calling smSMPCompleted */
  smSMPRequestBody->SMPCompletionFunc(
                                       agRoot,
                                       agIORequest,
                                       agIOStatus,
                                       agIOInfoLen,
                                       agFrameHandle
                                     );
  return;
}

osGLOBAL void
smSMPCompleted(
                agsaRoot_t            *agRoot,
                agsaIORequest_t       *agIORequest,
                bit32                 agIOStatus,
                bit32                 agIOInfoLen,
                agsaFrameHandle_t     agFrameHandle
              )
{
  smRoot_t           *smRoot = gsmRoot;
  smSMPRequestBody_t *smSMPRequestBody = (smSMPRequestBody_t *) agIORequest->osData;
  smDeviceData_t     *oneDeviceData;
  smDeviceHandle_t   *smDeviceHandle;
  smIORequest_t      *CurrentTaskTag;
  bit8                smpHeader[4];
  smSMPFrameHeader_t *smSMPFrameHeader;
  agsaDevHandle_t    *agDevHandle = agNULL;

  SM_DBG2(("smSMPCompleted: start\n"));

  if (smSMPRequestBody == agNULL)
  {
    SM_DBG1(("smSMPCompleted: smSMPRequestBody is NULL, wrong!!!\n"));
    return;
  }

  CurrentTaskTag  = smSMPRequestBody->CurrentTaskTag;
  oneDeviceData = smSMPRequestBody->smDeviceData;
  smDeviceHandle = smSMPRequestBody->smDevHandle;
  if (smDeviceHandle == agNULL)
  {
    SM_DBG2(("smSMPCompleted: smDeviceHandle is NULL, wrong!!!\n"));
    return;
  }

  if (oneDeviceData == agNULL)
  {
    SM_DBG2(("smSMPCompleted: oneDeviceData is NULL, wrong!!!\n"));
    return;
  }
  agDevHandle = oneDeviceData->agExpDevHandle;
  if (agIOStatus == OSSA_IO_SUCCESS)
  {
    saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4);
    smSMPFrameHeader = (smSMPFrameHeader_t *)smpHeader;
    if (smSMPFrameHeader->smpFunction == SMP_PHY_CONTROL)
    {
      SM_DBG3(("smSMPCompleted: phy control\n"));
      if (agIOInfoLen != 4 &&
          smSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) /*zero length is expected */
      {
        SM_DBG1(("smSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x!!!\n", agIOInfoLen, 4));
        tdsmFreeMemory(
                       smRoot,
                       smSMPRequestBody->osMemHandle,
                       sizeof(smSMPRequestBody_t)
                      );
        if (CurrentTaskTag != agNULL)
        {
          tdsmEventCB(smRoot,
                      smDeviceHandle,
                      smIntrEventTypeTaskManagement,
                      smTMFailed,
                      CurrentTaskTag);
        }

        return;
      }
      smPhyControlRespRcvd(smRoot,
                           agRoot,
                           agIORequest,
                           oneDeviceData,
                           smSMPFrameHeader,
                           agFrameHandle,
                           CurrentTaskTag
                           );
    }
    else
    {
      /* unknown SMP function */
      SM_DBG2(("smSMPCompleted: unknown smSMPFrameHeader %d!!!\n", smSMPFrameHeader->smpFunction));
      tdsmFreeMemory(
                      smRoot,
                      smSMPRequestBody->osMemHandle,
                      sizeof(smSMPRequestBody_t)
                     );
      if (CurrentTaskTag != agNULL)
      {
        tdsmEventCB(smRoot,
                    smDeviceHandle,
                    smIntrEventTypeTaskManagement,
                    smTMFailed,
                    CurrentTaskTag);
      }
      return;
    }
  }
  else
  {
    SM_DBG2(("smSMPCompleted: failed agIOStatus %d!!!\n", agIOStatus));
    if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE ||
        agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED ||
        agIOStatus == OSSA_IO_DS_NON_OPERATIONAL
       )
    {
      SM_DBG1(("smSMPCompleted: setting back to operational\n"));
      if (agDevHandle != agNULL)
      {
        saSetDeviceState(agRoot, agNULL, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, SA_DS_OPERATIONAL);
      }
      else
      {
        SM_DBG1(("smSMPCompleted: agDevHandle is NULL\n"));
      }
    }
    tdsmFreeMemory(
                    smRoot,
                    smSMPRequestBody->osMemHandle,
                    sizeof(smSMPRequestBody_t)
                  );
    if (CurrentTaskTag != agNULL)
    {
      tdsmEventCB(smRoot,
                  smDeviceHandle,
                  smIntrEventTypeTaskManagement,
                  smTMFailed,
                  CurrentTaskTag);
    }
    return;
  }

  tdsmFreeMemory(
                  smRoot,
                  smSMPRequestBody->osMemHandle,
                  sizeof(smSMPRequestBody_t)
                );
  return;
}

osGLOBAL void
smPhyControlRespRcvd(
                      smRoot_t              *smRoot,
                      agsaRoot_t            *agRoot,
                      agsaIORequest_t       *agIORequest,
                      smDeviceData_t        *oneDeviceData, /* sata disk */
                      smSMPFrameHeader_t    *frameHeader,
                      agsaFrameHandle_t     frameHandle,
                      smIORequest_t         *CurrentTaskTag
                     )
{
  smDeviceData_t        *TargetDeviceData = agNULL;
  agsaDevHandle_t       *agDevHandle = agNULL;
  smSMPRequestBody_t    *smSMPRequestBody;
  smDeviceHandle_t      *smDeviceHandle;

  SM_DBG2(("smPhyControlRespRcvd: start\n"));

  if (CurrentTaskTag == agNULL )
  {
    SM_DBG1(("smPhyControlRespRcvd: CurrentTaskTag is NULL; allowed\n"));
    return;
  }

  smSMPRequestBody = (smSMPRequestBody_t *)CurrentTaskTag->smData;
  if (smSMPRequestBody == agNULL)
  {
    SM_DBG1(("smPhyControlRespRcvd: smSMPRequestBody is NULL!!!\n"));
    return;
  }

  smDeviceHandle = smSMPRequestBody->smDevHandle;
  if (smDeviceHandle == agNULL)
  {
    SM_DBG2(("smPhyControlRespRcvd: smDeviceHandle is NULL!!!\n"));
    return;
  }

  TargetDeviceData = smSMPRequestBody->smDeviceData;
  if (oneDeviceData != TargetDeviceData)
  {
    SM_DBG1(("smPhyControlRespRcvd: oneDeviceData != TargetDeviceData!!!\n"));
    return;
  }

  agDevHandle = TargetDeviceData->agDevHandle;


  if (frameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED)
  {
    SM_DBG2(("smPhyControlRespRcvd: SMP success\n"));
    SM_DBG1(("smPhyControlRespRcvd: callback to TD layer with success\n"));
    TargetDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
    saSetDeviceState(agRoot, agNULL, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, SA_DS_OPERATIONAL);

    tdsmEventCB(smRoot,
                smDeviceHandle,
                smIntrEventTypeTaskManagement,
                smTMOK,
                CurrentTaskTag);
  }
  else
  {
    SM_DBG1(("smPhyControlRespRcvd: SMP failure; result %d!!!\n", frameHeader->smpFunctionResult));
    tdsmEventCB(smRoot,
                smDeviceHandle,
                smIntrEventTypeTaskManagement,
                smTMFailed,
                CurrentTaskTag);
  }
  return;
}

osGLOBAL void
smsatCheckPowerModeCB(
                      agsaRoot_t        *agRoot,
                      agsaIORequest_t   *agIORequest,
                      bit32             agIOStatus,
                      agsaFisHeader_t   *agFirstDword,
                      bit32             agIOInfoLen,
                      agsaFrameHandle_t agFrameHandle,
                      void              *ioContext
                     )
{
  /* callback for satDeResetDevice */
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL;
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatInternalIo_t        *satIntIo;
//  satDeviceData_t         *satDevData;
  smDeviceData_t           *oneDeviceData;
#ifdef  TD_DEBUG_ENABLE
  bit32                     ataStatus = 0;
  bit32                     ataError;
  agsaFisPioSetupHeader_t  *satPIOSetupHeader = agNULL;
#endif
  bit32                     AbortTM = agFALSE;
  smDeviceHandle_t         *smDeviceHandle;

  SM_DBG1(("smsatCheckPowerModeCB: start\n"));
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  smDeviceHandle         = oneDeviceData->smDevHandle;
  if (satIntIo == agNULL)
  {
    SM_DBG6(("smsatCheckPowerModeCB: External, OS generated\n"));
    satOrgIOContext      = satIOContext;
  }
  else
  {
    SM_DBG6(("smsatCheckPowerModeCB: Internal, TD generated\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG6(("smsatCheckPowerModeCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG6(("smsatCheckPowerModeCB: satOrgIOContext is NOT NULL\n"));
    }
  }
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;
  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatCheckPowerModeCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMFailed,
                 oneDeviceData->satTmTaskTag);

    oneDeviceData->satTmTaskTag = agNULL;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
      )
  {
    SM_DBG1(("smsatCheckPowerModeCB: OSSA_IO_OPEN_CNX_ERROR!!!\n"));
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMFailed,
                 oneDeviceData->satTmTaskTag);
    oneDeviceData->satTmTaskTag = agNULL;

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
 if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisPioSetup_t is expected */
#ifdef  TD_DEBUG_ENABLE
    satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
    ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
    ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
#endif
    SM_DBG1(("smsatCheckPowerModeCB: ataStatus 0x%x ataError 0x%x!!!\n", ataStatus, ataError));
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMFailed,
                 oneDeviceData->satTmTaskTag);
    oneDeviceData->satTmTaskTag = agNULL;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  /* success */
  SM_DBG1(("smsatCheckPowerModeCB: success!!!\n"));
  SM_DBG1(("smsatCheckPowerModeCB: TMF %d!!!\n", satOrgIOContext->TMF));

  if (satOrgIOContext->TMF == AG_ABORT_TASK)
  {
    AbortTM = agTRUE;
  }
  if (AbortTM == agTRUE)
  {
    SM_DBG1(("smsatCheckPowerModeCB: calling local satAbort!!!\n"));
    smsatAbort(smRoot, agRoot, satOrgIOContext->satToBeAbortedIOContext);
  }
  oneDeviceData->satTmTaskTag = agNULL;
  oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;

  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

  SM_DBG1(("smsatCheckPowerModeCB: satPendingIO %d satNCQMaxIO %d!!!\n", oneDeviceData->satPendingIO, oneDeviceData->satNCQMaxIO ));
  SM_DBG1(("smsatCheckPowerModeCB: satPendingNCQIO %d satPendingNONNCQIO %d!!!\n", oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));
  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);

  /* TM completed */
  tdsmEventCB( smRoot,
               smDeviceHandle,
               smIntrEventTypeTaskManagement,
               smTMOK,
               oneDeviceData->satTmTaskTag);
  SM_DBG5(("smsatCheckPowerModeCB: device %p pending IO %d\n", oneDeviceData, oneDeviceData->satPendingIO));
  SM_DBG2(("smsatCheckPowerModeCB: end\n"));
  return;
}

osGLOBAL void 
smsatCheckPowerModePassCB(
                      agsaRoot_t        *agRoot,
                      agsaIORequest_t   *agIORequest,
                      bit32             agIOStatus,
                      agsaFisHeader_t   *agFirstDword,
                      bit32             agIOInfoLen,
                      agsaFrameHandle_t agFrameHandle,
                      void              *ioContext
                     )

{
  
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL; 
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatInternalIo_t        *satIntIo;
  smIORequest_t             *smOrgIORequest;
  smIORequestBody_t         *smOrgIORequestBody;
//  satDeviceData_t         *satDevData;
  smDeviceData_t           *oneDeviceData;
#ifdef  TD_DEBUG_ENABLE
  bit32                     ataStatus = 0;
  bit32                     ataError;
  agsaFisPioSetupHeader_t  *satPIOSetupHeader = agNULL;
#endif
 
  smScsiRspSense_t			*pSense;
  bit8						bSenseKey = 0;
  bit16 					bSenseCodeInfo = 0;

  SM_DBG1(("smsatCheckPowerModePassCB: start\n"));
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;  
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG6(("smsatCheckPowerModePassCB: External, OS generated\n"));
    satOrgIOContext      = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satOrgIOContext->pSense;
  }
  else
  {
    SM_DBG6(("smsatCheckPowerModePassCB: Internal, TD generated\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    pSense          = satOrgIOContext->pSense;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG6(("smsatCheckPowerModePassCB: satOrgIOContext is NULL, wrong\n"));
      return;      
    }
    else
    {
      SM_DBG6(("smsatCheckPowerModePassCB: satOrgIOContext is NOT NULL\n"));
    }
  }  
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;
  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatCheckPowerModePassCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
  
    tdsmIOCompletedCB(
                       smRoot, 
                       smOrgIORequest,
                       smIOFailed, 
                       smDetailOtherError,
                       agNULL, 
                       satOrgIOContext->interruptContext
                      );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;

  }
  
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisPioSetup_t is expected */
#ifdef  TD_DEBUG_ENABLE
    satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
    ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
    ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
#endif
    SM_DBG1(("smsatCheckPowerModePassCB: ataStatus 0x%x ataError 0x%x!!!\n", ataStatus, ataError));
   

    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );
      
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
			      oneDeviceData,
			      satIntIo); 
      return;
    }
    smsatTranslateATAErrorsToSCSIErrors(
                                        agFirstDword->D2H.status,
                                        agFirstDword->D2H.error,
                                        &bSenseKey,
                                        &bSenseCodeInfo
                                        );
    smsatSetSensePayload(pSense, bSenseKey, 0, bSenseCodeInfo, satOrgIOContext);
    tdsmIOCompletedCB(smRoot,
                      smOrgIORequest,
                      smIOSuccess,
                      SCSI_STAT_CHECK_CONDITION, 
                      satOrgIOContext->pSmSenseData,
                      satOrgIOContext->interruptContext );
	
	
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
	
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;

  }
  /* success */
  SM_DBG1(("smsatCheckPowerModePassCB: success!!!\n"));
  
  tdsmIOCompletedCB( smRoot,
                     smOrgIORequest,
                     smIOSuccess,
                     SCSI_STAT_GOOD,
                     agNULL,
                     satOrgIOContext->interruptContext);
			  

  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
 
  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);
                            

  return;
}

osGLOBAL void 
smsatIDDataPassCB(
                  agsaRoot_t        *agRoot,
                  agsaIORequest_t   *agIORequest,
                  bit32             agIOStatus,
                  agsaFisHeader_t   *agFirstDword,
                  bit32             agIOInfoLen,
                  agsaFrameHandle_t agFrameHandle,
                  void              *ioContext
                 )
{
  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL; 
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  smSatInternalIo_t        *satIntIo;
  smIORequest_t             *smOrgIORequest;
  smIORequestBody_t         *smOrgIORequestBody;
//  satDeviceData_t         *satDevData;
  smDeviceData_t           *oneDeviceData;
#ifdef  TD_DEBUG_ENABLE
  bit32                     ataStatus = 0;
  bit32                     ataError;
  agsaFisPioSetupHeader_t  *satPIOSetupHeader = agNULL;
#endif
 
  smScsiRspSense_t			*pSense;
  bit8						bSenseKey = 0;
  bit16 					bSenseCodeInfo = 0;

  SM_DBG3(("smsatIDDataPassCB: start\n"));
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;  
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

  if (satIntIo == agNULL)
  {
    SM_DBG6(("smsatIDDataPassCB: External, OS generated\n"));
    satOrgIOContext      = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satOrgIOContext->pSense;
  }
  else
  {
    SM_DBG6(("smsatIDDataPassCB: Internal, TD generated\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    pSense          = satOrgIOContext->pSense;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG6(("smsatIDDataPassCB: satOrgIOContext is NULL, wrong\n"));
      return;      
    }
    else
    {
      SM_DBG6(("smsatIDDataPassCB: satOrgIOContext is NOT NULL\n"));
    }
  }  
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;
  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatIDDataPassCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
  
    tdsmIOCompletedCB(
                       smRoot, 
                       smOrgIORequest,
                       smIOFailed, 
                       smDetailOtherError,
                       agNULL, 
                       satOrgIOContext->interruptContext
                      );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;

  }
  
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisPioSetup_t is expected */
#ifdef  TD_DEBUG_ENABLE
    satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
    ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
    ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
#endif
    SM_DBG1(("smsatIDDataPassCB: ataStatus 0x%x ataError 0x%x!!!\n", ataStatus, ataError));
   

    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                        );
      
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
			      oneDeviceData,
			      satIntIo); 
      return;
    }
    smsatTranslateATAErrorsToSCSIErrors(
                                        agFirstDword->D2H.status,
                                        agFirstDword->D2H.error,
                                        &bSenseKey,
                                        &bSenseCodeInfo
                                        );
    smsatSetSensePayload(pSense, bSenseKey, 0, bSenseCodeInfo, satOrgIOContext);
    tdsmIOCompletedCB(smRoot,
                      smOrgIORequest,
                      smIOSuccess,
                      SCSI_STAT_CHECK_CONDITION, 
                      satOrgIOContext->pSmSenseData,
                      satOrgIOContext->interruptContext );
	
	
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
	
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;

  }
  /* success */
  SM_DBG3(("smsatIDDataPassCB: success!!!\n"));
  
  SM_DBG3(("smsatIDDataPassCB: extend 0x%x ck_cond 0x%x sectorCnt07 0x%x\n", satOrgIOContext->extend, 
  satIOContext->ck_cond, satOrgIOContext->sectorCnt07));
  SM_DBG3(("smsatIDDataPassCB: LBAHigh07 0x%x LBAMid07 0x%x LBALow07 0x%x\n", satOrgIOContext->LBAHigh07, 
  satOrgIOContext->LBAMid07, satOrgIOContext->LBALow07));
  
  if (satIOContext->ck_cond) 
  {  
    smsatSetSensePayload( pSense,
                          SCSI_SNSKEY_RECOVERED_ERROR,
                          satOrgIOContext->sectorCnt07,
                          SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE,
                          satIOContext);

    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOSuccess,
                       SCSI_STAT_CHECK_CONDITION,
                       satIOContext->pSmSenseData,
                       satOrgIOContext->interruptContext );
  }
  else
  {  			
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOSuccess,
                       SCSI_STAT_GOOD,
                       agNULL,
                       satOrgIOContext->interruptContext);
  }			  

  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
 
  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);
                            

  return;
}

osGLOBAL void
smsatResetDeviceCB(
                    agsaRoot_t        *agRoot,
                    agsaIORequest_t   *agIORequest,
                    bit32             agIOStatus,
                    agsaFisHeader_t   *agFirstDword,
                    bit32             agIOInfoLen,
                    agsaFrameHandle_t agFrameHandle,
                    void              *ioContext
                  )
{
  /* callback for satResetDevice */
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                  *smRoot = agNULL;
  smIntRoot_t               *smIntRoot = agNULL;
  smIntContext_t            *smAllShared = agNULL;
  smIORequestBody_t         *smIORequestBody;
  smIORequestBody_t         *smOrgIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatIOContext_t          *satNewIOContext;
  smSatInternalIo_t         *satIntIo;
  smSatInternalIo_t         *satNewIntIo = agNULL;
//  satDeviceData_t         *satDevData;
  smDeviceData_t            *oneDeviceData;
  smIORequest_t             *smOrgIORequest;
#ifdef  TD_DEBUG_ENABLE
  bit32                      ataStatus = 0;
  bit32                      ataError;
  agsaFisPioSetupHeader_t   *satPIOSetupHeader = agNULL;
#endif
  bit32                      status;
  smDeviceHandle_t          *smDeviceHandle;

  SM_DBG1(("smsatResetDeviceCB: start\n"));
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  smDeviceHandle         = oneDeviceData->smDevHandle;

  if (satIntIo == agNULL)
  {
    SM_DBG6(("smsatResetDeviceCB: External, OS generated\n"));
    satOrgIOContext      = satIOContext;
    smOrgIORequest       = smIORequestBody->smIORequest;
  }
  else
  {
    SM_DBG6(("smsatResetDeviceCB: Internal, TD generated\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG6(("smsatResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG6(("smsatResetDeviceCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
  }
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;
  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatResetDeviceCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMFailed,
                 oneDeviceData->satTmTaskTag);
    oneDeviceData->satTmTaskTag = agNULL;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
      )
  {
    SM_DBG1(("smsatResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR!!!\n"));
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMFailed,
                 oneDeviceData->satTmTaskTag);

    oneDeviceData->satTmTaskTag = agNULL;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisPioSetup_t is expected */
#ifdef  TD_DEBUG_ENABLE
    satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
    ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
    ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
#endif
    SM_DBG1(("smsatResetDeviceCB: ataStatus 0x%x ataError 0x%x!!!\n", ataStatus, ataError));
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMFailed,
                 oneDeviceData->satTmTaskTag);

    oneDeviceData->satTmTaskTag = agNULL;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  /* success */
  satNewIntIo = smsatAllocIntIoResource( smRoot,
                                         smOrgIORequest,
                                         oneDeviceData,
                                         0,
                                         satNewIntIo);
  if (satNewIntIo == agNULL)
  {
    oneDeviceData->satTmTaskTag = agNULL;

    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    /* memory allocation failure */
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMFailed,
                 oneDeviceData->satTmTaskTag);
    SM_DBG1(("smsatResetDeviceCB: momory allocation fails!!!\n"));
    return;
  } /* end of memory allocation failure */
    /*
     * Need to initialize all the fields within satIOContext
     */
    satNewIOContext = smsatPrepareNewIO(
                                         satNewIntIo,
                                         smOrgIORequest,
                                         oneDeviceData,
                                         agNULL,
                                         satOrgIOContext
                                        );
    /* send AGSA_SATA_PROTOCOL_SRST_DEASSERT */
    status = smsatDeResetDevice(smRoot,
                                smOrgIORequest,
                                satOrgIOContext->psmDeviceHandle,
                                agNULL,
                                satNewIOContext
                               );
    if (status != SM_RC_SUCCESS)
    {
      /* TM completed */
      tdsmEventCB( smRoot,
                   smDeviceHandle,
                   smIntrEventTypeTaskManagement,
                   smTMFailed,
                   oneDeviceData->satTmTaskTag);
      /* sending AGSA_SATA_PROTOCOL_SRST_DEASSERT fails */
      oneDeviceData->satTmTaskTag = agNULL;

      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satNewIntIo);
      return;
    }
//  oneDeviceData->satTmTaskTag = agNULL;

  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);
  SM_DBG5(("smsatResetDeviceCB: device %p pending IO %d\n", oneDeviceData, oneDeviceData->satPendingIO));
  SM_DBG6(("smsatResetDeviceCB: end\n"));
  return;
}

osGLOBAL void
smsatDeResetDeviceCB(
                      agsaRoot_t        *agRoot,
                      agsaIORequest_t   *agIORequest,
                      bit32             agIOStatus,
                      agsaFisHeader_t   *agFirstDword,
                      bit32             agIOInfoLen,
                      agsaFrameHandle_t agFrameHandle,
                      void              *ioContext
                   )
{
  /* callback for satDeResetDevice */
//  tdsaRootOsData_t        *osData = (tdsaRootOsData_t *)agRoot->osData;
//  tiRoot_t                *tiRoot = (tiRoot_t *)osData->tiRoot;
//  tdsaRoot_t              *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
//  tdsaContext_t           *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
  smRoot_t                  *smRoot = agNULL;
  smIntRoot_t               *smIntRoot = agNULL;
  smIntContext_t            *smAllShared = agNULL;
  smIORequestBody_t         *smIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatInternalIo_t         *satIntIo;
//  satDeviceData_t           *satDevData;
  smDeviceData_t            *oneDeviceData;
#ifdef  TD_DEBUG_ENABLE
  bit32                      ataStatus = 0;
  bit32                      ataError;
  agsaFisPioSetupHeader_t   *satPIOSetupHeader = agNULL;
#endif
  bit32                      AbortTM = agFALSE;
  smDeviceHandle_t          *smDeviceHandle;

  SM_DBG1(("smsatDeResetDeviceCB: start!!!\n"));
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  smDeviceHandle         = oneDeviceData->smDevHandle;
  if (satIntIo == agNULL)
  {
    SM_DBG6(("smsatDeResetDeviceCB: External, OS generated\n"));
    satOrgIOContext      = satIOContext;
  }
  else
  {
    SM_DBG6(("smsatDeResetDeviceCB: Internal, TD generated\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG6(("smsatDeResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
      return;
    }
    else
    {
      SM_DBG6(("smsatDeResetDeviceCB: satOrgIOContext is NOT NULL\n"));
    }
  }
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;
  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatDeResetDeviceCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMFailed,
                 oneDeviceData->satTmTaskTag);
    oneDeviceData->satTmTaskTag = agNULL;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
      agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
      )
  {
    SM_DBG1(("smsatDeResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR!!!\n"));

    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMFailed,
                 oneDeviceData->satTmTaskTag);
    oneDeviceData->satTmTaskTag = agNULL;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }
 if (agIOStatus != OSSA_IO_SUCCESS)
  {
    /* only agsaFisPioSetup_t is expected */
#ifdef  TD_DEBUG_ENABLE
    satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
    ataStatus     = satPIOSetupHeader->status;   /* ATA Status register */
    ataError      = satPIOSetupHeader->error;    /* ATA Eror register   */
#endif
    SM_DBG1(("smsatDeResetDeviceCB: ataStatus 0x%x ataError 0x%x!!!\n", ataStatus, ataError));
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMFailed,
                 oneDeviceData->satTmTaskTag);
    oneDeviceData->satTmTaskTag = agNULL;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

  /* success */
  SM_DBG1(("smsatDeResetDeviceCB: success !!!\n"));
  SM_DBG1(("smsatDeResetDeviceCB: TMF %d!!!\n", satOrgIOContext->TMF));

  if (satOrgIOContext->TMF == AG_ABORT_TASK)
  {
    AbortTM = agTRUE;
  }
  if (AbortTM == agTRUE)
  {
    SM_DBG1(("smsatDeResetDeviceCB: calling satAbort!!!\n"));
    smsatAbort(smRoot, agRoot, satOrgIOContext->satToBeAbortedIOContext);
  }
  oneDeviceData->satTmTaskTag = agNULL;
  oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

  SM_DBG1(("smsatDeResetDeviceCB: satPendingIO %d satNCQMaxIO %d!!!\n", oneDeviceData->satPendingIO, oneDeviceData->satNCQMaxIO ));
  SM_DBG1(("smsatDeResetDeviceCB: satPendingNCQIO %d satPendingNONNCQIO %d!!!\n", oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));
  smsatFreeIntIoResource( smRoot, oneDeviceData, satIntIo );

  /* TM completed */
  tdsmEventCB( smRoot,
               smDeviceHandle,
               smIntrEventTypeTaskManagement,
               smTMOK,
               oneDeviceData->satTmTaskTag);
  SM_DBG5(("smsatDeResetDeviceCB: device %p pending IO %d\n", oneDeviceData, oneDeviceData->satPendingIO));
  SM_DBG6(("smsatDeResetDeviceCB: end\n"));
  return;
}

osGLOBAL void
smaSATAAbortCB(
                agsaRoot_t        *agRoot,
                agsaIORequest_t   *agIORequest,
                bit32             flag,
                bit32             status
        )
{
  smRoot_t                  *smRoot = gsmRoot;
  smIORequestBody_t         *smIORequestBody = agNULL;
  smSatIOContext_t          *satIOContext;
  smDeviceHandle_t          *smDeviceHandle;
  smDeviceData_t            *oneDeviceData = agNULL;

  SM_DBG1(("smaSATAAbortCB: start\n"));

  smIORequestBody = (smIORequestBody_t *)agIORequest->osData;
  if (smIORequestBody == agNULL)
  {
    SM_DBG1(("smaSATAAbortCB: smIORequestBody is NULL!!! \n"));
    return;
  }

  satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
  if (satIOContext == agNULL)
  {
    SM_DBG1(("smaSATAAbortCB: satIOContext is NULL!!! \n"));
    if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL)
    {
      tdsmFreeMemory(smRoot,
                     smIORequestBody->IOType.InitiatorTMIO.osMemHandle,
                     sizeof(smIORequestBody_t)
                     );
    }
    return;
  }

  smDeviceHandle = smIORequestBody->smDevHandle;
  if (smDeviceHandle == agNULL)
  {
    SM_DBG1(("smaSATAAbortCB: smDeviceHandle is NULL!!!\n"));
    if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL)
    {
      tdsmFreeMemory(smRoot,
                     smIORequestBody->IOType.InitiatorTMIO.osMemHandle,
                     sizeof(smIORequestBody_t)
                     );
    }
    return;
  }

  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
  if (oneDeviceData == agNULL)
  {
    SM_DBG1(("smaSATAAbortCB: oneDeviceData is NULL!!!\n"));
    if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL)
    {
      tdsmFreeMemory(smRoot,
                     smIORequestBody->IOType.InitiatorTMIO.osMemHandle,
                     sizeof(smIORequestBody_t)
                     );
    }

    return;
  }

  if (flag == 2)
  {
    /* abort per port */
    SM_DBG1(("smaSATAAbortCB: abort per port, not yet!!!\n"));
  }
  else if (flag == 1)
  {
     SM_DBG1(("smaSATAAbortCB: abort all!!!\n"));
    if (oneDeviceData->OSAbortAll == agTRUE)
    {
      oneDeviceData->OSAbortAll = agFALSE;
#if 0
      ostiInitiatorEvent( tiRoot,
                            agNULL,
                            tiDeviceHandle,
                            tiIntrEventTypeLocalAbort,
                            tiAbortOK,
                            agNULL);
#endif
#if 1
      tdsmEventCB( smRoot,
                   smDeviceHandle,
                   smIntrEventTypeLocalAbort,
                   smTMOK,
                   agNULL);
#endif

    }
    if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL)
    {
      tdsmFreeMemory(smRoot,
                     smIORequestBody->IOType.InitiatorTMIO.osMemHandle,
                     sizeof(smIORequestBody_t)
                     );
    }
  }
  else if (flag == 0)
  {
    SM_DBG1(("smaSATAAbortCB: abort one\n"));
    if (status == OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smaSATAAbortCB: OSSA_IO_SUCCESS\n"));
    }
    else if (status == OSSA_IO_NOT_VALID)
    {
      SM_DBG1(("smaSATAAbortCB: OSSA_IO_NOT_VALID\n"));
    }
    else if (status == OSSA_IO_NO_DEVICE)
    {
      SM_DBG1(("smaSATAAbortCB: OSSA_IO_NO_DEVICE\n"));
    }
    else if (status == OSSA_IO_ABORT_IN_PROGRESS)
    {
      SM_DBG1(("smaSATAAbortCB: OSSA_IO_ABORT_IN_PROGRESS\n"));
    }
#ifdef REMOVED
    else if (status == OSSA_IO_ABORT_DELAYED)
    {
      SM_DBG1(("smaSATAAbortCB: OSSA_IO_ABORT_DELAYED\n"));
    }
#endif
    else
    {
      SM_DBG1(("smaSATAAbortCB: unspecified status 0x%x\n", status ));
    }
    if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL)
    {
      tdsmFreeMemory(smRoot,
                     smIORequestBody->IOType.InitiatorTMIO.osMemHandle,
                     sizeof(smIORequestBody_t)
                     );
    }
  }
  else
  {
    SM_DBG1(("smaSATAAbortCB: wrong flag %d\n", flag));
  }

  return;
}

osGLOBAL void
smLocalPhyControlCB(
                     agsaRoot_t     *agRoot,
                     agsaContext_t  *agContext,
                     bit32          phyId,
                     bit32          phyOperation,
                     bit32          status,
                     void           *parm
                    )
{
  smRoot_t                  *smRoot = gsmRoot;
  smIORequestBody_t         *smIORequestBody = agNULL;
  smDeviceHandle_t          *smDeviceHandle;
  smDeviceData_t            *oneDeviceData = agNULL;
  smIORequest_t             *currentTaskTag;
  agsaDevHandle_t           *agDevHandle = agNULL;

  SM_DBG1(("smLocalPhyControlCB: start phyId 0x%x phyOperation 0x%x status 0x%x\n",phyId,phyOperation,status));

  if (agContext == agNULL)
  {
    SM_DBG1(("smLocalPhyControlCB: agContext is NULL!!!\n"));
    return;
  }
  currentTaskTag = (smIORequest_t *)agContext->osData;
  if (currentTaskTag == agNULL)
  {
    SM_DBG1(("smLocalPhyControlCB: currentTaskTag is NULL!!!\n"));
    return;
  }
  smIORequestBody = (smIORequestBody_t *)currentTaskTag->smData;
  if (smIORequestBody == agNULL)
  {
    SM_DBG1(("smLocalPhyControlCB: smIORequestBody is NULL!!!\n"));
    return;
  }
  smDeviceHandle = smIORequestBody->smDevHandle;
  if (smDeviceHandle == agNULL)
  {
    SM_DBG1(("smLocalPhyControlCB: smDeviceHandle is NULL!!!\n"));
    return;
  }
  oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
  if (oneDeviceData == agNULL)
  {
    SM_DBG1(("smLocalPhyControlCB: oneDeviceData is NULL!!!\n"));
    return;
  }
  switch (phyOperation)
  {
  case AGSA_PHY_LINK_RESET: /* fall through */
  case AGSA_PHY_HARD_RESET:
    if (status == OSSA_SUCCESS)
    {
      SM_DBG2(("smLocalPhyControlCB: callback to TD layer with success\n"));
      agDevHandle = oneDeviceData->agDevHandle;
      SM_DBG2(("smLocalPhyControlCB: satPendingIO %d satNCQMaxIO %d\n", oneDeviceData->satPendingIO, oneDeviceData->satNCQMaxIO ));
      SM_DBG1(("smLocalPhyControlCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));
      oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
#ifdef REMOVED
      saSetDeviceState(agRoot,
                       agNULL,
                       tdsmRotateQnumber(smRoot, smDeviceHandle),
                       agDevHandle,
                       SA_DS_OPERATIONAL
                       );
      /* TM completed */
      tdsmEventCB( smRoot,
                   smDeviceHandle,
                   smIntrEventTypeTaskManagement,
                   smTMOK,
                   currentTaskTag);
#endif
    }
    else
    {
      SM_DBG1(("smLocalPhyControlCB: callback to TD layer with failure!!!\n"));
      /* TM completed */
      tdsmEventCB( smRoot,
                   smDeviceHandle,
                   smIntrEventTypeTaskManagement,
                   smTMFailed,
                   currentTaskTag);
    }
    break;
  default:
    SM_DBG1(("ossaLocalPhyControlCB: error default case. phyOperation is %d!!!\n", phyOperation));
    /* TM completed */
    tdsmEventCB( smRoot,
                 smDeviceHandle,
                 smIntrEventTypeTaskManagement,
                 smTMFailed,
                 currentTaskTag);
    break;
  }
  return;
}

osGLOBAL void
smsatSetFeaturesAACB(
    agsaRoot_t        *agRoot,
    agsaIORequest_t   *agIORequest,
    bit32             agIOStatus,
    agsaFisHeader_t   *agFirstDword,
    bit32             agIOInfoLen,
    void              *agParam,
    void              *ioContext
    )
{
    smRoot_t                  *smRoot = agNULL;
    smIntRoot_t               *smIntRoot = agNULL;
    smIntContext_t            *smAllShared = agNULL;
    smIORequestBody_t         *smIORequestBody;
    smIORequestBody_t         *smOrgIORequestBody = agNULL;
    smSatIOContext_t          *satIOContext;
    smSatIOContext_t          *satOrgIOContext;
    smSatInternalIo_t         *satIntIo;
    smDeviceData_t            *oneDeviceData;
    smIORequest_t             *smOrgIORequest;
    smDeviceHandle_t          *smDeviceHandle;
    smIORequest_t             *smIORequest;
    bit32                     ataStatus = 0;
    bit32                     ataError = 0;
    agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;

    SM_DBG2(("smsatSetFeaturesAACB: start\n"));
    smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
    satIOContext           = (smSatIOContext_t *) ioContext;
    if (satIOContext == agNULL)
    {
      SM_DBG1(("smsatSetFeaturesAACB: satIOContext is NULL\n"));
      return;
    }
    satIntIo               = satIOContext->satIntIoContext;
    oneDeviceData          = satIOContext->pSatDevData;
    smDeviceHandle         = satIOContext->psmDeviceHandle;
    smRoot                 = oneDeviceData->smRoot;
    smIntRoot              = (smIntRoot_t *)smRoot->smData;
    smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
    if (satIntIo == agNULL)
    {
      SM_DBG5(("smsatSetFeaturesAACB: External smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext = satIOContext;
      smOrgIORequest  = smIORequestBody->smIORequest;
      smIORequest     = smOrgIORequest;
    }
    else
    {
      SM_DBG5(("smsatSetFeaturesAACB: Internal smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext        = satIOContext->satOrgIOContext;
      smOrgIORequestBody  = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
      smOrgIORequest      = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    }
    smIORequest  = smOrgIORequestBody->smIORequest;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smIORequestBody->ioCompleted = agTRUE;
    smIORequestBody->ioStarted   = agFALSE;
    if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatSetFeaturesAACB: fail, case 1 agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    }
    if (agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatSetFeaturesAACB: fail, case 2 status %d!!!\n", agIOStatus));
    }
    if (agIOInfoLen != 0 && agIOStatus == OSSA_IO_SUCCESS)
    {
      statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
      ataStatus   = statDevToHostFisHeader->status;   /* ATA Status register */
      ataError    = statDevToHostFisHeader->error;    /* ATA Eror register   */
      if ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
      {
        SM_DBG1(("smsatSetFeaturesAACB: fail, case 3 ataStatus %d ataError %d!!!\n", ataStatus, ataError));
      }
      if (ataError != 0)
      {
        SM_DBG1(("smsatSetFeaturesAACB: fail, case 4 ataStatus %d ataError %d!!!\n", ataStatus, ataError));
      }
    }
    /* interal structure free */
    smsatFreeIntIoResource(smRoot,oneDeviceData, satIntIo);
    if (smIORequest->tdData == smIORequest->smData)
    {
      SM_DBG1(("smsatSetFeaturesAACB: the same tdData and smData error!\n"));
    }
    /*Complete this identify device IO */
    tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
    SM_DBG2(("smsatSetFeaturesAACB: end\n"));
}

/*****************************************************************************
*! \brief  smsatSetFeaturesDMACB
*
*   This routine is a callback function called from smllSATACompleted().
*   This CB routine deals with normal non-chained data I/O SATA request.
*
*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
*  \param   agIOStatus:  Status of completed I/O.
*  \param   agFirstDword:Pointer to the four bytes of FIS.
*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
*                        length.
*  \param   agParam:     Additional info based on status.
*  \param   ioContext:   Pointer to smSatIOContext_t.
*
*  \return: none
*
*****************************************************************************/
osGLOBAL void
smsatSetFeaturesDMACB(
    agsaRoot_t        *agRoot,
    agsaIORequest_t   *agIORequest,
    bit32             agIOStatus,
    agsaFisHeader_t   *agFirstDword,
    bit32             agIOInfoLen,
    void              *agParam,
    void              *ioContext
    )
{
    smRoot_t                  *smRoot = agNULL;
    smIntRoot_t               *smIntRoot = agNULL;
    smIntContext_t            *smAllShared = agNULL;
    smIORequestBody_t         *smIORequestBody;
    smIORequestBody_t         *smOrgIORequestBody = agNULL;
    smSatIOContext_t          *satIOContext;
    smSatIOContext_t          *satOrgIOContext;
    smSatIOContext_t          *satNewIOContext;
    smSatInternalIo_t         *satIntIo;
    smSatInternalIo_t         *satNewIntIo = agNULL;
    smDeviceData_t            *oneDeviceData;
    smIniScsiCmnd_t           *scsiCmnd;
    smIORequest_t             *smOrgIORequest;
    smDeviceHandle_t          *smDeviceHandle;
    bit32                      status = SM_RC_FAILURE;
    smIORequest_t             *smIORequest;

    SM_DBG2(("smsatSetFeaturesDMACB: start\n"));
    smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
    satIOContext           = (smSatIOContext_t *) ioContext;
    if (satIOContext == agNULL)
    {
      SM_DBG1(("smsatSetFeaturesDMACB: satIOContext is NULL\n"));
      return;
    }
    satIntIo               = satIOContext->satIntIoContext;
    oneDeviceData          = satIOContext->pSatDevData;
    smDeviceHandle         = satIOContext->psmDeviceHandle;
    smRoot                 = oneDeviceData->smRoot;
    smIntRoot              = (smIntRoot_t *)smRoot->smData;
    smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
    if (satIntIo == agNULL)
    {
      SM_DBG2(("smsatSetFeaturesDMACB: External smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext = satIOContext;
      smOrgIORequest  = smIORequestBody->smIORequest;
      scsiCmnd        = satIOContext->pScsiCmnd;
    }
    else
    {
      SM_DBG2(("smsatSetFeaturesDMACB: Internal smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext        = satIOContext->satOrgIOContext;
      smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
      smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
      scsiCmnd      = satOrgIOContext->pScsiCmnd;
    }
    smIORequest  = smOrgIORequestBody->smIORequest;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smIORequestBody->ioCompleted = agTRUE;
    smIORequestBody->ioStarted   = agFALSE;

    oneDeviceData->satDMAEnabled = agTRUE;
    /* interal structure free */
    smsatFreeIntIoResource(smRoot,
                           oneDeviceData,
                           satIntIo);

    if (smIORequest->tdData == smIORequest->smData)
    {
      SM_DBG1(("smsatSetFeaturesDMACB: the same tdData and smData error!\n"));
    }
    SM_DBG2(("smsatSetFeaturesDMACB: agIOStatus 0x%x\n", agIOStatus));
    /* check the agIOStatus */
    if (agIOStatus == OSSA_IO_ABORTED ||
        agIOStatus == OSSA_IO_NO_DEVICE ||
        agIOStatus == OSSA_IO_PORT_IN_RESET ||
        agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
        agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
        agIOStatus == OSSA_IO_DS_IN_ERROR ||
        agIOStatus == OSSA_IO_DS_INVALID
       )
    {
      SM_DBG1(("smsatSetFeaturesDMACB: error status 0x%x\n", agIOStatus));
      SM_DBG1(("smsatSetFeaturesDMACB: did %d!!!\n", oneDeviceData->id));
      tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
      return;
    }
    if (oneDeviceData->satDeviceType == SATA_ATAPI_DEVICE)
    {
       /*if ATAPI device, only need to enable PIO and DMA transfer mode, then complete this identify device command */
       tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
       return;
    }

    /* enble read look-ahead feature*/
    if (oneDeviceData->satReadLookAheadSupport == agTRUE)
    {
        satNewIntIo = smsatAllocIntIoResource(smRoot,
                                           smOrgIORequest,
                                           oneDeviceData,
                                           0,
                                           satNewIntIo);
        if (satNewIntIo == agNULL)
        {
            SM_DBG1(("smsatSetFeaturesDMACB: memory allocation fails\n"));
            /*Complete this identify packet device IO */
            tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
            return;
        } /* end memory allocation */

        satNewIOContext = smsatPrepareNewIO(satNewIntIo,
                                          smOrgIORequest,
                                          oneDeviceData,
                                          scsiCmnd,
                                          satOrgIOContext
                                          );
        /* sends SET FEATURES  command to enable Read Look-Ahead  */
        status = smsatSetFeaturesReadLookAhead(smRoot,
                                &satNewIntIo->satIntSmIORequest,
                                satNewIOContext->psmDeviceHandle,
                                &satNewIntIo->satIntSmScsiXchg,
                                satNewIOContext
                                );
        if (status != SM_RC_SUCCESS)
        {
            smsatFreeIntIoResource(smRoot, oneDeviceData, satNewIntIo);
            SM_DBG1(("smsatSetFeaturesDMACB: failed to call smsatSetFeatures()\n"));
            /*Complete this identify device IO */
            tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
        }
        SM_DBG2(("smsatSetFeaturesDMACB: end\n"));
        return;
    }
    /* enble Volatile Write Cache feature*/
    if (oneDeviceData->satVolatileWriteCacheSupport == agTRUE)
    {
       satNewIntIo = smsatAllocIntIoResource(smRoot,
                                             smOrgIORequest,
                                             oneDeviceData,
                                             0,
                                             satNewIntIo);
        if (satNewIntIo == agNULL)
        {
           SM_DBG1(("smsatSetFeaturesDMACB: memory allocation fails\n"));
           /*Complete this identify packet device IO */
           tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
           return;
        } /* end memory allocation */
        satNewIOContext = smsatPrepareNewIO(satNewIntIo,
                                            smOrgIORequest,
                                            oneDeviceData,
                                            scsiCmnd,
                                            satOrgIOContext
                                            );
        /* sends SET FEATURES command to enable Volatile Write Cache */
        status = smsatSetFeaturesVolatileWriteCache(smRoot,
                                    &satNewIntIo->satIntSmIORequest,
                                    satNewIOContext->psmDeviceHandle,
                                    &satNewIntIo->satIntSmScsiXchg,
                                    satNewIOContext
                                    );
        if (status != SM_RC_SUCCESS)
        {
           smsatFreeIntIoResource(smRoot, oneDeviceData, satNewIntIo);
           SM_DBG1(("smsatSetFeaturesDMACB: failed to call smsatSetFeatures()\n"));
           /*Complete this identify device IO */
           tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
        }
        SM_DBG2(("smsatSetFeaturesDMACB: end\n"));
        return;
    }
    /* turn on DMA Setup FIS auto-activate by sending set feature FIS */
    if (oneDeviceData->satNCQ == agTRUE && oneDeviceData->satDMASetupAA == agTRUE)
    {
        satNewIntIo = smsatAllocIntIoResource( smRoot,
                                               smOrgIORequest,
                                               oneDeviceData,
                                               0,
                                               satNewIntIo);

        if (satNewIntIo == agNULL)
        {
          SM_DBG1(("smsatSetFeaturesDMACB: momory allocation fails; can't send set feature\n"));
          tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
          return;
        } /* end memory allocation */
        satNewIOContext = smsatPrepareNewIO(satNewIntIo,
                                            smOrgIORequest,
                                            oneDeviceData,
                                            agNULL,
                                            satOrgIOContext
                                            );
        /* send the Set Feature ATA command to SATA device for enable DMA Setup FIS auto-activate */
        status = smsatSetFeaturesAA(smRoot,
                                    &satNewIntIo->satIntSmIORequest,
                                    satNewIOContext->psmDeviceHandle,
                                    &satNewIntIo->satIntSmScsiXchg, /* orginal from OS layer */
                                    satNewIOContext);
        if (status != SM_RC_SUCCESS)
        {
            SM_DBG1(("smsatSetFeaturesDMACB: failed to send set feature!!!\n"));
            smsatFreeIntIoResource( smRoot,
                                    oneDeviceData,
                                    satNewIntIo);
            tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOFailed, &(oneDeviceData->satIdentifyData));
        }
    }
    else
    {
        /*Complete this identify device IO */
        tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
    }
    SM_DBG2(("smsatSetFeaturesDMACB: end\n"));
}

/*****************************************************************************
*! \brief  smsatSetFeaturesReadLookAheadCB
*
*   This routine is a callback function called from smllSATACompleted().
*   This CB routine deals with normal non-chained data I/O SATA request.
*
*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
*  \param   agIOStatus:  Status of completed I/O.
*  \param   agFirstDword:Pointer to the four bytes of FIS.
*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
*                        length.
*  \param   agParam:     Additional info based on status.
*  \param   ioContext:   Pointer to smSatIOContext_t.
*
*  \return: none
*
*****************************************************************************/
osGLOBAL void
smsatSetFeaturesReadLookAheadCB(
    agsaRoot_t        *agRoot,
    agsaIORequest_t   *agIORequest,
    bit32             agIOStatus,
    agsaFisHeader_t   *agFirstDword,
    bit32             agIOInfoLen,
    void              *agParam,
    void              *ioContext
    )
{
    smRoot_t                  *smRoot = agNULL;
    smIntRoot_t               *smIntRoot = agNULL;
    smIntContext_t            *smAllShared = agNULL;
    smIORequestBody_t         *smIORequestBody;
    smIORequestBody_t         *smOrgIORequestBody = agNULL;
    smSatIOContext_t          *satIOContext;
    smSatIOContext_t          *satOrgIOContext;
    smSatIOContext_t          *satNewIOContext;
    smSatInternalIo_t         *satIntIo;
    smSatInternalIo_t         *satNewIntIo = agNULL;
    smDeviceData_t            *oneDeviceData;
    smIniScsiCmnd_t           *scsiCmnd;
    smIORequest_t             *smOrgIORequest;
    smDeviceHandle_t          *smDeviceHandle;
    bit32                      status = SM_RC_FAILURE;
    smIORequest_t             *smIORequest;

    SM_DBG2(("smsatSetFeaturesReadLookAheadCB: start\n"));
    smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
    satIOContext           = (smSatIOContext_t *) ioContext;
    if (satIOContext == agNULL)
    {
      SM_DBG1(("smsatSetFeaturesReadLookAheadCB: satIOContext is NULL\n"));
      return;
    }
    satIntIo               = satIOContext->satIntIoContext;
    oneDeviceData          = satIOContext->pSatDevData;
    smDeviceHandle         = satIOContext->psmDeviceHandle;
    smRoot                 = oneDeviceData->smRoot;
    smIntRoot              = (smIntRoot_t *)smRoot->smData;
    smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;

    if (satIntIo == agNULL)
    {
      SM_DBG2(("smsatSetFeaturesReadLookAheadCB: External smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext = satIOContext;
      smOrgIORequest  = smIORequestBody->smIORequest;
      scsiCmnd        = satIOContext->pScsiCmnd;
    }
    else
    {
      SM_DBG2(("smsatSetFeaturesReadLookAheadCB: Internal smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext        = satIOContext->satOrgIOContext;
      smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
      smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
      scsiCmnd      = satOrgIOContext->pScsiCmnd;
    }
    smIORequest  = smOrgIORequestBody->smIORequest;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smIORequestBody->ioCompleted = agTRUE;
    smIORequestBody->ioStarted   = agFALSE;

    oneDeviceData->satLookAheadEnabled = agTRUE;

    /* interal structure free */
    smsatFreeIntIoResource(smRoot,
                           oneDeviceData,
                           satIntIo);

    /* check the agIOStatus */
    if (agIOStatus == OSSA_IO_ABORTED ||
        agIOStatus == OSSA_IO_NO_DEVICE ||
        agIOStatus == OSSA_IO_PORT_IN_RESET ||
        agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
        agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
        agIOStatus == OSSA_IO_DS_IN_ERROR ||
        agIOStatus == OSSA_IO_DS_INVALID
       )
    {
      SM_DBG1(("smsatSetFeaturesReadLookAheadCB: error status 0x%x\n", agIOStatus));
      SM_DBG1(("smsatSetFeaturesReadLookAheadCB: did %d!!!\n", oneDeviceData->id));
      tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
      return;
    }



    /* enble Volatile Write Cache feature*/
    if (oneDeviceData->satVolatileWriteCacheSupport == agTRUE)
    {
        satNewIntIo = smsatAllocIntIoResource(smRoot,
                                           smOrgIORequest,
                                           oneDeviceData,
                                           0,
                                           satNewIntIo);
        if (satNewIntIo == agNULL)
        {
            SM_DBG1(("smsatSetFeaturesReadLookAheadCB: memory allocation fails\n"));
            /*Complete this identify packet device IO */
            tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
            return;
        } /* end memory allocation */

        satNewIOContext = smsatPrepareNewIO(satNewIntIo,
                                          smOrgIORequest,
                                          oneDeviceData,
                                          scsiCmnd,
                                          satOrgIOContext
                                          );
        /* sends SET FEATURES command to enable Volatile Write Cache */
        status = smsatSetFeaturesVolatileWriteCache(smRoot,
                                &satNewIntIo->satIntSmIORequest,
                                satNewIOContext->psmDeviceHandle,
                                &satNewIntIo->satIntSmScsiXchg,
                                satNewIOContext
                                );
        if (status != SM_RC_SUCCESS)
        {
            smsatFreeIntIoResource(smRoot, oneDeviceData, satNewIntIo);
            SM_DBG1(("smsatSetFeaturesReadLookAheadCB: failed to call smsatSetFeatures()\n"));
            /*Complete this identify device IO */
            tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
        }
        SM_DBG2(("smsatSetFeaturesReadLookAheadCB: end\n"));

        return;
    }

    /* turn on DMA Setup FIS auto-activate by sending set feature FIS */
    if (oneDeviceData->satNCQ == agTRUE && oneDeviceData->satDMASetupAA == agTRUE)
    {
        satNewIntIo = smsatAllocIntIoResource( smRoot,
                                               smOrgIORequest,
                                               oneDeviceData,
                                               0,
                                               satNewIntIo);

        if (satNewIntIo == agNULL)
        {
          SM_DBG1(("smsatSetFeaturesReadLookAheadCB: momory allocation fails; can't send set feature\n"));
          tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
          return;
        } /* end memory allocation */

        satNewIOContext = smsatPrepareNewIO(satNewIntIo,
                                            smOrgIORequest,
                                            oneDeviceData,
                                            agNULL,
                                            satOrgIOContext
                                            );
        /* send the Set Feature ATA command to SATA device for enable DMA Setup FIS auto-activate */
        status = smsatSetFeaturesAA(smRoot,
                                    &satNewIntIo->satIntSmIORequest,
                                    satNewIOContext->psmDeviceHandle,
                                    &satNewIntIo->satIntSmScsiXchg, /* orginal from OS layer */
                                    satNewIOContext);

        if (status != SM_RC_SUCCESS)
        {
            SM_DBG1(("smsatSetFeaturesReadLookAheadCB: failed to send set feature!!!\n"));
            smsatFreeIntIoResource( smRoot,
                                    oneDeviceData,
                                    satNewIntIo);
            /* clean up TD layer's IORequestBody */
            tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOFailed, &(oneDeviceData->satIdentifyData));
        }
    }
    else
    {
        /*Complete this identify device IO */
        tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
    }
    SM_DBG2(("smsatSetFeaturesReadLookAheadCB: end\n"));
}
/*****************************************************************************
*! \brief  smsatSetFeaturesVolatileWriteCacheCB
*
*   This routine is a callback function called from smllSATACompleted().
*   This CB routine deals with normal non-chained data I/O SATA request.
*
*  \param   agRoot:      Handles for this instance of SAS/SATA hardware
*  \param   agIORequest: Pointer to the LL I/O request context for this I/O.
*  \param   agIOStatus:  Status of completed I/O.
*  \param   agFirstDword:Pointer to the four bytes of FIS.
*  \param   agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
*                        length.
*  \param   agParam:     Additional info based on status.
*  \param   ioContext:   Pointer to smSatIOContext_t.
*
*  \return: none
*
*****************************************************************************/
osGLOBAL void
smsatSetFeaturesVolatileWriteCacheCB(
    agsaRoot_t        *agRoot,
    agsaIORequest_t   *agIORequest,
    bit32             agIOStatus,
    agsaFisHeader_t   *agFirstDword,
    bit32             agIOInfoLen,
    void              *agParam,
    void              *ioContext
    )
{
    smRoot_t                  *smRoot = agNULL;
    smIntRoot_t               *smIntRoot = agNULL;
    smIntContext_t            *smAllShared = agNULL;
    smIORequestBody_t         *smIORequestBody;
    smIORequestBody_t         *smOrgIORequestBody = agNULL;
    smSatIOContext_t          *satIOContext;
    smSatIOContext_t          *satOrgIOContext;
    smSatIOContext_t          *satNewIOContext;
    smSatInternalIo_t         *satIntIo;
    smSatInternalIo_t         *satNewIntIo = agNULL;
    smDeviceData_t            *oneDeviceData;
    smIORequest_t             *smOrgIORequest;
    smDeviceHandle_t          *smDeviceHandle;
    smIORequest_t             *smIORequest;
    bit32                     ataStatus = 0;
    bit32                     ataError = 0;
    agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
    bit32                     status = SM_RC_FAILURE;

    SM_DBG2(("smsatSetFeaturesVolatileWriteCacheCB: start\n"));
    smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
    satIOContext           = (smSatIOContext_t *) ioContext;
    if (satIOContext == agNULL)
    {
      SM_DBG1(("smsatSetFeaturesVolatileWriteCacheCB: satIOContext is NULL\n"));
      return;
    }
    satIntIo               = satIOContext->satIntIoContext;
    oneDeviceData          = satIOContext->pSatDevData;
    smDeviceHandle         = satIOContext->psmDeviceHandle;
    smRoot                 = oneDeviceData->smRoot;
    smIntRoot              = (smIntRoot_t *)smRoot->smData;
    smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
    if (satIntIo == agNULL)
    {
      SM_DBG5(("smsatSetFeaturesVolatileWriteCacheCB: External smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext = satIOContext;
      smOrgIORequest  = smIORequestBody->smIORequest;
      smIORequest     = smOrgIORequest;
    }
    else
    {
      SM_DBG5(("smsatSetFeaturesVolatileWriteCacheCB: Internal smSatInternalIo_t satIntIoContext\n"));
      satOrgIOContext        = satIOContext->satOrgIOContext;
      smOrgIORequestBody  = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
      smOrgIORequest      = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    }
    smIORequest  = smOrgIORequestBody->smIORequest;
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smIORequestBody->ioCompleted = agTRUE;
    smIORequestBody->ioStarted   = agFALSE;
    if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatSetFeaturesVolatileWriteCacheCB: fail, case 1 agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    }
    if (agIOStatus != OSSA_IO_SUCCESS)
    {
      SM_DBG1(("smsatSetFeaturesVolatileWriteCacheCB: fail, case 2 status %d!!!\n", agIOStatus));
    }
    if (agIOInfoLen != 0 && agIOStatus == OSSA_IO_SUCCESS)
    {
      statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
      ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
      ataError      = statDevToHostFisHeader->error;    /* ATA Eror register   */
      if ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
      {
        SM_DBG1(("smsatSetFeaturesVolatileWriteCacheCB: fail, case 3 ataStatus %d ataError %d!!!\n", ataStatus, ataError));
      }
      if (ataError != 0)
      {
        SM_DBG1(("smsatSetFeaturesVolatileWriteCacheCB: fail, case 4 ataStatus %d ataError %d!!!\n", ataStatus, ataError));
      }
    }

    oneDeviceData->satWriteCacheEnabled = agTRUE;

    /* interal structure free */
    smsatFreeIntIoResource(smRoot,oneDeviceData, satIntIo);
    /* check the agIOStatus */
    if (agIOStatus == OSSA_IO_ABORTED ||
        agIOStatus == OSSA_IO_NO_DEVICE ||
        agIOStatus == OSSA_IO_PORT_IN_RESET ||
        agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
        agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
        agIOStatus == OSSA_IO_DS_IN_ERROR ||
        agIOStatus == OSSA_IO_DS_INVALID
       )
    {
      SM_DBG1(("smsatSetFeaturesVolatileWriteCacheCB: error status 0x%x\n", agIOStatus));
      SM_DBG1(("smsatSetFeaturesVolatileWriteCacheCB: did %d!!!\n", oneDeviceData->id));
      tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
      return;
    }
    /* turn on DMA Setup FIS auto-activate by sending set feature FIS */
    if (oneDeviceData->satNCQ == agTRUE && oneDeviceData->satDMASetupAA == agTRUE)
    {
        satNewIntIo = smsatAllocIntIoResource( smRoot,
                                               smOrgIORequest,
                                               oneDeviceData,
                                               0,
                                               satNewIntIo);
        if (satNewIntIo == agNULL)
        {
          SM_DBG1(("smsatSetFeaturesVolatileWriteCacheCB: momory allocation fails; can't send set feature\n"));
          tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
          return;
        } /* end memory allocation */
        satNewIOContext = smsatPrepareNewIO(satNewIntIo,
                                            smOrgIORequest,
                                            oneDeviceData,
                                            agNULL,
                                            satOrgIOContext
                                            );
        /* send the Set Feature ATA command to SATA device for enable DMA Setup FIS auto-activate */
        status = smsatSetFeaturesAA(smRoot,
                                    &satNewIntIo->satIntSmIORequest,
                                    satNewIOContext->psmDeviceHandle,
                                    &satNewIntIo->satIntSmScsiXchg, /* orginal from OS layer */
                                    satNewIOContext);
        if (status != SM_RC_SUCCESS)
        {
            SM_DBG1(("smsatSetFeaturesVolatileWriteCacheCB: failed to send set feature!!!\n"));
            smsatFreeIntIoResource( smRoot,
                                    oneDeviceData,
                                    satNewIntIo);
            /* clean up TD layer's IORequestBody */
            tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOFailed, &(oneDeviceData->satIdentifyData));
        }
    }
    else
    {
        /*Complete this identify device IO */
        tdsmIDCompletedCB(smRoot, smIORequest, smDeviceHandle, smIOSuccess, &(oneDeviceData->satIdentifyData));
    }
    SM_DBG2(("smsatSetFeaturesVolatileWriteCacheCB: end\n"));
}


osGLOBAL void 
smsatSMARTEnablePassCB(
                     agsaRoot_t        *agRoot,
                     agsaIORequest_t   *agIORequest,
                     bit32             agIOStatus,
                     agsaFisHeader_t   *agFirstDword,
                     bit32             agIOInfoLen,
                     agsaFrameHandle_t agFrameHandle,
                     void              *ioContext
                    )
  {

  smRoot_t                 *smRoot = agNULL;
  smIntRoot_t              *smIntRoot = agNULL; 
  smIntContext_t           *smAllShared = agNULL;
  smIORequestBody_t        *smIORequestBody;
  smIORequestBody_t        *smOrgIORequestBody;
  smSatIOContext_t         *satIOContext;
  smSatIOContext_t         *satOrgIOContext;
  //smSatIOContext_t         *satNewIOContext;
  smSatInternalIo_t        *satIntIo;
 //smSatInternalIo_t        *satNewIntIo = agNULL;
//  satDeviceData_t           *satDevData;
  smDeviceData_t           *oneDeviceData;
  smIniScsiCmnd_t          *scsiCmnd;
  smIORequest_t            *smOrgIORequest;
  //bit32                     status;
  smScsiRspSense_t          *pSense;
  bit8						bSenseKey = 0;
  bit16 					bSenseCodeInfo = 0;
 

  SM_DBG2(("smsatSMARTEnablePassCB: start\n"));
  SM_DBG4(("smsatSMARTEnablePassCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate tiIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;  
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  /*ttttttthe one */
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatSMARTEnablePassCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    scsiCmnd        = satOrgIOContext->pScsiCmnd;   
	pSense          = satOrgIOContext->pSense;
  }
  else
  {
    SM_DBG4(("smsatSMARTEnablePassCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatSMARTEnablePassCB: satOrgIOContext is NULL, wrong\n"));
      return;      
    }
    else
    {
      SM_DBG4(("smsatSMARTEnablePassCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    scsiCmnd               = satOrgIOContext->pScsiCmnd; 
	pSense          = satOrgIOContext->pSense;
  }
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatSMARTEnablePassCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                      smRoot, 
                      smOrgIORequest,
                      smIOFailed, 
                      smDetailOtherError,
                      agNULL, 
                      satOrgIOContext->interruptContext
                     );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  } 
  /*
    checking IO status, FIS type and error status
  */
  if (agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatSMARTEnablePassCB: not success status, status %d!!!\n", agIOStatus));
    if (agIOStatus == OSSA_IO_ABORTED)
    {
      smsatProcessAbort(smRoot,
                        smOrgIORequest,
                        satOrgIOContext
                       );
  
      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo); 
      return;
    }
			
    smsatTranslateATAErrorsToSCSIErrors(
				agFirstDword->D2H.status,
				agFirstDword->D2H.error,
				&bSenseKey,
				&bSenseCodeInfo
				);
    smsatSetSensePayload(pSense, bSenseKey, 0, bSenseCodeInfo, satOrgIOContext);
    tdsmIOCompletedCB(smRoot,
                      smOrgIORequest,
                      smIOSuccess,
                      SCSI_STAT_CHECK_CONDITION, 
                      satOrgIOContext->pSmSenseData,
                      satOrgIOContext->interruptContext );

	
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);

    return;    
  }
  /* process success case */
  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);

 SM_DBG1(("smsatSMARTEnablePassCB:success status, status %d!!!\n", agIOStatus));
 tdsmIOCompletedCB(
					smRoot, 
					smOrgIORequest,
					smIOSuccess, 
					SCSI_STAT_GOOD,
					agNULL, 
					satOrgIOContext->interruptContext
				   );

 
                            
  return;
}

osGLOBAL void 
smsatSMARTRStatusPassCB(
                agsaRoot_t        *agRoot,
                agsaIORequest_t   *agIORequest,
                bit32             agIOStatus,
                agsaFisHeader_t   *agFirstDword,
                bit32             agIOInfoLen,
                void              *agParam,
                void              *ioContext                   
               )

{


  smRoot_t                  *smRoot = agNULL;
  smIntRoot_t               *smIntRoot = agNULL; 
  smIntContext_t            *smAllShared = agNULL;
  smIORequestBody_t         *smIORequestBody;
  smIORequestBody_t         *smOrgIORequestBody;
  smSatIOContext_t          *satIOContext;
  smSatIOContext_t          *satOrgIOContext;
  smSatInternalIo_t         *satIntIo;
//  satDeviceData_t          *satDevData;
  smDeviceData_t            *oneDeviceData;

  smScsiRspSense_t          *pSense;
  smIORequest_t             *smOrgIORequest;

  agsaFisRegHostToDevice_t  *hostToDevFis = agNULL;
  bit32                      ataStatus = 0;
  smScsiInitiatorRequest_t  *smScsiRequest; /* tiScsiXchg */
  smScsiInitiatorRequest_t  *smOrgScsiRequest; /* tiScsiXchg */
  agsaFisRegD2HHeader_t     *statDevToHostFisHeader = agNULL;
//  agsaFisRegD2HData_t        statDevToHostFisData;
  smIniScsiCmnd_t           *scsiCmnd;
  bit8						bSenseKey = 0;
  bit16 					bSenseCodeInfo = 0;
 
  
  SM_DBG2(("smsatSMARTRStatusPassCB: start\n"));
  SM_DBG5(("smsatSMARTRStatusPassCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody        = (smIORequestBody_t *)agIORequest->osData;
  satIOContext           = (smSatIOContext_t *) ioContext;
  satIntIo               = satIOContext->satIntIoContext;
  oneDeviceData          = satIOContext->pSatDevData;
  hostToDevFis           = satIOContext->pFis;
  smRoot                 = oneDeviceData->smRoot;
  smIntRoot              = (smIntRoot_t *)smRoot->smData;  
  smAllShared            = (smIntContext_t *)&smIntRoot->smAllShared;
  
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatSMARTRStatusPassCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest  = smIORequestBody->smIORequest;
    pSense          = satOrgIOContext->pSense;
    smOrgScsiRequest   = satOrgIOContext->smScsiXchg;
     /* ATA command response payload */
    smScsiRequest   = satOrgIOContext->smScsiXchg;
    scsiCmnd        = satOrgIOContext->pScsiCmnd;   
	SM_DBG1((" 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", scsiCmnd->cdb[0], scsiCmnd->cdb[1],scsiCmnd->cdb[2], scsiCmnd->cdb[3]));
	SM_DBG1((" 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", scsiCmnd->cdb[4], scsiCmnd->cdb[5],scsiCmnd->cdb[6], scsiCmnd->cdb[7]));
	SM_DBG1((" 0x%02x, 0x%02x, 0x%02x, 0x%02x,\n", scsiCmnd->cdb[8], scsiCmnd->cdb[9],scsiCmnd->cdb[10], scsiCmnd->cdb[11]));


  }
  else
  {
    SM_DBG4(("smsatSMARTRStatusPassCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext        = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatSMARTRStatusPassCB: satOrgIOContext is NULL\n"));
	  
	  return;
	  
    }
    else
    {
      SM_DBG4(("smsatSMARTRStatusPassCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody     = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest         = (smIORequest_t *)smOrgIORequestBody->smIORequest;
    
    smOrgScsiRequest   = satOrgIOContext->smScsiXchg;
    /* ATA command response payload */
    smScsiRequest   =  (smScsiInitiatorRequest_t *)&(satIntIo->satIntSmScsiXchg);
    scsiCmnd        = satOrgIOContext->pScsiCmnd; 
	pSense          = satOrgIOContext->pSense;
  }
  
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatSMARTRStatusPassCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                       smRoot, 
                       smOrgIORequest,
                       smIOFailed, 
                       smDetailOtherError,
                       agNULL, 
                       satOrgIOContext->interruptContext
                      );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }    
    
  if( agIOStatus != OSSA_IO_SUCCESS)
  {
  
    /* non-data -> device to host  fis are expected */
	 
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus     = statDevToHostFisHeader->status;   /* ATA Status register */
	
    if ( (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) ||
         ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
       )
    {
      /* for debugging */
      if( agIOStatus != OSSA_IO_SUCCESS)
      {
        SM_DBG1(("smsatSMARTRStatusPassCB: FAILED, NOT IO_SUCCESS!!!\n"));
      }
      else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
      {
        SM_DBG1(("smsatSMARTRStatusPassCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
      }
      else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
                (ataStatus & DF_ATA_STATUS_MASK)
               )      
      {
        SM_DBG1(("smsatSMARTRStatusPassCB: FAILED, FAILED, error status!!!\n"));
      }

      /* Process abort case */
      if (agIOStatus == OSSA_IO_ABORTED)
      {
        smsatProcessAbort(smRoot,
                          smOrgIORequest,
                          satOrgIOContext
                         );

        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
                                oneDeviceData,
                                satIntIo); 
        return;
      }
		
      smsatTranslateATAErrorsToSCSIErrors(
				agFirstDword->D2H.status,
				agFirstDword->D2H.error,
				&bSenseKey,
				&bSenseCodeInfo
				);
      smsatSetSensePayload(pSense, bSenseKey, 0, bSenseCodeInfo, satOrgIOContext);
      tdsmIOCompletedCB(smRoot,
                        smOrgIORequest,
                        smIOSuccess,
                        SCSI_STAT_CHECK_CONDITION, 
                        satOrgIOContext->pSmSenseData,
                        satOrgIOContext->interruptContext );


      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;

    } /* error checking */
  }

  /* prcessing the success case */
  SM_DBG5(("smsatSMARTRStatusPassCB: SAT_SMART_RETURN_STATUS success\n"));
      
  tdsmIOCompletedCB( smRoot,
                     smOrgIORequest,
                     smIOSuccess,
                     SCSI_STAT_GOOD,
                     agNULL,
                     satOrgIOContext->interruptContext);
                                  

  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
 
  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);
                                

 return;
}

osGLOBAL void 
smsatSMARTReadLogCB(
                agsaRoot_t        *agRoot,
                agsaIORequest_t   *agIORequest,
                bit32             agIOStatus,
                agsaFisHeader_t   *agFirstDword,
                bit32             agIOInfoLen,
                void              *agParam,
                void              *ioContext                   
               )
{

  smRoot_t                      *smRoot = agNULL;
  smIntRoot_t                   *smIntRoot = agNULL; 
  smIntContext_t                *smAllShared = agNULL;
  smIORequestBody_t             *smIORequestBody;
  smIORequestBody_t             *smOrgIORequestBody;
  smSatIOContext_t              *satIOContext;
  smSatIOContext_t              *satOrgIOContext;
  smSatInternalIo_t             *satIntIo;
//	satDeviceData_t 		 *satDevData;
  smDeviceData_t                *oneDeviceData;

  smScsiRspSense_t              *pSense;
  smIORequest_t                 *smOrgIORequest;

  agsaFisRegHostToDevice_t      *hostToDevFis = agNULL;
  bit32                         ataStatus = 0;
  smScsiInitiatorRequest_t      *smScsiRequest; /* tiScsiXchg */
  smScsiInitiatorRequest_t      *smOrgScsiRequest; /* tiScsiXchg */
//	  satReadLogExtSelfTest_t	*virtAddr1;
//	  satSmartReadLogSelfTest_t *virtAddr2;
  //bit8						*pLogPage;
//	  bit8						 SelfTestExecutionStatus = 0;
//	  bit32 					 i = 0;
  
  agsaFisRegD2HHeader_t         *statDevToHostFisHeader = agNULL;
//	  agsaFisRegD2HData_t		 statDevToHostFisData;
  smIniScsiCmnd_t               *scsiCmnd;
//	  bit32 					 lenReceived = 0;
  bit8                          bSenseKey = 0;
  bit16                         bSenseCodeInfo = 0;
	  
  SM_DBG2(("smsatSMARTReadLogCB: start\n"));
  SM_DBG5(("smsatSMARTReadLogCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));

  /* internally generate smIOContext */
  smIORequestBody		 = (smIORequestBody_t *)agIORequest->osData;
  satIOContext			 = (smSatIOContext_t *) ioContext;
  satIntIo				 = satIOContext->satIntIoContext;
  oneDeviceData 		 = satIOContext->pSatDevData;
  hostToDevFis			 = satIOContext->pFis;
  smRoot				 = oneDeviceData->smRoot;
  smIntRoot 			 = (smIntRoot_t *)smRoot->smData;  
  smAllShared			 = (smIntContext_t *)&smIntRoot->smAllShared;
  
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatSMARTReadLogCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest	= smIORequestBody->smIORequest;
    pSense			= satOrgIOContext->pSense;
    smOrgScsiRequest   = satOrgIOContext->smScsiXchg;

    /* ATA command response payload */
    smScsiRequest	= satOrgIOContext->smScsiXchg;
    scsiCmnd		= satOrgIOContext->pScsiCmnd;	 


  }
  else
  {
    SM_DBG4(("smsatSMARTReadLogCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext 	   = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatSMARTReadLogCB: satOrgIOContext is NULL\n"));
	  
      return;
	  
    }
    else
    {
      SM_DBG4(("smsatSMARTReadLogCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody	   = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest		   = (smIORequest_t *)smOrgIORequestBody->smIORequest;
	
    pSense		  = satOrgIOContext->pSense;
    smOrgScsiRequest   = satOrgIOContext->smScsiXchg;

    /* ATA command response payload */
    smScsiRequest	=  (smScsiInitiatorRequest_t *)&(satIntIo->satIntSmScsiXchg);
    scsiCmnd		= satOrgIOContext->pScsiCmnd;  
  }
	  
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;

  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatSMARTReadLogCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB(
                      smRoot, 
                      smOrgIORequest,
                      smIOFailed, 
                      smDetailOtherError,
                      agNULL, 
                      satOrgIOContext->interruptContext
                     );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }    

  //for Debuggings
  if(agFirstDword != NULL)
  {
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    SM_DBG1(("smsatSMARTReadLogCB: statDevToHostFisHeader->status, status %d!!!\n", statDevToHostFisHeader->status));
  }
  if ((agIOStatus != OSSA_IO_SUCCESS) && (agFirstDword != NULL))
  { 		   
    /* non-data and pio read -> device to host and pio setup fis are expected */
    /*
      first, assumed to be Reg Device to Host FIS
      This is OK to just find fis type
    */
    statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
    ataStatus	  = statDevToHostFisHeader->status;   /* ATA Status register */
  }
	
  if( agIOStatus != OSSA_IO_SUCCESS)
  {
    if ( ((statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) &&
         (statDevToHostFisHeader->fisType != PIO_SETUP_DEV_TO_HOST_FIS)) ||
         ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
       )
    {
      /* for debugging */
      if( agIOStatus != OSSA_IO_SUCCESS)
      {
        SM_DBG1(("smsatSMARTReadLogCB: FAILED, NOT IO_SUCCESS!!!\n"));
      }
      else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
      {
        SM_DBG1(("smsatSMARTReadLogCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
      }
      else if (statDevToHostFisHeader->fisType != PIO_SETUP_DEV_TO_HOST_FIS)
      {
        SM_DBG1(("smsatSMARTReadLogCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
      }
      else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
                (ataStatus & DF_ATA_STATUS_MASK)
              ) 	 
      {
        SM_DBG1(("smsatSMARTReadLogCB: FAILED, FAILED, error status!!!\n"));
      }
		
      /* Process abort case */
      if (agIOStatus == OSSA_IO_ABORTED)
      {
        smsatProcessAbort(smRoot,
                          smOrgIORequest,
                          satOrgIOContext
                         );
  
        smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

        smsatFreeIntIoResource( smRoot,
						  oneDeviceData,
						  satIntIo); 
        return;
      }
			
      /* for debugging */
  
      if (hostToDevFis->h.command == SAT_SMART)
      {
        if (hostToDevFis->h.features == SAT_SMART_READ_LOG)
        {
          SM_DBG1(("smsatSMARTReadLogCB: SAT_SMART_READ_LOG failed!!!\n"));
        }
        else
        {
          SM_DBG1(("smsatSMARTReadLogCB: error unknown command 0x%x feature 0x%x!!!\n", hostToDevFis->h.command, hostToDevFis->h.features));
        }
      }
      else
      {
        SM_DBG1(("smsatSMARTReadLogCB: error default case command 0x%x!!!\n", hostToDevFis->h.command));
      }
			
      smsatTranslateATAErrorsToSCSIErrors(
				agFirstDword->D2H.status,
				agFirstDword->D2H.error,
				&bSenseKey,
				&bSenseCodeInfo
				);
      smsatSetSensePayload(pSense, bSenseKey, 0, bSenseCodeInfo, satOrgIOContext);
      tdsmIOCompletedCB(smRoot,
                        smOrgIORequest,
                        smIOSuccess,
                        SCSI_STAT_CHECK_CONDITION, 
                        satOrgIOContext->pSmSenseData,
                        satOrgIOContext->interruptContext );


      smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

      smsatFreeIntIoResource( smRoot,
                              oneDeviceData,
                              satIntIo);
      return;

    } /* error checking */
  }
	
  /* prcessing the success case */
	  

  tdsmIOCompletedCB( smRoot,
                     smOrgIORequest,
                     smIOSuccess,
                     SCSI_STAT_GOOD,
                     agNULL,
                     satOrgIOContext->interruptContext);
							   
  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

  smsatFreeIntIoResource( smRoot,
                          oneDeviceData,
                          satIntIo);
			
  return;
}

osGLOBAL void 
smsatPassthroughCB(
                agsaRoot_t        *agRoot,
                agsaIORequest_t   *agIORequest,
                bit32             agIOStatus,
                agsaFisHeader_t   *agFirstDword,
                bit32             agIOInfoLen,
                void              *agParam,
                void              *ioContext                   
               )
{
  smRoot_t	                *smRoot = agNULL;
  smIntRoot_t			*smIntRoot = agNULL; 
  smIntContext_t		*smAllShared = agNULL;
  smIORequestBody_t 		*smIORequestBody;
  smIORequestBody_t 		*smOrgIORequestBody;
  smSatIOContext_t		*satIOContext;
  smSatIOContext_t		*satOrgIOContext;
  smSatInternalIo_t 		*satIntIo;
  smDeviceData_t		*oneDeviceData;
  smScsiRspSense_t		*pSense;
  smIORequest_t 		*smOrgIORequest;
  agsaFisRegHostToDevice_t	*hostToDevFis = agNULL;
  bit32 			 ataStatus = 0;
  smScsiInitiatorRequest_t	*smScsiRequest; /* tiScsiXchg */
  smScsiInitiatorRequest_t	*smOrgScsiRequest; /* tiScsiXchg */
	  
  agsaFisRegD2HHeader_t 	*statDevToHostFisHeader = agNULL;
  smIniScsiCmnd_t		*scsiCmnd;
  bit8				 bSenseKey = 0;
  bit16 			 bSenseCodeInfo = 0;
	  
  SM_DBG2(("smsatPassthroughCB: start\n"));
  SM_DBG5(("smsatPassthroughCB:agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
	
  /* internally generate smIOContext */
  smIORequestBody		 = (smIORequestBody_t *)agIORequest->osData;
  satIOContext			 = (smSatIOContext_t *) ioContext;
  satIntIo			 = satIOContext->satIntIoContext;
  oneDeviceData 		 = satIOContext->pSatDevData;
  hostToDevFis			 = satIOContext->pFis;
  smRoot			 = oneDeviceData->smRoot;
  smIntRoot 			 = (smIntRoot_t *)smRoot->smData;  
  smAllShared			 = (smIntContext_t *)&smIntRoot->smAllShared;
  
  if (satIntIo == agNULL)
  {
    SM_DBG4(("smsatPassthroughCB: External smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext = satIOContext;
    smOrgIORequest = smIORequestBody->smIORequest;
    pSense = satOrgIOContext->pSense;
    smOrgScsiRequest   = satOrgIOContext->smScsiXchg;

    /* ATA command response payload */
    smScsiRequest	= satOrgIOContext->smScsiXchg;
    scsiCmnd		= satOrgIOContext->pScsiCmnd;	 
  }
  else
  {
    SM_DBG4(("smsatPassthroughCB: Internal smSatInternalIo_t satIntIoContext\n"));
    satOrgIOContext 	   = satIOContext->satOrgIOContext;
    if (satOrgIOContext == agNULL)
    {
      SM_DBG4(("smsatPassthroughCB: satOrgIOContext is NULL\n"));
      return;
    }
    else
    {
      SM_DBG4(("smsatPassthroughCB: satOrgIOContext is NOT NULL\n"));
    }
    smOrgIORequestBody  = (smIORequestBody_t *)satOrgIOContext->smRequestBody;
    smOrgIORequest = (smIORequest_t *)smOrgIORequestBody->smIORequest;
		
    pSense = satOrgIOContext->pSense;
    smOrgScsiRequest   = satOrgIOContext->smScsiXchg;

    /* ATA command response payload */
    smScsiRequest	=  (smScsiInitiatorRequest_t *)&(satIntIo->satIntSmScsiXchg);
    scsiCmnd		= satOrgIOContext->pScsiCmnd;  
  }
	  
  smIORequestBody->ioCompleted = agTRUE;
  smIORequestBody->ioStarted = agFALSE;


   if (agIOStatus == OSSA_IO_UNDERFLOW)
  {
    SM_DBG1(("smsatPassthroughCB: IO_UNDERFLOW, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB( smRoot,
                       smOrgIORequest,
                       smIOUnderRun,
                       agIOInfoLen,
                       agNULL,
                       satOrgIOContext->interruptContext
                     );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);

    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
                            satIntIo);
    return;
  }

	
  if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
  {
    SM_DBG1(("smsatPassthroughCB: wrong. agFirstDword is NULL when error, status %d!!!\n", agIOStatus));
    tdsmIOCompletedCB( smRoot, 
		       smOrgIORequest,
		       smIOFailed, 
		       smDetailOtherError,
		       agNULL, 
		       satOrgIOContext->interruptContext
		     );
    smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
	
    smsatFreeIntIoResource( smRoot,
                            oneDeviceData,
			    satIntIo);
    return;
  }    

  //for Debuggings

   if ((agIOStatus != OSSA_IO_SUCCESS) && (agFirstDword != NULL))
   { 		   
     /* non-data and pio read -> device to host and pio setup fis are expected */
       /*
          first, assumed to be Reg Device to Host FIS
	  This is OK to just find fis type
        */
     statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
     ataStatus	  = statDevToHostFisHeader->status;   /* ATA Status register */
   }
   if( agIOStatus != OSSA_IO_SUCCESS)
   {
     if ( ((statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS) &&
          (statDevToHostFisHeader->fisType != PIO_SETUP_DEV_TO_HOST_FIS)) ||
	  ((ataStatus & ERR_ATA_STATUS_MASK) || (ataStatus & DF_ATA_STATUS_MASK))
        )
     {
       /* for debugging */
       if( agIOStatus != OSSA_IO_SUCCESS)
       {
         SM_DBG1(("smsatPassthroughCB: FAILED, NOT IO_SUCCESS!!!\n"));
       }
       else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
       {
         SM_DBG1(("smsatPassthroughCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
       }
       else if (statDevToHostFisHeader->fisType != PIO_SETUP_DEV_TO_HOST_FIS)
       {
         SM_DBG1(("smsatPassthroughCB: FAILED, Wrong FIS type 0x%x!!!\n",statDevToHostFisHeader->fisType));
       }
       else if ( (ataStatus & ERR_ATA_STATUS_MASK) ||
                 (ataStatus & DF_ATA_STATUS_MASK)
	       ) 	 
       {
         SM_DBG1(("smsatPassthroughCB: FAILED, FAILED, error status!!!\n"));
       }
		
       /* Process abort case */
       if (agIOStatus == OSSA_IO_ABORTED)
       {
         smsatProcessAbort( smRoot,
			    smOrgIORequest,
			    satOrgIOContext);
			  
	 smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
		
         smsatFreeIntIoResource( smRoot,
	                         oneDeviceData,
				 satIntIo); 
         return;
       }
			
       smsatTranslateATAErrorsToSCSIErrors( agFirstDword->D2H.status,
					    agFirstDword->D2H.error,
					    &bSenseKey,
					    &bSenseCodeInfo
					  );
       smsatSetSensePayload(pSense, bSenseKey, 0, bSenseCodeInfo, satOrgIOContext);
       tdsmIOCompletedCB( smRoot,
                          smOrgIORequest,
		          smIOSuccess,
			  SCSI_STAT_CHECK_CONDITION, 
			  satOrgIOContext->pSmSenseData,
			  satOrgIOContext->interruptContext );
		   
		    
       smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
       smsatFreeIntIoResource( smRoot,
                               oneDeviceData,
                              satIntIo);
       return;
		
     } /* error checking */
   }
	
   /* prcessing the success case */
   if(agFirstDword != NULL)
   {
     statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
     SM_DBG1(("smsatPassthroughCB: statDevToHostFisHeader->status, status %d!!!\n", statDevToHostFisHeader->status));
     smsatTranslateATAErrorsToSCSIErrors( agFirstDword->D2H.status,
					  agFirstDword->D2H.error,
					  &bSenseKey,
					  &bSenseCodeInfo);
     smsatSetSensePayload(pSense, bSenseKey, 0, bSenseCodeInfo, satOrgIOContext);
     if(agFirstDword->D2H.status & 0x01)
     {
       tdsmIOCompletedCB( smRoot,
                          smOrgIORequest,
			  smIOSuccess,
			  SCSI_STAT_CHECK_CONDITION, 
			  satOrgIOContext->pSmSenseData,
			  satOrgIOContext->interruptContext );
       smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
       smsatFreeIntIoResource( smRoot,
                               oneDeviceData,
                               satIntIo);
       return;
     }
   }

  tdsmIOCompletedCB( smRoot,
                     smOrgIORequest,
	             smIOSuccess,
	             SCSI_STAT_GOOD,
	             agNULL,
	             satOrgIOContext->interruptContext);
	 						   
  smsatDecrementPendingIO(smRoot, smAllShared, satIOContext);
	 
  smsatFreeIntIoResource( smRoot,
    			  oneDeviceData,
			  satIntIo);
					
  return;
}