core_xor.c
来自「6440linuxDriver的源代码」· C语言 代码 · 共 1,454 行 · 第 1/4 页
C
1,454 行
pSGBuf = GetSGBufferFromPool(pCore); if (pSGBuf == NULL) return MV_FALSE; *SG_Buffer = pSGBuf; sg = pSGBuf->Buffer_Vir;/*n=source count while m=target count. (1<=m<=2)XOR_PRD 0: GF coefficient and direct fill.XOR_PRD 1..n-1: GF multiply and XOR to the buffer.XOR_PRD n..n+m-1: Write to target*///XOR_PRD 0:#ifdef USE_NEW_SGTABLE consumed = sgdt_prepare_hwprd( pCore, &Source_SG_Table_List[0], sg, SG_BUFFER_SINGLE_COUNT );#else consumed = Source_SG_Table_List[0].Valid_Entry_Count; for(i=0;i<Source_SG_Table_List[0].Valid_Entry_Count;i++) { MV_CopyMemory(&sg[i], &Source_SG_Table_List[0].Entry_Ptr[i], sizeof(MV_SG_Entry)); }#endif MV_ASSERT( consumed ); pCmdTbl->XOR_PRD[0].PRDEntryCount = (MV_U8) consumed; pCmdTbl->XOR_PRD[0].PRDTableAddress=pSGBuf->Buffer_DMA.parts.low; pCmdTbl->XOR_PRD[0].PRDTableAddressHigh=pSGBuf->Buffer_DMA.parts.high; pCmdTbl->XOR_PRD[0].DataByte0=Coef[0]; pCmdTbl->XOR_PRD[0].Buffer0OpCode=OP_GF_ENABLE; if(Target_SG_Table_Count>1) { pCmdTbl->XOR_PRD[0].DataByte1=Coef[1*Max_Source_SG_Count]; pCmdTbl->XOR_PRD[0].Buffer1OpCode=OP_GF_ENABLE; } pCmdTbl->TotalByteCount=Source_SG_Table_List[0].Byte_Count;//XOR_PRD 1..n-1: for(sId=1;sId<Source_SG_Table_Count;sId++) { pNextSGBuf = GetSGBufferFromPool(pCore); if (pNextSGBuf == NULL) return MV_FALSE; pSGBuf->NextBuffer = pNextSGBuf; pSGBuf = pNextSGBuf; sg = pSGBuf->Buffer_Vir;#ifdef USE_NEW_SGTABLE consumed = sgdt_prepare_hwprd( pCore, &Source_SG_Table_List[sId], sg, SG_BUFFER_SINGLE_COUNT );#else consumed = Source_SG_Table_List[sId].Valid_Entry_Count; for(i=0;i<Source_SG_Table_List[sId].Valid_Entry_Count;i++) { MV_CopyMemory(&sg[i], &Source_SG_Table_List[sId].Entry_Ptr[i], sizeof(MV_SG_Entry)); }#endif MV_ASSERT( consumed ); pCmdTbl->XOR_PRD[sId].PRDEntryCount = (MV_U8) consumed; pCmdTbl->XOR_PRD[sId].PRDTableAddress=pSGBuf->Buffer_DMA.parts.low; pCmdTbl->XOR_PRD[sId].PRDTableAddressHigh=pSGBuf->Buffer_DMA.parts.high; pCmdTbl->XOR_PRD[sId].DataByte0=Coef[sId]; pCmdTbl->XOR_PRD[sId].Buffer0OpCode=OP_GF_XOR_ENABLE; //1st GF+XOR if(Target_SG_Table_Count>1) { pCmdTbl->XOR_PRD[sId].DataByte1=Coef[1*Max_Source_SG_Count+sId]; pCmdTbl->XOR_PRD[sId].Buffer1OpCode=OP_GF_XOR_ENABLE; //GF+XOR } }//XOR_PRD n..n+m-1(1 or 2): for(tId=0;tId<Target_SG_Table_Count;tId++) { pNextSGBuf = GetSGBufferFromPool(pCore); if (pNextSGBuf == NULL) return MV_FALSE; pSGBuf->NextBuffer = pNextSGBuf; pSGBuf = pNextSGBuf; sg = pSGBuf->Buffer_Vir;#ifdef USE_NEW_SGTABLE consumed = sgdt_prepare_hwprd( pCore, &Target_SG_Table_List[tId], sg, SG_BUFFER_SINGLE_COUNT );#else consumed = Target_SG_Table_List[tId].Valid_Entry_Count; for(i=0;i<Target_SG_Table_List[tId].Valid_Entry_Count;i++) { MV_CopyMemory(&sg[i], &Target_SG_Table_List[tId].Entry_Ptr[i], sizeof(MV_SG_Entry)); }#endif MV_ASSERT( consumed ); pCmdTbl->XOR_PRD[Source_SG_Table_Count+tId].PRDEntryCount = (MV_U8) consumed; pCmdTbl->XOR_PRD[Source_SG_Table_Count+tId].PRDTableAddress=pSGBuf->Buffer_DMA.parts.low; pCmdTbl->XOR_PRD[Source_SG_Table_Count+tId].PRDTableAddressHigh=pSGBuf->Buffer_DMA.parts.high; if(tId<1) pCmdTbl->XOR_PRD[Source_SG_Table_Count+tId].Buffer0OpCode=OP_WRITE_ENABLE; //write else pCmdTbl->XOR_PRD[Source_SG_Table_Count+tId].Buffer1OpCode=OP_WRITE_ENABLE; //write } pCmdTbl->ValidEntry=Source_SG_Table_Count+Target_SG_Table_Count; return MV_TRUE;}voidXORWriteCommand( IN PCore_Driver_Extension pCore, IN PMV_XOR_Request pReq ){ MV_U16 SlotNo; PMV_XOR_Command_Header pCmdHeader=NULL; PMV_XOR_Command_Table pCmdTbl=NULL; XOR_DELIVERY_QUEUE_ENTRY DELV_Q_Entry; MV_U32 i; MV_BOOLEAN ret=MV_TRUE; PXOR_Table_Wrapper pXORTableWrapper=NULL, pPreWrapper=NULL; MV_U8 tableCount = 0; PCORE_XOR_CONTEXT pContext = (PCORE_XOR_CONTEXT)pReq->Context[MODULE_CORE]; MV_U8 targetCount; PSG_Buffer pSGBuffer=NULL, pTempBuf=NULL; MV_DASSERT( pContext!=NULL ); SlotNo=XORGetOneCommandSlot(pCore, &pCmdHeader); pReq->SlotNo=SlotNo; tableCount = (pReq->Target_SG_Table_Count+1)/2; pContext->Context_Type = CORE_XOR_CONTEXT_TYPE_TABLE; MV_DASSERT(pContext->Table_Wrapper==NULL); for ( i=0; i<tableCount; i++ ) { pPreWrapper = pXORTableWrapper; pXORTableWrapper = GetXORTableWrapperFromPool(pCore); if ( pXORTableWrapper==NULL ) { MV_DASSERT(MV_FALSE); /* I suppose it shouldn't happen. */ goto release; } if (i==0) { /* For the first XOR table, set the XOR command header. */ pCmdHeader->Table_Address= pXORTableWrapper->Buffer_DMA.parts.low; pCmdHeader->Table_Address_High= pXORTableWrapper->Buffer_DMA.parts.high; pCmdHeader->XORTblLen=((sizeof(XOR_CMD_ENTRY)*MAX_XOR_CMD_ENTRY)/sizeof(MV_U32))+4; pContext->Table_Wrapper = pXORTableWrapper; } else { MV_DASSERT( pPreWrapper!=NULL ); pXORTableWrapper->NextBuffer = pContext->Table_Wrapper; pContext->Table_Wrapper = pXORTableWrapper; MV_ASSERT( pXORTableWrapper->Buffer_DMA.parts.high==pCmdHeader->Table_Address_High ); ((PMV_XOR_Command_Table)pPreWrapper->Buffer_Vir)->NextTableAddressLo = pXORTableWrapper->Buffer_DMA.parts.low; } pCmdTbl = (PMV_XOR_Command_Table)pXORTableWrapper->Buffer_Vir; MV_ZeroMemory(pCmdTbl, sizeof(MV_XOR_Command_Table)); targetCount = (pReq->Target_SG_Table_Count-i*2)>=2? 2:1; ret = XORWriteCommand_OneTable( pCore, pReq->Source_SG_Table_Count, targetCount, pReq->Source_SG_Table_List, &pReq->Target_SG_Table_List[i*2], &pReq->Coef[i*2][0], XOR_SOURCE_SG_COUNT, pCmdTbl, &pSGBuffer); /* No matter sucess or not, record the SG buffer. We'll release them. */ if ( pReq->SG_Buffer==NULL ) { pReq->SG_Buffer = pSGBuffer; } else { pTempBuf = pReq->SG_Buffer; while ( pTempBuf->NextBuffer ) pTempBuf = pTempBuf->NextBuffer; pTempBuf->NextBuffer = pSGBuffer; } if ( ret==MV_FALSE ) goto release; } /* It's the last table, enable interrupt. */ pCmdTbl->InterruptEnable=1; pCore->XOR_Running_Req[SlotNo]=pReq; pCore->XOR_Req_Count++; XORPrepareDeliveryQueueEntry(pCore, SlotNo, &DELV_Q_Entry); XORWriteDELV_Q_Entry(pCore, &DELV_Q_Entry); /* Request is sent to the hardware and not finished yet. */ pReq->Request_Status = XOR_STATUS_SUCCESS; return;release: Tag_ReleaseOne(&pCore->XOR_Tag_Pool, SlotNo); /* Release SG Buffer and XOR Wrapper */ MV_DPRINT(("Ran out of SG Buffers!\n")); while ( pReq->SG_Buffer ) { pTempBuf = ((PSG_Buffer)pReq->SG_Buffer)->NextBuffer; FreeSGBufferToPool(pCore, (PSG_Buffer *) &pReq->SG_Buffer); pReq->SG_Buffer = pTempBuf; } MV_DASSERT(pContext->Context_Type==CORE_XOR_CONTEXT_TYPE_TABLE); while ( pContext->Table_Wrapper ) { pXORTableWrapper = pContext->Table_Wrapper->NextBuffer; FreeXORTableWrapperToPool(pCore, (PXOR_Table_Wrapper*)&pContext->Table_Wrapper); pContext->Table_Wrapper = pXORTableWrapper; } List_Add(&pReq->Queue_Pointer, &pCore->XOR_Waiting_List);}voidXORCompareCommand( IN PCore_Driver_Extension pCore, IN PMV_XOR_Request pReq ){ MV_U16 SlotNo; PMV_XOR_Command_Header pCmdHeader; PMV_XOR_Command_Table pCmdTbl= NULL; PCORE_XOR_CONTEXT pContext = (PCORE_XOR_CONTEXT)pReq->Context[MODULE_CORE]; PXOR_Table_Wrapper pXORTableWrapper=NULL; XOR_DELIVERY_QUEUE_ENTRY DELV_Q_Entry; MV_U8 sId; /* source index. */ PMV_SG_Entry sg; PSG_Buffer pSGBuf, pNextSGBuf, pTempBuf; int consumed;#ifndef USE_NEW_SGTABLE MV_U32 i;#endif MV_DASSERT( pContext!=NULL ); MV_DASSERT( pReq->Source_SG_Table_Count==2 ); MV_DASSERT( pReq->Target_SG_Table_Count==0 ); SlotNo=XORGetOneCommandSlot(pCore, &pCmdHeader); pReq->SlotNo=SlotNo; pContext->Context_Type = CORE_XOR_CONTEXT_TYPE_TABLE; MV_DASSERT(pContext->Table_Wrapper==NULL); /* Get XOR Table: One table wrapper for one compare XOR request. */ pXORTableWrapper = GetXORTableWrapperFromPool(pCore); if ( pXORTableWrapper==NULL ) { MV_DASSERT(MV_FALSE); /* I suppose it shouldn't happen. */ goto release; } pCmdHeader->Table_Address= pXORTableWrapper->Buffer_DMA.parts.low; pCmdHeader->Table_Address_High= pXORTableWrapper->Buffer_DMA.parts.high; pCmdHeader->XORTblLen=((sizeof(XOR_CMD_ENTRY)*MAX_XOR_CMD_ENTRY)/sizeof(MV_U32))+4; pContext->Table_Wrapper = pXORTableWrapper; pCmdTbl = pXORTableWrapper->Buffer_Vir; MV_ZeroMemory(pCmdTbl, sizeof(MV_XOR_Command_Table)); /* Fill the table content. * Compare the value of the two source by checking the XOR result of these two streams. */ pSGBuf = GetSGBufferFromPool(pCore); if (pSGBuf == NULL) goto release; pReq->SG_Buffer = pSGBuf; sg = pSGBuf->Buffer_Vir;#ifdef USE_NEW_SGTABLE consumed = sgdt_prepare_hwprd( pCore, &pReq->Source_SG_Table_List[0], sg, SG_BUFFER_SINGLE_COUNT );#else consumed = pReq->Source_SG_Table_List[0].Valid_Entry_Count; for(i=0;i<pReq->Source_SG_Table_List[0].Valid_Entry_Count;i++) { MV_CopyMemory(&sg[i], &pReq->Source_SG_Table_List[0].Entry_Ptr[i], sizeof(MV_SG_Entry)); }#endif MV_ASSERT( consumed ); pCmdTbl->XOR_PRD[0].PRDEntryCount = (MV_U8) consumed; pCmdTbl->XOR_PRD[0].PRDTableAddress=pSGBuf->Buffer_DMA.parts.low; pCmdTbl->XOR_PRD[0].PRDTableAddressHigh=pSGBuf->Buffer_DMA.parts.high; pCmdTbl->XOR_PRD[0].Buffer0OpCode=OP_DIRECT_FILL; //direct fill pCmdTbl->TotalByteCount=pReq->Source_SG_Table_List[0].Byte_Count; for(sId=1;sId<pReq->Source_SG_Table_Count;sId++) { pNextSGBuf = GetSGBufferFromPool(pCore); if (pNextSGBuf == NULL) goto release; pSGBuf->NextBuffer = pNextSGBuf; pSGBuf = pNextSGBuf; sg = pSGBuf->Buffer_Vir;#ifdef USE_NEW_SGTABLE consumed = sgdt_prepare_hwprd( pCore, &pReq->Source_SG_Table_List[sId], sg, SG_BUFFER_SINGLE_COUNT );#else consumed = pReq->Source_SG_Table_List[sId].Valid_Entry_Count; for(i=0;i<pReq->Source_SG_Table_List[sId].Valid_Entry_Count;i++) { MV_CopyMemory(&sg[i], &pReq->Source_SG_Table_List[sId].Entry_Ptr[i], sizeof(MV_SG_Entry)); }#endif MV_ASSERT( consumed ); pCmdTbl->XOR_PRD[sId].PRDEntryCount = (MV_U8) consumed; pCmdTbl->XOR_PRD[sId].PRDTableAddress=pSGBuf->Buffer_DMA.parts.low; pCmdTbl->XOR_PRD[sId].PRDTableAddressHigh=pSGBuf->Buffer_DMA.parts.high; pCmdTbl->XOR_PRD[sId].Buffer0OpCode=OP_XOR_ENABLE; //XOR } pCmdTbl->XOR_PRD[pReq->Source_SG_Table_Count].PRDEntryCount=1; //to workaround hardware no-action check pCmdTbl->XOR_PRD[pReq->Source_SG_Table_Count].Buffer0OpCode=OP_ZERO_CHECK_ENABLE; //Zero Check pCmdTbl->ValidEntry=pReq->Source_SG_Table_Count+1; // add 1 for the zero check entry pCmdTbl->InterruptEnable=1; pCore->XOR_Running_Req[SlotNo]=pReq; pCore->XOR_Req_Count++; XORPrepareDeliveryQueueEntry(pCore, SlotNo, &DELV_Q_Entry); XORWriteDELV_Q_Entry(pCore, &DELV_Q_Entry); /* Request is sent to the hardware and not finished yet. */ pReq->Request_Status = XOR_STATUS_SUCCESS; return;release: Tag_ReleaseOne(&pCore->XOR_Tag_Pool, SlotNo); /* Release SG Buffer and XOR Wrapper */ MV_DPRINT(("Ran out of SG Buffers!\n")); while ( pReq->SG_Buffer ) { pTempBuf = ((PSG_Buffer)pReq->SG_Buffer)->NextBuffer; FreeSGBufferToPool(pCore, (PSG_Buffer *) &pReq->SG_Buffer); pReq->SG_Buffer = pTempBuf; } MV_DASSERT(pContext->Context_Type==CORE_XOR_CONTEXT_TYPE_TABLE); while ( pContext->Table_Wrapper ) { pXORTableWrapper = pContext->Table_Wrapper->NextBuffer; FreeXORTableWrapperToPool(pCore, (PXOR_Table_Wrapper*)&pContext->Table_Wrapper); pContext->Table_Wrapper = pXORTableWrapper; } List_Add(&pReq->Queue_Pointer, &pCore->XOR_Waiting_List);}#endif /* RAID6_HARDWARE_XOR */#endif /*RAID_DRIVER && !SOFTWARE_XOR*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?