core_xor.c

来自「6440linuxDriver的源代码」· C语言 代码 · 共 1,454 行 · 第 1/4 页

C
1,454
字号
#include "mv_include.h"	// MFC requires a common header, please dont checkin#if defined(RAID_DRIVER) && !defined(SOFTWARE_XOR)#include "core_header.h"#include "core_helper.h"void MV_DumpXORRegister(MV_PVOID This){#ifndef _OS_BIOS	PCore_Driver_Extension pCore = (PCore_Driver_Extension)This;	MV_U32 reg;	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, XOR_CONTROL);	MV_PRINT("XOR_CONTROL(R%x) = 0x%x\n",XOR_CONTROL,reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, XOR_IRQ_STAT);	MV_PRINT("XOR_IRQ_STAT(R%x) =0x%x\n",XOR_IRQ_STAT,reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, XOR_ERR_CODE );	MV_PRINT("XOR_ERR_CODE(R%x) =0x%x\n",XOR_ERR_CODE,reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, XOR_ERR_TBL_ADDR_HI );	MV_PRINT("XOR_ERR_TBL_ADDR(R%x) =0x%08x",XOR_ERR_TBL_ADDR,reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, XOR_ERR_TBL_ADDR );	MV_PRINT("%08x\n",reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, XOR_ERR_OFFSET0 );	MV_PRINT("XOR_ERR_OFFSET0(R%x) =0x%x\n",XOR_ERR_OFFSET0,reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, XOR_ERR_LEN0 );	MV_PRINT("XOR_ERR_LEN0(R%x) =0x%x\n",XOR_ERR_LEN0,reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, XOR_ERR_OFFSET1 );	MV_PRINT("XOR_ERR_OFFSET1(R%x) =0x%x\n",XOR_ERR_OFFSET1,reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, XOR_ERR_LEN1 );	MV_PRINT("XOR_ERR_LEN1(R%x) =0x%x\n",XOR_ERR_LEN1,reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_IRQ_MASK );	MV_PRINT("COMMON_IRQ_MASK = 0x%x\n",reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_IRQ_STAT );	MV_PRINT("COMMON_IRQ_STAT = 0x%x\n",reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, XOR_DELV_Q_RD_PTR );	MV_PRINT("XOR_DELV_Q_RD_PTR(R%x) = 0x%x\n",XOR_DELV_Q_RD_PTR,reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, XOR_CMPL_Q_WR_PTR );	MV_PRINT("XOR_CMPL_Q_WR_PTR(R%x) = 0x%x\n",XOR_CMPL_Q_WR_PTR,reg);#endif}void XORWriteDELV_Q_Entry(MV_PVOID This, PXOR_DELIVERY_QUEUE_ENTRY pDELV_Q_Entry){	MV_U32 tmp;	PCore_Driver_Extension pCore = (PCore_Driver_Extension)This;	PXOR_DELIVERY_QUEUE_ENTRY pDELV_Q_List = (PXOR_DELIVERY_QUEUE_ENTRY)pCore->XOR_DELV_Q;	MV_LPVOID mmio = pCore->Mmio_Base;	pCore->XOR_LastDELV_Q++;	if(pCore->XOR_LastDELV_Q >= pCore->Slot_Count_Supported) pCore->XOR_LastDELV_Q=0;	tmp = (MV_U32)(pCore->XOR_LastDELV_Q);	MV_CopyMemory(&pDELV_Q_List[tmp], pDELV_Q_Entry, sizeof(XOR_DELIVERY_QUEUE_ENTRY));	MV_REG_WRITE_DWORD(mmio, XOR_DELV_Q_WR_PTR, tmp);}void XORReadCMPL_QEntry(MV_PVOID This, MV_U16 SlotNo, PXOR_COMPLETION_QUEUE_ENTRY *pCMPL_QEntry){	MV_U32 tmp;	PCore_Driver_Extension pCore = (PCore_Driver_Extension)This;	PXOR_COMPLETION_QUEUE_ENTRY pCMPL_QList = (PXOR_COMPLETION_QUEUE_ENTRY)pCore->XOR_CMPL_Q;	*pCMPL_QEntry=NULL;	for(tmp=0;tmp<pCore->Slot_Count_Supported;tmp++)	{		if(pCMPL_QList[tmp].SLOT_NM==SlotNo)		{			*pCMPL_QEntry = &pCMPL_QList[tmp];			break;		}	}}/* output: slot number*/MV_U16 XORGetOneCommandSlot(MV_PVOID This, MV_PVOID *pCmdHeader){	MV_U16 tmp;	PCore_Driver_Extension pCore = (PCore_Driver_Extension)This;	if( (pCore->Device_Id==DEVICE_ID_6440)&&(pCore->Revision_Id==0x0) )	{		PMV_XOR_Command_Header_A1 pCmdList = (PMV_XOR_Command_Header_A1)pCore->XOR_Cmd_List;		tmp = (MV_U16)Tag_GetOne(&pCore->XOR_Tag_Pool);		*(PMV_XOR_Command_Header_A1 *)pCmdHeader = &pCmdList[tmp];		MV_ZeroMemory(*pCmdHeader, sizeof(MV_XOR_Command_Header_A1));	}	else	{		PMV_XOR_Command_Header pCmdList = (PMV_XOR_Command_Header)pCore->XOR_Cmd_List;		tmp = (MV_U16)Tag_GetOne(&pCore->XOR_Tag_Pool);		*(PMV_XOR_Command_Header *)pCmdHeader = &pCmdList[tmp];		MV_ZeroMemory(*pCmdHeader, sizeof(MV_XOR_Command_Header));	}	return tmp;}void XORPrepareDeliveryQueueEntry(MV_PVOID This, MV_U16 SlotNo, XOR_DELIVERY_QUEUE_ENTRY *pDELV_Q_Entry){	MV_ZeroMemory(pDELV_Q_Entry, sizeof(DELIVERY_QUEUE_ENTRY));	pDELV_Q_Entry->SLOT_NM = SlotNo;}void Core_CompleteXORReq(	IN PCore_Driver_Extension pCore, 	IN PMV_XOR_Request pXORReq	){	PSG_Buffer pTempBuf;#ifdef RAID6_HARDWARE_XOR	PCORE_XOR_CONTEXT pXORContext;	PXOR_Table_Wrapper pTableWrapper;#endif	/* release SG buffers */	while (pXORReq->SG_Buffer)	{		pTempBuf = ((PSG_Buffer)pXORReq->SG_Buffer)->NextBuffer;		FreeSGBufferToPool(pCore, (PSG_Buffer *) &pXORReq->SG_Buffer);		pXORReq->SG_Buffer = pTempBuf;	}#ifdef RAID6_HARDWARE_XOR	pXORContext = (PCORE_XOR_CONTEXT)pXORReq->Context[MODULE_CORE];	MV_DASSERT( pXORContext->Context_Type==CORE_XOR_CONTEXT_TYPE_TABLE );	while ( pXORContext->Table_Wrapper )	{		pTableWrapper = ((PXOR_Table_Wrapper)pXORContext->Table_Wrapper)->NextBuffer;		FreeXORTableWrapperToPool(pCore, (PXOR_Table_Wrapper*)&pXORContext->Table_Wrapper);		pXORContext->Table_Wrapper = pTableWrapper;	}	FreeCoreXORContextToPool(pCore, (PCORE_XOR_CONTEXT *)&pXORReq->Context[MODULE_CORE]);#endif	pXORReq->Completion( pXORReq->Cmd_Initiator, pXORReq );}voidXORWriteCommand_A1(	IN PCore_Driver_Extension pCore,	IN PMV_XOR_Request pReq	){	MV_U16 SlotNo;	MV_PHYSICAL_ADDR tmpPhyAddress;	PMV_XOR_Command_Header_A1 pCmdHeader;	PMV_XOR_Command_Table_A1 pCmdTbl= (PMV_XOR_Command_Table_A1)pCore->XOR_Cmd_Table;	XOR_DELIVERY_QUEUE_ENTRY DELV_Q_Entry;	MV_U8 sId,tId;									/* source index and target index. */	int availSg = SG_BUFFER_SINGLE_COUNT;	//---	int consumed;					//---	PMV_SG_Entry sg;				//---	PSG_Buffer pSGBuf, pNextSGBuf, pTempBuf; 	pSGBuf = GetSGBufferFromPool(pCore);	if (pSGBuf == NULL)	{		MV_DPRINT(("Ran out of SG Buffers!\n"));		List_Add(&pReq->Queue_Pointer, &pCore->XOR_Waiting_List);		return;	}	else	{		pReq->SG_Buffer = pSGBuf;	}	pReq->SlotNo=0xfff;	SlotNo=XORGetOneCommandSlot(pCore, &pCmdHeader);	pReq->SlotNo=SlotNo;	sg = pSGBuf->Buffer_Vir;	//---	tmpPhyAddress.value = pCore->Cmd_Table_DMA.value + ((MV_PU8)&pCmdTbl[SlotNo].NextTableAddressLo - (MV_PU8)pCore->Cmd_Table);	pCmdHeader->Table_Address= tmpPhyAddress.parts.low;	pCmdHeader->Table_Address_High= tmpPhyAddress.parts.high;	pCmdHeader->XORTblLen=((sizeof(XOR_CMD_ENTRY_A1)*MAX_XOR_CMD_ENTRY)/sizeof(MV_U32))+3;	MV_ZeroMemory(&pCmdTbl[SlotNo], sizeof(MV_XOR_Command_Table_A1));/*XOR_PRD 0:	1. Fill Buffer0 from Src[0]	2. if RAID6, Fill Buffer1 from Src[0]XOR_PRD 1..n:	3. XOR to Buffer0 from Src[1..n]	4. if RAID6, GF_Multiply and XOR to Buffer1 from Src[1..n]XOR_PRD n+1:	5. Write to Tgt0 from Buffer0XOR_PRD n+2:	6. if RAID6, Write to Tgt1 from Buffer1*///XOR_PRD 0:#ifdef USE_NEW_SGTABLE	consumed = sgdt_prepare_hwprd( pCore, &pReq->Source_SG_Table_List[0], sg, availSg );#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 );	MV_ASSERT( availSg >= consumed );	pCmdTbl[SlotNo].XOR_PRD[0].PRDEntryCount = (MV_U8) consumed;	U64_ASSIGN_U64(tmpPhyAddress, pSGBuf->Buffer_DMA);	sg += consumed;	availSg -= consumed;	pCmdTbl[SlotNo].XOR_PRD[0].PRDTableAddress=tmpPhyAddress.parts.low;	pCmdTbl[SlotNo].XOR_PRD[0].PRDTableAddressHigh=tmpPhyAddress.parts.high;	pCmdTbl[SlotNo].XOR_PRD[0].Buffer0OpCode=OP_DIRECT_FILL; //direct fill	if(pReq->Target_SG_Table_Count>1)		pCmdTbl[SlotNo].XOR_PRD[0].Buffer1OpCode=OP_DIRECT_FILL; //direct fill	pCmdTbl[SlotNo].TotalByteCount=pReq->Source_SG_Table_List[0].Byte_Count;//XOR_PRD 1..n:	for(sId=1;sId<pReq->Source_SG_Table_Count;sId++)	{		// if (availSg < pReq->Source_SG_Table_List[sId].Valid_Entry_Count)		// Need a better solution. We don't know how many entries will be used in sgdt_prepare_hwprd.		if (availSg < SG_BUFFER_SINGLE_COUNT)		{			pNextSGBuf = GetSGBufferFromPool(pCore);			if (pNextSGBuf == NULL)			{				MV_DPRINT(("Ran out of SG Buffers!\n"));				Tag_ReleaseOne(&pCore->XOR_Tag_Pool, SlotNo);				while (pReq->SG_Buffer)				{					pTempBuf = ((PSG_Buffer)pReq->SG_Buffer)->NextBuffer;					FreeSGBufferToPool(pCore, (PSG_Buffer *) &pReq->SG_Buffer);					pReq->SG_Buffer = pTempBuf;				}				List_Add(&pReq->Queue_Pointer, &pCore->XOR_Waiting_List);				return;			}			pSGBuf->NextBuffer = pNextSGBuf;			sg = pNextSGBuf->Buffer_Vir;			availSg = SG_BUFFER_SINGLE_COUNT; 			pSGBuf = pNextSGBuf;		}#ifdef USE_NEW_SGTABLE		consumed = sgdt_prepare_hwprd( pCore, &pReq->Source_SG_Table_List[sId], sg, availSg );#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 );		MV_ASSERT( availSg >= consumed );		pCmdTbl[SlotNo].XOR_PRD[sId].PRDEntryCount = (MV_U8) consumed;		tmpPhyAddress.value = pSGBuf->Buffer_DMA.value + ((MV_PU8)sg - (MV_PU8)pSGBuf->Buffer_Vir);		sg += consumed;		availSg -= consumed;		pCmdTbl[SlotNo].XOR_PRD[sId].PRDTableAddress=tmpPhyAddress.parts.low;		pCmdTbl[SlotNo].XOR_PRD[sId].PRDTableAddressHigh=tmpPhyAddress.parts.high;		pCmdTbl[SlotNo].XOR_PRD[sId].Buffer0OpCode=OP_XOR_ENABLE; //XOR		if(pReq->Target_SG_Table_Count>1)		{			pCmdTbl[SlotNo].XOR_PRD[sId].DataByte=pReq->Coef[1][sId];			pCmdTbl[SlotNo].XOR_PRD[sId].Buffer1OpCode=OP_GF_XOR_ENABLE; //GF+XOR		}	}//XOR_PRD n..m(1 or 2):	for(tId=0;tId<pReq->Target_SG_Table_Count;tId++)	{		//if (availSg < pReq->Target_SG_Table_List[tId].Valid_Entry_Count)		// Need a better solution. We don't know how many entries will be used in sgdt_prepare_hwprd		if (availSg < SG_BUFFER_SINGLE_COUNT)		{			pNextSGBuf = GetSGBufferFromPool(pCore);			if (pNextSGBuf == NULL)			{				MV_DPRINT(("Ran out of SG Buffers!\n"));				Tag_ReleaseOne(&pCore->XOR_Tag_Pool, SlotNo);				while (pReq->SG_Buffer)				{					pTempBuf = ((PSG_Buffer)pReq->SG_Buffer)->NextBuffer;					FreeSGBufferToPool(pCore, (PSG_Buffer *) &pReq->SG_Buffer);					pReq->SG_Buffer = pTempBuf;				}				List_Add(&pReq->Queue_Pointer, &pCore->XOR_Waiting_List);				return;			}			pSGBuf->NextBuffer = pNextSGBuf;			sg = pNextSGBuf->Buffer_Vir;			availSg = SG_BUFFER_SINGLE_COUNT; 			pSGBuf = pNextSGBuf;		}#ifdef USE_NEW_SGTABLE		consumed = sgdt_prepare_hwprd( pCore, &pReq->Target_SG_Table_List[tId], sg, availSg );#else		consumed = pReq->Target_SG_Table_List[tId].Valid_Entry_Count;		for(i=0;i<pReq->Target_SG_Table_List[tId].Valid_Entry_Count;i++)		{			MV_CopyMemory(&sg[i], &pReq->Target_SG_Table_List[tId].Entry_Ptr[i], sizeof(MV_SG_Entry));		}#endif		MV_ASSERT( consumed );		MV_ASSERT( availSg >= consumed );		pCmdTbl[SlotNo].XOR_PRD[pReq->Source_SG_Table_Count+tId].PRDEntryCount = (MV_U8) consumed;		tmpPhyAddress.value = pSGBuf->Buffer_DMA.value + ((MV_PU8)sg - (MV_PU8)pSGBuf->Buffer_Vir);		sg += consumed;		availSg -= consumed;		pCmdTbl[SlotNo].XOR_PRD[pReq->Source_SG_Table_Count+tId].PRDTableAddress=tmpPhyAddress.parts.low;		pCmdTbl[SlotNo].XOR_PRD[pReq->Source_SG_Table_Count+tId].PRDTableAddressHigh=tmpPhyAddress.parts.high;		if(tId<1)			pCmdTbl[SlotNo].XOR_PRD[pReq->Source_SG_Table_Count+tId].Buffer0OpCode=OP_WRITE_ENABLE; //write		else			pCmdTbl[SlotNo].XOR_PRD[pReq->Source_SG_Table_Count+tId].Buffer1OpCode=OP_WRITE_ENABLE; //write	}	pCmdTbl[SlotNo].InterruptEnable=1;	pCmdTbl[SlotNo].ValidEntry=pReq->Source_SG_Table_Count+pReq->Target_SG_Table_Count;	pCore->XOR_Running_Req[SlotNo]=pReq;	pCore->XOR_Req_Count++;	XORPrepareDeliveryQueueEntry(pCore, SlotNo, &DELV_Q_Entry);	XORWriteDELV_Q_Entry(pCore, &DELV_Q_Entry);	//MV_DumpXORRegister(pCore);	/* Request is sent to the hardware and not finished yet. */	pReq->Request_Status = XOR_STATUS_SUCCESS;}#ifndef RAID6_HARDWARE_XORvoidXORWriteCommand(	IN PCore_Driver_Extension pCore,	IN PMV_XOR_Request pReq	){	MV_U16 SlotNo;	MV_PHYSICAL_ADDR tmpPhyAddress;	PMV_XOR_Command_Header pCmdHeader;	PMV_XOR_Command_Table pCmdTbl= (PMV_XOR_Command_Table)pCore->XOR_Cmd_Table;	XOR_DELIVERY_QUEUE_ENTRY DELV_Q_Entry;	MV_U8 sId,tId;									/* source index and target index. */	int availSg = SG_BUFFER_SINGLE_COUNT;	//---	int consumed;					//---

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?