/******************************************************************************* *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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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; }