/******************************************************************************* ** *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 ** ********************************************************************************/ /*****************************************************************************/ /** \file * * This file contains initiator CB functions * */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef FDS_SM #include #include #include #endif #ifdef FDS_DM #include #include #include #endif #include #include #include #ifdef INITIATOR_DRIVER #include #include #include #endif #ifdef TARGET_DRIVER #include #include #include #endif #include #include /***************************************************************************** *! \brief itdssTaskCompleted * * Purpose: This routine is called to complete an task management request * previously issued to the LL Layer. All task management completes with * this function except query task management. * * \param agRoot: Pointer to driver Instance. * \param agIORequest: Pointer to the I/O Request data structure for * this I/O. * \param agIOStatus: Status of I/O just completed. * \param agIOInfoLen: Length of the I/O information associated with this * I/O request * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * \note - This is a initiator specific function called by the jump table. * *****************************************************************************/ osGLOBAL void itdssTaskCompleted( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; tiIORequest_t *taskTag = agNULL, *currentTaskTag = agNULL; tdIORequestBody_t *tdIORequestBody = agNULL; tdIORequestBody_t *TMtdIORequestBody = agNULL; tdIORequestBody_t *AborttdIORequestBody = agNULL; agsaIORequest_t *agTaskedIORequest; agsaSSPResponseInfoUnit_t agSSPRespIU; bit8 respData[128]; bit32 respLen; #ifdef TD_DEBUG_ENABLE bit32 data_status; #endif agsaSASRequestBody_t *agSASRequestBody = agNULL; agsaSSPScsiTaskMgntReq_t *agSSPTaskMgntRequest = agNULL; agsaIORequest_t *agAbortIORequest; tdIORequestBody_t *tdAbortIORequestBody; bit32 PhysUpper32; bit32 PhysLower32; bit32 memAllocStatus; void *osMemHandle; bit32 abortOrquery = agTRUE; tiDeviceHandle_t *tiDeviceHandle = agNULL; tdsaDeviceData_t *oneDeviceData = agNULL; agsaDevHandle_t *agDevHandle = agNULL; bit32 status = AGSA_RC_FAILURE; TI_DBG2(("itdssTaskCompleted: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; /* check the agIOStatus */ currentTaskTag = tdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag; if (currentTaskTag == agNULL) { TI_DBG1(("itdssTaskCompleted: currentTaskTag is NULL \n")); /* as the currentTaskTag is agNULL, shall not call ostiInitiatorEvent */ #if 0 ostiInitiatorEvent( tiRoot, NULL, NULL, tiIntrEventTypeTaskManagement, tiTMFailed, currentTaskTag ); #endif /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } if (agIOStatus != OSSA_IO_SUCCESS) { TI_DBG1(("itdssTaskCompleted: agIOStatus failed and tiTMFailed\n")); if (agIOStatus == OSSA_IO_TM_TAG_NOT_FOUND) { TI_DBG1(("itdssTaskCompleted: agIOStatus OSSA_IO_TM_TAG_NOT_FOUND\n")); } else if (agIOStatus == OSSA_IO_ABORTED) { TI_DBG1(("itdssTaskCompleted: agIOStatus OSSA_IO_ABORTED\n")); } else { TI_DBG1(("itdssTaskCompleted: agIOStatus 0x%x\n", agIOStatus)); } ostiInitiatorEvent( tiRoot, NULL, NULL, tiIntrEventTypeTaskManagement, tiTMFailed, currentTaskTag ); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } /* parse the task management response */ /* reads agsaSSPResponseInfoUnit_t */ saFrameReadBlock(agRoot, agParam, 0, &agSSPRespIU, sizeof(agsaSSPResponseInfoUnit_t)); #ifdef TD_DEBUG_ENABLE data_status = SA_SSPRESP_GET_DATAPRES(&agSSPRespIU); #endif respLen = SA_SSPRESP_GET_RESPONSEDATALEN(&agSSPRespIU); TI_DBG6(("itdssTaskCompleted: dataPres %d. should be 1\n", data_status)); /* reads response data */ saFrameReadBlock(agRoot, agParam, sizeof(agsaSSPResponseInfoUnit_t), respData, respLen); TI_DBG6(("itdssTaskCompleted: res code %d. should be 0\n", respData[3])); taskTag = tdIORequestBody->IOType.InitiatorTMIO.TaskTag; if (taskTag == agNULL) { /* other than Abort Task or Query Task */ TI_DBG1(("itdssTaskCompleted: taskTag is NULL\n")); abortOrquery = agFALSE; TMtdIORequestBody = (tdIORequestBody_t *)currentTaskTag->tdData; } else { /* Abort Task or Query Task */ TI_DBG2(("itdssTaskCompleted: taskTag is NOT NULL\n")); abortOrquery = agTRUE; TMtdIORequestBody = (tdIORequestBody_t *)currentTaskTag->tdData; } TI_DBG2(("itdssTaskCompleted: TMtdIORequestBody %p\n", TMtdIORequestBody)); if (TMtdIORequestBody == agNULL) { TI_DBG1(("itdssTaskCompleted: TMtdIORequestBody is NULL \n")); ostiInitiatorEvent( tiRoot, NULL, NULL, tiIntrEventTypeTaskManagement, tiTMFailed, currentTaskTag ); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } if (agIOStatus == OSSA_IO_SUCCESS && agIOInfoLen == 0) { TI_DBG1(("itdssTaskCompleted: agIOInfoLen is zero, wrong\n")); ostiInitiatorEvent( tiRoot, NULL, NULL, tiIntrEventTypeTaskManagement, tiTMFailed, currentTaskTag ); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } agSASRequestBody = (agsaSASRequestBody_t *)&(TMtdIORequestBody->transport.SAS.agSASRequestBody); agSSPTaskMgntRequest = (agsaSSPScsiTaskMgntReq_t *)&(agSASRequestBody->sspTaskMgntReq); TI_DBG2(("itdssTaskCompleted: agSSPTaskMgntRequest->taskMgntFunction 0x%x\n", agSSPTaskMgntRequest->taskMgntFunction)); if ( (agSSPTaskMgntRequest->taskMgntFunction == AGSA_ABORT_TASK || agSSPTaskMgntRequest->taskMgntFunction == AGSA_QUERY_TASK) && abortOrquery == agFALSE ) { TI_DBG1(("itdssTaskCompleted: incorrect tasktag, first\n")); ostiInitiatorEvent( tiRoot, NULL, NULL, tiIntrEventTypeTaskManagement, tiTMFailed, currentTaskTag ); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } if ((agSSPTaskMgntRequest->taskMgntFunction == AGSA_ABORT_TASK_SET || agSSPTaskMgntRequest->taskMgntFunction == AGSA_CLEAR_TASK_SET || agSSPTaskMgntRequest->taskMgntFunction == AGSA_LOGICAL_UNIT_RESET || agSSPTaskMgntRequest->taskMgntFunction == AGSA_CLEAR_ACA ) && abortOrquery == agTRUE ) { TI_DBG1(("itdssTaskCompleted: incorrect tasktag, second\n")); ostiInitiatorEvent( tiRoot, NULL, NULL, tiIntrEventTypeTaskManagement, tiTMFailed, currentTaskTag ); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } if (agSSPTaskMgntRequest->taskMgntFunction == AGSA_ABORT_TASK) { TI_DBG2(("itdssTaskCompleted: calling saSSPAbort()\n")); AborttdIORequestBody = (tdIORequestBody_t *)taskTag->tdData; if (AborttdIORequestBody == agNULL) { TI_DBG1(("itdssTaskCompleted: wrong, AborttdIORequestBody is NULL\n")); return; } tiDeviceHandle = AborttdIORequestBody->tiDevHandle; if (tiDeviceHandle == agNULL) { TI_DBG1(("itdssTaskCompleted: wrong, tiDeviceHandle is NULL\n")); return; } oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; if (oneDeviceData == agNULL) { TI_DBG1(("itdssTaskCompleted: wrong, oneDeviceData is NULL\n")); return; } agDevHandle = oneDeviceData->agDevHandle; if (agDevHandle == agNULL) { TI_DBG1(("itdssTaskCompleted: wrong, agDevHandle is NULL\n")); } agTaskedIORequest = (agsaIORequest_t *)&(AborttdIORequestBody->agIORequest); if (agTaskedIORequest == agNULL) { TI_DBG1(("itdssTaskCompleted: agTaskedIORequest is NULL \n")); ostiInitiatorEvent( tiRoot, NULL, NULL, tiIntrEventTypeTaskManagement, tiTMFailed, currentTaskTag ); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } /* allocating agIORequest for abort itself */ memAllocStatus = ostiAllocMemory( tiRoot, &osMemHandle, (void **)&tdAbortIORequestBody, &PhysUpper32, &PhysLower32, 8, sizeof(tdIORequestBody_t), agTRUE ); if (memAllocStatus != tiSuccess) { /* let os process IO */ TI_DBG1(("itdssTaskCompleted: ostiAllocMemory failed...\n")); return; } if (tdAbortIORequestBody == agNULL) { /* let os process IO */ TI_DBG1(("itdssTaskCompleted: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); return; } /* setup task management structure */ tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; tdAbortIORequestBody->tiDevHandle = tiDeviceHandle; /* setting callback */ tdAbortIORequestBody->IOCompletionFunc = itdssIOAbortedHandler; /* setting to NULL because the local abort is triggered by TD layer */ tdAbortIORequestBody->tiIOToBeAbortedRequest = agNULL; /* initialize agIORequest */ agAbortIORequest = &(tdAbortIORequestBody->agIORequest); agAbortIORequest->osData = (void *) tdAbortIORequestBody; agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ status = saSSPAbort(agRoot, agAbortIORequest, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, 0, agTaskedIORequest, agNULL); if (status != AGSA_RC_SUCCESS) { TI_DBG1(("itdssTaskCompleted: saSSPAbort failed agIOInfoLen is zero, wrong\n")); ostiFreeMemory( tiRoot, tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); } } /* parse the response and based on the parse, set the flag */ if (respData[3] == AGSA_TASK_MANAGEMENT_FUNCTION_COMPLETE || respData[3] == AGSA_TASK_MANAGEMENT_FUNCTION_SUCCEEDED) { TI_DBG2(("itdssTaskCompleted: tiTMOK\n")); tiDeviceHandle = TMtdIORequestBody->tiDevHandle; if (tiDeviceHandle == agNULL) { TI_DBG1(("itdssTaskCompleted: wrong, tiDeviceHandle is NULL\n")); return; } oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; if (oneDeviceData == agNULL) { TI_DBG1(("itdssTaskCompleted: wrong, oneDeviceData is NULL\n")); return; } agDevHandle = oneDeviceData->agDevHandle; if (agDevHandle == agNULL) { TI_DBG1(("itdssTaskCompleted: wrong, agDevHandle is NULL\n")); } TI_DBG2(("itdssTaskCompleted: setting Device state to SA_DS_OPERATIONAL\n")); saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_OPERATIONAL); ostiInitiatorEvent( tiRoot, NULL, NULL, tiIntrEventTypeTaskManagement, tiTMOK, currentTaskTag ); } else { TI_DBG1(("itdssTaskCompleted: tiTMFailed\n")); ostiInitiatorEvent( tiRoot, NULL, NULL, tiIntrEventTypeTaskManagement, tiTMFailed, currentTaskTag ); } /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } #ifdef INITIATOR_DRIVER /***************************************************************************** *! \brief itdssQueryTaskCompleted * * Purpose: This routine is called to complete an query task management request * previously issued to the LL Layer. * * \param agRoot: Pointer to driver Instance. * \param agIORequest: Pointer to the I/O Request data structure for * this I/O. * \param agIOStatus: Status of I/O just completed. * \param agIOInfoLen: Length of the I/O information associated with this * I/O request * \param agParam A Handle used to refer to the response frame or handle * of abort request * * \return: None * * \note - This is a initiator specific function called by the jump table. * *****************************************************************************/ osGLOBAL void itdssQueryTaskCompleted( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; tiIORequest_t *taskTag = agNULL; tdIORequestBody_t *tdIORequestBody = agNULL; /* query task */ tdIORequestBody_t *TMtdIORequestBody = agNULL; /* IO being query tasked */ agsaIORequest_t *agTaskedIORequest = agNULL; agsaSSPResponseInfoUnit_t agSSPRespIU; bit8 respData[128]; bit32 respLen; #ifdef TD_DEBUG_ENABLE bit32 data_status; #endif agsaSASRequestBody_t *agSASRequestBody = agNULL; agsaSSPScsiTaskMgntReq_t *agSSPTaskMgntRequest = agNULL; bit32 status; agsaIORequest_t *agAbortIORequest = agNULL; tdIORequestBody_t *tdAbortIORequestBody = agNULL; bit32 PhysUpper32; bit32 PhysLower32; bit32 memAllocStatus; void *osMemHandle = agNULL; tiDeviceHandle_t *tiDeviceHandle = agNULL; tdsaDeviceData_t *oneDeviceData = agNULL; agsaDevHandle_t *agDevHandle = agNULL; TI_DBG2(("itdssQueryTaskComplted: start\n")); /* query task management IORequestBody */ tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; /* OS's tiIORequest for this query taks, which is agNULL */ //currentTaskTag = tdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag; /* currentTaskTag is agNULL for query task since it is generated by TD layer */ if (agIOStatus != OSSA_IO_SUCCESS) { /* let os process IO */ TI_DBG1(("itdssQueryTaskComplted: agIOStatus failed and tiTMFailed\n")); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } /* parse the task management response */ /* reads agsaSSPResponseInfoUnit_t */ saFrameReadBlock(agRoot, agParam, 0, &agSSPRespIU, sizeof(agsaSSPResponseInfoUnit_t)); #ifdef TD_DEBUG_ENABLE data_status = SA_SSPRESP_GET_DATAPRES(&agSSPRespIU); #endif respLen = SA_SSPRESP_GET_RESPONSEDATALEN(&agSSPRespIU); TI_DBG6(("itdssQueryTaskCompleted: dataPres %d. should be 1\n", data_status)); /* reads response data */ saFrameReadBlock(agRoot, agParam, sizeof(agsaSSPResponseInfoUnit_t), respData, respLen); TI_DBG6(("itdssQueryTaskCompleted: res code %d. should be 0\n", respData[3])); /* IO being query tasked */ taskTag = tdIORequestBody->IOType.InitiatorTMIO.TaskTag; if (taskTag == agNULL) { TI_DBG1(("itdssQueryTaskComplted: taskTag is NULL \n")); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } /* request body of IO being query tasked */ TMtdIORequestBody = (tdIORequestBody_t *)taskTag->tdData; if (TMtdIORequestBody == agNULL) { TI_DBG1(("itdssQueryTaskComplted: TMtdIORequestBody is NULL \n")); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } agTaskedIORequest = &(TMtdIORequestBody->agIORequest); if (agTaskedIORequest == agNULL) { TI_DBG1(("itdssQueryTaskComplted: agTaskedIORequest is NULL \n")); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } if (agIOStatus == OSSA_IO_SUCCESS && agIOInfoLen == 0) { TI_DBG1(("itdssQueryTaskCompleted: agIOInfoLen is zero, wrong\n")); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } /* this is query task itself */ agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody); agSSPTaskMgntRequest = &(agSASRequestBody->sspTaskMgntReq); if (agSSPTaskMgntRequest->taskMgntFunction == AGSA_QUERY_TASK) { /* process response for query task For query task, response code must be either TASK MANAGEMENT FUNCTION COMPLETE or TASK MANAGEMENT FUNCTION SUCCEEDED by SAM 1. If TASK MANAGEMENT FUNCTION SUCCEEDE, do nothing 2. If TASK MANAGEMENT FUNCTION COMPLETE and IO is not completed, retry by saSSPAbort() */ if (respData[3] == AGSA_TASK_MANAGEMENT_FUNCTION_SUCCEEDED) { /* OK; IO is being process at the target; do nothing */ } else if (respData[3] == AGSA_TASK_MANAGEMENT_FUNCTION_COMPLETE) { tiDeviceHandle = TMtdIORequestBody->tiDevHandle; if (tiDeviceHandle == agNULL) { TI_DBG1(("itdssQueryTaskCompleted: wrong, tiDeviceHandle is NULL\n")); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; if (oneDeviceData == agNULL) { TI_DBG1(("itdssQueryTaskCompleted: wrong, oneDeviceData is NULL\n")); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } agDevHandle = oneDeviceData->agDevHandle; if (agDevHandle == agNULL) { TI_DBG1(("itdssQueryTaskCompleted: wrong, agDevHandle is NULL\n")); } /* if IO is not completed, retry IO by saSSPAbort() */ if (TMtdIORequestBody->ioCompleted != agTRUE) { /* allocating agIORequest for abort itself */ memAllocStatus = ostiAllocMemory( tiRoot, &osMemHandle, (void **)&tdAbortIORequestBody, &PhysUpper32, &PhysLower32, 8, sizeof(tdIORequestBody_t), agTRUE ); if (memAllocStatus != tiSuccess) { /* let os process IO */ TI_DBG1(("itdssQueryTaskCompleted: ostiAllocMemory failed...\n")); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } if (tdAbortIORequestBody == agNULL) { /* let os process IO */ TI_DBG1(("itdssQueryTaskCompleted: ostiAllocMemory returned NULL tdAbortIORequestBody\n")); /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } /* setup task management structure */ tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle; tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle; tdAbortIORequestBody->tiIOToBeAbortedRequest = agNULL; /* setting callback */ tdAbortIORequestBody->IOCompletionFunc = itdssIOAbortedHandler; /* initialize agIORequest */ agAbortIORequest = &(tdAbortIORequestBody->agIORequest); agAbortIORequest->osData = (void *) tdAbortIORequestBody; agAbortIORequest->sdkData = agNULL; /* LL takes care of this */ TI_DBG2(("itdssQueryTaskCompleted: issuing saSSPAbort()\n")); status = saSSPAbort(agRoot, agAbortIORequest, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, 0, agTaskedIORequest, agNULL); if (status != AGSA_RC_SUCCESS) { TI_DBG1(("itdssQueryTaskCompleted: saSSPAbort failed agIOInfoLen is zero, wrong\n")); ostiFreeMemory( tiRoot, tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); } } } else { TI_DBG1(("itdssQueryTaskComplted: not expected response 0x%x\n",respData[3])); } } else { TI_DBG1(("itdssQueryTaskCompleted: not expected task management fn %d\n",agSSPTaskMgntRequest->taskMgntFunction)); } /* free up allocated memory */ ostiFreeMemory( tiRoot, tdIORequestBody->IOType.InitiatorTMIO.osMemHandle, sizeof(tdIORequestBody_t) ); return; } #endif /***************************************************************************** *! \brief itssdosIOCompleted * * Purpose: This routine is called to complete an I/O request previously * issued to the LL Layer in saSSPStart(). * * \param agRoot: Pointer to driver Instance. * \param agIORequest: Pointer to the I/O Request data structure for * this I/O. * \param agIOStatus: Status of I/O just completed. * \param agIOInfoLen: Length of the I/O information associated with this * I/O request * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * \note - This is a initiator specific function called by the jump table. * *****************************************************************************/ FORCEINLINE void itdssIOCompleted( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; itdsaIni_t *Initiator = (itdsaIni_t *)osData->itdsaIni; tdIORequestBody_t *tdIORequestBody = agNULL; agsaSASRequestBody_t *agSASRequestBody = agNULL; agsaSSPInitiatorRequest_t *agSSPInitiatorRequest = agNULL; agsaSSPResponseInfoUnit_t agSSPRespIU; bit32 scsi_status = 0; tiDeviceHandle_t *tiDeviceHandle = agNULL; tdsaDeviceData_t *oneDeviceData = agNULL; TI_DBG6(("itdssIOCompleted: start\n")); TI_DBG6(("itdssIOCompleted: agIOInfoLen %d\n", agIOInfoLen)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; TD_ASSERT((NULL != tdIORequestBody), "itdssIOCompleted:tdIORequestBody NULL"); if ( NULL == tdIORequestBody ) // handle windows assert case { return; } Initiator->NumIOsActive--; #ifdef DBG if (tdIORequestBody->ioCompleted == agTRUE) { #ifdef TD_DEBUG_ENABLE tiDeviceHandle = tdIORequestBody->tiDevHandle; oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; #endif /*TD_DEBUG_ENABLE*/ TI_DBG1(("itdssIOCompleted: Error!!!!!! double completion\n")); #ifdef TD_DEBUG_ENABLE TI_DBG1(("itdssIOCompleted: did %d \n", oneDeviceData->id)); #endif /*TD_DEBUG_ENABLE*/ } if (Initiator->NumIOsActive == 0) { /* so far, no timer assocaicated here */ TI_DBG6(("itdssIOCompleted: no acitve IO's. Kill timers\n")); } if (tdIORequestBody->tiIORequest->osData == agNULL) { TI_DBG1( ("itdssIOCompleted: pos 1; " "tdIORequestBody->tiIORequest->osData is null, wrong\n") ); } #endif /*DBG*/ tdIORequestBody->ioCompleted = agTRUE; tdIORequestBody->ioStarted = agFALSE; /* Process completion for debugging, printing cbd */ agSASRequestBody = &(tdIORequestBody->transport.SAS.agSASRequestBody); agSSPInitiatorRequest = &(agSASRequestBody->sspInitiatorReq); TI_DBG6( ("itdssIOCompleted: CDB 0x%x\n", agSSPInitiatorRequest->sspCmdIU.cdb[0]) ); /* no respsonse or sense data; data has been processed */ if((agIOStatus == OSSA_IO_SUCCESS) && (agIOInfoLen == 0)) { // if this is a standard Inquiry command, notify Stoport to set the // device queue depth to maximize oustanding IO if ( (agSSPInitiatorRequest->sspCmdIU.cdb[0] == SCSIOPC_INQUIRY) && ((agSSPInitiatorRequest->sspCmdIU.cdb[1] & 0x01) == 0)) { bit32 qdepth = 32; tiDeviceHandle = tdIORequestBody->tiDevHandle; if( tiDeviceHandle ) { oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; if( oneDeviceData->DeviceType == TD_SAS_DEVICE ) { qdepth = MAX_OUTSTANDING_IO_PER_LUN; } if( oneDeviceData->DeviceType == TD_SATA_DEVICE ) { qdepth = 63; } } if ( ostiSetDeviceQueueDepth( tiRoot, tdIORequestBody->tiIORequest, MAX_OUTSTANDING_IO_PER_LUN ) == agFALSE ) { TI_DBG1( ( "itdssIOCompleted: failed to call " "ostiSetDeviceQueueDepth() Q=%d !!!\n", qdepth ) ); } else { TI_DBG2(("itdssIOCompleted: set ostiSetDeviceQueueDepth() Q=%d\n",qdepth)); } } // SCSI command was completed OK, this is the normal path. Now call the // OS Specific module about this completion. ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, tiIOSuccess, SCSI_STAT_GOOD, agNULL, agTRUE /* intContext; is not being used */ ); return; } else { TI_DBG6(("itdssIOCompleted: SUCCESS but data returned \n")); TI_DBG6( ("itdssIOCompleted: agIOStatus SUCCESS but data returned 0x%x\n", agIOStatus) ); if(tdIORequestBody) { tiDeviceHandle = tdIORequestBody->tiDevHandle; if(tiDeviceHandle) { oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; } } osti_memset(&agSSPRespIU, 0, sizeof(agsaSSPResponseInfoUnit_t)); saFrameReadBlock( agRoot, agParam, 0, &agSSPRespIU, sizeof(agsaSSPResponseInfoUnit_t) ); scsi_status = agSSPRespIU.status; switch (scsi_status) { case SCSI_STAT_GOOD: TI_DBG2( ("itdssIOCompleted: SCSI_STAT_GOOD %d\n", Initiator->ScsiStatusCounts.GoodStatus) ); Initiator->ScsiStatusCounts.GoodStatus++; break; case SCSI_STAT_CHECK_CONDITION: TI_DBG1( ("itdssIOCompleted: SCSI_STAT_CHECK_CONDITION %d\n", Initiator->ScsiStatusCounts.CheckCondition) ); Initiator->ScsiStatusCounts.CheckCondition++; break; case SCSI_STAT_BUSY: TI_DBG1( ("itdssIOCompleted: SCSI_STAT_BUSY %d\n", Initiator->ScsiStatusCounts.BusyStatus) ); Initiator->ScsiStatusCounts.BusyStatus++; break; case SCSI_STAT_RESV_CONFLICT: TI_DBG1( ("itdssIOCompleted: SCSI_STAT_RESV_CONFLICT %d\n", Initiator->ScsiStatusCounts.ResvConflict) ); Initiator->ScsiStatusCounts.ResvConflict++; break; case SCSI_STAT_TASK_SET_FULL: Initiator->ScsiStatusCounts.TaskSetFull++; //agIOStatus = OSSA_IO_FAILED; //agOtherInfo = tiDetailBusy; TI_DBG1( ("itdssIOCompleted: SCSI_STAT_TASK_SET_FULL %d\n", Initiator->ScsiStatusCounts.TaskSetFull) ); break; case SCSI_STAT_ACA_ACTIVE: Initiator->ScsiStatusCounts.AcaActive++; TI_DBG1( ("itdssIOCompleted: SCSI_STAT_ACA_ACTIVE %d\n", Initiator->ScsiStatusCounts.AcaActive) ); break; case SCSI_STAT_TASK_ABORTED: Initiator->ScsiStatusCounts.TaskAborted++; TI_DBG1( ("itdssIOCompleted: SCSI_STAT_TASK_ABORTED %d\n", Initiator->ScsiStatusCounts.TaskAborted) ); break; case SCSI_STAT_CONDITION_MET: Initiator->ScsiStatusCounts.ConditionMet++; TI_DBG1( ("itdssIOCompleted: SCSI_STAT_CONDITION_MET %d\n", Initiator->ScsiStatusCounts.ConditionMet) ); break; case SCSI_STAT_INTERMEDIATE: TI_DBG1( ("itdssIOCompleted: SCSI_STAT_INTERMEDIATE %d\n", Initiator->ScsiStatusCounts.ObsoleteStatus) ); Initiator->ScsiStatusCounts.ObsoleteStatus++; break; case SCSI_STAT_INTER_CONDIT_MET: TI_DBG1( ("itdssIOCompleted: SCSI_STAT_INTER_CONDIT_MET %d\n", Initiator->ScsiStatusCounts.ObsoleteStatus) ); Initiator->ScsiStatusCounts.ObsoleteStatus++; break; case SCSI_STAT_COMMANDTERMINATED: TI_DBG1( ("itdssIOCompleted: SCSI_STAT_COMMANDTERMINATED %d\n", Initiator->ScsiStatusCounts.ObsoleteStatus) ); Initiator->ScsiStatusCounts.ObsoleteStatus++; break; default: Initiator->ScsiStatusCounts.ObsoleteStatus++; TI_DBG1( ("itdssIOCompleted: Unknown scsi_status %d 0x%x\n", scsi_status,Initiator->ScsiStatusCounts.ObsoleteStatus) ); } switch (agIOStatus) { case OSSA_IO_SUCCESS: itdssIOSuccessHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_ABORTED: itdssIOAbortedHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_UNDERFLOW: itdssIOUnderFlowHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_FAILED: itdssIOFailedHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_ABORT_RESET: itdssIOAbortResetHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_NO_DEVICE: itdssIONoDeviceHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_XFER_ERROR_BREAK: itdssXferErrorBreakHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_XFER_ERROR_PHY_NOT_READY: itdssXferErrorPhyNotReadyHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: itdssOpenCnxErrorProtocolNotSupprotedHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION: itdssOpenCnxErrorZoneViolationHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_BREAK: itdssOpenCnxErrorBreakHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: itdssOpenCnxErrorITNexusLossHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION: itdssOpenCnxErrorBadDestinationHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: itdssOpenCnxErrorConnectionRateNotSupportedHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION: itdssOpenCnxErrorWrongDestinationHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR: itdssOpenCnxErrorUnknownErrorHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_XFER_ERROR_NAK_RECEIVED: itdssXferErrorNAKReceivedHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_XFER_ERROR_ACK_NAK_TIMEOUT: itdssXferErrorACKNAKTimeoutHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_XFER_ERROR_DMA: itdssXferErrorDMAHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_XFER_ERROR_OFFSET_MISMATCH: itdssXferErrorOffsetMismatchHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_XFER_OPEN_RETRY_TIMEOUT: itdssXferOpenRetryTimeoutHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_PORT_IN_RESET: itdssPortInResetHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_DS_NON_OPERATIONAL: itdssDsNonOperationalHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_DS_IN_RECOVERY: itdssDsInRecoveryHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_TM_TAG_NOT_FOUND: itdssTmTagNotFoundHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_SSP_EXT_IU_ZERO_LEN_ERROR: itdssSSPExtIUZeroLenHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_XFER_ERROR_UNEXPECTED_PHASE: itdssXferErrorUnexpectedPhaseHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; //new case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: itdssXferOpenRetryBackoffThresholdReachedHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO: itdssOpenCnxErrorItNexusLossOpenTmoHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: itdssOpenCnxErrorItNexusLossNoDestHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: itdssOpenCnxErrorItNexusLossOpenCollideHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: itdssOpenCnxErrorItNexusLossOpenPathwayBlockedHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; // encryption IO error handling case OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS: case OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH: case OSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID: case OSSA_IO_XFR_ERROR_DEK_IV_MISMATCH: case OSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR: case OSSA_IO_XFR_ERROR_INTERNAL_RAM: case OSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS: itdssEncryptionHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; /* DIF IO error handling */ case OSSA_IO_XFR_ERROR_DIF_MISMATCH: case OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH: case OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH: case OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH: itdssDifHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE: itdssIOResourceUnavailableHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_MPI_IO_RQE_BUSY_FULL: itdssIORQEBusyFullHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_XFR_ERROR_INVALID_SSP_RSP_FRAME: itdssXferErrorInvalidSSPRspFrameHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_XFER_ERR_EOB_DATA_OVERRUN: itdssXferErrorEOBDataOverrunHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; case OSSA_IO_OPEN_CNX_ERROR_OPEN_PREEMPTED: itdssOpenCnxErrorOpenPreemptedHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; default: TI_DBG1( ("itdssIOCompleted: Unknown agIOStatus 0x%x\n",agIOStatus) ); itdssIODefaultHandler( agRoot, agIORequest, agIOStatus, agIOInfoLen, agParam, agOtherInfo ); break; } } return; } #ifdef TD_DISCOVER /***************************************************************************** *! \brief itdssSMPCompleted * * Purpose: This routine is called to complete an SMP request previously * issued to the LL Layer in saSMPStart(). * * \param agRoot: Pointer to driver Instance. * \param agIORequest: Pointer to the I/O Request data structure for * this I/O. * \param agIOStatus: Status of I/O just completed. * \param agIOInfoLen: Length of the I/O information associated with this * I/O request * \param agFrameHandle A Handle used to refer to the response frame * * \return: None * * \note - This is a initiator specific function called by the jump table. * *****************************************************************************/ osGLOBAL void itdssSMPCompleted ( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, agsaFrameHandle_t agFrameHandle ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; #ifdef REMOVED tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData; tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared); #endif tdssSMPRequestBody_t *tdSMPRequestBody; agsaSASRequestBody_t *agSASRequestBody; agsaSMPFrame_t *agSMPFrame; tdsaDeviceData_t *oneDeviceData; tiIORequest_t *CurrentTaskTag; tdsaPortContext_t *onePortContext; tdsaPortContext_t *oldonePortContext; smpReqPhyControl_t *smpPhyControlReq; bit8 smpHeader[4]; tdssSMPFrameHeader_t *tdSMPFrameHeader; bit8 *tdSMPPayload; agsaDevHandle_t *agDevHandle; bit32 status; #ifndef DIRECT_SMP tdssSMPFrameHeader_t *tdRequestSMPFrameHeader; bit8 smpRequestHeader[4]; #endif bit8 SMPRequestFunction; TI_DBG3(("itdssSMPCompleted: start\n")); tdSMPRequestBody = (tdssSMPRequestBody_t *)agIORequest->osData; CurrentTaskTag = tdSMPRequestBody->CurrentTaskTag; oneDeviceData = tdSMPRequestBody->tdDevice; onePortContext = oneDeviceData->tdPortContext; agDevHandle = oneDeviceData->agDevHandle; agSASRequestBody = &(tdSMPRequestBody->agSASRequestBody); agSMPFrame = &(agSASRequestBody->smpFrame); #ifdef DIRECT_SMP SMPRequestFunction = tdSMPRequestBody->smpPayload[1]; #else saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 0, smpRequestHeader, 4); tdRequestSMPFrameHeader = (tdssSMPFrameHeader_t *)smpRequestHeader; SMPRequestFunction = tdRequestSMPFrameHeader->smpFunction; #endif TI_DBG3(("itdssSMPCompleted: agIORequest %p\n", agIORequest)); TI_DBG3(("itdssSMPCompleted: SMPRequestbody %p\n", tdSMPRequestBody)); if (onePortContext != agNULL) { TI_DBG3(("itdssSMPCompleted: pid %d\n", onePortContext->id)); } else { TI_DBG1(("itdssSMPCompleted: Wrong!!! onePortContext is NULL\n")); ostiFreeMemory( tiRoot, tdSMPRequestBody->osMemHandle, sizeof(tdssSMPRequestBody_t) ); #ifndef DIRECT_SMP ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPReqosMemHandle, tdSMPRequestBody->IndirectSMPReqLen ); ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPResposMemHandle, tdSMPRequestBody->IndirectSMPRespLen ); #endif return; } oldonePortContext = tdSMPRequestBody->tdPortContext; if (oldonePortContext != agNULL) { TI_DBG3(("itdssSMPCompleted: old pid %d\n", oldonePortContext->id)); } else { TI_DBG1(("itdssSMPCompleted: Wrong!!! oldonePortContext is NULL\n")); ostiFreeMemory( tiRoot, tdSMPRequestBody->osMemHandle, sizeof(tdssSMPRequestBody_t) ); #ifndef DIRECT_SMP ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPReqosMemHandle, tdSMPRequestBody->IndirectSMPReqLen ); ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPResposMemHandle, tdSMPRequestBody->IndirectSMPRespLen ); #endif return; } /* decrement the number of pending SMP */ onePortContext->discovery.pendingSMP--; /* for port invalid case; full discovery -> full discovery; incremental discovery -> full discovery */ if (onePortContext != oldonePortContext) { TI_DBG1(("itdssSMPCompleted: portcontext has changed!!!\n")); if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || SMPRequestFunction == SMP_REPORT_PHY_SATA || SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION ) { /* stop SMP timer */ if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) { tdsaKillTimer( tiRoot, &(onePortContext->discovery.DiscoverySMPTimer) ); } if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) { tdsaKillTimer( tiRoot, &(oldonePortContext->discovery.DiscoverySMPTimer) ); } } /* clean up expanders data strucures; move to free exp when device is cleaned */ tdsaCleanAllExp(tiRoot, oldonePortContext); /* remove devices */ tdssInternalRemovals(oldonePortContext->agRoot, oldonePortContext ); ostiFreeMemory( tiRoot, tdSMPRequestBody->osMemHandle, sizeof(tdssSMPRequestBody_t) ); #ifndef DIRECT_SMP ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPReqosMemHandle, tdSMPRequestBody->IndirectSMPReqLen ); ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPResposMemHandle, tdSMPRequestBody->IndirectSMPRespLen ); #endif return; } if (onePortContext->valid == agFALSE) { if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || SMPRequestFunction == SMP_REPORT_PHY_SATA || SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION ) { /* stop SMP timer */ if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) { tdsaKillTimer( tiRoot, &(onePortContext->discovery.DiscoverySMPTimer) ); } if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) { tdsaKillTimer( tiRoot, &(oldonePortContext->discovery.DiscoverySMPTimer) ); } } if (onePortContext->discovery.pendingSMP == 0) { TI_DBG1(("itdssSMPCompleted: aborting discovery\n")); tdsaSASDiscoverAbort(tiRoot, onePortContext); } else { TI_DBG1(("itdssSMPCompleted: not yet abort; non zero pendingSMP %d\n", onePortContext->discovery.pendingSMP)); } ostiFreeMemory( tiRoot, tdSMPRequestBody->osMemHandle, sizeof(tdssSMPRequestBody_t) ); #ifndef DIRECT_SMP ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPReqosMemHandle, tdSMPRequestBody->IndirectSMPReqLen ); ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPResposMemHandle, tdSMPRequestBody->IndirectSMPRespLen ); #endif return; } if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || SMPRequestFunction == SMP_REPORT_PHY_SATA || SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION ) { /* stop SMP timer */ if (onePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) { tdsaKillTimer( tiRoot, &(onePortContext->discovery.DiscoverySMPTimer) ); } if (oldonePortContext->discovery.DiscoverySMPTimer.timerRunning == agTRUE) { tdsaKillTimer( tiRoot, &(oldonePortContext->discovery.DiscoverySMPTimer) ); } } /* the host as of 4/16/08 does not use indirect SMP. So, check only OSSA_IO_SUCCESS status*/ if (agIOStatus == OSSA_IO_SUCCESS) { //tdhexdump("itdssSMPCompleted", (bit8*)agFrameHandle, agIOInfoLen); /* parsing SMP payload */ #ifdef DIRECT_SMP saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4); #else saFrameReadBlock(agRoot, tdSMPRequestBody->IndirectSMPResp, 0, smpHeader, 4); #endif tdSMPFrameHeader = (tdssSMPFrameHeader_t *)smpHeader; /* SMP function dependent payload */ switch (tdSMPFrameHeader->smpFunction) { case SMP_REPORT_GENERAL: TI_DBG3(("itdssSMPCompleted: report general\n")); if (agIOInfoLen != sizeof(smpRespReportGeneral_t) + 4 && tdSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) { TI_DBG1(("itdssSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespReportGeneral_t) + 4)); tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); ostiFreeMemory( tiRoot, tdSMPRequestBody->osMemHandle, sizeof(tdssSMPRequestBody_t) ); #ifndef DIRECT_SMP ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPReqosMemHandle, tdSMPRequestBody->IndirectSMPReqLen ); ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPResposMemHandle, tdSMPRequestBody->IndirectSMPRespLen ); #endif return; } tdsaReportGeneralRespRcvd( tiRoot, agRoot, agIORequest, oneDeviceData, tdSMPFrameHeader, agFrameHandle ); break; case SMP_DISCOVER: TI_DBG3(("itdssSMPCompleted: discover\n")); if (agIOInfoLen != sizeof(smpRespDiscover_t) + 4 && tdSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) { TI_DBG1(("itdssSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespDiscover_t) + 4)); tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); ostiFreeMemory( tiRoot, tdSMPRequestBody->osMemHandle, sizeof(tdssSMPRequestBody_t) ); #ifndef DIRECT_SMP ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPReqosMemHandle, tdSMPRequestBody->IndirectSMPReqLen ); ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPResposMemHandle, tdSMPRequestBody->IndirectSMPRespLen ); #endif return; } tdsaDiscoverRespRcvd( tiRoot, agRoot, agIORequest, oneDeviceData, tdSMPFrameHeader, agFrameHandle ); break; case SMP_REPORT_PHY_SATA: TI_DBG3(("itdssSMPCompleted: report phy sata\n")); if (agIOInfoLen != sizeof(smpRespReportPhySata_t) + 4 && tdSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) { TI_DBG1(("itdssSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, (unsigned int)sizeof(smpRespReportPhySata_t) + 4)); tdsaSATADiscoverDone(tiRoot, onePortContext, tiError); ostiFreeMemory( tiRoot, tdSMPRequestBody->osMemHandle, sizeof(tdssSMPRequestBody_t) ); #ifndef DIRECT_SMP ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPReqosMemHandle, tdSMPRequestBody->IndirectSMPReqLen ); ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPResposMemHandle, tdSMPRequestBody->IndirectSMPRespLen ); #endif return; } tdsaReportPhySataRcvd( tiRoot, agRoot, agIORequest, oneDeviceData, tdSMPFrameHeader, agFrameHandle ); break; case SMP_CONFIGURE_ROUTING_INFORMATION: TI_DBG1(("itdssSMPCompleted: configure routing information\n")); if (agIOInfoLen != 4 && tdSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) { TI_DBG1(("itdssSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4)); tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); ostiFreeMemory( tiRoot, tdSMPRequestBody->osMemHandle, sizeof(tdssSMPRequestBody_t) ); #ifndef DIRECT_SMP ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPReqosMemHandle, tdSMPRequestBody->IndirectSMPReqLen ); ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPResposMemHandle, tdSMPRequestBody->IndirectSMPRespLen ); #endif return; } tdsaConfigRoutingInfoRespRcvd( tiRoot, agRoot, agIORequest, oneDeviceData, tdSMPFrameHeader, agFrameHandle ); break; case SMP_PHY_CONTROL: TI_DBG3(("itdssSMPCompleted: phy control\n")); if (agIOInfoLen != 4 && tdSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) /*zero length is expected */ { TI_DBG1(("itdssSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4)); tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); ostiFreeMemory( tiRoot, tdSMPRequestBody->osMemHandle, sizeof(tdssSMPRequestBody_t) ); #ifndef DIRECT_SMP ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPReqosMemHandle, tdSMPRequestBody->IndirectSMPReqLen ); ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPResposMemHandle, tdSMPRequestBody->IndirectSMPRespLen ); #endif return; } tdsaPhyControlRespRcvd( tiRoot, agRoot, agIORequest, oneDeviceData, tdSMPFrameHeader, agFrameHandle, CurrentTaskTag ); break; #ifdef REMOVED //temp for testing case SMP_REPORT_MANUFACTURE_INFORMATION: TI_DBG1(("itdssSMPCompleted: REPORT_MANUFACTURE_INFORMATION\n")); if (agIOInfoLen != sizeof(smpRespReportManufactureInfo_t) + 4 && tdSMPFrameHeader->smpFunctionResult == SMP_FUNCTION_ACCEPTED) /*zero length is expected */ { TI_DBG1(("itdssSMPCompleted: mismatch len agIOInfoLen 0x%x 0x%x\n", agIOInfoLen, 4)); tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); ostiFreeMemory( tiRoot, tdSMPRequestBody->osMemHandle, sizeof(tdssSMPRequestBody_t) ); #ifndef DIRECT_SMP ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPReqosMemHandle, tdSMPRequestBody->IndirectSMPReqLen ); ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPResposMemHandle, tdSMPRequestBody->IndirectSMPRespLen ); #endif return; } tdsaReportManInfoRespRcvd( tiRoot, agRoot, oneDeviceData, tdSMPFrameHeader, agFrameHandle ); break; //end temp for testing #endif case SMP_REPORT_ROUTING_INFORMATION: case SMP_REPORT_PHY_ERROR_LOG: case SMP_PHY_TEST_FUNCTION: case SMP_REPORT_MANUFACTURE_INFORMATION: case SMP_READ_GPIO_REGISTER: case SMP_WRITE_GPIO_REGISTER: default: TI_DBG1(("itdssSMPCompleted: wrong SMP function 0x%x\n", tdSMPFrameHeader->smpFunction)); TI_DBG1(("itdssSMPCompleted: smpFrameType 0x%x\n", tdSMPFrameHeader->smpFrameType)); TI_DBG1(("itdssSMPCompleted: smpFunctionResult 0x%x\n", tdSMPFrameHeader->smpFunctionResult)); TI_DBG1(("itdssSMPCompleted: smpReserved 0x%x\n", tdSMPFrameHeader->smpReserved)); tdhexdump("itdssSMPCompleted: SMP payload", (bit8 *)agFrameHandle, agIOInfoLen); break; } } else if (agIOStatus == OSSA_IO_ABORTED || agIOStatus == OSSA_IO_INVALID_LENGTH) { /* no retry this case */ TI_DBG1(("itdssSMPCompleted: OSSA_IO_ABORTED\n")); } else if (agIOStatus == OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE) { TI_DBG1(("itdssSMPCompleted: OSSA_IO_ERROR_INTERNAL_SMP_RESOURCE\n")); saFrameReadBlock(agRoot, agFrameHandle, 0, smpHeader, 4); tdSMPFrameHeader = (tdssSMPFrameHeader_t *)smpHeader; status = saSMPStart( agRoot, agIORequest, tdSMPRequestBody->queueNumber, //tdsaAllShared->SMPQNum, //tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, AGSA_SMP_INIT_REQ, agSASRequestBody, &ossaSMPCompleted ); if (status == AGSA_RC_SUCCESS) { /* increment the number of pending SMP */ onePortContext->discovery.pendingSMP++; if (SMPRequestFunction == SMP_REPORT_GENERAL || SMPRequestFunction == SMP_DISCOVER || SMPRequestFunction == SMP_REPORT_PHY_SATA || SMPRequestFunction == SMP_CONFIGURE_ROUTING_INFORMATION ) { /* start discovery-related SMP timer */ tdsaDiscoverySMPTimer(tiRoot, onePortContext, (bit32)(tdSMPFrameHeader->smpFunction), tdSMPRequestBody); } return; } else if (status == AGSA_RC_BUSY) { if (tdSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || tdSMPFrameHeader->smpFunction == SMP_DISCOVER || tdSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || tdSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION ) { tdsaSMPBusyTimer(tiRoot, onePortContext, oneDeviceData, tdSMPRequestBody); } else if (tdSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) { /* For taskmanagement SMP, let's fail task management failure */ tdsaPhyControlFailureRespRcvd( tiRoot, agRoot, oneDeviceData, tdSMPFrameHeader, agFrameHandle, CurrentTaskTag ); } else { } } else /* AGSA_RC_FAILURE */ { if (tdSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || tdSMPFrameHeader->smpFunction == SMP_DISCOVER || tdSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || tdSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION ) { tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); } else if (tdSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) { /* task management failure */ tdsaPhyControlFailureRespRcvd( tiRoot, agRoot, oneDeviceData, tdSMPFrameHeader, agFrameHandle, CurrentTaskTag ); } else { } } } else { if (tdSMPRequestBody->retries < SMP_RETRIES) /* 5 */ { /* retry the SMP again */ TI_DBG1(("itdssSMPCompleted: failed! but retries %d agIOStatus 0x%x %d agIOInfoLen %d\n", tdSMPRequestBody->retries, agIOStatus, agIOStatus, agIOInfoLen)); 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 ) { saSetDeviceState(agRoot, agNULL, tdSMPRequestBody->queueNumber, agDevHandle, SA_DS_OPERATIONAL); } saSMPStart( agRoot, agIORequest, tdSMPRequestBody->queueNumber, //tdsaAllShared->SMPQNum, //tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, AGSA_SMP_INIT_REQ, agSASRequestBody, &ossaSMPCompleted ); /* increment the number of pending SMP */ onePortContext->discovery.pendingSMP++; tdSMPRequestBody->retries++; return; } else { tdSMPFrameHeader = (tdssSMPFrameHeader_t *)agSMPFrame->outFrameBuf; tdSMPPayload = (bit8 *)agSMPFrame->outFrameBuf + 4; TI_DBG1(("itdssSMPCompleted: failed! no more retry! agIOStatus 0x%x %d\n", agIOStatus, agIOStatus)); if (agIOStatus == OSSA_IO_DS_NON_OPERATIONAL) { TI_DBG1(("itdssSMPCompleted: failed! agIOStatus is OSSA_IO_DS_NON_OPERATIONAL\n")); } if (agIOStatus == OSSA_IO_DS_IN_RECOVERY) { TI_DBG1(("itdssSMPCompleted: failed! agIOStatus is OSSA_IO_DS_IN_RECOVERY\n")); } if (tdSMPFrameHeader->smpFunction == SMP_REPORT_GENERAL || tdSMPFrameHeader->smpFunction == SMP_DISCOVER || tdSMPFrameHeader->smpFunction == SMP_REPORT_PHY_SATA || tdSMPFrameHeader->smpFunction == SMP_CONFIGURE_ROUTING_INFORMATION ) { /* discovery failure */ TI_DBG1(("itdssSMPCompleted: SMP function 0x%x\n", tdSMPFrameHeader->smpFunction)); TI_DBG1(("itdssSMPCompleted: discover done with error\n")); tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); } else if (tdSMPFrameHeader->smpFunction == SMP_PHY_CONTROL) { TI_DBG1(("itdssSMPCompleted: SMP_PHY_CONTROL\n")); smpPhyControlReq = (smpReqPhyControl_t *)tdSMPPayload; if (smpPhyControlReq->phyOperation == SMP_PHY_CONTROL_CLEAR_AFFILIATION) { TI_DBG1(("itdssSMPCompleted: discover done with error\n")); tdsaSASDiscoverDone(tiRoot, onePortContext, tiError); } else if (smpPhyControlReq->phyOperation == SMP_PHY_CONTROL_HARD_RESET || smpPhyControlReq->phyOperation == SMP_PHY_CONTROL_LINK_RESET ) { TI_DBG1(("itdssSMPCompleted: device reset failed\n")); if (CurrentTaskTag != agNULL ) { TI_DBG1(("itdssSMPCompleted: callback to OS layer with failure\n")); ostiInitiatorEvent( tiRoot, NULL, NULL, tiIntrEventTypeTaskManagement, tiTMFailed, CurrentTaskTag ); } else { /* hard reset was not done with this device */ oneDeviceData->ResetCnt = 0; } } else { TI_DBG1(("itdssSMPCompleted: unknown phy operation 0x%x\n", smpPhyControlReq->phyOperation)); } } /* SMP_PHY_CONTROL */ else { TI_DBG1(("itdssSMPCompleted: SMP function 0x%x\n", tdSMPFrameHeader->smpFunction)); } } /* else */ } /* outer else */ ostiFreeMemory( tiRoot, tdSMPRequestBody->osMemHandle, sizeof(tdssSMPRequestBody_t) ); #ifndef DIRECT_SMP ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPReqosMemHandle, tdSMPRequestBody->IndirectSMPReqLen ); ostiFreeMemory( tiRoot, tdSMPRequestBody->IndirectSMPResposMemHandle, tdSMPRequestBody->IndirectSMPRespLen ); #endif return; } #else osGLOBAL void itdssSMPCompleted ( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, agsaFrameHandle_t agFrameHandle ) { /* pass the payload to OS layer */ TI_DBG3(("itdssSMPCompleted: start\n")); } #endif /***************************************************************************** *! \brief itdIoSuccessHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_SUCCESS * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIOSuccessHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; itdsaIni_t *Initiator = (itdsaIni_t *)osData->itdsaIni; tdIORequestBody_t *tdIORequestBody; agsaSSPResponseInfoUnit_t agSSPRespIU; tiSenseData_t senseData; bit8 senseDataPayload[256]; bit8 respData[128]; bit32 scsi_status; bit32 senseLen; bit32 respLen; bit32 data_status; bit32 i; tiDeviceHandle_t *tiDeviceHandle = agNULL; tdsaDeviceData_t *oneDeviceData = agNULL; TI_DBG2(("itdssIOSuccessHandler: start\n")); TI_DBG2(("itdssIOSuccessHandler: agIOInfoLen %d\n", agIOInfoLen)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; tdIORequestBody->ioCompleted = agTRUE; tdIORequestBody->ioStarted = agFALSE; /* agIOInfoLen must be >= sizeof(agsaSSPResponseInfoUnit_t), which is minimum date length */ if (agIOInfoLen < sizeof(agsaSSPResponseInfoUnit_t)) { TI_DBG1(("itdssIOSuccessHandler: First agIOInfoLen does not match!!!\n")); TI_DBG1(("itdssIOSuccessHandler: First agIOInfoLen 0x%x IU 0x%x\n", agIOInfoLen, (unsigned int)sizeof(agsaSSPResponseInfoUnit_t))); ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, /* tiIORequest */ tiIOFailed, tiDetailOtherError, agNULL, agTRUE /* intContext; is not being used */ ); return; } /* reads agsaSSPResponseInfoUnit_t */ saFrameReadBlock(agRoot, agParam, 0, &agSSPRespIU, sizeof(agsaSSPResponseInfoUnit_t)); data_status = SA_SSPRESP_GET_DATAPRES(&agSSPRespIU); scsi_status = agSSPRespIU.status; /* endianess is invovled here */ senseLen = SA_SSPRESP_GET_SENSEDATALEN(&agSSPRespIU); respLen = SA_SSPRESP_GET_RESPONSEDATALEN(&agSSPRespIU); TI_DBG2(("itdssIOSuccessHandler: dataPres=%x\n", data_status)); TI_DBG2(("itdssIOSuccessHandler: scsi status=0x%x, senselen=0x%x resplen 0x%x\n", scsi_status, senseLen, respLen)); /* sanity check: do not go beyond of agIOInfoLen. if happens, return error agIOInfoLen >= sizeof(agsaSSPResponseInfoUnit_t) + senseLen + respLen -> OK because frame must be divisible by 4, so there can be extra padding agIOInfoLen < sizeof(agsaSSPResponseInfoUnit_t) + senseLen + respLen -> NOT OK */ if (agIOInfoLen < sizeof(agsaSSPResponseInfoUnit_t) + senseLen + respLen) { TI_DBG1(("itdssIOSuccessHandler: Second agIOInfoLen does not match!!!\n")); TI_DBG1(("itdssIOSuccessHandler: Second agIOInfoLen 0x%x IU 0x%x senselen 0x%x resplen 0x%x\n", agIOInfoLen, (unsigned int)sizeof(agsaSSPResponseInfoUnit_t), senseLen, respLen)); ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, /* tiIORequest */ tiIOFailed, tiDetailOtherError, agNULL, agTRUE /* intContext; is not being used */ ); return; } /* reads response data */ saFrameReadBlock(agRoot, agParam, sizeof(agsaSSPResponseInfoUnit_t), respData, respLen); /* reads sense data */ saFrameReadBlock(agRoot, agParam, sizeof(agsaSSPResponseInfoUnit_t) + respLen, senseDataPayload, senseLen); if (data_status == 0) { /* NO_DATA */ TI_DBG1(("itdssIOSuccessHandler: no data scsi_status 0x%x\n",scsi_status)); ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, /* tiIORequest */ tiIOSuccess, scsi_status, agNULL, agTRUE /* intContext; is not being used */ ); return; } if (data_status == 1) { /* RESPONSE_DATA */ TI_DBG1(("itdssIOSuccessHandler: response data \n")); ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, /* tiIORequest */ tiIOSuccess, 0, agNULL, agTRUE /* intContext; is not being used */ ); return; } if (data_status == 2) { /* SENSE_DATA */ TI_DBG2(("itdssIOSuccessHandler: sense data \n")); senseData.senseData = &senseDataPayload; senseData.senseLen = MIN(256, senseLen); /* debugging */ tdhexdump("ResponseIU I", (bit8 *)&agSSPRespIU, sizeof(agsaSSPResponseInfoUnit_t)); tiDeviceHandle = tdIORequestBody->tiDevHandle; oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; TI_DBG1(("sense data Sense Key 0x%2X ASC(Code) 0x%2X ASCQ(Qualifier) 0x%2X, did 0x%x\n",*(senseDataPayload+ 2),*(senseDataPayload + 12),*(senseDataPayload + 13), oneDeviceData->id)); tdhexdump("sense data I", (bit8 *)senseDataPayload, senseLen); // tdhexdump("sense data II", (bit8 *)senseData.senseData, senseData.senseLen); if (senseDataPayload[2] == SCSI_SENSE_KEY_RECOVERED_ERROR) { Initiator->SenseKeyCounter.SoftError ++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_NOT_READY) { Initiator->SenseKeyCounter.MediumNotReady++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_MEDIUM_ERROR) { Initiator->SenseKeyCounter.MediumError++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_HARDWARE_ERROR) { Initiator->SenseKeyCounter.HardwareError++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_ILLEGAL_REQUEST) { Initiator->SenseKeyCounter.IllegalRequest++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_UNIT_ATTENTION) { Initiator->SenseKeyCounter.UnitAttention++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_ABORTED_COMMAND) { Initiator->SenseKeyCounter.AbortCommand++; } else { Initiator->SenseKeyCounter.OtherKeyType++; } /* when ASQ and ASCQ 0x04 0x11, does saLocalPhyControl for notify spinup */ if ((senseDataPayload[12] == 0x04 && senseDataPayload[13] == 0x11)) { TI_DBG2(("itdssIOSuccessHandler: sending notfify spinup\n")); tiDeviceHandle = tdIORequestBody->tiDevHandle; oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; if (oneDeviceData->directlyAttached == agTRUE) { for (i=0;iphyID, AGSA_PHY_NOTIFY_ENABLE_SPINUP, agNULL); } } } ostiInitiatorIOCompleted( tiRoot, /* tiIORequest */ tdIORequestBody->tiIORequest, tiIOSuccess, scsi_status, &senseData, agTRUE /* intContext; is not being used */ ); return; } if (data_status == 3) { /* RESERVED */ TI_DBG1(("itdssIOSuccessHandler: reserved wrong!!!\n")); ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, /* tiIORequest */ tiIOFailed, scsi_status, agNULL, agTRUE /* intContext; is not being used */ ); return; } } /***************************************************************************** *! \brief itdssIOAbortedHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_ABORTED * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ /* see itdosIOCompleted() and itdinit.c and itdIoAbortedHandler in itdio.c*/ osGLOBAL void itdssIOAbortedHandler ( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; tiDeviceHandle_t *tiDeviceHandle = agNULL; tdsaDeviceData_t *oneDeviceData = agNULL; TI_DBG2(("itdssIOAbortedHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; if (agIOStatus != OSSA_IO_ABORTED) { TI_DBG1(("itdssIOAbortedHandler: incorrect agIOStatus 0x%x\n", agIOStatus)); } if (tdIORequestBody == agNULL) { TI_DBG1(("itdssIOAbortedHandler: start\n")); return; } if (tdIORequestBody != agNULL) { tiDeviceHandle = tdIORequestBody->tiDevHandle; } if (tiDeviceHandle != agNULL) { oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; } if (oneDeviceData != agNULL) { TI_DBG2(("itdssIOAbortedHandler: did %d \n", oneDeviceData->id)); } else { TI_DBG1(("itdssIOAbortedHandler: oneDeviceData is NULL\n")); } ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailAborted, agNULL, intContext ); return; } #ifdef REMOVED /***************************************************************************** *! \brief itdssIOOverFlowHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OVERFLOW * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \return: None * * *****************************************************************************/ osGLOBAL void itdssIOOverFlowHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssIOOverFlowHandler: start\n")); TI_DBG2(("itdssIOOverFlowHandler: not transferred byte 0x%x\n", agIOInfoLen)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOOverRun, agIOInfoLen, agNULL, intContext ); return; } #endif /***************************************************************************** *! \brief itdssIOUnderFlowHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_UNDERFLOW * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIOUnderFlowHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG6(("itdssIOUnderFlowHandler: start\n")); TI_DBG6(("itdssIOUnderFlowHandler: agIOInfoLen 0x%x\n", agIOInfoLen)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOUnderRun, agIOInfoLen, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssIOFailedHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_FAILED * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIOFailedHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssIOFailedHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssIOAbortResetHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_ABORT_RESET * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIOAbortResetHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssIOAbortResetHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailAbortReset, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssIONotValidHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_NOT_VALID * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIONotValidHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssIONotValidHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailNotValid, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssIONoDeviceHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_NO_DEVICE * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIONoDeviceHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssIONoDeviceHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailNoLogin, agNULL, intContext ); return; } #ifdef REMOVED /* to do: removed from spec */ /***************************************************************************** *! \brief itdssIllegalParameterHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_ILLEGAL_PARAMETER * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \return: None * * *****************************************************************************/ osGLOBAL void itdssIllegalParameterHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssIllegalParameterHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } #endif /***************************************************************************** *! \brief itdssLinkFailureHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_LINK_FAILURE * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssLinkFailureHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssLinkFailureHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssProgErrorHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_PROG_ERROR * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssProgErrorHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssProgErrorHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorBreakHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_BREAK * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorBreakHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssXferErrorBreakHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorPhyNotReadyHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_PHY_NOT_READY * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorPhyNotReadyHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssXferErrorPhyNotReadyHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorProtocolNotSupprotedHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorProtocolNotSupprotedHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssOpenCnxErrorProtocolNotSupprotedHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorZoneViolationHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorZoneViolationHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssOpenCnxErrorZoneViolationHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorBreakHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_BREAK * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorBreakHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssOpenCnxErrorBreakHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorITNexusLossHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorITNexusLossHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssOpenCnxErrorITNexusLossHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorBadDestinationHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorBadDestinationHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssOpenCnxErrorBadDestinationHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorConnectionRateNotSupportedHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorConnectionRateNotSupportedHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { 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; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; agsaDevHandle_t *agDevHandle = agNULL; tiDeviceHandle_t *tiDeviceHandle = agNULL; tdsaDeviceData_t *oneDeviceData = agNULL; bit32 ConnRate = SAS_CONNECTION_RATE_12_0G; agsaContext_t *agContext = agNULL; TI_DBG1(("itdssOpenCnxErrorConnectionRateNotSupportedHandler: start\n")); /* we retry by lowering link rate retry should be in ossaSetDeviceInfoCB() */ tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; tiDeviceHandle = tdIORequestBody->tiDevHandle; oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; agDevHandle = oneDeviceData->agDevHandle; if (tdsaAllShared->RateAdjust) { if (oneDeviceData->valid == agTRUE && oneDeviceData->registered == agTRUE && oneDeviceData->tdPortContext != agNULL ) { ConnRate = DEVINFO_GET_LINKRATE(&oneDeviceData->agDeviceInfo); if (ConnRate == SAS_CONNECTION_RATE_1_5G) { /* no retry; completes IO */ ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); } else { ConnRate = ConnRate - 1; } agContext = &(tdIORequestBody->agContext); agContext->osData = agIORequest; saSetDeviceInfo(agRoot, agContext, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, 32, ConnRate << 28, ossaIniSetDeviceInfoCB); } } else { ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); } return; } /***************************************************************************** *! \brief itdssOpenCnxErrorSTPResourceBusyHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorSTPResourceBusyHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssOpenCnxErrorSTPResourceBusyHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorWrongDestinationHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorWrongDestinationHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssOpenCnxErrorWrongDestinationHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorUnknownErrorHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorUnknownErrorHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssOpenCnxErrorUnknownErrorHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorNAKReceivedHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_NAK_RECEIVED * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorNAKReceivedHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssXferErrorNAKReceivedHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorACKNAKTimeoutHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_ACK_NAK_TIMEOUT * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorACKNAKTimeoutHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssXferErrorACKNAKTimeoutHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorPeerAbortedHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_PEER_ABORTED * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorPeerAbortedHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssXferErrorPeerAbortedHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorRxFrameHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_RX_FRAME * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorRxFrameHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssXferErrorRxFrameHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorDMAHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_DMA * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorDMAHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssXferErrorDMAHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherErrorNoRetry, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorCreditTimeoutHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_CREDIT_TIMEOUT * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorCreditTimeoutHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssXferErrorCreditTimeoutHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorCMDIssueACKNAKTimeoutHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorCMDIssueACKNAKTimeoutHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssXferErrorCMDIssueACKNAKTimeoutHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorCMDIssueBreakBeforeACKNAKHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_CMD_ISSUE_BREAK_BEFORE_ACK_NAK * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorCMDIssueBreakBeforeACKNAKHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssXferErrorCMDIssueBreakBeforeACKNAKHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorCMDIssuePhyDownBeforeACKNAKHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_CMD_ISSUE_PHY_DOWN_BEFORE_ACK_NAK * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorCMDIssuePhyDownBeforeACKNAKHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssXferErrorCMDIssuePhyDownBeforeACKNAKHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorDisruptedPhyDownHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_DISRUPTED_PHY_DOWN * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorDisruptedPhyDownHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssXferErrorDisruptedPhyDownHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorOffsetMismatchHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_OFFSET_MISMATCH * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorOffsetMismatchHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssXferErrorOffsetMismatchHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorXferZeroDataLenHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_XFER_ZERO_DATA_LEN * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorXferZeroDataLenHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssXferErrorXferZeroDataLenHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferOpenRetryTimeoutHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_OPEN_RETRY_TIMEOUT * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferOpenRetryTimeoutHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { 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; itdsaIni_t *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; agsaDevHandle_t *agDevHandle = agNULL; tiDeviceHandle_t *tiDeviceHandle = agNULL; tdsaDeviceData_t *oneDeviceData = agNULL; bit32 saStatus = AGSA_RC_FAILURE; TI_DBG2(("itdssXferOpenRetryTimeoutHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; tiDeviceHandle = tdIORequestBody->tiDevHandle; oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; agDevHandle = oneDeviceData->agDevHandle; if (oneDeviceData->valid == agTRUE && oneDeviceData->registered == agTRUE && oneDeviceData->tdPortContext != agNULL ) { if (tdIORequestBody->reTries < OPEN_RETRY_RETRIES) /* 10 */ { saStatus = saSSPStart(agRoot, agIORequest, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, tdIORequestBody->agRequestType, &(tdIORequestBody->transport.SAS.agSASRequestBody), agNULL, &ossaSSPCompleted); if (saStatus == AGSA_RC_SUCCESS) { TI_DBG2(("itdssXferOpenRetryTimeoutHandler: retried\n")); Initiator->NumIOsActive++; tdIORequestBody->ioStarted = agTRUE; tdIORequestBody->ioCompleted = agFALSE; tdIORequestBody->reTries++; return; } else { TI_DBG1(("itdssXferOpenRetryTimeoutHandler: retry failed\n")); tdIORequestBody->ioStarted = agFALSE; tdIORequestBody->ioCompleted = agTRUE; tdIORequestBody->reTries = 0; } } else { TI_DBG1(("itdssXferOpenRetryTimeoutHandler: retry is over and fail\n")); tdIORequestBody->reTries = 0; } } else { TI_DBG1(("itdssXferOpenRetryTimeoutHandler: not valid deivce no retry\n")); tdIORequestBody->reTries = 0; } ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssPortInResetHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_PORT_IN_RESET * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssPortInResetHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssPortInResetHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssDsNonOperationalHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_DS_NON_OPERATIONAL * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssDsNonOperationalHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; agsaDevHandle_t *agDevHandle = agNULL; tiDeviceHandle_t *tiDeviceHandle = agNULL; tdsaDeviceData_t *oneDeviceData = agNULL; TI_DBG2(("itdssDsNonOperationalHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; #if 1 /* TBD */ /* let's do it only once ????? */ tiDeviceHandle = tdIORequestBody->tiDevHandle; oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; agDevHandle = oneDeviceData->agDevHandle; if (oneDeviceData->valid == agTRUE && oneDeviceData->registered == agTRUE && oneDeviceData->tdPortContext != agNULL ) { saSetDeviceState(agRoot, agNULL, tdsaRotateQnumber(tiRoot, oneDeviceData), agDevHandle, SA_DS_OPERATIONAL); } #endif ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssDsInRecoveryHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_DS_IN_RECOVERY * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssDsInRecoveryHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssDsInRecoveryHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssTmTagNotFoundHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_TM_TAG_NOT_FOUND * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssTmTagNotFoundHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssTmTagNotFoundHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssSSPExtIUZeroLenHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_SSP_EXT_IU_ZERO_LEN_ERROR * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssSSPExtIUZeroLenHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssSSPExtIUZeroLenHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorUnexpectedPhaseHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERROR_UNEXPECTED_PHASE * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorUnexpectedPhaseHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssXferErrorUnexpectedPhaseHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } #ifdef REMOVED /***************************************************************************** *! \brief itdssIOUnderFlowWithChkConditionHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_UNDERFLOW_WITH_CHK_COND * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \return: None * * *****************************************************************************/ /* How to report SCSI_STAT_CHECK_CONDITION and tiIOUnderRun simultaneoulsy??? ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, tiIOSuccess, SCSI_STAT_CHECK_CONDITION, &senseData, agTRUE ); vs ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOUnderRun, agIOInfoLen, agNULL, intContext ); For now, SCSI_STAT_CHECK_CONDITION is reported until TISA changes (as of 1/6/09) In other words, this handler is the practically same as itdssIOSuccessHandler() */ osGLOBAL void itdssIOUnderFlowWithChkConditionHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; tdIORequestBody_t *tdIORequestBody; agsaSSPResponseInfoUnit_t agSSPRespIU; tiSenseData_t senseData; bit8 senseDataPayload[256]; bit8 respData[128]; bit32 scsi_status; bit32 senseLen; bit32 respLen; bit32 data_status; bit32 i; tiDeviceHandle_t *tiDeviceHandle = agNULL; tdsaDeviceData_t *oneDeviceData = agNULL; TI_DBG2(("itdssIOUnderFlowWithChkConditionHandler: start\n")); TI_DBG2(("itdssIOUnderFlowWithChkConditionHandler: agIOInfoLen 0x%x\n", agIOInfoLen)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; tdIORequestBody->ioCompleted = agTRUE; tdIORequestBody->ioStarted = agFALSE; /* agIOInfoLen must be >= sizeof(agsaSSPResponseInfoUnit_t), which is minimum date length */ if (agIOInfoLen < sizeof(agsaSSPResponseInfoUnit_t)) { TI_DBG1(("itdssIOUnderFlowWithChkConditionHandler: First agIOInfoLen does not match!!!\n")); TI_DBG1(("itdssIOUnderFlowWithChkConditionHandler: First agIOInfoLen 0x%x IU 0x%x\n", agIOInfoLen, (unsigned int)sizeof(agsaSSPResponseInfoUnit_t))); ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, /* tiIORequest */ tiIOFailed, tiDetailOtherError, agNULL, agTRUE /* intContext; is not being used */ ); return; } /* reads agsaSSPResponseInfoUnit_t */ saFrameReadBlock(agRoot, agParam, 0, &agSSPRespIU, sizeof(agsaSSPResponseInfoUnit_t)); data_status = SA_SSPRESP_GET_DATAPRES(&agSSPRespIU); scsi_status = agSSPRespIU.status; /* endianess is invovled here */ senseLen = SA_SSPRESP_GET_SENSEDATALEN(&agSSPRespIU); respLen = SA_SSPRESP_GET_RESPONSEDATALEN(&agSSPRespIU); TI_DBG2(("itdssIOUnderFlowWithChkConditionHandler: dataPres=%x\n", data_status)); TI_DBG2(("itdssIOUnderFlowWithChkConditionHandler: scsi status=0x%x, senselen=0x%x resplen 0x%x\n", scsi_status, senseLen, respLen)); /* sanity check: do not go beyond of agIOInfoLen. if happens, return error agIOInfoLen >= sizeof(agsaSSPResponseInfoUnit_t) + senseLen + respLen -> OK because frame must be divisible by 4, so there can be extra padding agIOInfoLen < sizeof(agsaSSPResponseInfoUnit_t) + senseLen + respLen -> NOT OK */ if (agIOInfoLen < sizeof(agsaSSPResponseInfoUnit_t) + senseLen + respLen) { TI_DBG1(("itdssIOUnderFlowWithChkConditionHandler: Second agIOInfoLen does not match!!!\n")); TI_DBG1(("itdssIOUnderFlowWithChkConditionHandler: Second agIOInfoLen 0x%x IU 0x%x senselen 0x%x resplen 0x%x\n", agIOInfoLen, (unsigned int)sizeof(agsaSSPResponseInfoUnit_t), senseLen, respLen)); ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, /* tiIORequest */ tiIOFailed, tiDetailOtherError, agNULL, agTRUE /* intContext; is not being used */ ); return; } /* reads response data */ saFrameReadBlock(agRoot, agParam, sizeof(agsaSSPResponseInfoUnit_t), respData, respLen); /* reads sense data */ saFrameReadBlock(agRoot, agParam, sizeof(agsaSSPResponseInfoUnit_t) + respLen, senseDataPayload, senseLen); if (data_status == 0) { /* NO_DATA */ TI_DBG2(("itdssIOUnderFlowWithChkConditionHandler: no data\n")); ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, /* tiIORequest */ tiIOSuccess, scsi_status, agNULL, agTRUE /* intContext; is not being used */ ); return; } if (data_status == 1) { /* RESPONSE_DATA */ TI_DBG2(("itdssIOUnderFlowWithChkConditionHandler: response data \n")); ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, /* tiIORequest */ tiIOSuccess, 0, agNULL, agTRUE /* intContext; is not being used */ ); return; } if (data_status == 2) { /* SENSE_DATA */ TI_DBG2(("itdssIOUnderFlowWithChkConditionHandler: sense data \n")); senseData.senseData = &senseDataPayload; senseData.senseLen = MIN(256, senseLen); /* debugging */ tdhexdump("ResponseIU I", (bit8 *)&agSSPRespIU, sizeof(agsaSSPResponseInfoUnit_t)); tdhexdump("sense data I", (bit8 *)senseDataPayload, senseLen); tdhexdump("sense data II", (bit8 *)senseData.senseData, senseData.senseLen); if (senseDataPayload[2] == SCSI_SENSE_KEY_RECOVERED_ERROR) { Initiator->SenseKeyCounter.SoftError ++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_NOT_READY) { Initiator->SenseKeyCounter.MediumNotReady++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_MEDIUM_ERROR) { Initiator->SenseKeyCounter.MediumError++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_HARDWARE_ERROR) { Initiator->SenseKeyCounter.HardwareError++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_ILLEGAL_REQUEST) { Initiator->SenseKeyCounter.IllegalRequest++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_UNIT_ATTENTION) { Initiator->SenseKeyCounter.UnitAttention++; } else if (senseDataPayload[2] == SCSI_SENSE_KEY_ABORTED_COMMAND) { Initiator->SenseKeyCounter.AbortCommand++; } else { Initiator->SenseKeyCounter.OtherKeyType++; } /* when ASQ and ASCQ 0x04 0x11, does saLocalPhyControl for notify spinup */ if ((senseDataPayload[12] == 0x04 && senseDataPayload[13] == 0x11)) { TI_DBG2(("itdssIOUnderFlowWithChkConditionHandler: sending notfify spinup\n")); tiDeviceHandle = tdIORequestBody->tiDevHandle; oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData; if (oneDeviceData->directlyAttached == agTRUE) { for (i=0;iphyID, AGSA_PHY_NOTIFY_ENABLE_SPINUP, agNULL); } } } ostiInitiatorIOCompleted( tiRoot, /* tiIORequest */ tdIORequestBody->tiIORequest, tiIOSuccess, scsi_status, &senseData, agTRUE /* intContext; is not being used */ ); return; } if (data_status == 3) { /* RESERVED */ TI_DBG1(("itdssIOUnderFlowWithChkConditionHandler: reserved wrong!!!\n")); ostiInitiatorIOCompleted( tiRoot, tdIORequestBody->tiIORequest, /* tiIORequest */ tiIOFailed, scsi_status, agNULL, agTRUE /* intContext; is not being used */ ); return; } return; } #endif /***************************************************************************** *! \brief itdssXferOpenRetryBackoffThresholdReachedHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = * OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferOpenRetryBackoffThresholdReachedHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssXferOpenRetryBackoffThresholdReachedHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorItNexusLossOpenTmoHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorItNexusLossOpenTmoHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssOpenCnxErrorItNexusLossOpenTmoHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorItNexusLossNoDestHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorItNexusLossNoDestHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssOpenCnxErrorItNexusLossNoDestHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorItNexusLossOpenCollideHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorItNexusLossOpenCollideHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssOpenCnxErrorItNexusLossOpenCollideHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorItNexusLossOpenPathwayBlockedHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorItNexusLossOpenPathwayBlockedHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssOpenCnxErrorItNexusLossOpenPathwayBlockedHandler: start\n")); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssEncryptionHandler * * Purpose: This function processes I/Os completed and returned by SAS lower * layer with any encryption specific agIOStatus. * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \return: None * * *****************************************************************************/ osGLOBAL void itdssEncryptionHandler ( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; bit32 errorDetail = tiDetailOtherError; tdIORequestBody_t *tdIORequestBody; TI_DBG1(("itdssEncryptionHandler: start\n")); TI_DBG1(("itdssEncryptionHandler: agIOStatus 0x%x\n", agIOStatus)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; switch (agIOStatus) { case OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS: TI_DBG1(("itdssEncryptionHandler: OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS\n")); errorDetail = tiDetailDekKeyCacheMiss; break; case OSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID: TI_DBG1(("itdssEncryptionHandler: OSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID\n")); errorDetail = tiDetailCipherModeInvalid; break; case OSSA_IO_XFR_ERROR_DEK_IV_MISMATCH: TI_DBG1(("itdssEncryptionHandler: OSSA_IO_XFR_ERROR_DEK_IV_MISMATCH\n")); errorDetail = tiDetailDekIVMismatch; break; case OSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR: TI_DBG1(("itdssEncryptionHandler: OSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR\n")); errorDetail = tiDetailDekRamInterfaceError; break; case OSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS: TI_DBG1(("itdssEncryptionHandler: OSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS\n")); errorDetail = tiDetailDekIndexOutofBounds; break; case OSSA_IO_XFR_ERROR_DEK_ILLEGAL_TABLE: TI_DBG1(("itdssEncryptionHandler: OSSA_IO_XFR_ERROR_DEK_ILLEGAL_TABLE\n")); errorDetail = tiDetailOtherError; break; default: TI_DBG1(("itdssEncryptionHandler: other error!!! 0x%x\n", agIOStatus)); errorDetail = tiDetailOtherError; break; } ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOEncryptError, errorDetail, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssDifHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with any DIF specific agIOStatus * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssDifHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; bit32 errorDetail = tiDetailOtherError; tdIORequestBody_t *tdIORequestBody; #ifdef TD_DEBUG_ENABLE agsaDifDetails_t *DifDetail; #endif TI_DBG1(("itdssDifHandler: start\n")); TI_DBG1(("itdssDifHandler: agIOStatus 0x%x\n", agIOStatus)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; #ifdef TD_DEBUG_ENABLE DifDetail = (agsaDifDetails_t *)agParam; #endif switch (agIOStatus) { case OSSA_IO_XFR_ERROR_DIF_MISMATCH: errorDetail = tiDetailDifMismatch; TI_DBG1(("itdssDifHandler: OSSA_IO_XFR_ERROR_DIF_MISMATCH\n")); break; case OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH: errorDetail = tiDetailDifAppTagMismatch; TI_DBG1(("itdssDifHandler: OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH\n")); break; case OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH: errorDetail = tiDetailDifRefTagMismatch; TI_DBG1(("itdssDifHandler: OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH\n")); break; case OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH: errorDetail = tiDetailDifCrcMismatch; TI_DBG1(("itdssDifHandler: OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH\n")); break; default: errorDetail = tiDetailOtherError; TI_DBG1(("itdssDifHandler: other error!!! 0x%x\n", agIOStatus)); break; } TI_DBG1(("itdssDifHandler: DIF detail UpperLBA 0x%08x LowerLBA 0x%08x\n", DifDetail->UpperLBA, DifDetail->LowerLBA)); ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIODifError, errorDetail, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssIOResourceUnavailableHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIOResourceUnavailableHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssIOResourceUnavailableHandler: start\n")); TI_DBG2(("itdssIOResourceUnavailableHandler: agIOStatus 0x%x\n", agIOStatus)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailBusy, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssIORQEBusyFullHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_MPI_IO_RQE_BUSY_FULL * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIORQEBusyFullHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssIORQEBusyFullHandler: start\n")); TI_DBG2(("itdssIORQEBusyFullHandler: agIOStatus 0x%x\n", agIOStatus)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailBusy, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorInvalidSSPRspFrameHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFR_ERROR_INVALID_SSP_RSP_FRAME * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorInvalidSSPRspFrameHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssXferErrorInvalidSSPRspFrameHandler: start\n")); TI_DBG2(("itdssXferErrorInvalidSSPRspFrameHandler: agIOStatus 0x%x\n", agIOStatus)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssXferErrorEOBDataOverrunHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_XFER_ERR_EOB_DATA_OVERRUN * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssXferErrorEOBDataOverrunHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssXferErrorEOBDataOverrunHandler: start\n")); TI_DBG2(("itdssXferErrorEOBDataOverrunHandler: agIOStatus 0x%x\n", agIOStatus)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssOpenCnxErrorOpenPreemptedHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = OSSA_IO_OPEN_CNX_ERROR_OPEN_PREEMPTED * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssOpenCnxErrorOpenPreemptedHandler( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssOpenCnxErrorOpenPreemptedHandler: start\n")); TI_DBG2(("itdssOpenCnxErrorOpenPreemptedHandler: agIOStatus 0x%x\n", agIOStatus)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /* default */ /***************************************************************************** *! \brief itdssIODefaultHandler * * Purpose: This function processes I/Os completed and returned by SAS/SATA lower * layer with agIOStatus = unspecified * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIODefaultHandler ( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData; tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot; bit32 intContext = osData->IntContext; tdIORequestBody_t *tdIORequestBody; TI_DBG2(("itdssIODefaultHandler: start\n")); TI_DBG2(("itdssIODefaultHandler: agIOStatus 0x%x\n", agIOStatus)); tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData; ostiInitiatorIOCompleted ( tiRoot, tdIORequestBody->tiIORequest, tiIOFailed, tiDetailOtherError, agNULL, intContext ); return; } /***************************************************************************** *! \brief itdssIOForDebugging1Completed * * Purpose: This function is only for debugging. This function should NOT be * called. * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIOForDebugging1Completed( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { TI_DBG1(("itdssIOForDebugging1Completed: start, error!!! can't be called. \n")); } /***************************************************************************** *! \brief itdssIOForDebugging2Completed * * Purpose: This function is only for debugging. This function should NOT be * called. * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIOForDebugging2Completed( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { TI_DBG1(("itdssIOForDebugging2Completed: start, error!!! can't be called. \n")); } /***************************************************************************** *! \brief itdssIOForDebugging3Completed * * Purpose: This function is only for debugging. This function should NOT be * called. * * \param agRoot: pointer to port instance * \param agIORequest: pointer to I/O request * \param agIOStatus: I/O status given by LL layer * \param agIOInfoLen: lenth of complete SAS RESP frame * \param agParam A Handle used to refer to the response frame or handle * of abort request * \param agOtherInfo Residual count * \return: None * * *****************************************************************************/ osGLOBAL void itdssIOForDebugging3Completed( agsaRoot_t *agRoot, agsaIORequest_t *agIORequest, bit32 agIOStatus, bit32 agIOInfoLen, void *agParam, bit32 agOtherInfo ) { TI_DBG1(("itdssIOForDebugging3Completed: start, error!!! can't be called. \n")); }