core_helper.c

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

C
2,385
字号
#include "core_header.h"#include "core_exp.h"#include "core_helper.h"#include "core_init.h"void MV_DumpRegister(MV_PVOID This);#ifdef CORE_SAS_SUPPORT_ATA_COMMANDvoid CoreRestoreOriginalCDB(PCore_Driver_Extension pCore, PMV_Request pReq);#endifextern MV_BOOLEANSCSI_MakeSMARTReturnStatusCommand(	PCore_Driver_Extension pCore,	PMV_Request pReq	);extern MV_VOIDSCSI_MakeSynchronizeCacheCommmand(	PCore_Driver_Extension pCore,	PMV_Request pReq	);extern void Core_ResetCmdSlot(MV_PVOID Port, MV_U16 SlotNo);extern MV_BOOLEANSCSI_MakeCacheCommand(	PCore_Driver_Extension pCore,	PMV_Request pReq,	MV_BOOLEAN writeCache,	MV_BOOLEAN preread	);extern MV_BOOLEAN mvChannelStateMachine(	PCore_Driver_Extension pCore,	PDomain_Port pPort	);void Core_GetSupportedCounts(	MV_U16				maxIo,	MV_PU8				pDevCount,	MV_PU8				pExpanderCount,	MV_PU8				pPMCount,	MV_PU8				pInternalReqCount,	MV_PU8				pSGEntryCount,	MV_PU16				pSGBufferCount,	MV_PU8				pSATAScratchCount,	MV_PU8				pSMPScratchCount,	MV_PU16				pSlotCount,	MV_PU16				pContextCount,	MV_PU16				pSubReqCount	){	*pDevCount = MAX_DEVICE_SUPPORTED_PERFORMANCE;	if (maxIo==1) 	{		*pExpanderCount = MAX_EXPANDER_SUPPORTED_WHQL;		*pInternalReqCount = MIN_INTERNAL_REQ_COUNT;		*pSGEntryCount = MAX_SG_ENTRY_REDUCED;		*pSATAScratchCount = MIN_SATA_SCRATCH_COUNT;		*pSMPScratchCount = MIN_SMP_SCRATCH_COUNT;		*pSGBufferCount = MIN_SG_BUFFER_COUNT;		*pSlotCount = 4;		*pPMCount = MAX_PM_SUPPORTED_PERFORMANCE;		*pSubReqCount = 0;	}	else	{		*pExpanderCount = MAX_EXPANDER_SUPPORTED_PERFORMANCE;		*pSlotCount = MAX_CORE_REQUEST_NUMBER_PERFORMANCE;		*pInternalReqCount = *pDevCount;		*pSGEntryCount = MAX_SG_ENTRY;#ifndef SOFTWARE_XOR		*pSGBufferCount = MAX_SG_BUFFER_COUNT;#else		*pSGBufferCount = MAX_SG_BUFFER_COUNT_NO_XOR;#endif#ifndef SUPPORT_LARGE_REQUEST 		*pSubReqCount = 0;#else /* SUPPORT_LARGE_REQUEST */ 		*pSubReqCount = (MV_MAX_TRANSFER_SIZE + CORE_MAX_TRANSFER_SIZE-1)/CORE_MAX_TRANSFER_SIZE * (*pDevCount);#endif /* SUPPORT_LARGE_REQUEST */		*pSATAScratchCount = *pDevCount;		*pSMPScratchCount = *pDevCount;		*pPMCount = MAX_PM_SUPPORTED_PERFORMANCE;	}	*pContextCount = *pInternalReqCount + *pSlotCount + *pSubReqCount;}void Port_AbortRequests(	PDomain_Port pPort,	MV_U8 ScsiStatus,	PDomain_Device pDevice	){	PCore_Driver_Extension pCore = pPort->Core_Extension;	MV_U16 i, count;	PMV_Request pReq;	List_Head *pPos;	MV_U8 portId;	/* Device is gone. Return the Running_Req */	for ( i=0; i<pCore->Slot_Count_Supported; i++ )	{/* if this command has been queued for return, don't do abort */		if(pCore->Completing_Slot[i>>5]&(1L<<(i%32)))		{			MV_DPRINT(("Verified Slot(0x%x) in completion while aborting \n",i));			continue;		}		pReq = pCore->Running_Req[i];		if ( pReq != NULL )		{			PDomain_Device pReqDev=NULL;			if ( IS_A_SMP_REQ(pReq) )			{				if(pDevice != NULL)					continue;				portId=MapPortId(pCore, pReq->Device_Id);			}			else			{				portId=MapPortId(pCore, pReq->Device_Id);				if(MapDeviceId(pCore,pReq->Device_Id)!=ID_NOT_MAPPED)					pReqDev=&pCore->Devices[MapDeviceId(pCore,pReq->Device_Id)];			}			if( portId == pPort->Id )			{				if((pDevice != NULL)&&(pDevice->Id!=pReq->Device_Id))					continue;							if((ScsiStatus != REQ_STATUS_NO_DEVICE)&& (!IS_A_SMP_REQ(pReq)) &&					(IS_SSP(pReqDev))&&					(pReqDev->Error_Handling_State==EH_NONE) )				{					if(!IS_A_TSK_REQ(pReq))					{						pReq->Scsi_Status = ScsiStatus;						Device_MakeRequestTaskRequest(pPort,pReq,ABORT_TASK_TMF);					}				}				else				{					pReq->Scsi_Status = ScsiStatus;					MV_DPRINT(("AbortReq: Reset pPort(0x%x) Req->Device_Id(0x%x) Slot(0x%x)\n",MapPortId(pCore, pReq->Device_Id),pReq->Device_Id, i ));					Core_ResetCmdSlot( pPort, i );				}			}		}	}	if(ScsiStatus==REQ_STATUS_RETRY)		return;		/* Return the waiting request related to this device. */		//TBD: Do we have a better solution?	count = 0;	LIST_FOR_EACH(pPos, &pCore->Waiting_List) {		count++;	}	while ( (count>0)&&(!List_Empty(&pCore->Waiting_List)) )	{		pReq = (PMV_Request)List_GetFirstEntry(&pCore->Waiting_List, MV_Request, Queue_Pointer);		if((pDevice!=NULL)&&(pDevice->Id!=pReq->Device_Id))		{			List_AddTail(&pReq->Queue_Pointer, &pCore->Waiting_List);			count--;			continue;		}		portId=MapPortId(pCore, pReq->Device_Id);/* leave TASK requests on */		if( (portId==pPort->Id)&&(!IS_A_TSK_REQ(pReq)) )		{			pReq->Scsi_Status = ScsiStatus;			CompleteRequest(pCore, pReq, 0);		}		else		{			List_AddTail(&pReq->Queue_Pointer, &pCore->Waiting_List);		}		count--;	}}/* this is mainly for SATA/STP (NCQ etc.) *//* do not count SAS/SMP, etc requests in it */MV_BOOLEAN Port_IsRequestRunning( PCore_Driver_Extension pCore, MV_U8 portId ){	PMV_Request pReq;	struct _Domain_Device *pDevice = NULL;	MV_U16 deviceId;	MV_U16 i;	for( i=0; i<pCore->Slot_Count_Supported; i++ )	{		pReq = pCore->Running_Req[i];		if(pReq != NULL)		{			MV_U8 reqPortId;			reqPortId=MapPortId(pCore,pReq->Device_Id);			deviceId = MapDeviceId(pCore, pReq->Device_Id);			pDevice= &pCore->Devices[deviceId];			if((reqPortId == portId)&&IS_STP_OR_SATA(pDevice))				return MV_TRUE;		}	}	return MV_FALSE;}/* A memory-saving way to return an unique tag (return 32 if not found). Could be replaced by a tag pool if for performance regardless memory usage*/MV_U16 GetNCQTag(	PDomain_Device pDevice){	PCore_Driver_Extension pCore = pDevice->pPort->Core_Extension;	PMV_Command_Header pCmdHeader = (PMV_Command_Header)pCore->Cmd_List;	MV_U16 Tag;	MV_U16 i;	for(Tag=0;Tag<32;Tag++)	{		for(i=0;i<pCore->Slot_Count_Supported;i++)		{			if(pCore->Running_Req[i]!=NULL)			{				if(IS_A_SMP_REQ(pCore->Running_Req[i]))					continue;				if((pDevice->Id==pCore->Running_Req[i]->Device_Id)&&					(pCmdHeader[i].Tag==Tag)) break;			}		}		if(i==pCore->Slot_Count_Supported)			break; 	}	return Tag;}MV_BOOLEAN Core_WaitingForIdle(MV_PVOID pExtension){	PCore_Driver_Extension pCore = (PCore_Driver_Extension)pExtension;	MV_U8 i;	for(i=0;i<16;i++)	{		if ( pCore->Running_Slot[i] != 0 )			return MV_FALSE;	}		return MV_TRUE;}void Core_FillSenseData(PMV_Request pReq, MV_U8 senseKey, MV_U8 adSenseCode){	if (pReq->Sense_Info_Buffer != NULL) {		((MV_PU8)pReq->Sense_Info_Buffer)[0] = 0x70;	/* Current */		((MV_PU8)pReq->Sense_Info_Buffer)[2] = senseKey;		((MV_PU8)pReq->Sense_Info_Buffer)[7] = 0;		/* additional sense length */		((MV_PU8)pReq->Sense_Info_Buffer)[12] = adSenseCode;	/* additional sense code */	}}void MV_DumpRegister(MV_PVOID This){#ifndef _OS_BIOS	PCore_Driver_Extension pCore = (PCore_Driver_Extension)This;	MV_U32 reg;	MV_PTR_INTEGER offset;	MV_REG_WRITE_DWORD(pCore->Mmio_Base, COMMON_CMD_ADDR, CMD_PORT_ISS0);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_CMD_DATA);	MV_PRINT("CMD_PORT_ISS0 =0x%x\n",reg);	MV_REG_WRITE_DWORD(pCore->Mmio_Base, COMMON_CMD_ADDR, CMD_PORT_ACTIVE0);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_CMD_DATA);	MV_PRINT("CMD_PORT_ACTIVE0 =0x%x\n",reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_CONTROL );	MV_PRINT("COMMON_CONTROL = 0x%x\n",reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, PORT_PHY_CONTROL0 );	MV_PRINT("PORT_PHY_CONTROL0 = 0x%x\n",reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, PORT_IRQ_STAT0 );	MV_PRINT("PORT_IRQ_STAT0 = 0x%x\n",reg);	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, HBA_CONTROL );	MV_PRINT("HBA_CONTROL = 0x%x\n",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, COMMON_DELV_Q_RD_PTR );	MV_PRINT("COMMON_DELV_Q_RD_PTR = 0x%x\n",reg);	offset=COMMON_CMPL_Q_WR_PTR;	reg=MV_REG_READ_DWORD(pCore->Mmio_Base, offset );	MV_PRINT("COMMON_CMPL_Q_WR_PTR = 0x%x\n",reg);	MV_PRINT("CMPL_Q[0]= 0x%x\n",*(MV_U32 *)pCore->CMPL_Q);#endif}PMV_RequestFindRunningReqByTag(	IN PCore_Driver_Extension pCore,	IN MV_U16 Tag	){	MV_U16 SlotNo;		SlotNo= Tag&0x1ff;		if(pCore->Running_Req[SlotNo]!=NULL)	{		if((MV_U16)(pCore->Running_Req[SlotNo]->Tag<<pCore->MaxCmdSlotWidth)==(Tag&(0xffff<<pCore->MaxCmdSlotWidth)))		return (pCore->Running_Req[SlotNo]);	}	return NULL;}#if defined(_OS_WINDOWS) && defined(SUPPORT_ERROR_HANDLING)MV_VOID Core_ReqTimeout (MV_PVOID This, MV_PVOID temp);MV_VOID __add_timer(IN PCore_Driver_Extension pCore,		    IN PMV_Request pReq){	MV_U32 mapped_id;	PDomain_Device pDevice;	mapped_id = MapDeviceId(pCore, pReq->Device_Id);	pDevice = &pCore->Devices[mapped_id];	if (IS_A_SMP_REQ(pReq))		return;		/* start timer for error handling */	if (pDevice->Timer_ID == NO_CURRENT_TIMER)	{		if (pReq->Time_Out != 0)			pDevice->Timer_ID = Timer_AddRequest(pCore, 							     pReq->Time_Out * 2, 							     Core_ReqTimeout, 							     pDevice, NULL);		else			pDevice->Timer_ID = Timer_AddRequest(pCore, 							     REQUEST_TIME_OUT,							     Core_ReqTimeout,							     pDevice, NULL);	}}MV_VOID __cancel_timer(IN PCore_Driver_Extension pCore,		       PDomain_Device pDevice,		       IN PMV_Request pReq){	if (pDevice->Timer_ID != NO_CURRENT_TIMER)	{		Timer_CancelRequest(pCore, pDevice->Timer_ID);		pDevice->Timer_ID = NO_CURRENT_TIMER;	}}				  MV_VOID __renew_timer(IN PCore_Driver_Extension pCore,		      IN PMV_Request pReq){	PMV_Request pOldReq;	MV_U32 mapped_id;	PDomain_Device pDevice;	mapped_id = MapDeviceId(pCore, pReq->Device_Id);	pDevice = &pCore->Devices[mapped_id];	if (!IS_A_SMP_REQ(pReq) && (mapped_id != ID_NOT_MAPPED))	{		/* check if this is the oldest request */		MV_DASSERT(!List_Empty(&pDevice->Sent_Req_List));		pOldReq = (PMV_Request)List_GetFirstEntry(&pDevice->Sent_Req_List, MV_Request, Queue_Pointer);		if (pOldReq == pReq)		{			__cancel_timer(pCore, pDevice, pReq);			if (!List_Empty(&pDevice->Sent_Req_List))			{				/* this should not happen on a ATAPI device */				MV_DASSERT(!IS_ATAPI(pDevice));				MV_DASSERT(!IS_TAPE(pDevice));								__add_timer(pCore, pOldReq);			}		}		else		{			List_Add(&pOldReq->Queue_Pointer, &pDevice->Sent_Req_List);		}	}}#else  /* defined(_OS_WINDOWS) && defined(SUPPORT_ERROR_HANDLING) */MV_VOID Core_ReqTimeout (MV_PVOID This);MV_VOID __cancel_timer(IN PCore_Driver_Extension pCore,		       IN PDomain_Device pDevice,		       IN PMV_Request pReq){//	if (pReq)//		ossw_del_timer(&pReq->timer);}/* renew for windows means cancel for linux */MV_VOID __renew_timer(IN PCore_Driver_Extension pCore,		      IN PMV_Request pReq){	__cancel_timer(pCore, NULL, pReq);}MV_VOID __add_timer(IN PCore_Driver_Extension pCore,		    IN PMV_Request pReq){	MV_U32 tm;	if (IS_A_SMP_REQ(pReq))		return;		if (pReq->Time_Out != 0)		tm = pReq->Time_Out * 2;	else		tm = REQUEST_TIME_OUT;	//	ossw_add_timer(&pReq->timer, tm * 1000,//		       (OSSW_TIMER_FUNCTION) Core_ReqTimeout,//		       (OSSW_TIMER_DATA) pReq);}#endif /* defined(_OS_WINDOWS) && defined(SUPPORT_ERROR_HANDLING) */void FreeDeviceToPool( PCore_Driver_Extension pCore, PDomain_Device pDevice ){	MV_U16 index;	index=pCore->Device_Map[pDevice->Id];	pCore->Device_Map[pDevice->Id] = ID_NOT_MAPPED;	Tag_ReleaseOne(&pCore->Device_Pool, index);#ifdef USE_DYN_REGISTER_SET	if(pCore->Devices[index].Register_Set!=ID_NOT_MAPPED) FreeRegisterSet(pCore,&pCore->Devices[index]);#endif /* USE_DYN_REGISTER_SET */	__cancel_timer(pCore, pDevice, NULL);	pCore->Devices[index].State = DEVICE_STATE_IDLE;}void FreeExpanderToPool( PCore_Driver_Extension pCore, PDomain_Expander pExpander ){	MV_U16 index;	index=pCore->Device_Map[pExpander->ExpId];	pCore->Device_Map[pExpander->ExpId] = ID_NOT_MAPPED;	Tag_ReleaseOne(&pCore->Expander_Pool, index);}#ifdef SUPPORT_PMvoid FreePMToPool( PCore_Driver_Extension pCore, PDomain_PM pPM ){	MV_U16 index;	index=pCore->Device_Map[pPM->Id];	pCore->Device_Map[pPM->Id] = ID_NOT_MAPPED;	Tag_ReleaseOne(&pCore->PM_Pool, index);#ifdef USE_DYN_REGISTER_SET	if (pCore->PMs[index].Register_Set!=ID_NOT_MAPPED)		PM_FreeRegisterSet(pCore,&pCore->PMs[index]);#endif /* USE_DYN_REGISTER_SET */}void PreEmptyPM(PDomain_PM pPM){	MV_ZeroMemory((MV_U8 *)pPM,sizeof(Domain_PM));#ifdef SUPPORT_TIMER	pPM->Timer_ID=NO_CURRENT_TIMER;#endif#ifdef USE_DYN_REGISTER_SET	pPM->Register_Set=ID_NOT_MAPPED;

⌨️ 快捷键说明

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