--- ./source/private_module/quark/quark_inb.c	2020-04-30 00:03:49.182994000 +0800
+++ ./source/private_module/quark/quark_inb.c.hotpatch	2020-04-30 00:02:18.492769000 +0800
@@ -24,7 +24,7 @@
 #include "quark_adapter.h"
 
 
-
+extern OSP_S32 g_SwitchPhyByEccIsolation;
 /*----------------------------------------------*
  *           ⲿ                             *
  *----------------------------------------------*/
@@ -93,19 +93,19 @@
 	OSP_BOOL bMorePrioty = SAL_FALSE;
 	OSP_U32  uiCurSwitchPriorty = 0;
 	OSP_U32  uiLastSwitchPriorty = 0;
-
 	uiCurSwitchPriorty = Quark_GetPhySwitchReasonPriority(enCurSwitchPhyReason);
-	uiLastSwitchPriorty = Quark_GetPhySwitchReasonPriority(enLastStopPhyReason);
-
+	if (enLastStopPhyReason == g_SwitchPhyByEccIsolation) {
+		uiLastSwitchPriorty = 70;	/* closephy λоƬܿphy */
+	} else {
+		uiLastSwitchPriorty = Quark_GetPhySwitchReasonPriority(enLastStopPhyReason);
+	}
 	if (uiCurSwitchPriorty >= uiLastSwitchPriorty)
 	{
 		bMorePrioty = SAL_TRUE;
 	}
-	else
-	{
+	else {
 		bMorePrioty = SAL_FALSE;
 	}
-
 	return bMorePrioty;
 }
 /*DTS2017030700782 BDMͳIOʱλ޸룬ⲿڲ򿪷  xierenfeng 00221118 2017.3.1 end*/
--- ./source/private_module/quark/quark_init.c	2020-04-30 00:03:49.182994000 +0800
+++ ./source/private_module/quark/quark_init.c.hotpatch	2020-05-18 18:38:48.418801000 +0800
@@ -48,9 +48,9 @@
  * ⲿ˵                                 *
  *----------------------------------------------*/
 extern OSP_CHAR g_acLLSoftVer[SAL_MAX_CARD_NUM][SAL_MAX_CHIP_VER_STR_LEN];
-/*----------------------------------------------*
- * ȫֱ                                     *
- *----------------------------------------------*/
+extern OSP_VOID Quark_InitBitEccRecovInfo(OSP_U8 ucCardNo);
+extern OSP_VOID Quark_CheckCardIsolateReport(SAL_CARD_S *v_pstSALCard);
+
 
 /*----------------------------------------------*
  * ģ鼶                                   *
@@ -3383,7 +3383,7 @@
         *v_uiLogicId = uiPortLogicId;
 
     }
-
+    Quark_InitBitEccRecovInfo(pstSALCard->ucCardNo);	/* ʼ޸״̬ */
     return RETURN_OK;
 }
 
@@ -5175,6 +5175,7 @@
             
         case SAL_CHIP_OPT_ROUTE_CHECK:
             iRet = Quark_ChipFatalCheck(v_pstSalCard,v_ArgcIn);
+            Quark_CheckCardIsolateReport(v_pstSalCard);   /* ӿڿǷѾ룬Ѿ룬ϱchipfault */
             break;
             
         case SAL_CHIP_OPT_CLOCK_CHECK:    
--- ./source/private_module/quark/quark_outb.c	2020-04-30 00:02:18.492769000 +0800
+++ ./source/private_module/quark/quark_outb.c.hotpatch	2020-05-04 10:38:06.035035000 +0800
@@ -23,20 +23,20 @@
 
 //lint -e801
 
-
+#define STOP_PHY_ASYNC_MAGIC   0x5A5AA5A5	/* 첽phyı */
 Quark_ReqCB g_apfQuarkReqCB[QUARK_MAX_REQ_TYPE_NUM];
 Quark_EventCB g_apfQuarkHWEvent[QUARK_MAX_HW_EVNET_NUM];
 extern QUARK_EVENT_CODE_MAP_S g_stEventCodeMap[SAL_DEV_TYPE_BUTT][SAL_MAX_ERRHANDLE_ACTION_NUM];
-
-
-/*----------------------------------------------*
- * ⲿԭ˵                             *
- *----------------------------------------------*/
-
-
-/*----------------------------------------------*
- * ڲԭ˵                             *
- *----------------------------------------------*/
+OSP_VOID Quark_HandleSpecialSasEvent(OSP_U32 v_uiEvent, QUARK_CARD_S *v_pstCard, SAL_PORT_S *pstSalPort);
+/* SAS޸״̬ö */
+typedef enum tagSAS_CARD_RECOVERY_SATUS_E
+{
+    SAS_CARD_NORMAL,
+    SAS_CARD_SOFT_RESET,
+    SAS_CARD_CHIP_ERROR,
+    SAS_CARD_ISOLATED,
+    SAS_CARD_BUTT
+}SAS_CARD_RECOVERY_SATUS_E;
 OSP_VOID Quark_PhyUp(QUARK_CARD_S *v_pstCard, QUARK_HW_EVENT_OUB_S *v_pstHWEvent);
 OSP_VOID Quark_PhyDown(QUARK_CARD_S *v_pstCard, QUARK_HW_EVENT_OUB_S *v_pstHWEvent);
 OSP_S32 Quark_IniSSPCompRecv(QUARK_CARD_S *v_pstCard, QUARK_IO_MAP_S *v_pstReq,
@@ -48,18 +48,18 @@
 				                           QUARK_IO_MAP_S **v_pstReq, 
 				                           OSP_U32 v_uiTag, 
 				                           OSP_U32 v_uiReqType);
-
-
-
-
-/*------------------------------ģIOʱ----------------*/
+typedef struct tagSAS_CARD_RECOVERY_RECORD_S {
+    SAS_CARD_RECOVERY_SATUS_E eRecoveryStatus;		/* ޸״̬ */
+    OSP_BOOL bReportAlarmStat; 						/* ¼ĸ澯״̬TRUEΪѸ */  
+    OSP_ULONG ulLastRecoveryTime;					/* һ޸ʱ */
+}SAS_CARD_RECOVERY_RECORD_S;
 //extern OSP_U32 uiSalSimIoFatal;
 QUARK_SIM_IOBack_S sim_io_back3, sim_io_back4, sim_io_back5;
 SAS_TIMER_S stIObackTimer;  /* ģIOʱصTimer */
-/*------------------------------ģIOʱ----------------*/
-
-
-
+/* 򲹶û취SAL_SWITCH_PHY_REASON_EöмӺֱ꣬Ӷȫֱֵ0x100,SAL_SWITCH_PHY_REASON_E汾ֵͻ */
+OSP_S32 g_SwitchPhyByEccIsolation = 0x100;
+/* SAS8072״̬¼ÿſһṹ */
+SAS_CARD_RECOVERY_RECORD_S g_eCardRecoveryRecord[SAL_MAX_CARD_NUM];
 /*****************************************************************************
      : Quark_GetSALPhyRate
    : ͨFirmwareڲRATEȡSAS LAYER
@@ -346,6 +346,9 @@
 
         pstReq->uiStatus = RETURN_ERROR;
 		SAS_COMPLETE(&pstReq->stInboundComplete);
+		if (STOP_PHY_ASYNC_MAGIC == pstReq->stDMA.uiIODataLen) {
+			pstReq->stDMA.uiIODataLen = 0; Quark_FreeReq(v_pstLLCard, pstQuarkStopPhyRsp->uiTag);
+		}
 		return RETURN_ERROR;
     }
     else
@@ -359,12 +362,9 @@
                     uiStatus );
     }
     pstReq->uiStatus = RETURN_OK;
-
     pstLLPhy = &v_pstLLCard->astPhy[uiPhyId];
-
     pstSalPhy = pstLLPhy->pstUpLLPhy;
     uiPortId = pstSalPhy->ucPortId;
-
     pstLLPort = Quark_GetPortByPortId(v_pstLLCard, uiPortId);
     if (NULL != pstLLPort)
     {
@@ -381,10 +381,12 @@
 		
 			pstReq->uiStatus = RETURN_ERROR;
 			SAS_COMPLETE(&pstReq->stInboundComplete);
+			if (STOP_PHY_ASYNC_MAGIC == pstReq->stDMA.uiIODataLen) {
+				pstReq->stDMA.uiIODataLen = 0; Quark_FreeReq(v_pstLLCard, pstQuarkStopPhyRsp->uiTag);
+			}
 			return RETURN_ERROR;
 		}
 		/*END ⵥ:DTS2014121900804 add by chengwei 90006017 2014-12-18 */
-
 		if (uiFwPortId != uiPortId)
 		{
 			QUARK_TRACE(OSP_DBL_MAJOR, 4673, "Card:%d Phy:%2d belong to port:%d(state:0x%x) is abnormal(old:%d)",
@@ -393,12 +395,13 @@
 						uiFwPortId,
 						uiPortState,
 						uiPortId);
-		
 			pstReq->uiStatus = RETURN_ERROR;
 			SAS_COMPLETE(&pstReq->stInboundComplete);
+			if (STOP_PHY_ASYNC_MAGIC == pstReq->stDMA.uiIODataLen) {
+				pstReq->stDMA.uiIODataLen = 0; Quark_FreeReq(v_pstLLCard, pstQuarkStopPhyRsp->uiTag);
+			}
 			return RETURN_ERROR;
 		}
-
     	if (0 == uiPhyNum)
     	{
     	    SAS_SPIN_LOCK_IRQSAVE(&v_pstLLCard->stCardLock, ulFlag);
@@ -409,24 +412,21 @@
 											v_pstLLCard->ucCardId,
 											uiPortId);		
     	}
-
         pstSalPort = pstLLPort->pstUpLLPort;
     }
-
     SAS_MEMSET(&stPhyEventInfo, 0, sizeof(SAL_PHY_EVENT_S));
-
     stPhyEventInfo.enLinkRate = SAL_LINK_RATE_FREE;
     stPhyEventInfo.enEvent = SAL_PHY_EVENT_STOP_RSP;
     stPhyEventInfo.uiFwPortId = uiPortId;
     stPhyEventInfo.uiPhyId = uiPhyId;
     stPhyEventInfo.uiCardId = v_pstLLCard->ucCardId;
-
     (OSP_VOID)SAL_PhyEvent(pstSalPort,
                            pstSalPhy,
                            stPhyEventInfo);
-
     SAS_COMPLETE(&pstReq->stInboundComplete);
-
+	if (STOP_PHY_ASYNC_MAGIC == pstReq->stDMA.uiIODataLen) {
+		pstReq->stDMA.uiIODataLen = 0; Quark_FreeReq(v_pstLLCard, pstQuarkStopPhyRsp->uiTag);
+	}
     return RETURN_OK;
 
 }
@@ -3711,22 +3711,22 @@
 	                                                                   OSP_U32 v_uiOrgEventCode,
 	                                                                   OSP_U32 *v_puiClass)
 {
-    SAL_ERR_HANDLE_ACTION_E enEventOpcode = SAL_ERR_HANDLE_ACTION_BUTT;
-	
+	SAL_PORT_S *pstSalPort = NULL;
+    SAL_ERR_HANDLE_ACTION_E enEventOpcode = SAL_ERR_HANDLE_ACTION_BUTT;	
 	switch (v_uiOrgEventCode)
 	{
 		/*Ҫhost reset߸÷֧Ӷ0x50 0x54 0x56Ĵ*/
 		case QUARK_IO_XFER_ERROR_INTERNAL_CRC_ERROR:
 		case QUARK_IO_SGL_LENGTH_MISMATCH_DATA:
 		case QUARK_IO_XFER_READ_COMPL_ERR: 
-			enEventOpcode = QUARK_UnexpectSASEventProc(v_pstQuarkCard, v_pstMsg, 
-				                                       v_enDevType, v_uiOrgEventCode, v_puiClass);
+        	pstSalPort = v_pstMsg->pstDev->pstPort;       
+        	Quark_HandleSpecialSasEvent(v_uiOrgEventCode, v_pstQuarkCard, pstSalPort); 
+			enEventOpcode = SAL_ERR_HANDLE_ACTION_BUTT;
 		    break ;
 		default :
 			enEventOpcode = Quark_EventCodeTransform(v_pstMsg, v_enDevType, v_uiOrgEventCode, v_puiClass);
 			break;
-	}
-	   
+	}   
 	return enEventOpcode;
 
 }
@@ -5375,6 +5375,139 @@
     return ;
 }
 
+/*****************************************************************************       
+    : Quark_StopPhySasEvent       
+  : ·ֹͣphyϢӲ
+  :        
+  :        
+  ֵ  : OSP_S32       
+*****************************************************************************/        
+OSP_S32 Quark_StopPhySasEvent(QUARK_CARD_S *v_pstLLCard, OSP_U32 v_uiPhyId)
+{
+    QUARK_PHY_STOP_CMND_S stCmnd;
+    QUARK_IO_MAP_S *pstReq = NULL;
+
+    QUARK_TRACE(OSP_DBL_INFO, 4315, "Card:%d is going to stop phy:%2d.",
+                    v_pstLLCard->ucCardId, v_uiPhyId);
+
+    /* ׼· */       
+    pstReq = Quark_GetReq(v_pstLLCard);  
+    if (NULL == pstReq)
+    {       
+        QUARK_TRACE(OSP_DBL_MAJOR, 4316, "Card:%d get req failed.", v_pstLLCard->ucCardId);       
+        return RETURN_ERROR;       
+    }
+    
+    pstReq->stDMA.uiIODataLen = STOP_PHY_ASYNC_MAGIC; 
+
+    SAS_MEMSET(&stCmnd, 0, sizeof(QUARK_PHY_STOP_CMND_S));
+    pstReq->uiReqType = QUARK_OPC_INB_PHYSTOP;
+    stCmnd.uiTag = pstReq->uiHTag;
+    stCmnd.uiRelportPhyid = (QUARK_RELEASE_PORT_PS_INVALID_STAT << QUARK_RELEASE_PORT_SHIFT) | v_uiPhyId;
+
+    if (RETURN_OK != Quark_SendIOMB(v_pstLLCard, (OSP_U8*)&stCmnd, QUARK_OPC_INB_PHYSTOP,
+                                    (sizeof(QUARK_PHY_STOP_CMND_S) + QUARK_MPI_HEADER_LEN),
+                                    DEFAULT_IOMB_QUEUE))
+    {       
+        QUARK_TRACE(OSP_DBL_MAJOR, 4317, "Card:%d send IOMB failed,Tag:0x%x.", v_pstLLCard->ucCardId, stCmnd.uiTag); 
+        Quark_FreeReq(v_pstLLCard, pstReq->uiHTag);
+        return RETURN_ERROR;
+    }    
+    
+    return RETURN_OK;       
+}       
+
+/*****************************************************************************       
+    : Quark_HandleSpecialSasEvent       
+  : ޸¼ӦĴ
+  :        
+  :        
+  ֵ  : OSP_VOID       
+*****************************************************************************/        
+OSP_VOID Quark_HandleSpecialSasEvent(OSP_U32 v_uiEvent, QUARK_CARD_S *v_pstCard, SAL_PORT_S *pstSalPort)       
+{       
+    OSP_ULONG ulFlag = 0; 
+    OSP_U8 ucCardId = 0;  
+    OSP_U32 uiPhyId = 0;
+    SAL_CARD_S *pstSalCard = NULL;
+
+    QUARK_ASSERT(NULL != v_pstCard, return);
+    QUARK_ASSERT(NULL != pstSalPort, return);
+    QUARK_ASSERT(SAL_MAX_CARD_NUM > v_pstCard->ucCardId, return);
+
+    ucCardId = v_pstCard->ucCardId;
+    pstSalCard = v_pstCard->pstSALCard;
+    QUARK_ASSERT(NULL != pstSalCard, return);
+    
+    SAS_SPIN_LOCK_IRQSAVE(&pstSalCard->stCardLock, ulFlag);
+    /* оƬûи */     
+    if (g_eCardRecoveryRecord[ucCardId].eRecoveryStatus != SAS_CARD_ISOLATED)
+    {
+        g_eCardRecoveryRecord[ucCardId].eRecoveryStatus = SAS_CARD_ISOLATED;
+        g_eCardRecoveryRecord[ucCardId].ulLastRecoveryTime = jiffies;
+        SAS_SPIN_UNLOCK_IRQRESTORE(&pstSalCard->stCardLock, ulFlag);
+        QUARK_TRACE(OSP_DBL_MAJOR, 1, "Card:%d event 0x%x close port 0x%x.", ucCardId, v_uiEvent, pstSalPort->uiLogicId);       
+
+        for (uiPhyId = 0; uiPhyId < pstSalCard->uiPhyNum; uiPhyId++)
+        {
+            /* Ѿر */
+            if (SAL_PHY_CLOSED == pstSalCard->apstPhy[uiPhyId]->ucLinkStatus)
+            {
+                continue;
+            }
+            (OSP_VOID)Quark_StopPhySasEvent(v_pstCard, uiPhyId);
+            v_pstCard->astPhy[uiPhyId].enLastClosePhyReason = g_SwitchPhyByEccIsolation;    
+        }
+        QUARK_TRACE(OSP_DBL_MAJOR, 1, "Card:%d all linkup phy isolated.", ucCardId);
+        return;    
+    }       
+
+    SAS_SPIN_UNLOCK_IRQRESTORE(&pstSalCard->stCardLock, ulFlag);
+    return;
+} 
+
+/*****************************************************************************
+     : Quark_InitBitEccRecovInfo
+   : ʼbit ECCоƬ޸
+*****************************************************************************/ 
+OSP_VOID Quark_InitBitEccRecovInfo(OSP_U8 ucCardNo)
+{
+    /* ʼ¼bit ECCϸصĲ */
+    g_eCardRecoveryRecord[ucCardNo].eRecoveryStatus = SAS_CARD_NORMAL;
+    g_eCardRecoveryRecord[ucCardNo].bReportAlarmStat = SAL_FALSE;
+    g_eCardRecoveryRecord[ucCardNo].ulLastRecoveryTime = 0;
+
+    return ;
+}
+
+/*****************************************************************************
+     : Quark_CheckCardIsolateReport
+   : жǷѾڱ״̬δϱchipfaultĸ澯ϱchip fault
+*****************************************************************************/
+OSP_VOID Quark_CheckCardIsolateReport(SAL_CARD_S *v_pstSALCard)
+{
+    QUARK_CARD_S *pstQuarkCard = NULL;
+    OSP_U32 uiLogicId = 0;
+    
+    pstQuarkCard = (QUARK_CARD_S *)v_pstSALCard->pvDrvData;
+    QUARK_ASSERT(NULL != pstQuarkCard, return);
+
+    if ((g_eCardRecoveryRecord[pstQuarkCard->ucCardId].eRecoveryStatus == SAS_CARD_ISOLATED) &&
+        (g_eCardRecoveryRecord[pstQuarkCard->ucCardId].bReportAlarmStat == SAL_FALSE))
+    {
+        g_eCardRecoveryRecord[pstQuarkCard->ucCardId].bReportAlarmStat = SAL_TRUE;
+		
+        //QUARK_TRACE_FRQLIMIT(OSP_DBL_MAJOR, msecs_to_jiffies(20000), 1, /* 20000Ϊ־ӡƵʣ20Sһδӡ */
+        //                     "Card:%u has been isolated, need report chip fault.", v_pstSALCard->ucCardNo);
+		
+        /* ˵ӿڿѾԭ˶˿ڣҪϱchip fault */
+        uiLogicId = SAL_CommGetLogicId(v_pstSALCard->ucCardNo, 0) & 0x00FFFFFF;
+        (OSP_VOID)SAL_EventNotify(uiLogicId, SAL_DRV_DEVT_PORT_CHIP_FAULT);
+    }
+
+    return;
+}
+
 
 //lint +e801
 
