📄 core_swxor.c
字号:
#include "mv_include.h" // MFC requires a common header, please dont checkin#if defined(RAID_DRIVER) && defined(USE_NEW_SGTABLE)typedef struct _xor_strm_t{ sgd_t sgd[2]; MV_U32 off;} xor_strm_t;static MV_PVOID sgd_kmap( PCore_Driver_Extension pCore, sgd_t* sg ){ sgd_pctx_t* pctx = (sgd_pctx_t*) sg; MV_PTR_INTEGER addr = (MV_PTR_INTEGER)(pctx->baseAddr.value); MV_DASSERT( sg->flags & SGD_PCTX ); addr &= ~0x80000000L; // just for fun, refer to GenerateSGTable in win_helper.c return (MV_PVOID) addr;}static void sgd_kunmap( PCore_Driver_Extension pCore, sgd_t* sg, MV_PVOID mapped_addr ){ //...}void CopySGs( PCore_Driver_Extension pCore, PMV_SG_Table srctbl, PMV_SG_Table dsttbl );#endif#if defined(RAID_DRIVER) && defined(SOFTWARE_XOR)#include "core_header.h"#ifndef USE_NEW_SGTABLE/* * Software XOR operations */void mvXORWrite (MV_PVOID This, PMV_XOR_Request pXORReq);void mvXORCompare (MV_PVOID This, PMV_XOR_Request pXORReq);void mvXORDMA (MV_PVOID This, PMV_XOR_Request pXORReq);#ifndef SUPPORT_RAID6MV_U8 mvXORInitArray ( MV_PVOID This, PMV_XOR_Request pXORReq, PMV_SG_Entry *SG_entry, MV_PU32 SG_size, MV_PU8 *pSource, MV_PU32 table_size);#endif#ifdef SIMULATORvoid _Core_ModuleSendXORRequest(MV_PVOID This, PMV_XOR_Request pXORReq)#else /*SIMULATOR*/void Core_ModuleSendXORRequest(MV_PVOID This, PMV_XOR_Request pXORReq)#endif /*!SIMULATOR*/{ PCore_Driver_Extension pCore = (PCore_Driver_Extension)This; switch (pXORReq->Request_Type) { case XOR_REQUEST_WRITE: mvXORWrite (pCore, pXORReq); break; case XOR_REQUEST_COMPARE: mvXORCompare (pCore, pXORReq); break; case XOR_REQUEST_DMA: mvXORDMA (pCore, pXORReq); break; default: pXORReq->Request_Status = XOR_STATUS_INVALID_REQUEST; break; }#ifndef SIMULATOR pXORReq->Completion( pXORReq->Cmd_Initiator, pXORReq );#endif /*!SIMULATOR*/}#ifndef SUPPORT_RAID6void mvXORWrite (MV_PVOID This, PMV_XOR_Request pXORReq){ MV_ASSERT(MV_FALSE);}void mvXORCompare (MV_PVOID This, PMV_XOR_Request pXORReq){ PCore_Driver_Extension pCore = (PCore_Driver_Extension)This;// PMV_SG_Entry SG_entry[MAX_SG_ENTRY + 1]; // last element is target PMV_SG_Entry SG_entry[2];// MV_U32 SG_size[MAX_SG_ENTRY + 1]; MV_U32 SG_size[2]; // number of source, currently support 2 sources MV_U32 min_size; MV_U32 table_size, total_byte = 0; MV_U8 num_sources, sourceCount; MV_U32 sizeCount; //PMV_SG_Table current_table;// MV_PU8 pSource[MAX_SG_ENTRY]; MV_PU8 pSource[2]; MV_U8 xorResult; num_sources = pXORReq->Source_SG_Table_Count; if (num_sources==0) { pXORReq->Request_Status = XOR_STATUS_INVALID_PARAMETER; return; } // init array & error checking if ( mvXORInitArray(pCore, pXORReq, SG_entry, SG_size, pSource, &table_size) != num_sources ) { pXORReq->Request_Status = XOR_STATUS_INVALID_PARAMETER; return; } while (total_byte < table_size) { min_size = SG_size[0]; for (sourceCount=1; sourceCount<num_sources; sourceCount++) { if (min_size > SG_size[sourceCount]) min_size = SG_size[sourceCount]; } for (sizeCount=0; sizeCount<min_size; sizeCount++) { xorResult = *pSource[0]; for (sourceCount=1; sourceCount<num_sources; sourceCount++) {// *pSource[0] = *pSource[0] ^ *pSource[sourceCount]; xorResult = xorResult ^ *pSource[sourceCount]; pSource[sourceCount]++; }// if (*pSource[0] != 0) if (xorResult != 0) { pXORReq->Request_Status = XOR_STATUS_ERROR; pXORReq->Error_Offset = total_byte + sizeCount; return; } pSource[0]++; } total_byte += min_size; if (total_byte<table_size) { // make new size array & increment entry pointer if needed for (sourceCount=0; sourceCount<num_sources; sourceCount++) { SG_size[sourceCount] -= min_size; if (SG_size[sourceCount] == 0) { SG_entry[sourceCount]++; SG_size[sourceCount] = SG_entry[sourceCount]->Size; pSource[sourceCount] = raid_physical_to_virtual(pXORReq->Cmd_Initiator, SG_entry[sourceCount]->Base_Address); } } } } pXORReq->Request_Status = XOR_STATUS_SUCCESS;}void mvXORDMA (MV_PVOID This, PMV_XOR_Request pXORReq){ MV_ASSERT(MV_FALSE);}MV_U8 mvXORInitArray ( MV_PVOID This, PMV_XOR_Request pXORReq, PMV_SG_Entry *SG_entry, MV_PU32 SG_size, MV_PU8 *pSource, MV_PU32 table_size){ //PCore_Driver_Extension pCore = (PCore_Driver_Extension)This; PMV_SG_Table current_table = NULL; //MV_U8 j; MV_U8 i = 0; *table_size = 0; for (i=0; i<pXORReq->Source_SG_Table_Count; i++) {// while ( !List_Empty(&pXORReq->Source_SG_Table_List) )// {// current_table = (PMV_SG_Table)List_GetFirstEntry(&pXORReq->Source_SG_Table_List, MV_XOR_Request, Queue_Pointer); current_table = pXORReq->Source_SG_Table_List[i]; MV_ASSERT( current_table!=NULL ); SG_entry[i] = ¤t_table->Entry_Ptr[0]; SG_size[i] = current_table->Entry_Ptr[0].Size;// pSource[i] = (MV_PU8)SG_entry[i]->Base_Address; pSource[i] = raid_physical_to_virtual(pXORReq->Cmd_Initiator, current_table->Entry_Ptr[0].Base_Address);// i++; } MV_DASSERT( current_table!=NULL ); if ( current_table ) *table_size = current_table->Byte_Count; return i;}#else /* SUPPORT_RAID6 */void mvXORInit( PMV_SG_Entry *pSGPtr, MV_PU32 SGSizePtr, MV_PVOID *pVirPtr, PMV_SG_Table SGListPtr, MV_U8 tableCount, MV_PU32 minSizePtr){ MV_U8 id; for ( id=0; id<tableCount; id++ ) { pSGPtr[id] = SGListPtr[id].Entry_Ptr; pVirPtr[id] = (MV_PVOID) ( (MV_PTR_INTEGER)pSGPtr[id]->Base_Address | (MV_PTR_INTEGER)pSGPtr[id]->Base_Address_High<<32 ); SGSizePtr[id] = pSGPtr[id]->Size; if ( *minSizePtr > SGSizePtr[id] ) *minSizePtr=SGSizePtr[id]; }}void mvXORUpdateEntry( PMV_SG_Entry *pSGPtr, MV_PU32 SGSizePtr, MV_PVOID *pVirPtr, MV_U32 finishSize, MV_U8 tableCount, MV_PU32 minSizePtr){ MV_U8 id; for ( id=0; id<tableCount; id++ ) { if ( SGSizePtr[id] > finishSize ) SGSizePtr[id] -= finishSize; else { pSGPtr[id]++; pVirPtr[id] = (MV_PVOID) ( (MV_PTR_INTEGER)pSGPtr[id]->Base_Address | (MV_PTR_INTEGER)pSGPtr[id]->Base_Address_High<<32 ); SGSizePtr[id] = pSGPtr[id]->Size; } if ( *minSizePtr > SGSizePtr[id] ) *minSizePtr=SGSizePtr[id]; }}MV_U8 mvXORByte( MV_PU8 *pSourceVirPtr, PMV_XOR_Request pXORReq, MV_U8 tId){ MV_U8 xorResult, sId; xorResult = GF_Multiply(*pSourceVirPtr[0], pXORReq->Coef[tId][0]); for ( sId=1; sId<pXORReq->Source_SG_Table_Count; sId++ ) { xorResult = GF_Add(xorResult, GF_Multiply(*pSourceVirPtr[sId], pXORReq->Coef[tId][sId])); } return xorResult;}#ifdef SUPPORT_XOR_DWORDMV_U32 mvXORDWord( MV_PU32 *pSourceVirPtr, PMV_XOR_Request pXORReq, MV_U8 tId){ MV_U8 sId; MV_U32 xorResult; xorResult = GF_Multiply(*pSourceVirPtr[0], pXORReq->Coef[tId][0]); for ( sId=1; sId<pXORReq->Source_SG_Table_Count; sId++ ) { xorResult = GF_Add(xorResult, GF_Multiply(*pSourceVirPtr[sId], pXORReq->Coef[tId][sId])); } return xorResult;}#endif/* The SG Table should have the virtual address instead of the physical address. */void mvXORWrite(MV_PVOID This, PMV_XOR_Request pXORReq){ PMV_SG_Entry pSourceSG[XOR_SOURCE_SG_COUNT]; PMV_SG_Entry pTargetSG[XOR_TARGET_SG_COUNT]; MV_U32 sourceSize[XOR_SOURCE_SG_COUNT]; MV_U32 targetSize[XOR_TARGET_SG_COUNT]; MV_U32 i; MV_U8 sId,tId; /* source index and target index. */ MV_U32 size, remainSize, minSize;#ifdef SUPPORT_XOR_DWORD MV_PU32 pSourceVir[XOR_SOURCE_SG_COUNT]; MV_PU32 pTargetVir[XOR_TARGET_SG_COUNT]; MV_U32 xorResult, Dword_size;#else MV_PU8 pSourceVir[XOR_SOURCE_SG_COUNT]; MV_PU8 pTargetVir[XOR_TARGET_SG_COUNT]; MV_U8 xorResult;#endif /* Initialize these two variables. */ remainSize = pXORReq->Source_SG_Table_List[0].Byte_Count; /* All the SG table should have same Byte_Count */ minSize = remainSize; /* Initialize XOR source */ mvXORInit(pSourceSG, sourceSize, (MV_PVOID*)pSourceVir, pXORReq->Source_SG_Table_List, pXORReq->Source_SG_Table_Count, &minSize); /* Initialize XOR target */ mvXORInit(pTargetSG, targetSize, (MV_PVOID*)pTargetVir, pXORReq->Target_SG_Table_List, pXORReq->Target_SG_Table_Count, &minSize);/* for ( sId=0; sId<pXORReq->Source_SG_Table_Count; sId++ ) { pSourceSG[sId] = pXORReq->Source_SG_Table_List[sId].Entry; sourceSize[sId] = pSourceSG[sId]->Size; pSourceVir[sId] = (MV_PVOID) ( (MV_PTR_INTEGER)pSourceSG[sId]->Base_Address | (MV_PTR_INTEGER)pSourceSG[sId]->Base_Address_High<<32 ); MV_DASSERT( remainSize==pXORReq->Source_SG_Table_List[sId].Byte_Count ); if ( minSize>sourceSize[sId] ) minSize=sourceSize[sId]; } for ( tId=0; tId<pXORReq->Target_SG_Table_Count; tId++ ) { pTargetSG[tId] = pXORReq->Target_SG_Table_List[tId].Entry; targetSize[tId] = pTargetSG[tId]->Size; pTargetVir[tId] = (MV_PVOID) ( (MV_PTR_INTEGER)pTargetSG[tId]->Base_Address | (MV_PTR_INTEGER)pTargetSG[tId]->Base_Address_High<<32 ); MV_DASSERT( remainSize==pXORReq->Target_SG_Table_List[tId].Byte_Count ); if ( minSize>targetSize[tId] ) minSize=targetSize[tId]; }*/ /* Navigate all the SG table, calculate the target xor value. */ while ( remainSize>0 ) { size = minSize;#ifdef SUPPORT_XOR_DWORD MV_DASSERT( !(size%4) ); Dword_size = size/4; for ( i=0; i<Dword_size; i++ ) #else for ( i=0; i<size; i++ ) #endif { for ( tId=0; tId<pXORReq->Target_SG_Table_Count; tId++ ) {#ifdef SUPPORT_XOR_DWORD xorResult = mvXORDWord(pSourceVir, pXORReq, tId);#else xorResult = mvXORByte(pSourceVir, pXORReq, tId);#endif/* tmp = GF_Multiply(*pSourceVir[0], pXORReq->Coef[tId][0]); for ( sId=1; sId<pXORReq->Source_SG_Table_Count; sId++ ) { tmp = GF_Add(tmp, GF_Multiply(*pSourceVir[sId], pXORReq->Coef[tId][sId])); } *pTargetVir[tId] = tmp;*/ *pTargetVir[tId] = xorResult; pTargetVir[tId]++; } for ( sId=0; sId<pXORReq->Source_SG_Table_Count; sId++ ) pSourceVir[sId]++; } /* Update entry pointer, size */ MV_DASSERT( remainSize>=size ); remainSize -= size; minSize = remainSize; /* Update XOR source */ mvXORUpdateEntry(pSourceSG, sourceSize, (MV_PVOID*)pSourceVir, size, pXORReq->Source_SG_Table_Count, &minSize); /* Update XOR target */ mvXORUpdateEntry(pTargetSG, targetSize, (MV_PVOID*)pTargetVir, size, pXORReq->Target_SG_Table_Count, &minSize);/* for ( sId=0; sId<pXORReq->Source_SG_Table_Count; sId++ ) { if ( sourceSize[sId]>size ) { sourceSize[sId]-=size; } else { pSourceSG[sId]++; pSourceVir[sId] = (MV_PVOID) ( (MV_PTR_INTEGER)pSourceSG[sId]->Base_Address | (MV_PTR_INTEGER)pSourceSG[sId]->Base_Address_High<<32 ); sourceSize[sId] = pSourceSG[sId]->Size; } if ( minSize>sourceSize[sId] ) minSize=sourceSize[sId]; } for ( tId=0; tId<pXORReq->Target_SG_Table_Count; tId++ ) { if ( targetSize[tId]>size ) { targetSize[tId]-=size; } else { pTargetSG[tId]++; pTargetVir[tId] = (MV_PVOID) ( (MV_PTR_INTEGER)pTargetSG[tId]->Base_Address | (MV_PTR_INTEGER)pTargetSG[tId]->Base_Address_High<<32 ); targetSize[tId] = pTargetSG[tId]->Size; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -