/******************************************************************************* *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 saint.c * \brief The file implements the functions to handle/enable/disable interrupt * */ /*******************************************************************************/ #include #include #include #define SA_CLEAR_ODCR_IN_INTERRUPT //#define SA_TEST_FW_SPURIOUS_INT #ifdef SA_TEST_FW_SPURIOUS_INT bit32 gOurIntCount = 0; bit32 gSpuriousIntCount = 0; bit32 gSpuriousInt[64]= { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 }; bit32 gSpuriousInt1[64]= { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0 }; #endif /* SA_TEST_FW_SPURIOUS_INT */ #ifdef SA_ENABLE_TRACE_FUNCTIONS #ifdef siTraceFileID #undef siTraceFileID #endif /* siTraceFileID */ #define siTraceFileID 'G' #endif /* SA_ENABLE_TRACE_FUNCTIONS */ LOCAL FORCEINLINE bit32 siProcessOBMsg( agsaRoot_t *agRoot, bit32 count, bit32 queueNum ); LOCAL bit32 siFatalInterruptHandler( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { agsaLLRoot_t *saRoot = agNULL; agsaFatalErrorInfo_t fatal_error; bit32 value; bit32 ret = AGSA_RC_FAILURE; bit32 Sendfatal = agTRUE; SA_ASSERT((agNULL != agRoot), ""); if (agRoot == agNULL) { SA_DBG1(("siFatalInterruptHandler: agRoot == agNULL\n")); return AGSA_RC_FAILURE; } saRoot = (agsaLLRoot_t *)(agRoot->sdkData); SA_ASSERT((agNULL != saRoot), ""); if (saRoot == agNULL) { SA_DBG1(("siFatalInterruptHandler: saRoot == agNULL\n")); return AGSA_RC_FAILURE; } value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1); if (saRoot->ResetFailed) { SA_DBG1(("siFatalInterruptHandler: ResetFailed\n")); ossaDisableInterrupts(agRoot, interruptVectorIndex); return AGSA_RC_FAILURE; } if(SCRATCH_PAD1_V_ERROR_STATE( value ) ) { si_memset(&fatal_error, 0, sizeof(agsaFatalErrorInfo_t)); /* read detail fatal errors */ value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0, MSGU_SCRATCH_PAD_0); fatal_error.errorInfo0 = value; SA_DBG1(("siFatalInterruptHandler: ScratchPad0 AAP error 0x%x code 0x%x\n",SCRATCH_PAD1_V_ERROR_STATE( value ), value)); value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1); fatal_error.errorInfo1 = value; /* AAP error state */ SA_DBG1(("siFatalInterruptHandler: AAP error state and error code 0x%x\n", value)); value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2, MSGU_SCRATCH_PAD_2); fatal_error.errorInfo2 = value; SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2 0x%08x\n", fatal_error.errorInfo2 )); #if defined(SALLSDK_DEBUG) if(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_ILA_ERR) { SA_DBG1(("siFatalInterruptHandler:SCRATCH_PAD1_V_ERROR_STATE SCRATCH_PAD2_FW_ILA_ERR 0x%08x\n", SCRATCH_PAD2_FW_ILA_ERR)); } if(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_FLM_ERR) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_FW_FLM_ERR 0x%08x\n", SCRATCH_PAD2_FW_FLM_ERR)); } if(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_FW_ASRT_ERR) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_FW_FW_ASRT_ERR 0x%08x\n", SCRATCH_PAD2_FW_FW_ASRT_ERR)); } if(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_WDG_ERR) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_FW_HW_WDG_ERR 0x%08x\n", SCRATCH_PAD2_FW_HW_WDG_ERR)); } if(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_GEN_EXCEPTION_ERR) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_FW_GEN_EXCEPTION_ERR 0x%08x\n", SCRATCH_PAD2_FW_GEN_EXCEPTION_ERR)); } if(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_UNDTMN_ERR) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_FW_UNDTMN_ERR 0x%08x\n",SCRATCH_PAD2_FW_UNDTMN_ERR )); } if(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_FATAL_ERR) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_FW_HW_FATAL_ERR 0x%08x\n", SCRATCH_PAD2_FW_HW_FATAL_ERR)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_PCS_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_PCS_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_GSM_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_GSM_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_OSSP0_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_OSSP0_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) ==SCRATCH_PAD2_HW_ERROR_INT_INDX_OSSP1_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_OSSP1_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_OSSP2_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_OSSP2_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_ERAAE_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_ERAAE_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_SDS_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_SDS_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_PCIE_CORE_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_PCIE_CORE_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_PCIE_AL_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_PCIE_AL_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_MSGU_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_MSGU_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_SPBC_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_SPBC_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_BDMA_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_BDMA_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_MCPSL2B_ERR) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_MCPSL2B_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_MCPSDC_ERR ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_MCPSDC_ERR 0x%08x\n", value)); } if((fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_MASK) == SCRATCH_PAD2_HW_ERROR_INT_INDX_UNDETERMINED_ERROR_OCCURRED ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_HW_ERROR_INT_INDX_UNDETERMINED_ERROR_OCCURRED 0x%08x\n", value)); } #endif /* SALLSDK_DEBUG */ if( fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_NON_FATAL_ERR && !(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_ILA_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_FLM_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_FW_ASRT_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_WDG_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_GEN_EXCEPTION_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_UNDTMN_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_PCS_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_GSM_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_OSSP0_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_OSSP2_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_ERAAE_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_SDS_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_PCIE_CORE_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_PCIE_AL_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_MSGU_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_SPBC_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_BDMA_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_MCPSL2B_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_MCPSDC_ERR) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_HW_ERROR_INT_INDX_UNDETERMINED_ERROR_OCCURRED) && !(fatal_error.errorInfo2 & SCRATCH_PAD2_FW_HW_FATAL_ERR) ) { SA_DBG1(("siFatalInterruptHandler: SCRATCH_PAD2_FW_HW_NON_FATAL_ERR 0x%08x\n", value)); Sendfatal = agFALSE; } value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_3, MSGU_SCRATCH_PAD_3); SA_DBG1(("siFatalInterruptHandler: ScratchPad3 IOP error code 0x%08x\n", value)); fatal_error.errorInfo3 = value; if (agNULL != saRoot) { fatal_error.regDumpBusBaseNum0 = saRoot->mainConfigTable.regDumpPCIBAR; fatal_error.regDumpOffset0 = saRoot->mainConfigTable.FatalErrorDumpOffset0; fatal_error.regDumpLen0 = saRoot->mainConfigTable.FatalErrorDumpLength0; fatal_error.regDumpBusBaseNum1 = saRoot->mainConfigTable.regDumpPCIBAR; fatal_error.regDumpOffset1 = saRoot->mainConfigTable.FatalErrorDumpOffset1; fatal_error.regDumpLen1 = saRoot->mainConfigTable.FatalErrorDumpLength1; } else { fatal_error.regDumpBusBaseNum0 = 0; fatal_error.regDumpOffset0 = 0; fatal_error.regDumpLen0 = 0; fatal_error.regDumpBusBaseNum1 = 0; fatal_error.regDumpOffset1 = 0; fatal_error.regDumpLen1 = 0; } /* Call Back with error */ SA_DBG1(("siFatalInterruptHandler: Sendfatal %x HostR0 0x%x\n",Sendfatal ,ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_Rsvd_0_Register ) )); SA_DBG1(("siFatalInterruptHandler: ScratchPad2 0x%x ScratchPad3 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0,V_Host_Scratchpad_2_Register), ossaHwRegReadExt(agRoot, PCIBAR0,V_Host_Scratchpad_3_Register) )); ossaHwCB(agRoot, agNULL, OSSA_HW_EVENT_MALFUNCTION, Sendfatal, (void *)&fatal_error, agNULL); ret = AGSA_RC_SUCCESS; } else { bit32 host_reg0; host_reg0 = ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_Rsvd_0_Register ); if( host_reg0 == 0x2) { Sendfatal = agFALSE; SA_DBG1(("siFatalInterruptHandler: Non fatal ScratchPad1 0x%x HostR0 0x%x\n", value,host_reg0)); SA_DBG1(("siFatalInterruptHandler: ScratchPad0 0x%x ScratchPad1 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_0_Register), ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_1_Register) )); SA_DBG1(("siFatalInterruptHandler: ScratchPad2 0x%x ScratchPad3 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_2_Register), ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_3_Register) )); ossaHwCB(agRoot, agNULL, OSSA_HW_EVENT_MALFUNCTION, Sendfatal, (void *)&fatal_error, agNULL); ret = AGSA_RC_SUCCESS; } else if( host_reg0 == HDA_AES_DIF_FUNC) { SA_DBG1(("siFatalInterruptHandler: HDA_AES_DIF_FUNC 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_Rsvd_0_Register))); Sendfatal = agFALSE; ret = AGSA_RC_SUCCESS; } else { SA_DBG1(("siFatalInterruptHandler: No error detected ScratchPad1 0x%x HostR0 0x%x\n", value,host_reg0)); SA_DBG1(("siFatalInterruptHandler: ScratchPad0 0x%x ScratchPad1 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_0_Register), ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_1_Register) )); SA_DBG1(("siFatalInterruptHandler: ScratchPad2 0x%x ScratchPad3 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_2_Register), ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_3_Register) )); SA_DBG1(("siFatalInterruptHandler: Doorbell_Set %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_Register), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_RegisterU))); SA_DBG1(("siFatalInterruptHandler: Doorbell_Mask %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_Register ), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_RegisterU ))); ret = AGSA_RC_FAILURE; } } return ret; } GLOBAL bit32 saFatalInterruptHandler( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { agsaLLRoot_t *saRoot = agNULL; bit32 ret = AGSA_RC_FAILURE; /* sanity check */ SA_ASSERT((agNULL != agRoot), ""); saRoot = (agsaLLRoot_t *)(agRoot->sdkData); SA_ASSERT((agNULL != saRoot), ""); if (saRoot->ResetFailed) { SA_DBG1(("saFatalInterruptHandler: ResetFailed\n")); ossaDisableInterrupts(agRoot, interruptVectorIndex); return AGSA_RC_FAILURE; } if (saRoot->swConfig.fatalErrorInterruptEnable != 1) { SA_DBG1(("saFatalInterruptHandler: fatalErrorInterrtupt is NOT enabled\n")); ossaDisableInterrupts(agRoot, interruptVectorIndex); return AGSA_RC_FAILURE; } if (saRoot->swConfig.fatalErrorInterruptVector != interruptVectorIndex) { SA_DBG1(("saFatalInterruptHandler: interruptVectorIndex does not match 0x%x 0x%x\n", saRoot->swConfig.fatalErrorInterruptVector, interruptVectorIndex)); SA_DBG1(("saFatalInterruptHandler: ScratchPad0 0x%x ScratchPad1 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_0_Register), ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_1_Register) )); SA_DBG1(("saFatalInterruptHandler: ScratchPad2 0x%x ScratchPad3 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_2_Register), ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_3_Register) )); ossaDisableInterrupts(agRoot, interruptVectorIndex); return AGSA_RC_FAILURE; } ret = siFatalInterruptHandler(agRoot,interruptVectorIndex); ossaDisableInterrupts(agRoot, interruptVectorIndex); return ret; } /******************************************************************************/ /*! \brief Function to process the interrupts * * The saInterruptHandler() function is called after an interrupts has * been received * This function disables interrupts * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex message that caused MSI message * * \return TRUE if we caused interrupt * */ /*******************************************************************************/ FORCEINLINE bit32 saInterruptHandler( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); bit32 ToBeProcessedCount = 0; bit32 our_int = 0; #ifdef SA_TEST_FW_SPURIOUS_INT bit8 i; #endif/* SA_TEST_FW_SPURIOUS_INT */ if( agNULL == saRoot ) { /* Can be called before initialize is completed in a shared interrupt environment like windows 2003 */ return(ToBeProcessedCount); } if( (our_int = saRoot->OurInterrupt(agRoot,interruptVectorIndex)) == FALSE ) { #ifdef SA_TEST_FW_SPURIOUS_INT gSpuriousIntCount++; smTrace(hpDBG_REGISTERS,"S1",gSpuriousIntCount); /* TP:S1 gSpuriousIntCount */ #endif /* SA_TEST_FW_SPURIOUS_INT */ return(ToBeProcessedCount); } smTraceFuncEnter(hpDBG_TICK_INT, "5q"); smTrace(hpDBG_TICK_INT,"VI",interruptVectorIndex); /* TP:Vi interrupt VectorIndex */ if ( agFALSE == saRoot->sysIntsActive ) { // SA_ASSERT(0, "saInterruptHandler sysIntsActive not set"); #ifdef SA_PRINTOUT_IN_WINDBG #ifndef DBG DbgPrint("saInterruptHandler: sysIntsActive not set Doorbell_Mask_Set %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_Register), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_RegisterU) ); #endif /* DBG */ #endif /* SA_PRINTOUT_IN_WINDBG */ SA_DBG1(("saInterruptHandler: Doorbell_Mask_Set %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_Register), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_RegisterU))); ossaDisableInterrupts(agRoot, interruptVectorIndex); return(ToBeProcessedCount); } /* Allow replacement of disable interrupt */ ossaDisableInterrupts(agRoot, interruptVectorIndex); #ifdef SA_TEST_FW_SPURIOUS_INT /* count for my interrupt */ gOurIntCount++; smTrace(hpDBG_REGISTERS,"S4",gOurIntCount); /* TP:S4 gOurIntCount */ #endif /* SA_TEST_FW_SPURIOUS_INT */ smTraceFuncExit(hpDBG_TICK_INT, 'a', "5q"); return(TRUE); } /******************************************************************************/ /*! \brief Function to disable MSIX interrupts * * siDisableMSIXInterrupts disables interrupts * called thru macro ossaDisableInterrupts * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex - vector index for message * */ /*******************************************************************************/ GLOBAL void siDisableMSIXInterrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { bit32 msi_index; #ifndef SA_CLEAR_ODCR_IN_INTERRUPT bit32 value; #endif /* SA_CLEAR_ODCR_IN_INTERRUPT */ msi_index = interruptVectorIndex * MSIX_TABLE_ELEMENT_SIZE; msi_index += MSIX_TABLE_BASE; ossaHwRegWrite(agRoot,msi_index , MSIX_INTERRUPT_DISABLE); ossaHwRegRead(agRoot, msi_index); /* Dummy read */ #ifndef SA_CLEAR_ODCR_IN_INTERRUPT value = (1 << interruptVectorIndex); ossaHwRegWrite(agRoot, MSGU_ODCR, value); #endif /* SA_CLEAR_ODCR_IN_INTERRUPT */ } /******************************************************************************/ /*! \brief Function to disable MSIX V interrupts * * siDisableMSIXInterrupts disables interrupts * called thru macro ossaDisableInterrupts * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex - vector index for message * */ /*******************************************************************************/ void siDisableMSIX_V_Interrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { bit64 mask; agsabit32bit64 u64; mask =( (bit64)1 << interruptVectorIndex); u64.B64 = mask; if(smIS64bInt(agRoot)) { SA_DBG4(("siDisableMSIX_V_Interrupts: VI %d U 0x%08X L 0x%08X\n",interruptVectorIndex,u64.S32[1],u64.S32[0])); ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Mask_Set_RegisterU,u64.S32[1]); } ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Mask_Set_Register, u64.S32[0]); } /******************************************************************************/ /*! \brief Function to disable MSI interrupts * * siDisableMSIInterrupts disables interrupts * called thru macro ossaDisableInterrupts * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex - vector index for message * */ /*******************************************************************************/ GLOBAL void siDisableMSIInterrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { bit32 ODMRValue; bit32 mask; mask = 1 << interruptVectorIndex; /*Must be protected for interuption */ ODMRValue = ossaHwRegRead(agRoot, MSGU_ODMR); ODMRValue |= mask; ossaHwRegWrite(agRoot, MSGU_ODMR, ODMRValue); ossaHwRegWrite(agRoot, MSGU_ODCR, mask); } /******************************************************************************/ /*! \brief Function to disable MSI V interrupts * * siDisableMSIInterrupts disables interrupts * called thru macro ossaDisableInterrupts * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex - vector index for message * */ /*******************************************************************************/ GLOBAL void siDisableMSI_V_Interrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { SA_ASSERT(0, "Should not be called"); SA_DBG4(("siDisableMSI_V_Interrupts:\n")); } /******************************************************************************/ /*! \brief Function to process Legacy interrupts * * siDisableLegacyInterrupts disables interrupts * called thru macro ossaDisableInterrupts * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex not used in legacy case * */ /*******************************************************************************/ GLOBAL void siDisableLegacyInterrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { ossaHwRegWrite(agRoot, MSGU_ODMR, ODMR_MASK_ALL); #ifndef SA_CLEAR_ODCR_IN_INTERRUPT ossaHwRegWrite(agRoot, MSGU_ODCR, ODCR_CLEAR_ALL); #endif /* SA_CLEAR_ODCR_IN_INTERRUPT */ } /******************************************************************************/ /*! \brief Function to process Legacy V interrupts * * siDisableLegacyInterrupts disables interrupts * called thru macro ossaDisableInterrupts * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex not used in legacy case * */ /*******************************************************************************/ GLOBAL void siDisableLegacy_V_Interrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { bit64 mask; agsabit32bit64 u64; mask =( (bit64)1 << interruptVectorIndex); u64.B64 = mask; SA_DBG4(("siDisableLegacy_V_Interrupts:IN MSGU_READ_ODR %08X\n",siHalRegReadExt(agRoot, GEN_MSGU_ODR, V_Outbound_Doorbell_Set_Register))); SA_DBG4(("siDisableLegacy_V_Interrupts:IN MSGU_READ_ODMR %08X\n",siHalRegReadExt(agRoot, GEN_MSGU_ODMR, V_Outbound_Doorbell_Mask_Set_Register ))); if(smIS64bInt(agRoot)) { SA_DBG4(("siDisableLegacy_V_Interrupts: VI %d U 0x%08X L 0x%08X\n",interruptVectorIndex,u64.S32[1],u64.S32[0])); ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Mask_Set_Register,u64.S32[1] ); } ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Mask_Set_RegisterU,u64.S32[0]); } /******************************************************************************/ /*! \brief Function to process MSIX interrupts * * siOurMSIXInterrupt checks if we generated interrupt * called thru function pointer saRoot->OurInterrupt * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \return always true */ /*******************************************************************************/ GLOBAL bit32 siOurMSIXInterrupt( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { return(TRUE); } /******************************************************************************/ /*! \brief Function to process MSIX V interrupts * * siOurMSIXInterrupt checks if we generated interrupt * called thru function pointer saRoot->OurInterrupt * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \return always true */ /*******************************************************************************/ GLOBAL bit32 siOurMSIX_V_Interrupt( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { return(TRUE); } /******************************************************************************/ /*! \brief Function to process MSI interrupts * * siOurMSIInterrupt checks if we generated interrupt * called thru function pointer saRoot->OurInterrupt * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \return always true */ /*******************************************************************************/ bit32 siOurMSIInterrupt( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { return(TRUE); } /******************************************************************************/ /*! \brief Function to process MSI V interrupts * * siOurMSIInterrupt checks if we generated interrupt * called thru function pointer saRoot->OurInterrupt * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \return always true */ /*******************************************************************************/ bit32 siOurMSI_V_Interrupt( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { SA_DBG4((":siOurMSI_V_Interrupt\n")); return(TRUE); } /******************************************************************************/ /*! \brief Function to process Legacy interrupts * * siOurLegacyInterrupt checks if we generated interrupt * called thru function pointer saRoot->OurInterrupt * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \return true if we claim interrupt */ /*******************************************************************************/ bit32 siOurLegacyInterrupt( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { bit32 Int_masked; bit32 Int_active; Int_masked = MSGU_READ_ODMR; Int_active = MSGU_READ_ODR; if(Int_masked & 1 ) { return(FALSE); } if(Int_active & 1 ) { return(TRUE); } return(FALSE); } /******************************************************************************/ /*! \brief Function to process Legacy V interrupts * * siOurLegacyInterrupt checks if we generated interrupt * called thru function pointer saRoot->OurInterrupt * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \return true if we claim interrupt */ /*******************************************************************************/ bit32 siOurLegacy_V_Interrupt( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { bit32 Int_active; Int_active = siHalRegReadExt(agRoot, GEN_MSGU_ODR, V_Outbound_Doorbell_Set_Register ); return(Int_active ? TRUE : FALSE); } /******************************************************************************/ /*! \brief Function to process the cause of interrupt * * The saDelayedInterruptHandler() function is called after an interrupt messages has * been received it may be called by a deferred procedure call * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex - vector index for message * \param count Number of completion queue entries to consume * * \return number of messages processed * */ /*******************************************************************************/ FORCEINLINE bit32 saDelayedInterruptHandler( agsaRoot_t *agRoot, bit32 interruptVectorIndex, bit32 count ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); bit32 processedMsgCount = 0; bit32 pad1 = 0; bit32 host_reg0 = 0; #if defined(SALLSDK_DEBUG) bit32 host_reg1 = 0; #endif bit8 i = 0; OSSA_OUT_ENTER(agRoot); smTraceFuncEnter(hpDBG_VERY_LOUD,"5p"); smTrace(hpDBG_VERY_LOUD,"Vd",interruptVectorIndex); /* TP:Vd delayed VectorIndex */ smTrace(hpDBG_VERY_LOUD,"Vc",count); /* TP:Vc IOMB count*/ if( saRoot->swConfig.fatalErrorInterruptEnable && saRoot->swConfig.fatalErrorInterruptVector == interruptVectorIndex ) { pad1 = siHalRegReadExt(agRoot,GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1); host_reg0 = ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_Rsvd_0_Register ); if(saRoot->swConfig.hostDirectAccessMode & 2 ) { if( host_reg0 == HDA_AES_DIF_FUNC) { host_reg0 = 0; } } #if defined(SALLSDK_DEBUG) host_reg1 = ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_Rsvd_1_Register ); #endif if( (SCRATCH_PAD1_V_ERROR_STATE( pad1 ) != 0 ) && host_reg0 ) { SA_DBG1(("saDelayedInterruptHandler: vi %d Error %08X\n",interruptVectorIndex, SCRATCH_PAD1_V_ERROR_STATE( pad1 ))); SA_DBG1(("saDelayedInterruptHandler: Sp 1 %08X Hr0 %08X Hr1 %08X\n",pad1,host_reg0,host_reg1 )); SA_DBG1(("saDelayedInterruptHandler: SCRATCH_PAD1_V_ERROR_STATE %08X\n", SCRATCH_PAD1_V_ERROR_STATE( pad1 ))); SA_DBG1(("saDelayedInterruptHandler: SCRATCH_PAD1_V_ILA_ERROR_STATE %08X\n", SCRATCH_PAD1_V_ILA_ERROR_STATE( pad1 ))); SA_DBG1(("saDelayedInterruptHandler: SCRATCH_PAD1_V_RAAE_ERROR_STATE %08X\n", SCRATCH_PAD1_V_RAAE_ERROR_STATE( pad1 ))); SA_DBG1(("saDelayedInterruptHandler: SCRATCH_PAD1_V_IOP0_ERROR_STATE %08X\n", SCRATCH_PAD1_V_IOP0_ERROR_STATE( pad1 ))); SA_DBG1(("saDelayedInterruptHandler: SCRATCH_PAD1_V_IOP1_ERROR_STATE %08X\n", SCRATCH_PAD1_V_IOP1_ERROR_STATE( pad1 ))); siFatalInterruptHandler( agRoot, interruptVectorIndex ); ossaDisableInterrupts(agRoot, interruptVectorIndex); } else { SA_DBG2(("saDelayedInterruptHandler: Fatal Check VI %d SCRATCH_PAD1 %08X host_reg0 %08X host_reg1 %08X\n",interruptVectorIndex, pad1,host_reg0,host_reg1)); SA_DBG2(("saDelayedInterruptHandler: ScratchPad0 0x%x ScratchPad1 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_0_Register), ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_1_Register) )); SA_DBG2(("saDelayedInterruptHandler: ScratchPad2 0x%x ScratchPad3 0x%x\n", ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_2_Register), ossaHwRegReadExt(agRoot, PCIBAR0,V_Scratchpad_3_Register) )); SA_DBG2(("saDelayedInterruptHandler: Doorbell_Set %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_Register), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_RegisterU))); SA_DBG2(("saDelayedInterruptHandler: Doorbell_Mask %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_Register ), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_RegisterU ))); } } #ifdef SA_LNX_PERF_MODE return siProcessOBMsg(agRoot, count, interruptVectorIndex); #endif /* check all the configuration outbound queues within a vector bitmap */ SA_ASSERT((saRoot->QueueConfig.numOutboundQueues < 65), "numOutboundQueue"); for ( i = 0; i < saRoot->QueueConfig.numOutboundQueues; i++ ) { /* process IOMB in the outbound queue 0 to 31 if bit set in the vector bitmap */ if (i < OQ_NUM_32) { if (saRoot->interruptVecIndexBitMap[interruptVectorIndex] & (1 << i)) { processedMsgCount += siProcessOBMsg(agRoot, count, i); } else if (saRoot->QueueConfig.outboundQueues[i].interruptEnable == 0) { /* polling mode - interruptVectorIndex = 0 only and no bit set */ processedMsgCount += siProcessOBMsg(agRoot, count, i); } #ifdef SA_FW_TEST_INTERRUPT_REASSERT else if (saRoot->CheckAll) { /* polling mode - interruptVectorIndex = 0 only and no bit set */ processedMsgCount += siProcessOBMsg(agRoot, count, i); } #endif /* SA_FW_TEST_INTERRUPT_REASSERT */ } else { /* process IOMB in the outbound queue 32 to 63 if bit set in the vector bitmap */ if (saRoot->interruptVecIndexBitMap1[interruptVectorIndex] & (1 << (i - OQ_NUM_32))) { processedMsgCount += siProcessOBMsg(agRoot, count, i); } /* check interruptEnable bit for polling mode of OQ */ /* the following code can be removed, we do not care about the bit */ else if (saRoot->QueueConfig.outboundQueues[i].interruptEnable == 0) { /* polling mode - interruptVectorIndex = 0 only and no bit set */ processedMsgCount += siProcessOBMsg(agRoot, count, i); } #ifdef SA_FW_TEST_INTERRUPT_REASSERT else if (saRoot->CheckAll) { /* polling mode - interruptVectorIndex = 0 only and no bit set */ processedMsgCount += siProcessOBMsg(agRoot, count, i); } #endif /* SA_FW_TEST_INTERRUPT_REASSERT */ } } #ifdef SA_FW_TEST_INTERRUPT_REASSERT saRoot->CheckAll = 0; #endif /* SA_FW_TEST_INTERRUPT_REASSERT */ #ifndef SA_RENABLE_IN_OSLAYER if ( agTRUE == saRoot->sysIntsActive ) { /* Allow replacement of enable interrupt */ ossaReenableInterrupts(agRoot, interruptVectorIndex); } #endif /* SA_RENABLE_IN_OSLAYER */ smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "5p"); OSSA_OUT_LEAVE(agRoot); return processedMsgCount; } /******************************************************************************/ /*! \brief Function to reenable MSIX interrupts * * siReenableMSIXInterrupts reenableinterrupts * called thru macro ossaReenableInterrupts * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex - vector index for message * */ /*******************************************************************************/ void siReenableMSIXInterrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { bit32 msi_index; #ifdef SA_CLEAR_ODCR_IN_INTERRUPT bit32 value; #endif /* SA_CLEAR_ODCR_IN_INTERRUPT */ msi_index = interruptVectorIndex * MSIX_TABLE_ELEMENT_SIZE; msi_index += MSIX_TABLE_BASE; ossaHwRegWriteExt(agRoot, PCIBAR0,msi_index, MSIX_INTERRUPT_ENABLE); SA_DBG4(("siReenableMSIXInterrupts:interruptVectorIndex %d\n",interruptVectorIndex)); #ifdef SA_CLEAR_ODCR_IN_INTERRUPT value = (1 << interruptVectorIndex); siHalRegWriteExt(agRoot, GEN_MSGU_ODCR, MSGU_ODCR, value); #endif /* SA_CLEAR_ODCR_IN_INTERRUPT */ } /******************************************************************************/ /*! \brief Function to reenable MSIX interrupts * * siReenableMSIXInterrupts reenableinterrupts * called thru macro ossaReenableInterrupts * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex - vector index for message * */ /*******************************************************************************/ void siReenableMSIX_V_Interrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); bit64 mask; agsabit32bit64 u64; mask =( (bit64)1 << interruptVectorIndex); u64.B64 = mask; SA_DBG4(("siReenableMSIX_V_Interrupts:\n")); if(saRoot->sysIntsActive) { if(smIS64bInt(agRoot)) { SA_DBG4(("siReenableMSIX_V_Interrupts: VI %d U 0x%08X L 0x%08X\n",interruptVectorIndex,u64.S32[1],u64.S32[0])); ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Mask_Clear_RegisterU,u64.S32[1] ); } ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Mask_Clear_Register,u64.S32[0]); } else { SA_DBG1(("siReenableMSIX_V_Interrupts: VI %d sysIntsActive off\n",interruptVectorIndex)); } } /******************************************************************************/ /*! \brief Function to reenable MSI interrupts * * siReenableMSIXInterrupts reenableinterrupts * called thru macro ossaReenableInterrupts * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex - vector index for message * */ /*******************************************************************************/ GLOBAL void siReenableMSIInterrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { bit32 ODMRValue; ODMRValue = siHalRegReadExt(agRoot, GEN_MSGU_ODMR, MSGU_ODMR); ODMRValue &= ~(1 << interruptVectorIndex); siHalRegWriteExt(agRoot, GEN_MSGU_ODMR, MSGU_ODMR, ODMRValue); } /******************************************************************************/ /*! \brief Function to reenable MSI V interrupts * * siReenableMSIXInterrupts reenableinterrupts * called thru macro ossaReenableInterrupts * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex - vector index for message * */ /*******************************************************************************/ GLOBAL void siReenableMSI_V_Interrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { SA_ASSERT(0, "Should not be called"); SA_DBG4(("siReenableMSI_V_Interrupts:\n")); } /******************************************************************************/ /*! \brief Function to reenable Legacy interrupts * * siReenableLegacyInterrupts reenableinterrupts * called thru macro ossaReenableInterrupts * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex always zero * */ /*******************************************************************************/ GLOBAL void siReenableLegacyInterrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { siHalRegWriteExt(agRoot, GEN_MSGU_ODMR, MSGU_ODMR, ODMR_CLEAR_ALL); #ifdef SA_CLEAR_ODCR_IN_INTERRUPT siHalRegWriteExt(agRoot, GEN_MSGU_ODCR, MSGU_ODCR, ODCR_CLEAR_ALL); #endif /* SA_CLEAR_ODCR_IN_INTERRUPT */ } /******************************************************************************/ /*! \brief Function to reenable Legacy V interrupts * * siReenableLegacyInterrupts reenableinterrupts * called thru macro ossaReenableInterrupts * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex always zero * */ /*******************************************************************************/ GLOBAL void siReenableLegacy_V_Interrupts( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { bit32 mask; mask = 1 << interruptVectorIndex; SA_DBG5(("siReenableLegacy_V_Interrupts:IN MSGU_READ_ODR %08X\n",siHalRegReadExt(agRoot, GEN_MSGU_ODR, V_Outbound_Doorbell_Set_Register))); SA_DBG5(("siReenableLegacy_V_Interrupts:IN MSGU_READ_ODMR %08X\n",siHalRegReadExt(agRoot, GEN_MSGU_ODMR, V_Outbound_Doorbell_Mask_Set_Register ))); ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Mask_Clear_Register, mask); ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Clear_Register, mask ); SA_DBG5(("siReenableLegacy_V_Interrupts:OUT MSGU_READ_ODMR %08X\n",siHalRegReadExt(agRoot, GEN_MSGU_ODMR, V_Outbound_Doorbell_Mask_Set_Register ))); } /******************************************************************************/ /*! \brief Function to enable a single interrupt vector * * * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex Interrupt vector to enable * */ /*******************************************************************************/ /******************************************************************************/ /*! \brief saSystemInterruptsEnable * Function to enable a single interrupt vector * * \param agRoot OS Layer-specific and LL Layer-specific context handles for this * instance of SAS/SATA hardware * \param interruptVectorIndex Interrupt vector to enable * */ /*******************************************************************************/ GLOBAL FORCEINLINE void saSystemInterruptsEnable( agsaRoot_t *agRoot, bit32 interruptVectorIndex ) { ossaReenableInterrupts(agRoot, interruptVectorIndex); } /******************************************************************************/ /*! \brief Routine to handle Outbound Message * * The handle for outbound message * * \param agRoot handles for this instance of SAS/SATA hardware * \param count interrupt message count * \param queueNum outbound queue * * \return */ /*******************************************************************************/ LOCAL FORCEINLINE bit32 siProcessOBMsg( agsaRoot_t *agRoot, bit32 count, bit32 queueNum ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); mpiOCQueue_t *circularQ = agNULL; void *pMsg1 = agNULL; bit32 ret, processedMsgCount = 0; bit32 ParseOBIombStatus = 0; #ifdef SA_ENABLE_TRACE_FUNCTIONS bit32 i = 0; #endif bit16 opcode = 0; mpiMsgCategory_t category; bit8 bc = 0; smTraceFuncEnter(hpDBG_VERY_LOUD,"5r"); SA_DBG3(("siProcessOBMsg: queueNum 0x%x\n", queueNum)); ossaSingleThreadedEnter(agRoot, LL_IOREQ_OBQ_LOCK + queueNum); circularQ = &saRoot->outboundQueue[queueNum]; OSSA_READ_LE_32(circularQ->agRoot, &circularQ->producerIdx, circularQ->piPointer, 0); if (circularQ->producerIdx == circularQ->consumerIdx) { ossaSingleThreadedLeave(agRoot, LL_IOREQ_OBQ_LOCK + queueNum); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "5r"); return processedMsgCount; } ossaSingleThreadedLeave(agRoot, LL_IOREQ_OBQ_LOCK + queueNum); do { /* ossaSingleThreadedEnter(agRoot, LL_IOREQ_OBQ_LOCK + queueNum); */ ret = mpiMsgConsume(circularQ, &pMsg1, &category, &opcode, &bc); /* ossaSingleThreadedLeave(agRoot, LL_IOREQ_OBQ_LOCK + queueNum); */ if (AGSA_RC_SUCCESS == ret) { smTrace(hpDBG_IOMB,"M0",queueNum); /* TP:M0 queueNum */ smTrace(hpDBG_VERY_LOUD,"MA",opcode); /* TP:MA opcode */ smTrace(hpDBG_IOMB,"MB",category); /* TP:MB category */ #ifdef SA_ENABLE_TRACE_FUNCTIONS for (i=0; i<((bit32)bc*(circularQ->elementSize/4)); i++) { /* The -sizeof(mpiMsgHeader_t) is to account for mpiMsgConsume incrementing the pointer past the header*/ smTrace(hpDBG_IOMB,"MC",*( ((bit32*)((bit8 *)pMsg1 - sizeof(mpiMsgHeader_t))) + i)); /* TP:MC Outbound IOMB Dword */ } #endif MPI_DEBUG_TRACE( circularQ->qNumber,((circularQ->producerIdx << 16 ) | circularQ->consumerIdx),MPI_DEBUG_TRACE_OBQ, (void *)(((bit8*)pMsg1) - sizeof(mpiMsgHeader_t)), circularQ->elementSize); ossaLogIomb(circularQ->agRoot, circularQ->qNumber, FALSE, (void *)(((bit8*)pMsg1) - sizeof(mpiMsgHeader_t)), bc*circularQ->elementSize); ossaQueueProcessed(agRoot, queueNum, circularQ->producerIdx, circularQ->consumerIdx); /* process the outbound message */ ParseOBIombStatus = mpiParseOBIomb(agRoot, (bit32 *)pMsg1, category, opcode); if (ParseOBIombStatus == AGSA_RC_FAILURE) { SA_DBG1(("siProcessOBMsg, Failed Q %2d PI 0x%03x CI 0x%03x\n", queueNum, circularQ->producerIdx, circularQ->consumerIdx)); #if defined(SALLSDK_DEBUG) /* free the message for debug: this is a hang! */ mpiMsgFreeSet(circularQ, pMsg1, bc); processedMsgCount ++; #endif /**/ break; } /* free the message from the outbound circular buffer */ mpiMsgFreeSet(circularQ, pMsg1, bc); processedMsgCount ++; } else //if (AGSA_RC_BUSY == ret) // always (circularQ->producerIdx == circularQ->consumerIdx) // || (AGSA_RC_FAILURE == ret) { break; } } /* end of message processing if hit the count */ while(count > processedMsgCount); /* #define SALLSDK_FATAL_ERROR_DETECT 1 */ /* this comments are to be removed fill in 0x1D 0x1e 0x1f 0x20 in MPI table for bit32 regDumpBusBaseNum0; bit32 regDumpOffset0; bit32 regDumpLen0; bit32 regDumpBusBaseNum1; bit32 regDumpOffset1; bit32 regDumpLen1; in agsaFatalErrorInfo_t ??? regDumpBusBaseNum0 and regDumpBusBaseNum1 saRoot->mainConfigTable.regDumpPCIBAR = pcibar; saRoot->mainConfigTable.FatalErrorDumpOffset0 = config->FatalErrorDumpOffset0; saRoot->mainConfigTable.FatalErrorDumpLength0 = config->FatalErrorDumpLength0; saRoot->mainConfigTable.FatalErrorDumpOffset1 = config->FatalErrorDumpOffset1; saRoot->mainConfigTable.FatalErrorDumpLength1 = config->FatalErrorDumpLength1; */ #if defined(SALLSDK_FATAL_ERROR_DETECT) if( smIS_SPC(agRoot) ) /* SPC only */ { /* any fatal error happened */ /* executing this code impacts performance by 1% when no error is detected */ { agsaFatalErrorInfo_t fatal_error; bit32 value; bit32 value1; value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1); value1 = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2, MSGU_SCRATCH_PAD_2); if( (value & SA_FATAL_ERROR_SP1_AAP1_ERR_MASK) == SA_FATAL_ERROR_FATAL_ERROR || (value1 & SA_FATAL_ERROR_SP2_IOP_ERR_MASK) == SA_FATAL_ERROR_FATAL_ERROR ) { si_memset(&fatal_error, 0, sizeof(agsaFatalErrorInfo_t)); /* read detail fatal errors */ value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_0, MSGU_SCRATCH_PAD_0); fatal_error.errorInfo0 = value; SA_DBG1(("siProcessOBMsg: ScratchPad0 AAP error code 0x%x\n", value)); value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_1, MSGU_SCRATCH_PAD_1); fatal_error.errorInfo1 = value; /* AAP error state */ SA_DBG1(("siProcessOBMsg: AAP error state and error code 0x%x\n", value)); value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_2, MSGU_SCRATCH_PAD_2); fatal_error.errorInfo2 = value; /* IOP error state */ SA_DBG1(("siProcessOBMsg: IOP error state and error code 0x%x\n", value)); value = siHalRegReadExt(agRoot, GEN_MSGU_SCRATCH_PAD_3, MSGU_SCRATCH_PAD_3); SA_DBG1(("siProcessOBMsg: ScratchPad3 IOP error code 0x%x\n", value)); fatal_error.errorInfo3 = value; if (agNULL != saRoot) { fatal_error.regDumpBusBaseNum0 = saRoot->mainConfigTable.regDumpPCIBAR; fatal_error.regDumpOffset0 = saRoot->mainConfigTable.FatalErrorDumpOffset0; fatal_error.regDumpLen0 = saRoot->mainConfigTable.FatalErrorDumpLength0; fatal_error.regDumpBusBaseNum1 = saRoot->mainConfigTable.regDumpPCIBAR; fatal_error.regDumpOffset1 = saRoot->mainConfigTable.FatalErrorDumpOffset1; fatal_error.regDumpLen1 = saRoot->mainConfigTable.FatalErrorDumpLength1; } else { fatal_error.regDumpBusBaseNum0 = 0; fatal_error.regDumpOffset0 = 0; fatal_error.regDumpLen0 = 0; fatal_error.regDumpBusBaseNum1 = 0; fatal_error.regDumpOffset1 = 0; fatal_error.regDumpLen1 = 0; } /* Call Back with error */ SA_DBG1(("siProcessOBMsg: SALLSDK_FATAL_ERROR_DETECT \n")); ossaHwCB(agRoot, agNULL, OSSA_HW_EVENT_MALFUNCTION, 0, (void *)&fatal_error, agNULL); } } } #endif /* SALLSDK_FATAL_ERROR_DETECT */ smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "5r"); return processedMsgCount; } /******************************************************************************/ /*! \brief Function to enable/disable interrupts * * The saSystemInterruptsActive() function is called to indicate to the LL Layer * whether interrupts are available. The parameter sysIntsActive indicates whether * interrupts are available at this time. * * \param agRoot handles for this instance of SAS/SATA hardware * \param sysIntsActive flag for enable/disable interrupt * * \return -void- * */ /*******************************************************************************/ GLOBAL void saSystemInterruptsActive( agsaRoot_t *agRoot, agBOOLEAN sysIntsActive ) { bit32 x; agsaLLRoot_t *saRoot; SA_ASSERT((agNULL != agRoot), ""); if (agRoot == agNULL) { SA_DBG1(("saSystemInterruptsActive: agRoot == agNULL\n")); return; } saRoot = (agsaLLRoot_t *)(agRoot->sdkData); SA_ASSERT((agNULL != saRoot), ""); if (saRoot == agNULL) { SA_DBG1(("saSystemInterruptsActive: saRoot == agNULL\n")); return; } smTraceFuncEnter(hpDBG_TICK_INT,"5s"); SA_DBG1(("saSystemInterruptsActive: now 0x%X new 0x%x\n",saRoot->sysIntsActive,sysIntsActive)); SA_DBG3(("saSystemInterruptsActive: Doorbell_Set %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_Register), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_RegisterU))); SA_DBG3(("saSystemInterruptsActive: Doorbell_Mask %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_Register ), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_RegisterU ))); if( saRoot->sysIntsActive && sysIntsActive ) { SA_DBG1(("saSystemInterruptsActive: Already active 0x%X new 0x%x\n",saRoot->sysIntsActive,sysIntsActive)); smTraceFuncExit(hpDBG_TICK_INT, 'a', "5s"); return; } if( !saRoot->sysIntsActive && !sysIntsActive ) { if(smIS_SPC(agRoot)) { siHalRegWriteExt(agRoot, GEN_MSGU_ODMR, MSGU_ODMR,AGSA_INTERRUPT_HANDLE_ALL_CHANNELS ); } else { ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Mask_Set_Register, AGSA_INTERRUPT_HANDLE_ALL_CHANNELS); ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Mask_Set_RegisterU, AGSA_INTERRUPT_HANDLE_ALL_CHANNELS); } SA_DBG1(("saSystemInterruptsActive: Already disabled 0x%X new 0x%x\n",saRoot->sysIntsActive,sysIntsActive)); smTraceFuncExit(hpDBG_TICK_INT, 'b', "5s"); return; } /* Set the flag is sdkData */ saRoot->sysIntsActive = (bit8)sysIntsActive; smTrace(hpDBG_TICK_INT,"Vq",sysIntsActive); /* TP:Vq sysIntsActive */ /* If sysIntsActive is true */ if ( agTRUE == sysIntsActive ) { SA_DBG1(("saSystemInterruptsActive: Doorbell_Set %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_Register), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_RegisterU))); SA_DBG1(("saSystemInterruptsActive: Doorbell_Mask_Set %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_Register), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_RegisterU))); if(smIS_SPCV(agRoot)) { ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Clear_Register, 0xFFFFFFFF); ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Clear_RegisterU, 0xFFFFFFFF); } /* enable interrupt */ for(x=0; x < saRoot->numInterruptVectors; x++) { ossaReenableInterrupts(agRoot,x ); } if(saRoot->swConfig.fatalErrorInterruptEnable) { ossaReenableInterrupts(agRoot,saRoot->swConfig.fatalErrorInterruptVector ); } siHalRegWriteExt(agRoot, GEN_MSGU_ODMR, MSGU_ODMR, 0); } /* If sysIntsActive is false */ else { /* disable interrupt */ if(smIS_SPC(agRoot)) { siHalRegWriteExt(agRoot, GEN_MSGU_ODMR, MSGU_ODMR,AGSA_INTERRUPT_HANDLE_ALL_CHANNELS ); } else { ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Mask_Set_Register, AGSA_INTERRUPT_HANDLE_ALL_CHANNELS); ossaHwRegWriteExt(agRoot, PCIBAR0,V_Outbound_Doorbell_Mask_Set_RegisterU, AGSA_INTERRUPT_HANDLE_ALL_CHANNELS); } } SA_DBG3(("saSystemInterruptsActive: Doorbell_Set %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_Register), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Set_RegisterU))); SA_DBG3(("saSystemInterruptsActive: Doorbell_Mask %08X U %08X\n", ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_Register ), ossaHwRegReadExt(agRoot, PCIBAR0, V_Outbound_Doorbell_Mask_Set_RegisterU ))); smTraceFuncExit(hpDBG_TICK_INT, 'c', "5s"); } /******************************************************************************/ /*! \brief Routine to handle for received SAS with data payload event * * The handle for received SAS with data payload event * * \param agRoot handles for this instance of SAS/SATA hardware * \param pRequest handles for the IOrequest * \param pRespIU the pointer to the Response IU * \param param Payload Length * * \return -void- */ /*******************************************************************************/ GLOBAL void siEventSSPResponseWtDataRcvd( agsaRoot_t *agRoot, agsaIORequestDesc_t *pRequest, agsaSSPResponseInfoUnit_t *pRespIU, bit32 param, bit32 sspTag ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); agsaDeviceDesc_t *pDevice; bit32 count = 0; bit32 padCount; smTraceFuncEnter(hpDBG_VERY_LOUD,"5g"); /* get frame handle */ /* If the request is still valid */ if ( agTRUE == pRequest->valid ) { /* get device */ pDevice = pRequest->pDevice; /* Delete the request from the pendingIORequests */ ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); if (sspTag & SSP_RESCV_BIT) { /* get the pad count, bit 17 and 18 of sspTag */ padCount = (sspTag >> SSP_RESCV_PAD_SHIFT) & 0x3; /* get Residual Count */ count = *(bit32 *)((bit8 *)pRespIU + param + padCount); } (*(ossaSSPCompletedCB_t)(pRequest->completionCB))(agRoot, pRequest->pIORequestContext, OSSA_IO_SUCCESS, param, (void *)pRespIU, (bit16)(sspTag & SSPTAG_BITS), count); ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); pRequest->valid = agFALSE; /* return the request to free pool */ if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) { SA_DBG1(("siEventSSPResponseWtDataRcvd: saving pRequest (%p) for later use\n", pRequest)); saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); } else { /* return the request to free pool */ saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); } ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); } else { SA_DBG1(("siEventSSPResponseWtDataRcvd: pRequest->Valid not TRUE\n")); } smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "5g"); return; } /******************************************************************************/ /*! \brief Routine to handle successfully completed IO event * * Handle successfully completed IO * * \param agRoot handles for this instance of SAS/SATA hardware * \param pRequest Pointer of IO request of the IO * \param status status of the IO * * \return -void- */ /*******************************************************************************/ GLOBAL FORCEINLINE void siIODone( agsaRoot_t *agRoot, agsaIORequestDesc_t *pRequest, bit32 status, bit32 sspTag ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); agsaDeviceDesc_t *pDevice = agNULL; smTraceFuncEnter(hpDBG_VERY_LOUD,"5h"); SA_ASSERT(NULL != pRequest, "pRequest cannot be null"); /* If the request is still valid */ if ( agTRUE == pRequest->valid ) { /* get device */ pDevice = pRequest->pDevice; /* process different request type */ switch (pRequest->requestType & AGSA_REQTYPE_MASK) { case AGSA_SSP_REQTYPE: { SA_ASSERT(pRequest->valid, "pRequest not valid"); pRequest->completionCB(agRoot, pRequest->pIORequestContext, OSSA_IO_SUCCESS, 0, agNULL, (bit16)(sspTag & SSPTAG_BITS), 0); ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); /* Delete the request from the pendingIORequests */ saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); /* return the request to free pool */ pRequest->valid = agFALSE; saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); break; } case AGSA_SATA_REQTYPE: { SA_DBG5(("siIODone: SATA complete\n")); if ( agNULL != pRequest->pIORequestContext ) { SA_DBG5(("siIODone: Complete Request\n")); (*(ossaSATACompletedCB_t)(pRequest->completionCB))(agRoot, pRequest->pIORequestContext, OSSA_IO_SUCCESS, agNULL, 0, agNULL); } ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); /* Delete the request from the pendingIORequests */ saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); /* return the request to free pool */ saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); pRequest->valid = agFALSE; break; } case AGSA_SMP_REQTYPE: { if ( agNULL != pRequest->pIORequestContext ) { (*(ossaSMPCompletedCB_t)(pRequest->completionCB))(agRoot, pRequest->pIORequestContext, OSSA_IO_SUCCESS, 0, agNULL); } ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); /* Delete the request from the pendingSMPRequests */ saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); /* return the request to free pool */ if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) { SA_DBG1(("siIODone: saving pRequest (%p) for later use\n", pRequest)); saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); } else { saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); } ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); pRequest->valid = agFALSE; break; } default: { SA_DBG1(("siIODone: unknown request type (%x) is completed. HTag=0x%x\n", pRequest->requestType, pRequest->HTag)); break; } } } else { SA_DBG1(("siIODone: The request is not valid any more. HTag=0x%x requestType=0x%x\n", pRequest->HTag, pRequest->requestType)); } smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "5h"); } /******************************************************************************/ /*! \brief Routine to handle abnormal completed IO/SMP event * * Handle abnormal completed IO/SMP * * \param agRoot handles for this instance of SAS/SATA hardware * \param pRequest Pointer of IO request of the IO * \param status status of the IO * \param param Length * * \return -void- */ /*******************************************************************************/ GLOBAL void siAbnormal( agsaRoot_t *agRoot, agsaIORequestDesc_t *pRequest, bit32 status, bit32 param, bit32 sspTag ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); agsaDeviceDesc_t *pDevice; smTraceFuncEnter(hpDBG_VERY_LOUD,"5i"); if (agNULL == pRequest) { SA_DBG1(("siAbnormal: pRequest is NULL.\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "5i"); return; } /* If the request is still valid */ if ( agTRUE == pRequest->valid ) { /* get device */ SA_ASSERT((pRequest->pIORequestContext->osData != pRequest->pIORequestContext->sdkData), "pIORequestContext"); pDevice = pRequest->pDevice; /* remove the IO request from IOMap */ saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; saRoot->IOMap[pRequest->HTag].IORequest = agNULL; saRoot->IOMap[pRequest->HTag].agContext = agNULL; smTrace(hpDBG_VERY_LOUD,"P6",status ); /* TP:P6 siAbnormal status */ smTrace(hpDBG_VERY_LOUD,"P7",param ); /* TP:P7 siAbnormal param */ /* process different request type */ switch (pRequest->requestType & AGSA_REQTYPE_MASK) { case AGSA_SSP_REQTYPE: { (*(ossaSSPCompletedCB_t)(pRequest->completionCB))(agRoot, pRequest->pIORequestContext, status, param, agNULL, (bit16)(sspTag & SSPTAG_BITS), ((sspTag & SSP_AGR_S_BIT)? (1 << 0) : 0)); ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); /* Delete the request from the pendingIORequests */ saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); pRequest->valid = agFALSE; /* return the request to free pool */ if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) { SA_DBG1(("siAbnormal: saving pRequest (%p) for later use\n", pRequest)); saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); } else { /* return the request to free pool */ saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); } ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); break; } case AGSA_SATA_REQTYPE: { SA_DBG5(("siAbnormal: SATA \n")); if ( agNULL != pRequest->pIORequestContext ) { SA_DBG5(("siAbnormal: Calling SATACompletedCB\n")); (*(ossaSATACompletedCB_t)(pRequest->completionCB))(agRoot, pRequest->pIORequestContext, status, agNULL, param, agNULL); } ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); /* Delete the request from the pendingIORequests */ saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); /* return the request to free pool */ pRequest->valid = agFALSE; if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) { SA_DBG1(("siAbnormal: saving pRequest (%p) for later use\n", pRequest)); saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); } else { /* return the request to free pool */ saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); } ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); break; } case AGSA_SMP_REQTYPE: { if ( agNULL != pRequest->pIORequestContext ) { (*(ossaSMPCompletedCB_t)(pRequest->completionCB))(agRoot, pRequest->pIORequestContext, status, param, agNULL); } ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); /* Delete the request from the pendingSMPRequests */ saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); /* return the request to free pool */ pRequest->valid = agFALSE; if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) { SA_DBG1(("siAbnormal: saving pRequest (%p) for later use\n", pRequest)); saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); } else { /* return the request to free pool */ saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); } ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); break; } default: { SA_DBG1(("siAbnormal: unknown request type (%x) is completed. Tag=0x%x\n", pRequest->requestType, pRequest->HTag)); break; } } } else { SA_DBG1(("siAbnormal: The request is not valid any more. Tag=0x%x\n", pRequest->HTag)); } smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "5i"); return; } /******************************************************************************/ /*! \brief Routine to handle abnormal DIF completed IO/SMP event * * Handle abnormal completed IO/SMP * * \param agRoot handles for this instance of SAS/SATA hardware * \param pRequest Pointer of IO request of the IO * \param status status of the IO * \param param Length * * \return -void- */ /*******************************************************************************/ GLOBAL void siDifAbnormal( agsaRoot_t *agRoot, agsaIORequestDesc_t *pRequest, bit32 status, bit32 param, bit32 sspTag, bit32 *pMsg1 ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); agsaDeviceDesc_t *pDevice; smTraceFuncEnter(hpDBG_VERY_LOUD,"2S"); if (agNULL == pRequest) { SA_DBG1(("siDifAbnormal: pRequest is NULL.\n")); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2S"); return; } /* If the request is still valid */ if ( agTRUE == pRequest->valid ) { /* get device */ pDevice = pRequest->pDevice; /* remove the IO request from IOMap */ saRoot->IOMap[pRequest->HTag].Tag = MARK_OFF; saRoot->IOMap[pRequest->HTag].IORequest = agNULL; saRoot->IOMap[pRequest->HTag].agContext = agNULL; smTrace(hpDBG_VERY_LOUD,"P6",status ); /* TP:P6 siDifAbnormal status */ /* process different request type */ switch (pRequest->requestType & AGSA_REQTYPE_MASK) { case AGSA_SSP_REQTYPE: { agsaDifDetails_t agDifDetails; agsaSSPCompletionDifRsp_t *pIomb; pIomb = (agsaSSPCompletionDifRsp_t *)pMsg1; si_memset(&agDifDetails, 0, sizeof(agDifDetails)); OSSA_READ_LE_32(agRoot, &agDifDetails.UpperLBA, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionDifRsp_t,UpperLBA )); OSSA_READ_LE_32(agRoot, &agDifDetails.LowerLBA, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionDifRsp_t,LowerLBA )); OSSA_READ_LE_32(agRoot, &agDifDetails.sasAddressHi, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionDifRsp_t,sasAddressHi )); OSSA_READ_LE_32(agRoot, &agDifDetails.sasAddressLo, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionDifRsp_t,sasAddressLo)); OSSA_READ_LE_32(agRoot, &agDifDetails.ExpectedCRCUDT01, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionDifRsp_t,ExpectedCRCUDT01 )); OSSA_READ_LE_32(agRoot, &agDifDetails.ExpectedUDT2345, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionDifRsp_t,ExpectedUDT2345)); OSSA_READ_LE_32(agRoot, &agDifDetails.ActualCRCUDT01, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionDifRsp_t,ActualCRCUDT01 )); OSSA_READ_LE_32(agRoot, &agDifDetails.ActualUDT2345, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionDifRsp_t,ActualUDT2345)); OSSA_READ_LE_32(agRoot, &agDifDetails.DIFErrDevID, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionDifRsp_t,DIFErrDevID )); OSSA_READ_LE_32(agRoot, &agDifDetails.ErrBoffsetEDataLen, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionDifRsp_t,ErrBoffsetEDataLen )); agDifDetails.frame = (void *)(bit8*)(pIomb+ OSSA_OFFSET_OF(agsaSSPCompletionDifRsp_t, EDATA_FRM)); (*(ossaSSPCompletedCB_t)(pRequest->completionCB))(agRoot, pRequest->pIORequestContext, status, param, &agDifDetails, (bit16)(sspTag & SSPTAG_BITS), ((sspTag & SSP_AGR_S_BIT)? (1 << 0) : 0)); ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); pRequest->valid = agFALSE; /* Delete the request from the pendingIORequests */ saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); /* return the request to free pool */ if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) { SA_DBG1(("siDifAbnormal: saving pRequest (%p) for later use\n", pRequest)); saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); } else { /* return the request to free pool */ saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); } ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); break; } default: { SA_DBG1(("siDifAbnormal: unknown request type (%x) is completed. Tag=0x%x\n", pRequest->requestType, pRequest->HTag)); break; } } } else { SA_DBG1(("siDifAbnormal: The request is not valid any more. Tag=0x%x\n", pRequest->HTag)); } smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2S"); return; } /******************************************************************************/ /*! \brief Routine to handle for received SMP response event * * The handle for received SMP response event * * \param agRoot handles for this instance of SAS/SATA hardware * \param pIomb Pointer of payload of IOMB * \param payloadSize size of the payload * \param tag the tag of the request SMP * * \return -void- */ /*******************************************************************************/ GLOBAL void siSMPRespRcvd( agsaRoot_t *agRoot, agsaSMPCompletionRsp_t *pIomb, bit32 payloadSize, bit32 tag ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); agsaFrameHandle_t frameHandle; agsaIORequestDesc_t *pRequest; agsaDeviceDesc_t *pDevice; agsaPort_t *pPort; smTraceFuncEnter(hpDBG_VERY_LOUD,"5j"); /* get the request */ pRequest = (agsaIORequestDesc_t*)saRoot->IOMap[tag].IORequest; SA_ASSERT(pRequest, "pRequest"); /* get the port */ pPort = pRequest->pPort; SA_ASSERT(pPort, "pPort"); if (pRequest->IRmode == 0) { /* get frame handle - direct response mode */ frameHandle = (agsaFrameHandle_t)(&(pIomb->SMPrsp[0])); #if defined(SALLSDK_DEBUG) SA_DBG3(("saSMPRespRcvd(direct): smpRspPtr=0x%p - len=0x%x\n", frameHandle, payloadSize )); #endif /* SALLSDK_DEBUG */ } else { /* indirect response mode */ frameHandle = agNULL; } /* If the request is still valid */ if ( agTRUE == pRequest->valid ) { /* get device */ pDevice = pRequest->pDevice; SA_ASSERT(pDevice, "pDevice"); /* Delete the request from the pendingSMPRequests */ ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); saLlistIORemove(&(pDevice->pendingIORequests), &(pRequest->linkNode)); ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); /* If the request is from OS layer */ if ( agNULL != pRequest->pIORequestContext ) { if (agNULL == frameHandle) { /* indirect mode */ /* call back with success */ (*(ossaSMPCompletedCB_t)(pRequest->completionCB))(agRoot, pRequest->pIORequestContext, OSSA_IO_SUCCESS, payloadSize, frameHandle); } else { /* direct mode */ /* call back with success */ (*(ossaSMPCompletedCB_t)(pRequest->completionCB))(agRoot, pRequest->pIORequestContext, OSSA_IO_SUCCESS, payloadSize, frameHandle); } } /* remove the IO request from IOMap */ saRoot->IOMap[tag].Tag = MARK_OFF; saRoot->IOMap[tag].IORequest = agNULL; saRoot->IOMap[tag].agContext = agNULL; ossaSingleThreadedEnter(agRoot, LL_IOREQ_LOCKEQ_LOCK); pRequest->valid = agFALSE; if(saLlistIOGetCount(&(saRoot->freeReservedRequests)) < SA_RESERVED_REQUEST_COUNT) { SA_DBG1(("siSMPRespRcvd: saving pRequest (%p) for later use\n", pRequest)); saLlistIOAdd(&(saRoot->freeReservedRequests), &(pRequest->linkNode)); } else { /* return the request to free pool */ saLlistIOAdd(&(saRoot->freeIORequests), &(pRequest->linkNode)); } ossaSingleThreadedLeave(agRoot, LL_IOREQ_LOCKEQ_LOCK); } smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "5j"); return; } /******************************************************************************/ /*! \brief Routine to handle for received Phy Up event * * The handle for received Phy Up event * * \param agRoot handles for this instance of SAS/SATA hardware * \param phyId for the Phy Up event happened * \param agSASIdentify is the remote phy Identify * \param portId is the port context index of the phy up event * \param deviceId is the device context index * \param linkRate link up rate from SPC * * \return -void- */ /*******************************************************************************/ GLOBAL void siEventPhyUpRcvd( agsaRoot_t *agRoot, bit32 phyId, agsaSASIdentify_t *agSASIdentify, bit32 portId, bit32 npipps, bit8 linkRate ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); agsaPhy_t *pPhy = &(saRoot->phys[phyId]); agsaPort_t *pPort; agsaSASIdentify_t remoteIdentify; agsaPortContext_t *agPortContext; smTraceFuncEnter(hpDBG_VERY_LOUD,"5k"); /* Read remote SAS Identify from response message and save it */ remoteIdentify = *agSASIdentify; /* get port context from portMap */ SA_DBG2(("siEventPhyUpRcvd:PortID 0x%x PortStatus 0x%x PortContext %p\n",saRoot->PortMap[portId & PORTID_MASK].PortID,saRoot->PortMap[portId & PORTID_MASK].PortStatus,saRoot->PortMap[portId & PORTID_MASK].PortContext)); agPortContext = (agsaPortContext_t *)saRoot->PortMap[portId].PortContext; SA_DBG2(("siEventPhyUpRcvd: portID %d PortContext %p linkRate 0x%X\n", portId, agPortContext,linkRate)); if (smIS_SPCV8006(agRoot)) { SA_DBG1(("siEventPhyUpRcvd: SAS_PHY_UP received for SATA Controller\n")); return; } if (agNULL != agPortContext) { /* existing port */ pPort = (agsaPort_t *) (agPortContext->sdkData); pPort->portId = portId; /* include the phy to the port */ pPort->phyMap[phyId] = agTRUE; /* Set the port for the phy */ saRoot->phys[phyId].pPort = pPort; /* Update port state */ if (OSSA_PORT_VALID == (npipps & PORT_STATE_MASK)) { pPort->status &= ~PORT_INVALIDATING; saRoot->PortMap[portId].PortStatus &= ~PORT_INVALIDATING; SA_DBG1(("siEventPhyUpRcvd: portID %d PortContext %p, hitting workaround\n", portId, agPortContext)); } } else { ossaSingleThreadedEnter(agRoot, LL_PORT_LOCK); /* new port */ /* Allocate a free port */ pPort = (agsaPort_t *) saLlistGetHead(&(saRoot->freePorts)); if (agNULL != pPort) { /* Acquire port list lock */ saLlistRemove(&(saRoot->freePorts), &(pPort->linkNode)); /* setup the port data structure */ pPort->portContext.osData = agNULL; pPort->portContext.sdkData = pPort; /* Add to valid port list */ saLlistAdd(&(saRoot->validPorts), &(pPort->linkNode)); /* Release port list lock */ ossaSingleThreadedLeave(agRoot, LL_PORT_LOCK); /* include the phy to the port */ pPort->phyMap[phyId] = agTRUE; /* Set the port for the phy */ saRoot->phys[phyId].pPort = pPort; /* Setup portMap based on portId */ saRoot->PortMap[portId].PortID = portId; saRoot->PortMap[portId].PortContext = &(pPort->portContext); pPort->portId = portId; SA_DBG3(("siEventPhyUpRcvd: NewPort portID %d PortContext %p\n", portId, saRoot->PortMap[portId].PortContext)); } else { ossaSingleThreadedLeave(agRoot, LL_PORT_LOCK); /* pPort is agNULL*/ smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "5k"); return; } if (OSSA_PORT_VALID == (npipps & PORT_STATE_MASK)) { pPort->status &= ~PORT_INVALIDATING; saRoot->PortMap[portId].PortStatus &= ~PORT_INVALIDATING; } else { SA_DBG1(("siEventPhyUpRcvd: PortInvalid portID %d PortContext %p\n", portId, saRoot->PortMap[portId].PortContext)); } } /* adjust the bit fields before callback */ phyId = (linkRate << SHIFT8) | phyId; /* report PhyId, NPIP, PortState */ phyId |= (npipps & PHY_IN_PORT_MASK) | ((npipps & PORT_STATE_MASK) << SHIFT16); ossaHwCB(agRoot, &(pPort->portContext), OSSA_HW_EVENT_SAS_PHY_UP, phyId, agNULL, &remoteIdentify); /* set PHY_UP status */ PHY_STATUS_SET(pPhy, PHY_UP); smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "5k"); /* return */ return; } /******************************************************************************/ /*! \brief Routine to handle for received SATA signature event * * The handle for received SATA signature event * * \param agRoot handles for this instance of SAS/SATA hardware * \param phyId the phy id of the phy received the frame * \param pMsg the pointer to the message payload * \param portId the port context index of the phy up event * \param deviceId the device context index * \param linkRate link up rate from SPC * * \return -void- */ /*******************************************************************************/ GLOBAL void siEventSATASignatureRcvd( agsaRoot_t *agRoot, bit32 phyId, void *pMsg, bit32 portId, bit32 npipps, bit8 linkRate ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); agsaPhy_t *pPhy = &(saRoot->phys[phyId]); agsaPort_t *pPort = agNULL; agsaPortContext_t *agPortContext; #if defined(SALLSDK_DEBUG) agsaFisRegDeviceToHost_t *fisD2H; /* Read the D2H FIS */ fisD2H = (agsaFisRegDeviceToHost_t *)pMsg; #endif /* SALLSDK_DEBUG */ smTraceFuncEnter(hpDBG_VERY_LOUD,"5m"); SA_DBG5(("siEventSATASignatureRcvd: About to read the signatureFIS data\n")); SA_DBG5(("agsaFisRegDeviceToHost_t:\n")); SA_DBG5((" fisType = %x\n", fisD2H->h.fisType)); SA_DBG5((" i_pmPort = %x\n", fisD2H->h.i_pmPort)); SA_DBG5((" status = %x\n", fisD2H->h.status)); SA_DBG5((" error = %x\n", fisD2H->h.error)); SA_DBG5((" lbaLow = %x\n", fisD2H->d.lbaLow)); SA_DBG5((" lbaMid = %x\n", fisD2H->d.lbaMid)); SA_DBG5((" lbaHigh = %x\n", fisD2H->d.lbaHigh)); SA_DBG5((" device = %x\n", fisD2H->d.device)); SA_DBG5((" lbaLowExp = %x\n", fisD2H->d.lbaLowExp)); SA_DBG5((" lbaMidExp = %x\n", fisD2H->d.lbaMidExp)); SA_DBG5((" lbaHighExp = %x\n", fisD2H->d.lbaHighExp)); SA_DBG5((" reserved4 = %x\n", fisD2H->d.reserved4)); SA_DBG5((" sectorCount = %x\n", fisD2H->d.sectorCount)); SA_DBG5((" sectorCountExp = %x\n", fisD2H->d.sectorCountExp)); SA_DBG5((" reserved5 = %x\n", fisD2H->d.reserved5)); SA_DBG5((" reserved6 = %x\n", fisD2H->d.reserved6)); SA_DBG5((" reserved7 (32) = %08X\n", fisD2H->d.reserved7)); SA_DBG5(("siEventSATASignatureRcvd: GOOD signatureFIS data\n")); #if defined(SALLSDK_DEBUG) /* read signature */ pPhy->remoteSignature[0] = (bit8) fisD2H->d.sectorCount; pPhy->remoteSignature[1] = (bit8) fisD2H->d.lbaLow; pPhy->remoteSignature[2] = (bit8) fisD2H->d.lbaMid; pPhy->remoteSignature[3] = (bit8) fisD2H->d.lbaHigh; pPhy->remoteSignature[4] = (bit8) fisD2H->d.device; #endif /* get port context from portMap */ SA_DBG2(("siEventSATASignatureRcvd:PortID 0x%x PortStatus 0x%x PortContext %p\n",saRoot->PortMap[portId & PORTID_MASK].PortID,saRoot->PortMap[portId & PORTID_MASK].PortStatus,saRoot->PortMap[portId & PORTID_MASK].PortContext)); agPortContext = (agsaPortContext_t *)saRoot->PortMap[portId].PortContext; SA_DBG2(("siEventSATASignatureRcvd: portID %d PortContext %p\n", portId, agPortContext)); if (agNULL != agPortContext) { /* exist port */ pPort = (agsaPort_t *) (agPortContext->sdkData); pPort->portId = portId; /* include the phy to the port */ pPort->phyMap[phyId] = agTRUE; /* Set the port for the phy */ saRoot->phys[phyId].pPort = pPort; } else { ossaSingleThreadedEnter(agRoot, LL_PORT_LOCK); /* new port */ /* Allocate a free port */ pPort = (agsaPort_t *) saLlistGetHead(&(saRoot->freePorts)); if (agNULL != pPort) { /* Acquire port list lock */ saLlistRemove(&(saRoot->freePorts), &(pPort->linkNode)); /* setup the port data structure */ pPort->portContext.osData = agNULL; pPort->portContext.sdkData = pPort; /* Add to valid port list */ saLlistAdd(&(saRoot->validPorts), &(pPort->linkNode)); /* Release port list lock */ ossaSingleThreadedLeave(agRoot, LL_PORT_LOCK); /* include the phy to the port */ pPort->phyMap[phyId] = agTRUE; /* Set the port for the phy */ saRoot->phys[phyId].pPort = pPort; /* Setup portMap based on portId */ saRoot->PortMap[portId].PortID = portId; saRoot->PortMap[portId].PortContext = &(pPort->portContext); pPort->portId = portId; SA_DBG3(("siEventSATASignatureRcvd: NewPort portID %d portContect %p\n", portId, saRoot->PortMap[portId].PortContext)); } else { ossaSingleThreadedLeave(agRoot, LL_PORT_LOCK); /* pPort is agNULL*/ smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "5m"); return; } if (OSSA_PORT_VALID == (npipps & PORT_STATE_MASK)) { pPort->status &= ~PORT_INVALIDATING; saRoot->PortMap[portId].PortStatus &= ~PORT_INVALIDATING; } else { SA_DBG1(("siEventSATASignatureRcvd: PortInvalid portID %d PortContext %p\n", portId, saRoot->PortMap[portId].PortContext)); } } /* adjust the bit fields before callback */ phyId = (linkRate << SHIFT8) | phyId; /* report PhyId, NPIP, PortState */ phyId |= (npipps & PHY_IN_PORT_MASK) | ((npipps & PORT_STATE_MASK) << SHIFT16); ossaHwCB(agRoot, &(pPort->portContext), OSSA_HW_EVENT_SATA_PHY_UP, phyId, agNULL, pMsg); /* set PHY_UP status */ PHY_STATUS_SET(pPhy, PHY_UP); smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "5m"); /* return */ return; } /******************************************************************************/ /*! \brief Process Outbound IOMB Message * * Process Outbound IOMB from SPC * * \param agRoot Handles for this instance of SAS/SATA LL Layer * \param pMsg1 Pointer of Response IOMB message 1 * \param category category of outbpond IOMB header * \param opcode Opcode of Outbound IOMB header * \param bc buffer count of IOMB header * * \return success or fail * */ /*******************************************************************************/ GLOBAL bit32 mpiParseOBIomb( agsaRoot_t *agRoot, bit32 *pMsg1, mpiMsgCategory_t category, bit16 opcode ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); bit32 ret = AGSA_RC_SUCCESS; bit32 parserStatus = AGSA_RC_SUCCESS; smTraceFuncEnter(hpDBG_VERY_LOUD, "2f"); switch (opcode) { case OPC_OUB_COMBINED_SSP_COMP: { agsaSSPCoalescedCompletionRsp_t *pIomb = (agsaSSPCoalescedCompletionRsp_t *)pMsg1; agsaIORequestDesc_t *pRequest = agNULL; bit32 tag = 0; bit32 sspTag = 0; bit32 count = 0; #ifdef SALL_API_TEST saRoot->LLCounters.IOCounter.numSSPCompleted++; SA_DBG3(("mpiParseOBIomb, SSP_COMP Response received IOMB=%p %d\n", pMsg1, saRoot->LLCounters.IOCounter.numSSPCompleted)); #else SA_DBG3(("mpiParseOBIomb, OPC_OUB_COMBINED_SSP_COMP Response received IOMB=%p\n", pMsg1)); #endif /* get Tag */ for (count = 0; count < pIomb->coalescedCount; count++) { tag = pIomb->sspComplCxt[count].tag; sspTag = pIomb->sspComplCxt[count].SSPTag; pRequest = (agsaIORequestDesc_t *)saRoot->IOMap[tag].IORequest; SA_ASSERT((pRequest), "pRequest"); if(pRequest == agNULL) { SA_DBG1(("mpiParseOBIomb,OPC_OUB_COMBINED_SSP_COMP Resp IOMB tag=0x%x, status=0x%x, param=0x%x, SSPTag=0x%x\n", tag, OSSA_IO_SUCCESS, 0, sspTag)); #ifdef SA_ENABLE_PCI_TRIGGER if( saRoot->swConfig.PCI_trigger & PCI_TRIGGER_COAL_IOMB_ERROR ) { siPCITriger(agRoot); } #endif /* SA_ENABLE_PCI_TRIGGER */ return(AGSA_RC_FAILURE); } SA_ASSERT((pRequest->valid), "pRequest->valid"); #ifdef SA_ENABLE_PCI_TRIGGER if(!pRequest->valid) { if( saRoot->swConfig.PCI_trigger & PCI_TRIGGER_COAL_INVALID ) { siPCITriger(agRoot); } } #endif /* SA_ENABLE_PCI_TRIGGER */ SA_DBG3(("mpiParseOBIomb, OPC_OUB_COMBINED_SSP_COMP IOMB tag=0x%x, status=0x%x, param=0x%x, SSPTag=0x%x\n", tag, OSSA_IO_SUCCESS, 0, sspTag)); /* Completion of SSP without Response Data */ siIODone( agRoot, pRequest, OSSA_IO_SUCCESS, sspTag); } } break; case OPC_OUB_SSP_COMP: { #ifdef SALL_API_TEST saRoot->LLCounters.IOCounter.numSSPCompleted++; SA_DBG3(("mpiParseOBIomb, SSP_COMP Response received IOMB=%p %d\n", pMsg1, saRoot->LLCounters.IOCounter.numSSPCompleted)); #else SA_DBG3(("mpiParseOBIomb, SSP_COMP Response received IOMB=%p\n", pMsg1)); #endif /* process the SSP IO Completed response message */ mpiSSPCompletion(agRoot, pMsg1); break; } case OPC_OUB_COMBINED_SATA_COMP: { agsaSATACoalescedCompletionRsp_t *pIomb; agsaIORequestDesc_t *pRequest; bit32 tag; bit32 count; #ifdef SALL_API_TEST saRoot->LLCounters.IOCounter.numSSPCompleted++; SA_DBG3(("mpiParseOBIomb, OPC_OUB_COMBINED_SATA_COMP Response received IOMB=%p %d\n", pMsg1, saRoot->LLCounters.IOCounter.numSSPCompleted)); #else SA_DBG3(("mpiParseOBIomb, OPC_OUB_COMBINED_SATA_COMP Response received IOMB=%p\n", pMsg1)); #endif pIomb = (agsaSATACoalescedCompletionRsp_t *)pMsg1; /* get Tag */ for (count = 0; count < pIomb->coalescedCount; count++) { tag = pIomb->stpComplCxt[count].tag; pRequest = (agsaIORequestDesc_t *)saRoot->IOMap[tag].IORequest; SA_ASSERT((pRequest), "pRequest"); if(pRequest == agNULL) { SA_DBG1(("mpiParseOBIomb,OPC_OUB_COMBINED_SATA_COMP Resp IOMB tag=0x%x, status=0x%x, param=0x%x\n", tag, OSSA_IO_SUCCESS, 0)); return(AGSA_RC_FAILURE); } SA_ASSERT((pRequest->valid), "pRequest->valid"); SA_DBG3(("mpiParseOBIomb, OPC_OUB_COMBINED_SATA_COMP IOMB tag=0x%x, status=0x%x, param=0x%x\n", tag, OSSA_IO_SUCCESS, 0)); /* Completion of SATA without Response Data */ siIODone( agRoot, pRequest, OSSA_IO_SUCCESS, 0); } break; } case OPC_OUB_SATA_COMP: { #ifdef SALL_API_TEST saRoot->LLCounters.IOCounter.numSataCompleted++; SA_DBG3(("mpiParseOBIomb, SATA_COMP Response received IOMB=%p %d\n", pMsg1, saRoot->LLCounters.IOCounter.numSataCompleted)); #else SA_DBG3(("mpiParseOBIomb, SATA_COMP Response received IOMB=%p\n", pMsg1)); #endif /* process the response message */ mpiSATACompletion(agRoot, pMsg1); break; } case OPC_OUB_SSP_ABORT_RSP: { #ifdef SALL_API_TEST saRoot->LLCounters.IOCounter.numSSPAbortedCB++; #else SA_DBG3(("mpiParseOBIomb, SSP_ABORT Response received IOMB=%p\n", pMsg1)); #endif /* process the response message */ parserStatus = mpiSSPAbortRsp(agRoot, (agsaSSPAbortRsp_t *)pMsg1); if(parserStatus != AGSA_RC_SUCCESS) { SA_DBG3(("mpiParseOBIomb, mpiSSPAbortRsp FAIL IOMB=%p\n", pMsg1)); } break; } case OPC_OUB_SATA_ABORT_RSP: { #ifdef SALL_API_TEST saRoot->LLCounters.IOCounter.numSataAbortedCB++; #else SA_DBG3(("mpiParseOBIomb, SATA_ABORT Response received IOMB=%p\n", pMsg1)); #endif /* process the response message */ mpiSATAAbortRsp(agRoot, (agsaSATAAbortRsp_t *)pMsg1); break; } case OPC_OUB_SATA_EVENT: { SA_DBG3(("mpiParseOBIomb, SATA_EVENT Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSATAEvent(agRoot, (agsaSATAEventRsp_t *)pMsg1); break; } case OPC_OUB_SSP_EVENT: { SA_DBG3(("mpiParseOBIomb, SSP_EVENT Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSSPEvent(agRoot, (agsaSSPEventRsp_t *)pMsg1); break; } case OPC_OUB_SMP_COMP: { #ifdef SALL_API_TEST saRoot->LLCounters.IOCounter.numSMPCompleted++; SA_DBG3(("mpiParseOBIomb, SMP_COMP Response received IOMB=%p, %d\n", pMsg1, saRoot->LLCounters.IOCounter.numSMPCompleted)); #else SA_DBG3(("mpiParseOBIomb, SMP_COMP Response received IOMB=%p\n", pMsg1)); #endif /* process the response message */ mpiSMPCompletion(agRoot, (agsaSMPCompletionRsp_t *)pMsg1); break; } case OPC_OUB_ECHO: { #ifdef SALL_API_TEST saRoot->LLCounters.IOCounter.numEchoCB++; SA_DBG3(("mpiParseOBIomb, ECHO Response received %d\n", saRoot->LLCounters.IOCounter.numEchoCB)); #else SA_DBG3(("mpiParseOBIomb, ECHO Response received\n")); #endif /* process the response message */ mpiEchoRsp(agRoot, (agsaEchoRsp_t *)pMsg1); break; } case OPC_OUB_GET_NVMD_DATA: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_GET_NVMD_DATA received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGetNVMDataRsp(agRoot, (agsaGetNVMDataRsp_t *)pMsg1); break; } case OPC_OUB_SPC_HW_EVENT: { SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC"); SA_DBG3(("mpiParseOBIomb, OPC_OUB_SPC_HW_EVENT Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiHWevent(agRoot, (agsaHWEvent_SPC_OUB_t *)pMsg1); break; } case OPC_OUB_HW_EVENT: { SA_DBG3(("mpiParseOBIomb, HW_EVENT Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiHWevent(agRoot, (agsaHWEvent_SPC_OUB_t *)pMsg1); break; } case OPC_OUB_PHY_START_RESPONSE: { SA_DBG1(("mpiParseOBIomb, OPC_OUB_PHY_START_RESPONSE Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiPhyStartEvent( agRoot, (agsaHWEvent_Phy_OUB_t *)pMsg1 ); break; } case OPC_OUB_PHY_STOP_RESPONSE: { SA_DBG1(("mpiParseOBIomb, OPC_OUB_PHY_STOP_RESPONSE Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiPhyStopEvent( agRoot, (agsaHWEvent_Phy_OUB_t *)pMsg1 ); break; } case OPC_OUB_LOCAL_PHY_CNTRL: { SA_DBG3(("mpiParseOBIomb, PHY CONTROL Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiPhyCntrlRsp(agRoot, (agsaLocalPhyCntrlRsp_t *)pMsg1); break; } case OPC_OUB_SPC_DEV_REGIST: { SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC"); SA_DBG3(("mpiParseOBIomb, OPC_OUB_SPC_DEV_REGIST Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiDeviceRegRsp(agRoot, (agsaDeviceRegistrationRsp_t *)pMsg1); break; } case OPC_OUB_DEV_REGIST: { SA_DBG2(("mpiParseOBIomb, DEV_REGISTRATION Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiDeviceRegRsp(agRoot, (agsaDeviceRegistrationRsp_t *)pMsg1); break; } case OPC_OUB_DEREG_DEV: { SA_DBG3(("mpiParseOBIomb, DEREGISTRATION DEVICE Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiDeregDevHandleRsp(agRoot, (agsaDeregDevHandleRsp_t *)pMsg1); break; } case OPC_OUB_GET_DEV_HANDLE: { SA_DBG3(("mpiParseOBIomb, GET_DEV_HANDLE Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGetDevHandleRsp(agRoot, (agsaGetDevHandleRsp_t *)pMsg1); break; } case OPC_OUB_SPC_DEV_HANDLE_ARRIV: { SA_DBG3(("mpiParseOBIomb, SPC_DEV_HANDLE_ARRIV Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiDeviceHandleArrived(agRoot, (agsaDeviceHandleArrivedNotify_t *)pMsg1); break; } case OPC_OUB_DEV_HANDLE_ARRIV: { SA_DBG3(("mpiParseOBIomb, DEV_HANDLE_ARRIV Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiDeviceHandleArrived(agRoot, (agsaDeviceHandleArrivedNotify_t *)pMsg1); break; } case OPC_OUB_SSP_RECV_EVENT: { SA_DBG3(("mpiParseOBIomb, SSP_RECV_EVENT Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSSPReqReceivedNotify(agRoot, (agsaSSPReqReceivedNotify_t *)pMsg1); break; } case OPC_OUB_DEV_INFO: { SA_ASSERT((smIS_SPCV(agRoot)), "smIS_SPCV"); SA_DBG3(("mpiParseOBIomb, DEV_INFO Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGetDevInfoRsp(agRoot, (agsaGetDevInfoRspV_t *)pMsg1); break; } case OPC_OUB_GET_PHY_PROFILE_RSP: { SA_ASSERT((smIS_SPCV(agRoot)), "smIS_SPCV"); SA_DBG2(("mpiParseOBIomb, OPC_OUB_GET_PHY_PROFILE_RSP Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGetPhyProfileRsp(agRoot, (agsaGetPhyProfileRspV_t *)pMsg1); break; } case OPC_OUB_SET_PHY_PROFILE_RSP: { SA_ASSERT((smIS_SPCV(agRoot)), "smIS_SPCV"); SA_DBG3(("mpiParseOBIomb, OPC_OUB_SET_PHY_PROFILE_RSP Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSetPhyProfileRsp(agRoot, (agsaSetPhyProfileRspV_t *)pMsg1); break; } case OPC_OUB_SPC_DEV_INFO: { SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC"); SA_DBG3(("mpiParseOBIomb, DEV_INFO Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGetDevInfoRspSpc(agRoot, (agsaGetDevInfoRsp_t *)pMsg1); break; } case OPC_OUB_FW_FLASH_UPDATE: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_FW_FLASH_UPDATE Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiFwFlashUpdateRsp(agRoot, (agsaFwFlashUpdateRsp_t *)pMsg1); break; } case OPC_OUB_FLASH_OP_EXT_RSP: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_FLASH_OP_EXT_RSP Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiFwExtFlashUpdateRsp(agRoot, (agsaFwFlashOpExtRsp_t *)pMsg1); break; } #ifdef SPC_ENABLE_PROFILE case OPC_OUB_FW_PROFILE: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_FW_PROFILE Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiFwProfileRsp(agRoot, (agsaFwProfileRsp_t *)pMsg1); break; } #endif case OPC_OUB_SET_NVMD_DATA: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_SET_NVMD_DATA received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSetNVMDataRsp(agRoot, (agsaSetNVMDataRsp_t *)pMsg1); break; } case OPC_OUB_GPIO_RESPONSE: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_SET_GPIO_RESPONSE Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGPIORsp(agRoot, (agsaGPIORsp_t *)pMsg1); break; } case OPC_OUB_GPIO_EVENT: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_SET_GPIO_RESPONSE Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGPIOEventRsp(agRoot, (agsaGPIOEvent_t *)pMsg1); break; } case OPC_OUB_GENERAL_EVENT: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_SET_GENERAL_EVENT Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGeneralEventRsp(agRoot, (agsaGeneralEventRsp_t *)pMsg1); break; } case OPC_OUB_SAS_DIAG_MODE_START_END: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_SAS_DIAG_MODE_START_END Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSASDiagStartEndRsp(agRoot, (agsaSASDiagStartEndRsp_t *)pMsg1); break; } case OPC_OUB_SAS_DIAG_EXECUTE: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_SAS_DIAG_EXECUTE_RSP Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSASDiagExecuteRsp(agRoot, (agsaSASDiagExecuteRsp_t *)pMsg1); break; } case OPC_OUB_GET_TIME_STAMP: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_GET_TIME_STAMP Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGetTimeStampRsp(agRoot, (agsaGetTimeStampRsp_t *)pMsg1); break; } case OPC_OUB_SPC_SAS_HW_EVENT_ACK: { SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC"); SA_DBG3(("mpiParseOBIomb,OPC_OUB_SPC_SAS_HW_EVENT_ACK Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSASHwEventAckRsp(agRoot, (agsaSASHwEventAckRsp_t *)pMsg1); break; } case OPC_OUB_SAS_HW_EVENT_ACK: { SA_ASSERT((smIS_SPCV(agRoot)), "smIS_SPCV"); SA_DBG1(("mpiParseOBIomb, OPC_OUB_SAS_HW_EVENT_ACK Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSASHwEventAckRsp(agRoot, (agsaSASHwEventAckRsp_t *)pMsg1); break; } case OPC_OUB_PORT_CONTROL: { SA_DBG1(("mpiParseOBIomb, OPC_OUB_PORT_CONTROL Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiPortControlRsp(agRoot, (agsaPortControlRsp_t *)pMsg1); break; } case OPC_OUB_SMP_ABORT_RSP: { #ifdef SALL_API_TEST saRoot->LLCounters.IOCounter.numSMPAbortedCB++; SA_DBG3(("mpiParseOBIomb, SMP_ABORT Response received IOMB=%p, %d\n", pMsg1, saRoot->LLCounters.IOCounter.numSMPAbortedCB)); #else SA_DBG3(("mpiParseOBIomb, OPC_OUB_SMP_ABORT_RSP Response received IOMB=%p\n", pMsg1)); #endif /* process the response message */ mpiSMPAbortRsp(agRoot, (agsaSMPAbortRsp_t *)pMsg1); break; } case OPC_OUB_DEVICE_HANDLE_REMOVAL: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_DEVICE_HANDLE_REMOVAL received IOMB=%p\n", pMsg1)); /* process the response message */ mpiDeviceHandleRemoval(agRoot, (agsaDeviceHandleRemoval_t *)pMsg1); break; } case OPC_OUB_SET_DEVICE_STATE: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_SET_DEVICE_STATE received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSetDeviceStateRsp(agRoot, (agsaSetDeviceStateRsp_t *)pMsg1); break; } case OPC_OUB_GET_DEVICE_STATE: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_GET_DEVICE_STATE received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGetDeviceStateRsp(agRoot, (agsaGetDeviceStateRsp_t *)pMsg1); break; } case OPC_OUB_SET_DEV_INFO: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_SET_DEV_INFO received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSetDevInfoRsp(agRoot, (agsaSetDeviceInfoRsp_t *)pMsg1); break; } case OPC_OUB_SAS_RE_INITIALIZE: { SA_ASSERT((smIS_SPC(agRoot)), "smIS_SPC"); SA_DBG3(("mpiParseOBIomb, OPC_OUB_SAS_RE_INITIALIZE received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSasReInitializeRsp(agRoot, (agsaSasReInitializeRsp_t *)pMsg1); break; } case OPC_OUB_SGPIO_RESPONSE: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_SGPIO_RESPONSE Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiSGpioRsp(agRoot, (agsaSGpioRsp_t *)pMsg1); break; } case OPC_OUB_PCIE_DIAG_EXECUTE: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_PCIE_DIAG_EXECUTE Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiPCIeDiagExecuteRsp(agRoot, (agsaPCIeDiagExecuteRsp_t *)pMsg1); break; } case OPC_OUB_GET_VIST_CAP_RSP: { SA_DBG3(("mpiParseOBIomb, OPC_INB_GET_VIST_CAP Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGetVHistRsp(agRoot, (agsaGetVHistCapRsp_t *)pMsg1); break; } case 2104: { if(smIS_SPC6V(agRoot)) { SA_DBG3(("mpiParseOBIomb, OPC_OUB_GET_DFE_DATA_RSP Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGetDFEDataRsp(agRoot, (agsaGetDDEFDataRsp_t *)pMsg1); } if(smIS_SPC12V(agRoot)) { SA_DBG3(("mpiParseOBIomb, OPC_INB_GET_VIST_CAP Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiGetVHistRsp(agRoot, (agsaGetVHistCapRsp_t *)pMsg1); } else { SA_DBG1(("mpiParseOBIomb, 2104 Response received IOMB=%p\n", pMsg1)); /* process the response message */ } break; } case OPC_OUB_SET_CONTROLLER_CONFIG: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_SET_CONTROLLER_CONFIG Response received IOMB=%p\n", pMsg1)); mpiSetControllerConfigRsp(agRoot, (agsaSetControllerConfigRsp_t *)pMsg1); break; } case OPC_OUB_GET_CONTROLLER_CONFIG: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_GET_CONTROLLER_CONFIG Response received IOMB=%p\n", pMsg1)); mpiGetControllerConfigRsp(agRoot, (agsaGetControllerConfigRsp_t *)pMsg1); break; } case OPC_OUB_KEK_MANAGEMENT: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_KEK_MANAGEMENT Response received IOMB=%p\n", pMsg1)); mpiKekManagementRsp(agRoot, (agsaKekManagementRsp_t *)pMsg1); break; } case OPC_OUB_DEK_MANAGEMENT: { SA_DBG3(("mpiParseOBIomb, OPC_OUB_DEK_MANAGEMENT Response received IOMB=%p\n", pMsg1)); mpiDekManagementRsp(agRoot, (agsaDekManagementRsp_t *)pMsg1); break; } case OPC_OUB_OPR_MGMT: { SA_DBG1(("mpiParseOBIomb, OPC_OUB_OPR_MGMT Response received IOMB=%p\n", pMsg1)); mpiOperatorManagementRsp(agRoot, (agsaOperatorMangmenRsp_t *)pMsg1); break; } case OPC_OUB_ENC_TEST_EXECUTE: { SA_DBG1(("mpiParseOBIomb, OPC_OUB_ENC_TEST_EXECUTE Response received IOMB=%p\n", pMsg1)); mpiBistRsp(agRoot, (agsaEncryptBistRsp_t *)pMsg1); break; } case OPC_OUB_SET_OPERATOR: { SA_DBG1(("mpiParseOBIomb, OPC_OUB_SET_OPERATOR Response received IOMB=%p\n", pMsg1)); mpiSetOperatorRsp(agRoot, (agsaSetOperatorRsp_t *)pMsg1); break; } case OPC_OUB_GET_OPERATOR: { SA_DBG1(("mpiParseOBIomb, OPC_OUB_GET_OPERATOR Response received IOMB=%p\n", pMsg1)); mpiGetOperatorRsp(agRoot, (agsaGetOperatorRsp_t *)pMsg1); break; } case OPC_OUB_DIF_ENC_OFFLOAD_RSP: { SA_ASSERT((smIS_SPCV(agRoot)), "smIS_SPCV"); SA_DBG1(("mpiParseOBIomb, OPC_OUB_DIF_ENC_OFFLOAD_RSP Response received IOMB=%p\n", pMsg1)); /* process the response message */ mpiDifEncOffloadRsp(agRoot, (agsaDifEncOffloadRspV_t *)pMsg1); break; } default: { #ifdef SALL_API_TEST saRoot->LLCounters.IOCounter.numUNKNWRespIOMB++; SA_DBG1(("mpiParseOBIomb, UnKnown Response received IOMB=%p, %d\n", pMsg1, saRoot->LLCounters.IOCounter.numUNKNWRespIOMB)); #else SA_DBG1(("mpiParseOBIomb, Unknown IOMB Response received opcode 0x%X IOMB=%p\n",opcode, pMsg1)); #endif break; } } /* switch */ smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2f"); return ret; } /******************************************************************************/ /*! \brief SPC MPI SATA Completion * * This function handles the SATA completion. * * \param agRoot Handles for this instance of SAS/SATA LLL * \param pIomb1 Pointer of Message1 * \param bc buffer count * * \return The read value * */ /*******************************************************************************/ GLOBAL FORCEINLINE bit32 mpiSATACompletion( agsaRoot_t *agRoot, bit32 *pIomb1 ) { bit32 ret = AGSA_RC_SUCCESS; agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); bit32 status; bit32 tag; bit32 param; agsaIORequestDesc_t *pRequest; bit32 *agFirstDword; bit32 *pResp; smTraceFuncEnter(hpDBG_VERY_LOUD,"2s"); OSSA_READ_LE_32(AGROOT, &tag, pIomb1, OSSA_OFFSET_OF(agsaSATACompletionRsp_t, tag)) ; OSSA_READ_LE_32(AGROOT, &status, pIomb1, OSSA_OFFSET_OF(agsaSATACompletionRsp_t, status)) ; OSSA_READ_LE_32(AGROOT, ¶m, pIomb1, OSSA_OFFSET_OF(agsaSATACompletionRsp_t, param)) ; SA_DBG3(("mpiSATACompletion: start, HTAG=0x%x\n", tag)); /* get IOrequest from IOMap */ pRequest = (agsaIORequestDesc_t*)saRoot->IOMap[tag].IORequest; SA_ASSERT((pRequest), "pRequest"); if(agNULL == pRequest) { SA_DBG1(("mpiSATACompletion: agNULL == pRequest tag 0x%X status 0x%X\n",tag, status )); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "2s"); return AGSA_RC_FAILURE; } SA_ASSERT((pRequest->valid), "pRequest->valid"); if(!pRequest->valid) { SA_DBG1(("mpiSATACompletion: not valid IOMB tag=0x%x status=0x%x param=0x%x Device =0x%x\n", tag, status, param, pRequest->pDevice ? pRequest->pDevice->DeviceMapIndex : -1)); } switch (status) { case OSSA_IO_SUCCESS: { SA_DBG3(("mpiSATACompletion: OSSA_IO_SUCCESS, param=0x%x\n", param)); if (!param) { /* SATA request completion */ siIODone( agRoot, pRequest, OSSA_IO_SUCCESS, 0); } else { /* param number bytes of SATA Rsp */ agFirstDword = &pIomb1[3]; pResp = &pIomb1[4]; /* CB function to the up layer */ /* Response Length not include firstDW */ saRoot->IoErrorCount.agOSSA_IO_COMPLETED_ERROR_SCSI_STATUS++; SA_DBG2(("mpiSATACompletion: param 0x%x agFirstDwordResp 0x%x Resp 0x%x tag 0x%x\n",param,*agFirstDword,*pResp ,tag)); siEventSATAResponseWtDataRcvd(agRoot, pRequest, agFirstDword, pResp, (param - 4)); } break; } case OSSA_IO_ABORTED: { SA_DBG2(("mpiSATACompletion: OSSA_IO_ABORTED tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_ABORTED++; siAbnormal(agRoot, pRequest, status, param, 0); break; } case OSSA_IO_UNDERFLOW: { /* SATA Completion with error */ SA_DBG1(("mpiSATACompletion, OSSA_IO_UNDERFLOW tag 0x%X\n", tag)); /*underflow means underrun, treat it as success*/ saRoot->IoErrorCount.agOSSA_IO_UNDERFLOW++; siAbnormal(agRoot, pRequest, status, param, 0); break; } case OSSA_IO_NO_DEVICE: { SA_DBG1(("mpiSATACompletion, OSSA_IO_NO_DEVICE tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_NO_DEVICE++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFER_ERROR_BREAK: { SA_DBG1(("mpiSATACompletion, OSSA_IO_XFER_ERROR_BREAK SPC tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_BREAK++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFER_ERROR_PHY_NOT_READY: { SA_DBG1(("mpiSATACompletion, OSSA_IO_XFER_ERROR_PHY_NOT_READY tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_PHY_NOT_READY++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_BREAK: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_BREAK SPC tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_BREAK++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFER_ERROR_NAK_RECEIVED: { SA_DBG1(("mpiSATACompletion, OSSA_IO_XFER_ERROR_NAK_RECEIVED tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_NAK_RECEIVED++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFER_ERROR_DMA: { SA_DBG1(("mpiSATACompletion, OSSA_IO_XFER_ERROR_DMA tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_DMA++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT: { SA_DBG1(("mpiSATACompletion, OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE: { SA_DBG1(("mpiSATACompletion, OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFER_OPEN_RETRY_TIMEOUT: { SA_DBG1(("mpiSATACompletion, OSSA_IO_XFER_OPEN_RETRY_TIMEOUT tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFER_OPEN_RETRY_TIMEOUT++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_PORT_IN_RESET: { SA_DBG1(("mpiSATACompletion: OSSA_IO_PORT_IN_RESET tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_PORT_IN_RESET++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_DS_NON_OPERATIONAL: { SA_DBG1(("mpiSATACompletion: OSSA_IO_DS_NON_OPERATIONAL tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_DS_NON_OPERATIONAL++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_DS_IN_RECOVERY: { SA_DBG1(("mpiSATACompletion: OSSA_IO_DS_IN_RECOVERY tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_DS_IN_RECOVERY++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_DS_IN_ERROR: { SA_DBG1(("mpiSATACompletion: OSSA_IO_DS_IN_ERROR tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_DS_IN_ERROR++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: { SA_DBG1(("mpiSATACompletion: OSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_ABORT_IN_PROGRESS: { SA_DBG1(("mpiSATACompletion: OSSA_IO_ABORT_IN_PROGRESS tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_ABORT_IN_PROGRESS++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_ABORT_DELAYED: { SA_DBG1(("mpiSATACompletion: OSSA_IO_ABORT_DELAYED tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_ABORT_DELAYED++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY_ALT: { SA_DBG1(("mpiSATACompletion: OSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY_ALT tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY_ALT++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: { SA_DBG1(("mpiSATACompletion: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED HTAG = 0x%x\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO tag 0x%x\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO++; siAbnormal(agRoot, pRequest, status, 0, 0 ); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST tag 0x%x\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST++; siAbnormal(agRoot, pRequest, status, 0, 0 ); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE tag 0x%x\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE++; siAbnormal(agRoot, pRequest, status, 0, 0 ); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: { SA_DBG1(("mpiSATACompletion, OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED tag 0x%x\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED++; siAbnormal(agRoot, pRequest, status, 0, 0 ); break; } case OSSA_IO_DS_INVALID: { SA_DBG1(("mpiSATACompletion: OSSA_IO_DS_INVALID tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_DS_INVALID++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFER_ERR_LAST_PIO_DATAIN_CRC_ERR: { SA_DBG1(("mpiSATACompletion: OSSA_IO_XFER_ERR_LAST_PIO_DATAIN_CRC_ERR tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERR_LAST_PIO_DATAIN_CRC_ERR++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_MPI_IO_RQE_BUSY_FULL: { SA_DBG1(("mpiSATACompletion: OSSA_MPI_IO_RQE_BUSY_FULL tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_MPI_IO_RQE_BUSY_FULL++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } #ifdef REMOVED case OSSA_IO_XFER_ERR_EOB_DATA_OVERRUN: { SA_DBG1(("mpiSATACompletion: OSSA_IO_XFER_ERR_EOB_DATA_OVERRUN tag 0x%x\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERR_EOB_DATA_OVERRUN++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } #endif case OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE: { SA_DBG1(("mpiSATACompletion: OPC_OUB_SATA_COMP:OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE \n")); saRoot->IoErrorCount.agOSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_MPI_ERR_ATAPI_DEVICE_BUSY: { SA_DBG1(("mpiSATACompletion: OSSA_MPI_ERR_ATAPI_DEVICE_BUSY tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_MPI_ERR_ATAPI_DEVICE_BUSY++; siAbnormal(agRoot, pRequest, status, param, 0 ); break; } case OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS: { SA_DBG1(("mpiSATACompletion: OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID: { SA_DBG1(("mpiSATACompletion: OSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFR_ERROR_DEK_IV_MISMATCH: { SA_DBG1(("mpiSATACompletion: OSSA_IO_XFR_ERROR_DEK_IV_MISMATCH tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_IV_MISMATCH++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR: { SA_DBG1(("mpiSATACompletion: OSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_OPEN_CNX_ERROR_OPEN_PREEMPTED: { SA_DBG1(("mpiSATACompletion: OSSA_IO_OPEN_CNX_ERROR_OPEN_PREEMPTED tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_OPEN_PREEMPTED++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH: { SA_DBG1(("mpiSATACompletion: OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS: { SA_DBG1(("mpiSATACompletion: OSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } case OSSA_IO_XFR_ERROR_DEK_ILLEGAL_TABLE: { SA_DBG1(("mpiSATACompletion: OSSA_IO_XFR_ERROR_DEK_ILLEGAL_TABLE tag 0x%X\n", tag)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS++; siAbnormal(agRoot, pRequest, status, 0, 0); break; } default: { SA_DBG1(("mpiSATACompletion: Unknown status 0x%x tag 0x%x\n", status, tag)); saRoot->IoErrorCount.agOSSA_IO_UNKNOWN_ERROR++; siAbnormal(agRoot, pRequest, status, param, 0); break; } } /* The HTag should equal to the IOMB tag */ if (pRequest->HTag != tag) { SA_DBG1(("mpiSATACompletion: Error Htag %d not equal IOMBtag %d\n", pRequest->HTag, tag)); } smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "2s"); return ret; } /******************************************************************************/ /*! \brief SPC MPI SSP Completion * * This function handles the SSP completion. * * \param agRoot Handles for this instance of SAS/SATA LLL * \param pIomb1 Pointer of Message1 * \param bc buffer count * * \return The read value * */ /*******************************************************************************/ GLOBAL FORCEINLINE bit32 mpiSSPCompletion( agsaRoot_t *agRoot, bit32 *pIomb1 ) { agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData); agsaSSPCompletionRsp_t *pIomb = (agsaSSPCompletionRsp_t *)pIomb1; agsaIORequestDesc_t *pRequest = agNULL; agsaSSPResponseInfoUnit_t *pRespIU = agNULL; bit32 tag = 0; bit32 sspTag = 0; bit32 status, param = 0; bit32 ret = AGSA_RC_SUCCESS; smTraceFuncEnter(hpDBG_VERY_LOUD, "5A"); /* get Tag */ OSSA_READ_LE_32(agRoot, &tag, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, tag)); OSSA_READ_LE_32(agRoot, &status, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, status)); OSSA_READ_LE_32(agRoot, ¶m, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, param)); OSSA_READ_LE_32(agRoot, &sspTag, pIomb, OSSA_OFFSET_OF(agsaSSPCompletionRsp_t, SSPTag)); /* get SSP_START IOrequest from IOMap */ pRequest = (agsaIORequestDesc_t *)saRoot->IOMap[tag].IORequest; SA_ASSERT((pRequest), "pRequest"); if(pRequest == agNULL) { SA_DBG1(("mpiSSPCompletion,AGSA_RC_FAILURE SSP Resp IOMB tag=0x%x, status=0x%x, param=0x%x, SSPTag=0x%x\n", tag, status, param, sspTag)); smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "5A"); return(AGSA_RC_FAILURE); } SA_ASSERT((pRequest->valid), "pRequest->valid"); if(!pRequest->valid) { SA_DBG1(("mpiSSPCompletion, SSP Resp IOMB tag=0x%x, status=0x%x, param=0x%x, SSPTag=0x%x Device =0x%x\n", tag, status, param, sspTag, pRequest->pDevice ? pRequest->pDevice->DeviceMapIndex : -1)); } switch (status) { case OSSA_IO_SUCCESS: { if (!param) { /* Completion of SSP without Response Data */ siIODone( agRoot, pRequest, OSSA_IO_SUCCESS, sspTag); } else { /* Get SSP Response with Response Data */ pRespIU = (agsaSSPResponseInfoUnit_t *)&(pIomb->SSPrsp); if (pRespIU->status == 0x02 || pRespIU->status == 0x18 || pRespIU->status == 0x30 || pRespIU->status == 0x40 ) { /* SCSI status is CHECK_CONDITION, RESV_CONFLICT, ACA_ACTIVE, TASK_ABORTED */ saRoot->IoErrorCount.agOSSA_IO_COMPLETED_ERROR_SCSI_STATUS++; SA_DBG2(("mpiSSPCompletion: pRespIU->status 0x%x tag 0x%x\n", pRespIU->status,tag)); } siEventSSPResponseWtDataRcvd(agRoot, pRequest, pRespIU, param, sspTag); } break; } case OSSA_IO_XFR_ERROR_INVALID_SSP_RSP_FRAME: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_INVALID_SSP_RSP_FRAME tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_INVALID_SSP_RSP_FRAME++; /* Get SSP Response with Response Data */ pRespIU = (agsaSSPResponseInfoUnit_t *)&(pIomb->SSPrsp); if (pRespIU->status == 0x02 || pRespIU->status == 0x18 || pRespIU->status == 0x30 || pRespIU->status == 0x40 ) { /* SCSI status is CHECK_CONDITION, RESV_CONFLICT, ACA_ACTIVE, TASK_ABORTED */ saRoot->IoErrorCount.agOSSA_IO_COMPLETED_ERROR_SCSI_STATUS++; SA_DBG2(("mpiSSPCompletion: pRespIU->status 0x%x tag 0x%x\n", pRespIU->status,tag)); } siEventSSPResponseWtDataRcvd(agRoot, pRequest, pRespIU, param, sspTag); break; } case OSSA_IO_ABORTED: { #ifdef SALL_API_TEST saRoot->LLCounters.IOCounter.numSSPAborted++; SA_DBG3(("mpiSSPCompletion, OSSA_IO_ABORTED Response received IOMB=%p %d\n", pIomb1, saRoot->LLCounters.IOCounter.numSSPAborted)); #endif SA_DBG2(("mpiSSPCompletion, OSSA_IO_ABORTED IOMB tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_ABORTED++; /* SSP Abort CB */ siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_UNDERFLOW: { /* SSP Completion with error */ SA_DBG2(("mpiSSPCompletion, OSSA_IO_UNDERFLOW tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); /*saRoot->IoErrorCount.agOSSA_IO_UNDERFLOW++;*/ siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_NO_DEVICE: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_NO_DEVICE tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_NO_DEVICE++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_XFER_ERROR_BREAK: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFER_ERROR_BREAK tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_BREAK++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_XFER_ERROR_PHY_NOT_READY: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFER_ERROR_PHY_NOT_READY tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_PHY_NOT_READY++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION: { saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION++; siAbnormal(agRoot, pRequest, status, 0, sspTag); SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); break; } case OSSA_IO_OPEN_CNX_ERROR_BREAK: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_BREAK tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_BREAK++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_XFER_ERROR_NAK_RECEIVED: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFER_ERROR_NAK_RECEIVED tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_NAK_RECEIVED++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_XFER_ERROR_ACK_NAK_TIMEOUT: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFER_ERROR_ACK_NAK_TIMEOUT tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_ACK_NAK_TIMEOUT++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_XFER_ERROR_DMA: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFER_ERROR_DMA tag 0x%x ssptag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_DMA++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_XFER_OPEN_RETRY_TIMEOUT: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFER_OPEN_RETRY_TIMEOUT tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFER_OPEN_RETRY_TIMEOUT++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_XFER_ERROR_UNEXPECTED_PHASE: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFER_ERROR_UNEXPECTED_PHASE tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_UNEXPECTED_PHASE++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_XFER_ERROR_OFFSET_MISMATCH: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFER_ERROR_OFFSET_MISMATCH tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_OFFSET_MISMATCH++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_PORT_IN_RESET: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_PORT_IN_RESET tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_PORT_IN_RESET++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_DS_NON_OPERATIONAL: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_DS_NON_OPERATIONAL tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_DS_NON_OPERATIONAL++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_DS_IN_RECOVERY: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_DS_IN_RECOVERY tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_DS_IN_RECOVERY++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_TM_TAG_NOT_FOUND: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_TM_TAG_NOT_FOUND tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_TM_TAG_NOT_FOUND++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_XFER_PIO_SETUP_ERROR: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFER_PIO_SETUP_ERROR tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFER_PIO_SETUP_ERROR++; /* not allowed case. Therefore, return failed status */ siAbnormal(agRoot, pRequest, OSSA_IO_FAILED, param, sspTag); break; } case OSSA_IO_SSP_EXT_IU_ZERO_LEN_ERROR: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_SSP_IU_ZERO_LEN_ERROR tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_SSP_EXT_IU_ZERO_LEN_ERROR++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_DS_IN_ERROR: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_DS_IN_ERROR tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_DS_IN_ERROR++; /* not allowed case. Therefore, return failed status */ siAbnormal(agRoot, pRequest, OSSA_IO_FAILED, param, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY++; /* not allowed case. Therefore, return failed status */ siAbnormal(agRoot, pRequest, OSSA_IO_FAILED, param, sspTag); break; } case OSSA_IO_ABORT_IN_PROGRESS: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_ABORT_IN_PROGRESS tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_ABORT_IN_PROGRESS++; /* not allowed case. Therefore, return failed status */ siAbnormal(agRoot, pRequest, OSSA_IO_FAILED, param, sspTag); break; } case OSSA_IO_ABORT_DELAYED: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_ABORT_DELAYED tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_ABORT_DELAYED++; /* not allowed case. Therefore, return failed status */ siAbnormal(agRoot, pRequest, OSSA_IO_FAILED, param, sspTag); break; } case OSSA_IO_INVALID_LENGTH: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_INVALID_LENGTH tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_INVALID_LENGTH++; /* not allowed case. Therefore, return failed status */ siAbnormal(agRoot, pRequest, OSSA_IO_FAILED, param, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY_ALT: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY_ALT tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY_ALT++; /* not allowed case. Therefore, return failed status */ siAbnormal(agRoot, pRequest, OSSA_IO_FAILED, param, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED HTAG = 0x%x ssptag = 0x%x\n", tag, sspTag)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED++; siAbnormal(agRoot, pRequest, status, 0, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_DS_INVALID: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_DS_INVALID tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_DS_INVALID++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_MPI_IO_RQE_BUSY_FULL: { SA_DBG1(("mpiSSPCompletion: OSSA_MPI_IO_RQE_BUSY_FULL tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_MPI_IO_RQE_BUSY_FULL++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE: { SA_DBG1(("mpiSSPCompletion: OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_CIPHER_MODE_INVALID++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_XFR_ERROR_DEK_IV_MISMATCH: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_DEK_IV_MISMATCH tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_IV_MISMATCH++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_XFR_ERROR_INTERNAL_RAM: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_INTERNAL_RAM tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_INTERNAL_RAM++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_XFR_ERROR_DEK_ILLEGAL_TABLE: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_DEK_ILLEGAL_TABLE tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DEK_ILLEGAL_TABLE++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } #ifdef SA_TESTBASE_EXTRA /* TestBase */ case OSSA_IO_HOST_BST_INVALID: { SA_DBG1(("mpiParseOBIomb, OPC_OUB_SSP_COMP: OSSA_IO_HOST_BST_INVALID 0x%x\n", status)); siAbnormal(agRoot, pRequest, status, param, sspTag); break; } #endif /* SA_TESTBASE_EXTRA */ case OSSA_IO_XFR_ERROR_DIF_MISMATCH: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_DIF_MISMATCH tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DIF_MISMATCH++; siDifAbnormal(agRoot, pRequest, status, param, sspTag, pIomb1); break; } case OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH++; siDifAbnormal(agRoot, pRequest, status, param, sspTag, pIomb1); break; } case OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH++; siDifAbnormal(agRoot, pRequest, status, param, sspTag, pIomb1); break; } case OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH++; siDifAbnormal(agRoot, pRequest, status, param, sspTag, pIomb1); break; } case OSSA_IO_XFER_ERROR_DIF_INTERNAL_ERROR: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFER_ERROR_DIF_INTERNAL_ERROR tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERROR_DIF_INTERNAL_ERROR++; siDifAbnormal(agRoot, pRequest, status, param, sspTag, pIomb1); break; } case OSSA_IO_XFER_ERR_EOB_DATA_OVERRUN: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_XFER_ERR_EOB_DATA_OVERRUN tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_XFER_ERR_EOB_DATA_OVERRUN++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } case OSSA_IO_OPEN_CNX_ERROR_OPEN_PREEMPTED: { SA_DBG1(("mpiSSPCompletion: OSSA_IO_OPEN_CNX_ERROR_OPEN_PREEMPTED tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); saRoot->IoErrorCount.agOSSA_IO_OPEN_CNX_ERROR_OPEN_PREEMPTED++; siAbnormal(agRoot, pRequest, status, param, sspTag); break; } default: { SA_DBG1(("mpiSSPCompletion: Unknown tag 0x%x sspTag 0x%x status 0x%x param 0x%x\n", tag,sspTag,status,param)); /* not allowed case. Therefore, return failed status */ saRoot->IoErrorCount.agOSSA_IO_UNKNOWN_ERROR++; siAbnormal(agRoot, pRequest, OSSA_IO_FAILED, param, sspTag); break; } } smTraceFuncExit(hpDBG_VERY_LOUD, 'b', "5A"); return ret; }