⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 core_init.c

📁 6440linuxDriver的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	MapDeviceId(pCore,MapIndexA) = MapDeviceId(pCore,MapIndexB);	MapDeviceId(pCore,MapIndexB) = Index;}MV_VOID SwapExpID(	IN PCore_Driver_Extension pCore,	IN MV_U8 MapIndexA,	IN MV_U8 MapIndexB){	MV_U8 Index;	pCore->Expanders[MapDeviceId(pCore,MapIndexA)].ExpId=MapIndexB;	pCore->Expanders[MapDeviceId(pCore,MapIndexB)].ExpId=MapIndexA;	Index = MapDeviceId(pCore,MapIndexA);	MapDeviceId(pCore,MapIndexA) = MapDeviceId(pCore,MapIndexB);	MapDeviceId(pCore,MapIndexB) = Index;}MV_VOID SwapPortID(	IN PCore_Driver_Extension pCore,	IN MV_U8 MapIndexA,	IN MV_U8 MapIndexB){	MV_U8 Index;	pCore->Ports[MapPortEntry(pCore,MapIndexA)].Id=MapIndexB;	pCore->Ports[MapPortEntry(pCore,MapIndexB)].Id=MapIndexA;	Index = MapPortEntry(pCore,MapIndexA);	MapPortEntry(pCore,MapIndexA) = MapPortEntry(pCore,MapIndexB);	MapPortEntry(pCore,MapIndexB) = Index;}MV_U8 GetFirstPhy(	IN PCore_Driver_Extension pCore,	IN PDomain_Port pPort){	MV_U8 i;	MV_U8 phyMap=pPort->MemberPhyMap;	for(i=0; i<pCore->Phy_Num; i++)	{		if(phyMap>>i)			break;	}	return i;}MV_VOID IDSorting(	IN PCore_Driver_Extension pCore	){	PDomain_Device pDevice = NULL;	MV_U8 IndexA, IndexB, MinIndex;	MV_U32 WeightA, WeightB;	MV_U8 i=0,j=0;/* This routine try to re-arrange only the order of port_map/device_map, but the ports[]/devices[]/expanders[] order should stay the same.*/// re-arrange the port_map order by their least phy number	for( i=0; i<=pCore->Port_Num; i++ )	{		if( pCore->Port_Map[i] == ID_NOT_MAPPED )			continue;		IndexA=GetFirstPhy(pCore, &pCore->Ports[MapPortEntry(pCore,i)]);		if(IndexA >= pCore->Phy_Num )			continue; // virtual				MinIndex=i;		for(j=i; j<=pCore->Port_Num; j++ )		{			if( pCore->Port_Map[j] == ID_NOT_MAPPED )				continue;			IndexB=GetFirstPhy(pCore, &pCore->Ports[MapPortEntry(pCore,j)]);			if(IndexB >= pCore->Phy_Num )				continue; // virtual			if(IndexA>IndexB)			{				MinIndex=j;				IndexA=IndexB;			}		}		if(MinIndex!=i)			SwapPortID(pCore,i,MinIndex); 	}// re-arrange the expander_map order by their port ID	for( i=MIN_EXPANDER_ID; i<=pCore->Current_Expander_Id; i++ )	{		if( pCore->Device_Map[i] == ID_NOT_MAPPED )			continue;		IndexA = pCore->Expanders[MapDeviceId(pCore,i)].pPort->Id;				MinIndex=i;		for(j=i; j<=pCore->Current_Expander_Id; j++ )		{			if( pCore->Device_Map[j] == ID_NOT_MAPPED )				continue;			IndexB = pCore->Expanders[MapDeviceId(pCore,j)].pPort->Id;			if(IndexA>IndexB)			{				MinIndex=j;				IndexA=IndexB;			}		}		if(MinIndex!=i)			SwapExpID(pCore,i,MinIndex); 	}// re-arrange the device_map order by their least phy number and port ID // portId.exp.phyId	for( i=0; i<=pCore->Current_Device_Id; i++ )	{		if( pCore->Device_Map[i] == ID_NOT_MAPPED )			continue;		pDevice=&pCore->Devices[MapDeviceId(pCore,i)];		if(pDevice->pPort==NULL)			continue; // virtual		WeightA=pDevice->Phy_Id +			(pDevice->pPort->Id <<16);		if(pDevice->pExpander!=NULL)			WeightA += pDevice->pExpander->ExpId <<8;		MinIndex=i;		for(j=i; j<=pCore->Current_Device_Id; j++ )		{			if( pCore->Device_Map[j] == ID_NOT_MAPPED )				continue;			pDevice=&pCore->Devices[MapDeviceId(pCore,j)];			if(pDevice->pPort==NULL)				continue; // virtual			WeightB=pDevice->Phy_Id +				(pDevice->pPort->Id <<16);			if(pDevice->pExpander!=NULL)				WeightB += pDevice->pExpander->ExpId <<8;			if(WeightA>WeightB)			{				MinIndex=j;				WeightA=WeightB;			}		}		if(MinIndex!=i)			SwapDeviceID(pCore,i,MinIndex); 	}}MV_BOOLEAN mvChannelStateMachine(	PCore_Driver_Extension pCore,	PDomain_Port pPort	){	MV_U8 i,j;	MV_U8 index;	MV_U8 portState;	PDomain_Device pDevice = NULL;	if ( pPort==NULL )		portState = PORT_STATE_IDLE;	else		portState = pPort->Port_State;	//Each step: if fail like no device, should go to the end.	/* Channel state machine */	switch ( portState )	{		case PORT_STATE_IDLE:			/* To do reset */			/* if there are any SATA drives, need to wait sometime			   for signature FIS to come back 			   NOTE: This is for certain models of Seagate drives which will hang				     if we send soft reset before the power-on signature FIS is					 received. To save time, we do a wait here for 5 seconds 					 for all SATA drives instead of doing them in sequence later					 in SATA_PortReset */			for (i=0; i<MAX_PORT_ID; i++)			{				MV_U8 index=pCore->Port_Map[i];				if (index == ID_NOT_MAPPED)					continue;				pPort = &pCore->Ports[index];				if ( pPort->Type & PORT_TYPE_SATA )				{					MV_DPRINT(("Waiting for 5 seconds before resetting SATA port\n"));					HBA_SleepMillisecond(pCore, 5000);					break;				}			}			for( i=0; i<MAX_PORT_ID; i++ )			{				MV_U8 index=pCore->Port_Map[i];				if (index == ID_NOT_MAPPED)					continue;				pPort = &pCore->Ports[index];				MV_DASSERT( pPort->Port_State==PORT_STATE_IDLE );				if ( pPort->Type&PORT_TYPE_SAS )				{					SAS_PortReset( pPort, MV_FALSE );				}				else				{					SATA_PortReset( pPort, MV_FALSE );				}			}/* for no port case */			if(pCore->Port_Pool.Top==MAX_PORT_NUMBER)			{				if(pPort==NULL)				{					if ( pCore->State==CORE_STATE_IDLE )					{						pCore->State = CORE_STATE_STARTED;												/* The 1st time init */						core_start_cmpl_notify(pCore);					}				}				else				{					pPort->Port_State=PORT_STATE_INIT_DONE;					mvChannelStateMachine(pCore, pPort);				}			}			break;		/* 		 * Each port will call mvDeviceStateMachine for its devices. 		 * When all the devices for that port are done, will call mvChannelStateMachine.		 */		case PORT_STATE_INIT_DONE:			/* Check whether all the ports are done. */			for ( j=0; j<MAX_PORT_ID; j++ )			{				index=pCore->Port_Map[j];				if(index==ID_NOT_MAPPED)					continue;				pPort = &pCore->Ports[index];				if ( pPort->Port_State!=PORT_STATE_INIT_DONE )				{					// hibernation: check if this port has devices 					// waiting to be initialized   /* In case that another port is doing discovery (not finished yet),    the device list could be empty */   /* MV_DASSERT( !List_Empty(&pPort->Device_List) ); */					for( i=0; i<pPort->Device_Number; i++ )					{						pDevice = (PDomain_Device)List_GetFirstEntry(&pPort->Device_List, Domain_Device, Queue_Pointer);						List_AddTail( &pDevice->Queue_Pointer, &pPort->Device_List );						if( pDevice->State != DEVICE_STATE_INIT_DONE )						{							// if this device is waiting, try sending request again							if( pDevice->Is_Waiting )							{								if( IS_STP_OR_SATA(pDevice) )									SATA_DeviceStateMachine( pCore, pDevice );								else if( IS_SSP(pDevice) )									SAS_DeviceStateMachine( pCore, pDevice );							}							return MV_TRUE;						}				}					return MV_TRUE;				}			}			/* Discovery procedure is finished. */			if (pCore->State == CORE_STATE_IDLE)			{				/* do a ID sorting */ 				IDSorting(pCore); 				pCore->State = CORE_STATE_STARTED;#ifdef SUPPORT_SGPIO 				SGPIO_Initialize(pCore);#endif#ifdef SUPPORT_I2C 				I2C_ModuleInitialize(pCore);#else				core_start_cmpl_notify(pCore);#endif /* SUPPORT_I2C */ 			} 			else 			{ 				for ( j=0; j<MAX_PORT_ID; j++ ) 				{ 					index = pCore->Port_Map[j]; 					if (index == ID_NOT_MAPPED) 						continue;  					pPort = &pCore->Ports[index];  					/* check which device on this port needs to be reported */ 					//MV_PRINT("pPort->Device_Number = %d\n", pPort->Device_Number); 					for( i=0; i<pPort->Device_Number; i++ )					{							pDevice = (PDomain_Device)List_GetFirstEntry(&pPort->Device_List, Domain_Device, Queue_Pointer);							List_AddTail( &pDevice->Queue_Pointer, &pPort->Device_List );						if ( pDevice->Need_Notify )						{							core_notify_device_hotplug(pCore, EVENT_DEVICE_ARRIVAL, pDevice->Id);							pDevice->Need_Notify = MV_FALSE;								#ifdef SUPPORT_PM							/*							if (pDevice->pPM)							{								pDevice->pPM->PluginNotify &= ~MV_BIT(pDevice->PM_Number);							}							*/							#endif						}					}				}			}			break;	}	return MV_TRUE;}static MV_BOOLEAN SAS_DeviceStateMachine(	PCore_Driver_Extension pCore,	PDomain_Device pDevice	){	MV_U8 i;	PDomain_Port pPort = pDevice->pPort;	/* prevent running recursive state machine like hotplug */	if(pCore->Device_Map[pDevice->Id] == ID_NOT_MAPPED)		return MV_FALSE;	switch ( pDevice->State )	{		case DEVICE_STATE_RESET_DONE:			MV_DPRINT(("Device %d DEVICE_STATE_RESET_DONE.\n", pDevice->Id));			/* To do inquiry */			Device_MakeInquiryTaskRequest( pDevice );			break;		case DEVICE_STATE_INQUIRY_DONE:			MV_DPRINT(("Device %d DEVICE_STATE_INQUIRY_DONE.\n", pDevice->Id));			/* To do read capacity */			Device_MakeReadCapacityTaskRequest( pDevice );			break;		case DEVICE_STATE_INQUIRY_16_DONE:			MV_DPRINT(("Device %d DEVICE_STATE_INQUIRY_16_DONE.\n", pDevice->Id));			/* To do read capacity 16 */			Device_MakeReadCapacity16TaskRequest( pDevice );			break;		case DEVICE_STATE_READ_CAPACITY_DONE:			MV_DPRINT(("Device %d DEVICE_STATE_READ_CAPACITY_DONE.\n", pDevice->Id));			/* To do read capacity */			Device_MakeStartStopUnitRequest( pDevice, 1 ); /* Start */			break;		case DEVICE_STATE_STARTSTOP_DONE:			MV_DPRINT(("Device %d DEVICE_STATE_STARTSTOP_DONE.\n", pDevice->Id));	#ifdef CORE_SAS_SUPPORT_ATA_COMMAND			/* To do mode sense to get device parameter */			Device_MakeModeSenseRequest( pDevice );			break;		case DEVICE_STATE_MODE_SENSE_DONE:			MV_DPRINT(("Device %d DEVICE_STATE_MODE_SENSE_DONE.\n", pDevice->Id));			/* To enable pre-read and write cache.*/			Device_MakeModeSelectRequest( pDevice );			break;		case DEVICE_STATE_MODE_SELECT_DONE:			MV_DPRINT(("Device %d DEVICE_STATE_MODE_SELECT_DONE.\n", pDevice->Id));	#endif			/* Initialization procedure is done. */			pDevice->State = DEVICE_STATE_INIT_DONE;        	/* No break here. */		case DEVICE_STATE_INIT_DONE:			MV_DPRINT(("Device %d DEVICE_STATE_INIT_DONE.\n", pDevice->Id));			for( i=0; i<pPort->Device_Number; i++ )			{				pDevice = (PDomain_Device)List_GetFirstEntry(&pPort->Device_List, Domain_Device, Queue_Pointer);				List_AddTail( &pDevice->Queue_Pointer, &pPort->Device_List );				if( pDevice->State != DEVICE_STATE_INIT_DONE )				{					// if this device is waiting, try sending request again					if( pDevice->Is_Waiting )					{						if( IS_STP_OR_SATA(pDevice) )							SATA_DeviceStateMachine( pCore, pDevice );						else if( IS_SSP(pDevice) )							SAS_DeviceStateMachine( pCore, pDevice );					}					return MV_TRUE;				}				else					pDevice->Is_Waiting = MV_FALSE;			}			pPort->Port_State = PORT_STATE_INIT_DONE;			mvChannelStateMachine(pCore, pPort);			break;		default:			break;	}	return MV_TRUE;}MV_BOOLEAN SATA_DeviceStateMachine(	PCore_Driver_Extension pCore,	PDomain_Device pDevice	){	MV_U8 i;

⌨️ 快捷键说明

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