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 + -
显示快捷键?