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

📄 core_api.c

📁 6440linuxDriver的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	PDomain_Expander pExp;	PMV_Request pOrgReq = (PMV_Request)pReq->Org_Req;	struct SMPResponse *pSMPResp = (struct SMPResponse *)pReq->Data_Buffer;	MV_U8 phyIndex = (MV_U8)pReq->Req_Flag;	pExp = &pCore->Expanders[MapDeviceId(pCore, pExpInfo->Link.Self.DevID)];	if( pSMPResp->Function == DISCOVER )	{		pExpInfo->Link.Self.PhyID[phyIndex] = pSMPResp->Response.Discover.AttachedPhyIdentifier;		if( phyIndex == 0 )		{			// only need to store the SAS address once, should be the same for all parent phys			MV_CopyMemory( pExpInfo->Link.Parent.SAS_Address, pSMPResp->Response.Discover.SASAddress, 8 );		}						FreeSMPScratchToPool( pCore, (PSMP_Scratch_Buffer)pReq->Scratch_Buffer );		FreeInternalReqToPool( pCore, pReq );		if( phyIndex == pExpInfo->Link.Self.PhyCnt-1 )			Core_GetExpInformationHardware( pCore, pExp, pExpInfo, pOrgReq, REPORT_GENERAL, 0 );		else			Core_GetExpInformationHardware( pCore, pExp, pExpInfo, pOrgReq, DISCOVER, phyIndex+1 );		return;	}	else if( pSMPResp->Function == REPORT_GENERAL )	{		pExpInfo->Configuring = pSMPResp->Response.ReportGeneral.Configuring;		MV_CopyMemory( &pExpInfo->ExpChangeCount, pSMPResp->Response.ReportGeneral.ExpanderChangeCount, 2 );			FreeSMPScratchToPool( pCore, (PSMP_Scratch_Buffer)pReq->Scratch_Buffer );		FreeInternalReqToPool( pCore, pReq );		pCore->Scratch_Count2++;		/* convert SAS addr to little-endian */		if (pExpInfo->Link.Parent.SAS_Address[0] != 0x50)			mv_swap_bytes(pExpInfo->Link.Parent.SAS_Address, 8);		if (pExpInfo->Link.Self.SAS_Address[0] != 0x50)			mv_swap_bytes(pExpInfo->Link.Self.SAS_Address, 8);		if (pCore->Scratch_Count2 == pCore->Scratch_Count1)			CompleteRequest(pCore, pOrgReq, 0);	}}void Core_GetExpInformationHardware(	PCore_Driver_Extension pCore, 	PDomain_Expander pExp,	PExp_Info pExpInfo, 	PMV_Request pReq,	MV_U8 requestType,	MV_U8 phyIndex	){	PMV_Request pNewReq = GetInternalReqFromPool(pCore);	PSMP_Scratch_Buffer pSMPSB;	struct SMPRequest *pSMPReq;    PMV_SG_Table pSGTable;	if( pNewReq == NULL ) 	{		MV_DPRINT(("ERROR: No more free internal requests. Request aborted.\n"));		return;	}	pSMPSB = GetSMPScratchFromPool(pCore);	if( pSMPSB == NULL )	{		FreeInternalReqToPool(pCore, pReq);		MV_DPRINT(("ERROR: No more free SMP scratch buffer. Request aborted.\n"));		return;	}	pSGTable = &pReq->SG_Table;	/* Prepare identify ATA task */	pNewReq->Cdb[0] = SCSI_CMD_MARVELL_SPECIFIC;	pNewReq->Cdb[1] = CDB_CORE_MODULE;	pNewReq->Cdb[2] = CDB_CORE_SMP;	pNewReq->Tag = 0xbb;	pNewReq->Device_Id = (requestType == DISCOVER) ? pExp->pParent->ExpId : pExp->ExpId;	pNewReq->Cmd_Initiator = pCore;	pNewReq->Data_Transfer_Length = sizeof(struct SMPRequest);	pNewReq->Data_Buffer = &pSMPSB->SMP_Req;	pNewReq->Org_Req = pReq;#ifndef CORE_SAS_SUPPORT_ATA_COMMAND	pNewReq->Context[MODULE_CORE] = pExpInfo;#else	((PCORE_CONTEXT)(pNewReq->Context[MODULE_CORE]))->u.cdb.Data_Buffer = pExpInfo;#endif /* CORE_SAS_SUPPORT_ATA_COMMAND */	pNewReq->Scratch_Buffer = pSMPSB;	pSMPReq = (struct SMPRequest *)pNewReq->Data_Buffer;	pSMPReq->Function = requestType;	if( requestType == DISCOVER )	{		// send discover on every phy; use Req_Flag to keep track of what phy we're on		pSMPReq->Request.Discover.PhyIdentifier = pExp->ParentPhyId[phyIndex];			pNewReq->Req_Flag = phyIndex;	}	pSMPReq->SMPFrameType = SMP_REQUEST_FRAME;	pNewReq->Completion = (void(*)(MV_PVOID,PMV_Request))Core_GetExpInformationCallback;	/* Make SG table */	SGTable_Init(pSGTable, 0);	/* Send this internal request */	Core_ModuleSendRequest(pCore, pNewReq);}MV_VOIDCore_GetExpInformation(	PCore_Driver_Extension pCore,	IN PDomain_Expander pExp,	OUT PExp_Info pExpInfo,	IN PMV_Request pReq	){	MV_U8 i, phyId=0;	pExpInfo->Link.Self.DevType = DEVICE_TYPE_EXPANDER;	pExpInfo->Link.Self.DevID = pExp->ExpId;	pExpInfo->Link.Self.PhyCnt = pExp->ParentPhyCount;	MV_CopyMemory( pExpInfo->Link.Self.SAS_Address, &pExp->SASAddr.value, 8 );	if( pExp->pParent != NULL )	{		pExpInfo->Link.Parent.DevType = DEVICE_TYPE_EXPANDER;		pExpInfo->Link.Parent.DevID = pExp->pParent->ExpId;	}	else if( pExp->pPort != NULL )	{			for( i=0; i<pCore->Phy_Num; i++ )			{				if( pExp->pPort->MemberPhyMap & MV_BIT(i) )				{					pExpInfo->Link.Self.PhyID[phyId] = (MV_U8)(pCore->Phy[i].AttDevInfo >> 24);					phyId++;				}			}		pExpInfo->Link.Parent.DevType = DEVICE_TYPE_PORT;		pExpInfo->Link.Parent.DevID = pExp->pPort->Id;		MV_CopyMemory( pExpInfo->Link.Parent.SAS_Address, &pExp->SASAddr, 8 );	}	pExpInfo->Link.Parent.PhyCnt = pExp->ParentPhyCount;	MV_CopyMemory( pExpInfo->Link.Parent.PhyID, pExp->ParentPhyId, 8 ); 	pExpInfo->RouteTableConfigurable = pExp->configurable_route_table;	pExpInfo->PhyCount = pExp->Phy_Count;	pExpInfo->MaxRouteIndexes = (MV_U16)pExp->Route_Index_Count;	/* the following is dummy code for now - later will merge with official discovery 	   engine and it will provide the needed info */	pExpInfo->ComponentID = pExp->ComponentID;	pExpInfo->ComponentRevisionID = pExp->ComponentRevisionID;	MV_CopyMemory( pExpInfo->ComponentVendorID, pExp->ComponentVendorID, 8 );	MV_CopyMemory( pExpInfo->VendorID, pExp->VendorID, 8 );	MV_CopyMemory( pExpInfo->ProductID, pExp->ProductID, 16 );	MV_CopyMemory( pExpInfo->ProductRev, pExp->ProductRev, 4 );	/* Following info needs hardware access, will obtain through REPORT_GENERAL	   		MV_BOOLEAN		Configuring;				MV_U16			ExpChangeCount;	 */	/* if parent is an expander, we first issue DISCOVER, then REPORT_GENERAL	   otherwise, skip DISCOVER */	if( pExp->pParent != NULL )		Core_GetExpInformationHardware( pCore, pExp, pExpInfo, pReq, DISCOVER, 0 );	else		Core_GetExpInformationHardware( pCore, pExp, pExpInfo, pReq, REPORT_GENERAL, 0 );}	#ifdef SUPPORT_PMMV_VOIDCore_GetPMInformation(	PCore_Driver_Extension pCore,	IN PDomain_Port pPort,	OUT PPM_Info pPM 	){	PDomain_PM pPortMultiplier;		pPM->Link.Self.DevType = DEVICE_TYPE_PM;	pPM->Link.Self.DevID = pPort->Id;	pPM->Link.Self.PhyCnt = 1;	pPM->Link.Self.PhyID[0] = pPort->Id;	pPM->Link.Parent.DevType = DEVICE_TYPE_PORT;	pPM->Link.Parent.DevID = 0;	pPM->Link.Parent.PhyCnt = 1;	pPM->Link.Parent.PhyID[0] = pPort->Id;	pPortMultiplier = pPort->pPM;		pPM->VendorId = pPortMultiplier->VendorId;	pPM->DeviceId = pPortMultiplier->DeviceId;	pPM->ProductRevision = pPortMultiplier->ProductRevision;	pPM->PMSpecRevision = pPortMultiplier->SpecRevision;		pPM->NumberOfPorts = pPortMultiplier->NumberOfPorts;}#endif /* SUPPORT_PM */#ifndef BIOS_NOT_SUPPORTMV_VOIDCore_GetHDConfiguration(	PCore_Driver_Extension pCore,	IN PDomain_Port pPort,	IN PDomain_Device pDevice,    OUT PHD_Config pHD 	){	if ( !(pDevice->Status & DEVICE_STATUS_FUNCTIONAL) )	{		pHD->HDID = 0xFF;		return;	}	pHD->HDID = pDevice->Id ;		if (pDevice->Setting & DEVICE_SETTING_WRITECACHE_ENABLED)		pHD->WriteCacheOn = MV_TRUE;	else		pHD->WriteCacheOn = MV_FALSE;	if ( pDevice->Setting & DEVICE_SETTING_SMART_ENABLED )		pHD->SMARTOn = MV_TRUE;	else		pHD->SMARTOn = MV_FALSE;	if ( pDevice->NegotiatedLinkRate == PHY_LINKRATE_3 )		pHD->DriveSpeed = HD_SPEED_3G;	else		pHD->DriveSpeed = HD_SPEED_1_5G;}#endif /* #ifndef BIOS_NOT_SUPPORT */MV_BOOLEAN core_pd_request_get_HD_info(PCore_Driver_Extension pCore, PMV_Request pMvReq){	PHD_Info pHDInfo = (PHD_Info)pMvReq->Data_Buffer;	MV_U16 HDID; #ifdef DEBUG_BIOS	//MV_DUMP32(0xCCCCEEE1);#endif	MV_CopyMemory(&HDID, &pMvReq->Cdb[2], 2);	Core_GetHDInfo( pCore, HDID, pHDInfo );	if (HDID != 0xFF && pHDInfo->Link.Self.DevType == DEVICE_TYPE_NONE)	{		if (pMvReq->Sense_Info_Buffer != NULL)			((MV_PU8)pMvReq->Sense_Info_Buffer)[0] = ERR_INVALID_HD_ID;		pMvReq->Scsi_Status = REQ_STATUS_ERROR_WITH_SENSE;	}	else		pMvReq->Scsi_Status = REQ_STATUS_SUCCESS;	return MV_TRUE;}MV_BOOLEAN core_pd_request_get_HD_info_ext(PCore_Driver_Extension pCore, PMV_Request pMvReq){	PHD_Info pHDInfo = (PHD_Info)pMvReq->Data_Buffer;	MV_U16 HDID; #ifdef DEBUG_BIOS	//MV_DUMP32(0xCCCCEEE1);#endif	MV_CopyMemory(&HDID, &pMvReq->Cdb[2], 2);	Core_GetHDInfo_Ext( pCore, HDID, pHDInfo );	if (HDID != 0xFF && pHDInfo->Link.Self.DevType == DEVICE_TYPE_NONE)	{		if (pMvReq->Sense_Info_Buffer != NULL)			((MV_PU8)pMvReq->Sense_Info_Buffer)[0] = ERR_INVALID_HD_ID;		pMvReq->Scsi_Status = REQ_STATUS_ERROR_WITH_SENSE;	}	else		pMvReq->Scsi_Status = REQ_STATUS_SUCCESS;	return MV_TRUE;}MV_BOOLEAN core_pd_request_get_expander_info( PCore_Driver_Extension pCore, PMV_Request pMvReq ){	PExp_Info pExpInfo = (PExp_Info)pMvReq->Data_Buffer;	MV_U16 ExpID; 	MV_U8	status = REQ_STATUS_SUCCESS;	MV_CopyMemory(&ExpID, &pMvReq->Cdb[2], 2);	if (ExpID != 0xFF && ExpID > pCore->Expander_Count_Supported+MIN_EXPANDER_ID)	{		status = ERR_INVALID_EXP_ID;	}	else	{		Core_GetExpInfo( pCore, ExpID, pExpInfo, pMvReq );		if (ExpID != 0xFF && pExpInfo->Link.Self.DevType == DEVICE_TYPE_NONE)		{			status = ERR_INVALID_EXP_ID;		}	}	if (status != REQ_STATUS_SUCCESS)	{		if (pMvReq->Sense_Info_Buffer != NULL)			((MV_PU8)pMvReq->Sense_Info_Buffer)[0] = status;		pMvReq->Scsi_Status = REQ_STATUS_ERROR_WITH_SENSE;	}	else		pMvReq->Scsi_Status = REQ_STATUS_SUCCESS;	// done getting info for all the expanders, finish here;	// if not done, the request will be completed later after requests 	// returned from hardware	if( pCore->Scratch_Count2 == pCore->Scratch_Count1 )		CompleteRequest( pCore, pMvReq, 0 );	return MV_TRUE;}#ifdef SUPPORT_PMMV_BOOLEAN core_pd_request_get_PM_info( PCore_Driver_Extension pCore, PMV_Request pMvReq ){	PPM_Info pPMInfo = (PPM_Info)pMvReq->Data_Buffer;	MV_U16 PMID; 	MV_CopyMemory(&PMID, &pMvReq->Cdb[2], 2);	if (PMID != 0xFF && PMID > MAX_PM_SUPPORTED)	{		if (pMvReq->Sense_Info_Buffer != NULL)			((MV_PU8)pMvReq->Sense_Info_Buffer)[0] = ERR_INVALID_PM_ID;		pMvReq->Scsi_Status = REQ_STATUS_ERROR_WITH_SENSE;		return MV_TRUE;	}	Core_GetPMInfo( pCore, PMID, pPMInfo );		pMvReq->Scsi_Status = REQ_STATUS_SUCCESS;	return MV_TRUE;}#endif /* SUPPORT_PM */#ifndef BIOS_NOT_SUPPORTMV_BOOLEAN core_pd_request_get_HD_config( PCore_Driver_Extension pCore, PMV_Request pMvReq ){	PHD_Config pHDConfig = (PHD_Config)pMvReq->Data_Buffer;	MV_U16 ConfigID; 	MV_CopyMemory(&ConfigID, &pMvReq->Cdb[2], 2);	Core_GetHDConfig( pCore, ConfigID, pHDConfig );	if (ConfigID != 0xFF && pHDConfig->HDID == 0xFF)	{		if (pMvReq->Sense_Info_Buffer != NULL)			((MV_PU8)pMvReq->Sense_Info_Buffer)[0] = ERR_INVALID_HD_ID;		pMvReq->Scsi_Status = REQ_STATUS_ERROR_WITH_SENSE;	}	else		pMvReq->Scsi_Status = REQ_STATUS_SUCCESS;	return MV_TRUE;}MV_BOOLEAN core_pd_request_get_HD_status( PCore_Driver_Extension pCore, PMV_Request pMvReq ){	PHD_Status pHDStatus = (PHD_Status)pMvReq->Data_Buffer;	PDomain_Port pPort = NULL;	PDomain_Device pDevice = NULL;	MV_U8 portId, deviceId;	MV_U16 HDId; 	MV_U8	cacheMode = 0;	MV_U8 status = REQ_STATUS_SUCCESS;	MV_CopyMemory(&HDId, &pMvReq->Cdb[2], 2);	if ( Core_MapHDId(pCore, HDId, &portId, &deviceId) )	{		pPort = &pCore->Ports[MapPortEntry(pCore,portId)];		pDevice = &pCore->Devices[deviceId];		if ( !(pDevice->Status & DEVICE_STATUS_FUNCTIONAL) )		{			status = ERR_INVALID_HD_ID;		}#ifndef CORE_SAS_SUPPORT_ATA_COMMAND		else if (IS_SSP(pDevice))		{			// if SAS drive we bypass for now			pMvReq->Scsi_Status = REQ_STATUS_SUCCESS;			return MV_TRUE;		}#endif		else 		{			if (pMvReq->Cdb[4] == APICDB4_PD_SMART_RETURN_STATUS)			{				cacheMode = CDB_CORE_SMART_RETURN_STATUS;			}			else				status = ERR_INVALID_REQUEST;		}		if (status == REQ_STATUS_SUCCESS)		{			// Convert it into SCSI_CMD_MARVELL_SPECIFIC request.			pMvReq->Cdb[0] = SCSI_CMD_MARVELL_SPECIFIC;			pMvReq->Cdb[1] = CDB_CORE_MODULE;			pMvReq->Cdb[2] = cacheMode;			pMvReq->Device_Id = pDevice->Id;			if (pHDStatus)				pHDStatus->HDID = pDevice->Id;		}	} 	else	{		status = ERR_INVALID_HD_ID;	}	if (status != REQ_STATUS_SUCCESS)	{		if (pMvReq->Sense_Info_Buffer != NULL)			((MV_PU8)pMvReq->Sense_Info_Buffer)[0] = status;		pMvReq->Scsi_Status = REQ_STATUS_ERROR_WITH_SENSE;		return MV_TRUE;		}	else	{		pMvReq->Scsi_Status = REQ_STATUS_SUCCESS;		return MV_FALSE;	// Need to access hardware.	}}MV_BOOLEAN core_pd_request_set_HD_config( PCore_Driver_Extension pCore, PMV_Request pMvReq ){	PDomain_Port pPort = NULL;	PDomain_Device pDevice = NULL;	MV_U8 portId, deviceId, i;	MV_U16 HDId; 	MV_U8 cacheMode = 0;	MV_U8 status = REQ_STATUS_SUCCESS;	MV_U32 phy_status;	MV_CopyMemory(&HDId, &pMvReq->Cdb[2], 2);	if ( Core_MapHDId(pCore, HDId, &portId, &deviceId) )	{		pPort = &pCore->Ports[MapPortEntry(pCore,portId)];		pDevice = &pCore->Devices[deviceId];		if ( !(pDevice->Status & DEVICE_STATUS_FUNCTIONAL) )		{			status = ERR_INVALID_HD_ID;		}#ifndef CORE_SAS_SUPPORT_ATA_COMMAND		else if (IS_SSP(pDevice))		{			if ( !((pMvReq->Cdb[4] == APICDB4_PD_SET_SPEED_3G) ||				 (pMvReq->Cdb[4] == APICDB4_PD_SET_SPEED_1_5G)) )			{				// if SAS drive we bypass for now				pMvReq->Scsi_Status = REQ_STATUS_SUCCESS;				return MV_TRUE;			}		}#endif		else 		{			if (pMvReq->Cdb[4] == APICDB4_PD_SET_WRITE_CACHE_OFF)			{				cacheMode = CDB_CORE_DISABLE_WRITE_CACHE;			}			else if (pMvReq->Cdb[4] == APICDB4_PD_SET_WRITE_CACHE_ON)			{				cacheMode = CDB_CORE_ENABLE_WRITE_CACHE;			}			else if (pMvReq->Cdb[4] == APICDB4_PD_SET_SMART_OFF)			{				cacheMode = CDB_CORE_DISABLE_SMART;			}			else if (pMvReq->Cdb[4] == APICDB4_PD_SET_SMART_ON)			{				cacheMode = CDB_CORE_ENABLE_SMART;			}			else if (pMvReq->Cdb[4] == APICDB4_PD_SET_SPEED_3G)			{				if (!(pDevice->Capacity & DEVICE_CAPACITY_RATE_3G))				{					status = ERR_INVALID_PARAMETER;				}				else				{/* allow speed setting only when idle */					if(pDevice->Outstanding_Req>0)						status = ERR_NO_RESOURCE;					else					{						if(pDevice->pExpander==NULL)						{							if (pDevice->NegotiatedLinkRate != PHY_LINKRATE_3)							{								for(i=0;i<pCore->Phy_Num;i++)								{									if(pPort->MemberPhyMap&MV_BIT(i))									{										phy_status = READ_PORT_PHY_CONTROL(pCore->Mmio_Base, i); 										phy_status &= ~MV_MAX_SPP_PHYS_LINK_RATE_MASK;										phy_status |= PHY_LINKRATE_3 << 12;/* this will only set the max linkrate */										WRITE_PORT_PHY_CONTROL(pCore->Mmio_Base, i, phy_status);									}								}								pDevice->NegotiatedLinkRate = PHY_LINKRATE_3;/* the actual negotiated linkrate will be set after reset */							}							mv_reset_phy(pCore, pPort->MemberPhyMap, MV_FALSE);						}						else						{/* for devices behind expander: *//* Issuing a SMP phy_control to the expander to set max and min programmed linkrate and reset *//* this will only set the max linkrate *//* the actual negotiated linkrate will be set after reset, the result depends on its connection path */							Expander_SMPRequest_PhyControl(pPort,pDevice->pExpander,pDevice->Phy_Id,LINK_RESET,(PHY_LINKRATE_3<<4)+PHY_LINKRATE_1_5);						}					}					pMvReq->Scsi_Status = REQ_STATUS_SUCCESS;					return MV_TRUE;	// Do not need to access hardware.				}			}			else if (pMvReq->Cdb[4] == APICDB4_PD_SET_SPEED_1_5G)			{				if (!(pDevice->Capacity & DEVICE_CAPACITY_RATE_1_5G))				{					status = ERR_INVALID_PARAMETER;				}				else				{					if(pDevice->Outstanding_Req>0)						status = ERR_NO_RESOURCE;					else					{						if(pDevice->pExpander==NULL)						{							if (pDevice->NegotiatedLinkRate != PHY_LINKRATE_1_5)							{								for(i=0;i<pCore->Phy_Num;i++)								{									if(pPort->MemberPhyMap&MV_BIT(i))									{										phy_status = READ_PORT_PHY_CONTROL(pCore->Mmio_Base, i); 										phy_status &= ~MV_MAX_SPP_PHYS_LINK_RATE_MASK;										phy_status |= PHY_LINKRATE_1_5 << 12;										WRITE_PORT_PHY_CONTROL(pCore->Mmio_Base, i, phy_status);									}								}								pDevice->NegotiatedLinkRate = PHY_LINKRATE_1_5;/* the actual negotiated linkrate will be set after reset */							}							mv_reset_phy(pCore, pPort->MemberPhyMap, MV_FALSE);						}						else						{/* for devices behind expander: *//* Issuing a SMP phy_control to the expander to set max and min programmed linkrate and reset *//* this will only set the max linkrate *//* the actual negotiated linkrate will be set after reset, the result depends on its connection path */							Expander_SMPRequest_PhyControl(pPort,pDevice->pExpander,pDevice->Phy_Id,LINK_RESET,(PHY_LINKRATE_1_5<<4)+PHY_LINKRATE_1_5);						}					}					pMvReq->Scsi_Status = REQ_STATUS_SUCCESS;					return MV_TRUE;	// Do not need to access hardware.

⌨️ 快捷键说明

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