--- ./source/private_module/quark/quark_outb.c	2021-05-29 07:50:50.726501375 +0000
+++ ./source/private_module/quark/quark_outb.c.hotpatch	2021-06-02 10:57:21.710501375 +0000
@@ -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_PatchHandleSpecialSasEvent(OSP_U32 v_uiEvent, QUARK_CARD_S *v_pstCard, SAL_PORT_S *pstSalPort);
+/* SAS޸״̬ö */
+typedef enum tagSAS_CARD_RECOVERY_STATUS_E
+{
+    SAS_CARD_NORMAL,
+    SAS_CARD_SOFT_RESET,
+    SAS_CARD_CHIP_ERROR,
+    SAS_CARD_ISOLATED,
+    SAS_CARD_BUTT
+} SAS_CARD_RECOVERY_STATUS_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_STATUS_E eRecoveryStatus;		/* ޸״̬ */
+    OSP_BOOL bReportAlarmStat; 						/* ¼ĸ澯״̬TRUEΪѸ */  
+    OSP_ULONG ulLastRecoveryTime;					/* һ޸ʱ */
+} SAS_CARD_RECOVERY_RECORD;
 //extern OSP_U32 uiSalSimIoFatal;
 QUARK_SIM_IOBack_S sim_io_back3, sim_io_back4, sim_io_back5;
 SAS_TIMER_S stIObackTimer;  /* ģIOʱصTimer */
-/*------------------------------ģIOʱ----------------*/
-
 
 
+/* SAS8072״̬¼ÿſһṹ */
+SAS_CARD_RECOVERY_RECORD g_eCardRecoveryRecord2[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_PatchHandleSpecialSasEvent(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,7 +5375,164 @@
     return ;
 }
 
+/*****************************************************************************       
+    : Quark_StopPhySasEvent       
+  : ·ֹͣphyϢӲ
+*****************************************************************************/        
+OSP_S32 Quark_PatchStopPhySasEvent(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, 1, "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, 1, "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, 1, "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 Quark_PatchHandleSpecialSasEvent(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_eCardRecoveryRecord2[ucCardId].eRecoveryStatus != SAS_CARD_ISOLATED) {
+        g_eCardRecoveryRecord2[ucCardId].eRecoveryStatus = SAS_CARD_ISOLATED;
+        g_eCardRecoveryRecord2[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_PatchStopPhySasEvent(v_pstCard, uiPhyId);
+        }
+        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_PatchInitBitEccRecovInfo(OSP_U8 ucCardNo)
+{
+    /* ʼ¼bit ECCϸصĲ */
+    g_eCardRecoveryRecord2[ucCardNo].eRecoveryStatus = SAS_CARD_NORMAL;
+    g_eCardRecoveryRecord2[ucCardNo].bReportAlarmStat = SAL_FALSE;
+    g_eCardRecoveryRecord2[ucCardNo].ulLastRecoveryTime = 0;
+
+    return ;
+}
+
+OSP_VOID Quark_ErrRecoverNotify(SAL_CARD_S *v_pstCard)
+{
+
+    DRV_SNDEVT_DATA_S stSendEventData = {0};
+
+    /* frame */
+    /* һpv660oops */
+    stSendEventData.uiDevID = DRV_STDDEV_PORT;
+    if (v_pstCard->pstPciDev != NULL) {
+        stSendEventData.uDat.stChipRecoverEvent.pciebus = v_pstCard->pstPciDev->bus->number;
+        stSendEventData.uDat.stChipRecoverEvent.pciedevfn = v_pstCard->pstPciDev->devfn;
+    }
+    stSendEventData.uDat.stChipRecoverEvent.drvtype = SAS_MODULE_ID;
+    /* chiperr޸,Ӱҵ */
+    stSendEventData.uDat.stChipRecoverEvent.errinfo = 1;
+    QUARK_TRACE(OSP_DBL_INFO, 0, "Card %d report chip recovery to upper pcie.", v_pstCard->ucCardNo);
+    DRV_SendEvent(DRV_DEVT_PORT_CHIP_RECOVER, (OSP_VOID *)&stSendEventData);
+    return;
+
+}
+
+/*****************************************************************************
+     : Quark_CheckCardIsolateReport
+   : жǷѾڱ״̬δϱchipfaultĸ澯ϱchip fault
+*****************************************************************************/
+OSP_VOID Quark_PatchCheckCardIsolateReport(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_eCardRecoveryRecord2[pstQuarkCard->ucCardId].eRecoveryStatus == SAS_CARD_ISOLATED) &&
+        (g_eCardRecoveryRecord2[pstQuarkCard->ucCardId].bReportAlarmStat == SAL_FALSE)) {
+        g_eCardRecoveryRecord2[pstQuarkCard->ucCardId].bReportAlarmStat = SAL_TRUE;
+		
+        /* ˵ӿڿѾԭ˶˿ڣҪϱchip fault */
+        uiLogicId = SAL_CommGetLogicId(v_pstSALCard->ucCardNo, 0) & 0x00FFFFFF;
+        (OSP_VOID)SAL_EventNotify(uiLogicId, SAL_DRV_DEVT_PORT_CHIP_FAULT);
+        
+        /* оƬڲECC󣬱ǸϱPCIE޸ԿٱOUT */
+        Quark_ErrRecoverNotify(v_pstSALCard);
+        g_SalInserted.stCardInsert[v_pstSALCard->ucCardNo].uiNeedTest = SAL_CARD_NEED_TEST; /* SAL_CARD_NEED_TESTȷδλİβܹûָ澯 */
+    }
+
+    return;
+}
+
+/*****************************************************************************
+     : Quark_IsCardIsolated
+   : Card״̬, Ѿ, TRUE
+*****************************************************************************/ 
+OSP_BOOL Quark_IsCardIsolated(OSP_U8 ucCardNo)
+{
+    if (g_eCardRecoveryRecord2[ucCardNo].eRecoveryStatus == SAS_CARD_ISOLATED) {
+        return TRUE;
+    }
+
+    return FALSE;
+}
 
+EXPORT_SYMBOL(Quark_PatchInitBitEccRecovInfo);
+EXPORT_SYMBOL(g_eCardRecoveryRecord2);
+EXPORT_SYMBOL(Quark_ErrRecoverNotify);
+EXPORT_SYMBOL(Quark_IsCardIsolated);
 //lint +e801
 
 
--- ./source/private_module/quark/quark_init.c	2021-05-29 07:50:50.730501375 +0000
+++ ./source/private_module/quark/quark_init.c.hotpatch	2021-05-29 07:50:50.730501375 +0000
@@ -48,9 +48,9 @@
  * ⲿ˵                                 *
  *----------------------------------------------*/
 extern OSP_CHAR g_acLLSoftVer[SAL_MAX_CARD_NUM][SAL_MAX_CHIP_VER_STR_LEN];
-/*----------------------------------------------*
- * ȫֱ                                     *
- *----------------------------------------------*/
+
+extern OSP_VOID Quark_PatchCheckCardIsolateReport(SAL_CARD_S *v_pstSALCard);
+
 
 /*----------------------------------------------*
  * ģ鼶                                   *
@@ -3333,7 +3333,7 @@
     OSP_U32 uiBoardId = 0;
     OSP_U32 uiPortId = 0;
 
-    QUARK_ASSERT(NULL != pstLLCard, return RETURN_ERROR);
+    QUARK_ASSERT(pstLLCard != NULL, return RETURN_ERROR);
     QUARK_ASSERT(NULL != pstLLCard->pstSALCard, return RETURN_ERROR);
 
     pstSALCard = pstLLCard->pstSALCard;
@@ -5175,8 +5175,8 @@
             
         case SAL_CHIP_OPT_ROUTE_CHECK:
             iRet = Quark_ChipFatalCheck(v_pstSalCard,v_ArgcIn);
-            break;
-            
+            Quark_PatchCheckCardIsolateReport(v_pstSalCard);   /* ӿڿǷѾ룬Ѿ룬ϱchipfault */
+            break;            
         case SAL_CHIP_OPT_CLOCK_CHECK:    
             iRet = Quark_ChipClockCheck(v_pstSalCard,(SAL_CARD_CLOCK_S *)v_ArgcIn);
             break;
--- ./source/private_module/quark/quark_inb.c	2021-05-29 07:50:50.726501375 +0000
+++ ./source/private_module/quark/quark_inb.c.hotpatch	2021-05-29 07:50:50.730501375 +0000
@@ -24,7 +24,7 @@
 #include "quark_adapter.h"
 
 
-
+extern OSP_BOOL Quark_IsCardIsolated(OSP_U8 ucCardNo);
 /*----------------------------------------------*
  *           ⲿ                             *
  *----------------------------------------------*/
@@ -140,7 +140,7 @@
     	"Unknown"
 				
     };
-	
+    if (Quark_IsCardIsolated(v_pstLLCard->ucCardId) == TRUE) { return RETURN_OK; }
     QUARK_REF(pcWireTypeStr[0]);
 	uiWireTypeIndex = v_pstLLCard->pstSALCard->apstPhy[v_uiPhyId]->uiConnectWireType;
 	QUARK_ASSERT(uiWireTypeIndex < SAL_WIRE_TYPE_BUTT,return RETURN_ERROR);
