--- ./source/private_module/ioc/ioc_hba.c	2020-11-02 03:31:37.146501375 +0000
+++ ./source/private_module/ioc/ioc_hba.c.hotpatch	2020-11-02 01:51:36.054501375 +0000
@@ -7022,25 +7022,26 @@
 *****************************************************************************/
 UNF_U32 IOC_QueueRoutine(UNF_VOID * v_pstHba)
 {
-#define IOC_IOB_ROUTINE_MAX_FAIL_COUNT 9
-#define IOC_IOB_ROUTINE_TIMEOUT_MS     (10 * 1000)
-
     UNF_U64     ulCurrentJiffies = jiffies;
     UNF_U32     uiLoop           = 0; 
     UNF_U32     uiRet            = RETURN_ERROR;
     IOC_HBA_S * pstHba           = v_pstHba;
     UNF_U64     ulRoutineIobStsFlag = 0;
-
+    UNF_ULONG   ulFlag = 0;
+    UNF_BOOL    bNewDetectIob = UNF_FALSE;
+    
     IOC_CHECK(INVALID_VALUE32, NULL != pstHba, return RETURN_ERROR);
 
     /* ֧Queue⣬߶˿ΪFCoEģʽ */
-    if ((!pstHba->ucFwSupportDFT) || (UNF_IOC_FCOE == pstHba->ucPortType))
+    if ((!pstHba->ucFwSupportDFT) || (UNF_IOC_FCOE == pstHba->ucPortType) || (B_TRUE == pstHba->usRemoving))
     {
         return RETURN_OK;
     }
 
     /* Ϊ˱RoutineIobStsFlagʹùбQueueӦı䣬ھֲʹ */
+    UNF_OS_SPIN_LOCK_IRQSAVE(&pstHba->stHbaLock, ulFlag);
     ulRoutineIobStsFlag = pstHba->ulRoutineIobStsFlag;
+    UNF_OS_SPIN_UNLOCK_IRQRESTORE(&pstHba->stHbaLock, ulFlag);
 
     /* Ѿϱchiperr⣬ȴӿڿµ */
     if (ulRoutineIobStsFlag & IOC_BIT_7)
@@ -7048,74 +7049,73 @@
         return RETURN_OK;
     }
 
-    if (ulCurrentJiffies - pstHba->ulRoutineIobStartTime < UNF_OS_MS_TO_JIFFIES(IOC_IOB_ROUTINE_TIMEOUT_MS))
+    if ((ulRoutineIobStsFlag & (IOC_BIT_0 | IOC_BIT_1 | IOC_BIT_2)) == (IOC_BIT_0 | IOC_BIT_1 | IOC_BIT_2))    /* 3жδյӦ */
     {
-        return RETURN_OK;
+        if (UNF_OS_TIMER_AFTER(ulCurrentJiffies, (pstHba->ulRoutineIobStartTime + UNF_OS_MS_TO_JIFFIES((10 * 1000))))) /* Ѿ10S */
+        {
+            UNF_TRACE(0x5738, UNF_LOG_LOGIN_ATT, UNF_MAJOR, 
+                       "HBA(0x%x) Iob routine timeout(0x%llx_0x%llx), report chip recover.", 
+                       pstHba->stPortCfg.uiPortID, ulCurrentJiffies, pstHba->ulRoutineIobStartTime);
+            (UNF_VOID)UNF_LowLevelPortEvent(pstHba->pstLport, UNF_PORT_CORE_FATAL_ERROR, NULL);
+            
+            /*Ѿϱchiperr7λΪ1*/
+            UNF_OS_SPIN_LOCK_IRQSAVE(&pstHba->stHbaLock, ulFlag);
+            pstHba->ulRoutineIobStsFlag |= IOC_BIT_7;
+            UNF_OS_SPIN_UNLOCK_IRQRESTORE(&pstHba->stHbaLock, ulFlag);  
+            
+            return RETURN_OK;
+        }
+        UNF_TRACE(0x5738, UNF_LOG_IO_ATT, UNF_MAJOR, 
+            "HBA(0x%x) last routine iob all not back (0x%llx_0x%llx) for %u ms.", 
+            pstHba->stPortCfg.uiPortID, ulCurrentJiffies, pstHba->ulRoutineIobStartTime, UNF_OS_JIFFIES_TO_MS(ulCurrentJiffies - pstHba->ulRoutineIobStartTime));
     }
-
-    if (0 == ulRoutineIobStsFlag)
+    else 
     {
-        pstHba->ulRoutineIobStartTime = ulCurrentJiffies;
-        UNF_OS_MEMSET(pstHba->aucRoutineIobFailCount, 0, sizeof(pstHba->aucRoutineIobFailCount));
-        uiRet = IOC_IobSendQueueRoutine(pstHba);
+        bNewDetectIob = UNF_TRUE;
+        UNF_OS_SPIN_LOCK_IRQSAVE(&pstHba->stHbaLock, ulFlag);            
+        pstHba->ulRoutineIobStartTime = jiffies;      
+        /* ̽IOBøñ */       
+        pstHba->ulRoutineIobStsFlag |= (IOC_BIT_0 | IOC_BIT_1 | IOC_BIT_2);
+        UNF_OS_SPIN_UNLOCK_IRQRESTORE(&pstHba->stHbaLock, ulFlag);
     }
-    else
-    {
-        for (uiLoop = 0; uiLoop < IOC_FCP_QSET_NUM + IOC_ELS_QSET_NUM; uiLoop++)
-        {
-            if (ulRoutineIobStsFlag & IOC_BIT(uiLoop))
-            {
-                pstHba->aucRoutineIobFailCount[uiLoop]++;
-            }
-
-            if (pstHba->aucRoutineIobFailCount[uiLoop] > IOC_IOB_ROUTINE_MAX_FAIL_COUNT)
-            {
-                UNF_TRACE(0x5738, UNF_LOG_EQUIP_ATT, UNF_MAJOR, 
-                          "HBA(0x%x) Iob routine fail, status flag(0x%llx), timeout count(%d_%d_%d), report chip recover.", 
-                          pstHba->stPortCfg.uiPortID, ulRoutineIobStsFlag, 
-                          pstHba->aucRoutineIobFailCount[0], pstHba->aucRoutineIobFailCount[1], 
-                          pstHba->aucRoutineIobFailCount[2]);
-
-                (UNF_VOID)UNF_LowLevelPortEvent(pstHba->pstLport, UNF_PORT_CORE_FATAL_ERROR, NULL);
 
-                /*Ѿϱchiperr7λΪ1*/
-                pstHba->ulRoutineIobStsFlag |= IOC_BIT_7;
-
-                return RETURN_OK;
-            }
+    uiRet = IOC_IobSendQueueRoutine(pstHba);
+    if ((RETURN_OK != uiRet) && (UNF_TRUE == bNewDetectIob)) /* ̽IOBʧ */
+    {       
+        UNF_OS_SPIN_LOCK_IRQSAVE(&pstHba->stHbaLock, ulFlag);            
+        pstHba->ulRoutineIobStsFlag &= ~(IOC_BIT_0 | IOC_BIT_1 | IOC_BIT_2);
+        UNF_OS_SPIN_UNLOCK_IRQRESTORE(&pstHba->stHbaLock, ulFlag);
+    }
+    
+    for (uiLoop = 0; uiLoop < IOC_FCP_QSET_NUM + IOC_ELS_QSET_NUM; uiLoop++)
+    {       
+        if (pstHba->aucRoutineIobFailCount[uiLoop] >= 3)
+        {
+            UNF_TRACE(0x5738, UNF_LOG_EQUIP_ATT, UNF_MAJOR, 
+                      "HBA(0x%x) Iob routine fail, status flag(0x%llx), timeout count(%d_%d_%d), report chip recover.", 
+                      pstHba->stPortCfg.uiPortID, ulRoutineIobStsFlag, pstHba->aucRoutineIobFailCount[0], 
+                      pstHba->aucRoutineIobFailCount[1], pstHba->aucRoutineIobFailCount[2]);            
+            (UNF_VOID)UNF_LowLevelPortEvent(pstHba->pstLport, UNF_PORT_CORE_FATAL_ERROR, NULL);               
+            /*Ѿϱchiperr7λΪ1*/
+            UNF_OS_SPIN_LOCK_IRQSAVE(&pstHba->stHbaLock, ulFlag);
+            pstHba->ulRoutineIobStsFlag |= IOC_BIT_7;
+            UNF_OS_SPIN_UNLOCK_IRQRESTORE(&pstHba->stHbaLock, ulFlag);  
+            
+            return RETURN_OK;
         }
         
-        UNF_TRACE(0x5738, UNF_LOG_EQUIP_ATT, UNF_MAJOR, 
-                  "HBA(0x%x) Iob routine timeout, status flag(0x%llx), timeout count(%d_%d_%d), retry.", 
-                  pstHba->stPortCfg.uiPortID, pstHba->ulRoutineIobStsFlag, 
-                  pstHba->aucRoutineIobFailCount[0], pstHba->aucRoutineIobFailCount[1], 
-                  pstHba->aucRoutineIobFailCount[2]);
-        
-        pstHba->ulRoutineIobStartTime = ulCurrentJiffies;
-        pstHba->ulRoutineIobStsFlag   = 0;
-        uiRet = IOC_IobSendQueueRoutine(pstHba);
-    }    
-
+        if (pstHba->aucRoutineIobFailCount[uiLoop] != 0)
+        {
+            UNF_TRACE(0x5738, UNF_LOG_EQUIP_ATT, UNF_MAJOR, 
+                      "HBA(0x%x) Iob routine timeout, status flag(0x%llx), timeout count(%d_%d_%d), retry.", 
+                      pstHba->stPortCfg.uiPortID, pstHba->ulRoutineIobStsFlag,  pstHba->aucRoutineIobFailCount[0], 
+                      pstHba->aucRoutineIobFailCount[1], pstHba->aucRoutineIobFailCount[2]);
+        }
+    }     
+    
     return uiRet;
 }
 
-/*****************************************************************************
-     : IOC_SetSimulatePcieErrCode
-   : PCIE
-   : IOC_HBA_S *pstHba  
-             UNF_U32 uiErrCode  
-             UNF_U32 uiTimes    
-   : 
-   ֵ  : UNF_S32
- ú  : 
-   : 
- 
- ޸ʷ      :
-  1.       : 2013625
-           : z00228969
-    ޸   : ɺ
-
-*****************************************************************************/
 UNF_S32 IOC_SetSimulatePcieErrCode(IOC_HBA_S *pstHba, UNF_U32 uiErrCode, UNF_U32 uiTimes)
 {
     UNF_U32 uiLoop = 0;
--- ./source/private_module/ioc/ioc_io.c	2020-11-02 03:31:37.150501375 +0000
+++ ./source/private_module/ioc/ioc_io.c.hotpatch	2020-10-31 02:46:04.618501375 +0000
@@ -2004,22 +2004,24 @@
 *****************************************************************************/
 UNF_U32 IOC_RcvQueueRoutineIobSts(UNF_VOID * pvQueue, const IOB_FW_DFT_RSP_S *pstIob)
 { 
-    IOC_HBA_S   *pstHba   = NULL;  
-    IOC_QUEUE_S *pstQueue = pvQueue;
+    IOC_HBA_S   *pstHba           = NULL;  
+    IOC_QUEUE_S *pstQueue         = pvQueue;
+    UNF_ULONG    ulFlag           = 0;
 
     pstHba = pstQueue->pstHba;
     IOC_CHECK(INVALID_VALUE32, NULL != pstHba, return RETURN_ERROR);
-    
+	
+    /* ȥӡӰ쵽ӡΪUNF_INFOôӡ򲻳ɣעⲻҪreturn */       
     if (pstHba->ulRoutineIobStartTime != pstIob->ullRspJiffies)
     {
-        UNF_TRACE(0x6241, UNF_LOG_EQUIP_ATT, UNF_MAJOR, "Routine Iob's jiffies is not match(%lu_%lu).",
+        UNF_TRACE(0x6241, UNF_LOG_EQUIP_ATT, UNF_INFO, "Routine Iob's jiffies is not match(%lu_%lu).",
                   pstHba->ulRoutineIobStartTime, pstIob->ullRspJiffies);
-
-        return RETURN_OK;
     }
-
-    clear_bit(pstQueue->usQId, (UNF_VOID*)&pstHba->ulRoutineIobStsFlag);
-    pstHba->aucRoutineIobFailCount[pstQueue->usQId] = 0;
+        
+    UNF_OS_SPIN_LOCK_IRQSAVE(&pstHba->stHbaLock, ulFlag);            
+    /* жеı */       
+    pstHba->ulRoutineIobStsFlag &= ~(IOC_BIT_0 | IOC_BIT_1 | IOC_BIT_2);
+    UNF_OS_SPIN_UNLOCK_IRQRESTORE(&pstHba->stHbaLock, ulFlag);
 
     return RETURN_OK;
 }
@@ -2030,8 +2032,6 @@
    : pvQueue  
              *pstIob  
    : 
-   ֵ  : 
- ú  : 
    : 
  
  ޸ʷ      :
--- ./source/private_module/ioc/ioc_iob.c	2020-11-02 03:31:37.138501375 +0000
+++ ./source/private_module/ioc/ioc_iob.c.hotpatch	2020-10-31 03:39:25.630501375 +0000
@@ -2884,11 +2884,11 @@
 
     UNF_U8             aucIob[IOC_WR_QUEUE_ELEM_SIZE] = {0};
     UNF_U32            uiRet                          = RETURN_ERROR;
+    UNF_U32            uiResult                       = RETURN_ERROR; /* ֻжж·ʧܲŷʧܣ·ɹ򷵳ɹ */
     UNF_U16            usLoop                         = 0;
     UNF_U16            usIobRetry                     = 0;
     IOC_QUEUE_S      * pstWrQueue                     = NULL;
-    IOB_FW_DFT_REQ_S * pstIob                         = NULL;
-    
+    IOB_FW_DFT_REQ_S * pstIob                         = NULL; 
     IOC_CHECK(INVALID_VALUE32, NULL != pstHba, return RETURN_ERROR);
 
     if(B_TRUE == pstHba->usRemoving)
@@ -2896,7 +2896,7 @@
         UNF_TRACE(0x6601, UNF_LOG_EQUIP_ATT, UNF_MAJOR, 
                   "HBA(0x%x) is removing, no need routine.", pstHba->stPortCfg.uiPortID);
 
-        return RETURN_ERROR;
+        return RETURN_ERROR;	/* ˴V3RETURN_OKܻΪֲ̬ԭЧʱñIOC_QueueRoutineҲһЧˣ˴OK/ERRORû */
     }
 
     pstIob = (IOB_FW_DFT_REQ_S *)aucIob;
@@ -2908,7 +2908,6 @@
     for (usLoop = 0; usLoop < pstHba->usQsetCount; usLoop++)
     {
         pstWrQueue = &(pstHba->pstQsetBase[usLoop].qWR);
-        set_bit(pstWrQueue->usQId, (UNF_VOID*)&pstHba->ulRoutineIobStsFlag);
 
         /* ҵѹ£IOB벻entry󱨣 */
         for (usIobRetry = 0; usIobRetry < IOC_IOB_RETRY_MAX; usIobRetry++ )
@@ -2920,26 +2919,27 @@
             }
 
             UNF_OS_MSLEEP(100);
-        }        
+        }  
+        
+        if (RETURN_OK == uiRet)
+        {
+            pstHba->aucRoutineIobFailCount[usLoop] = 0;
+            uiResult = RETURN_OK;    
+        }
+        else 
+        {            
+            pstHba->aucRoutineIobFailCount[usLoop]++;
+        }
     }
 
-    return uiRet;
+    return uiResult;
 }
 
 /*****************************************************************************
      : IOC_ProcessChipErrorEvent
    : FW쳣
    : const IOC_QUEUE_S * pstRspQueue  
-             const UNF_VOID *pvIob            
-   : 
-   ֵ  : UNF_U32
- ú  : 
-   : 
- 
- ޸ʷ      :
-  1.       : 2014326
-           : z00228969
-    ޸   : ɺ
+
 
 *****************************************************************************/
 UNF_U32 IOC_ProcessChipErrorEvent(const IOC_QUEUE_S * pstRspQueue, const CHIP_ERROR_EVENT_S *pstIob)
