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

📄 core_api.c

📁 6440linuxDriver的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				}			}			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;		}	} 	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_BSL_dump( PCore_Driver_Extension pCore, PMV_Request pMvReq ){	// TBD	pMvReq->Scsi_Status = REQ_STATUS_ERROR;	return MV_TRUE;}#endif	/* #ifndef BIOS_NOT_SUPPORT */CORE_Management_Command_Handler BASEATTR core_pd_cmd_handler[APICDB1_PD_MAX] = {	core_pd_request_get_HD_info,	core_pd_request_get_expander_info,#ifdef SUPPORT_PM	core_pd_request_get_PM_info,#endif#ifndef BIOS_NOT_SUPPORT	core_pd_request_get_HD_config,	core_pd_request_set_HD_config,	core_pd_request_BSL_dump,	NULL,	NULL,	core_pd_request_get_HD_status,	core_pd_request_get_HD_info_ext#else	NULL,	NULL,	NULL,	NULL,	NULL,	NULL,	NULL#endif};MV_BOOLEAN Core_pd_command(	IN MV_PVOID extension,	IN PMV_Request pReq	){	PCore_Driver_Extension pCore = (PCore_Driver_Extension)extension;	if ( pReq->Cdb[1] >= APICDB1_PD_MAX ) 	{		pReq->Scsi_Status = REQ_STATUS_INVALID_PARAMETER;		return MV_TRUE;	}	if (core_pd_cmd_handler[pReq->Cdb[1]] == NULL)	{		pReq->Scsi_Status = REQ_STATUS_INVALID_PARAMETER;		return MV_TRUE;	}	return core_pd_cmd_handler[pReq->Cdb[1]](pCore, pReq);}#if defined(SUPPORT_CSMI)MV_BOOLEAN Core_CSMI_Request_FirmwareDownload(     PCore_Driver_Extension pCore,     PMV_Request pMvReq ){    PCSMI_SAS_FIRMWARE_DOWNLOAD pcsmiFwDl = (PCSMI_SAS_FIRMWARE_DOWNLOAD)pMvReq->Data_Buffer;    AdapterInfo AI;    MV_U32 i, tmp;    MV_U8   *pImage = (MV_U8*)&pcsmiFwDl[1];    	AI.bar[2] = pCore->Base_Address[2];    if( -1==OdinSPI_Init( &AI ) )        return MV_FALSE;    if( -1==OdinSPI_ChipErase( &AI ) )        return MV_FALSE;    for( i=0; i<pcsmiFwDl->uBufferLength; i+=4 )    {        if( -1 == OdinSPI_Write( &AI, i, *(MV_U32*)&pImage[i] ) )        {            MV_DPRINT( ( "Write failed at %5.5lX\n", (unsigned long) i ) );            pMvReq->Scsi_Status = REQ_STATUS_ERROR;            return MV_FALSE;        }    }    for( i=0; i<pcsmiFwDl->uBufferLength; i+=4 )    {        if( -1 == OdinSPI_Read( &AI, i, (MV_U8*)&tmp, 4 )||           tmp != *(MV_U32*)&pImage[i] )        {            MV_DPRINT( ( "Verify failed at %5.5lX\n", (unsigned long) i ) );            pMvReq->Scsi_Status = REQ_STATUS_ERROR;            return MV_FALSE;        }    }	    pMvReq->Scsi_Status = REQ_STATUS_SUCCESS;    pMvReq->Completion(pMvReq->Cmd_Initiator, pMvReq);    return MV_TRUE;}void Core_CSMI_SMPRequest_ReportGeneral(	IN MV_PVOID pUpperReq,	IN PDomain_Port pPort,	IN PDomain_Expander pExpander	);void Core_CSMI_SMPRequest_Discover(	IN MV_PVOID pUpperReq,	IN PDomain_Port pPort,	IN PDomain_Expander pExpander,	IN MV_U8 PhyId	);void Core_CSMI_SMPRequest_PhyControl(	IN PMV_Request pOrgReq,	IN PDomain_Port pPort,	IN PDomain_Expander pTgt,	IN MV_U8 PhyId	);void Core_CSMI_Device_MakeRequestTask(	IN PCore_Driver_Extension pCore,	IN PMV_Request pOrgReq	);MV_BOOLEAN Core_CSMI_Command(	IN MV_PVOID extension,	IN PMV_Request pReq	){	PCore_Driver_Extension pCore = (PCore_Driver_Extension)extension;	switch( pReq->Cdb[1] )	{		/* FIXME : this constant is TOO large in linux */		case (CC_CSMI_SAS_FIRMWARE_DOWNLOAD & 0xFF):		{			return Core_CSMI_Request_FirmwareDownload(pCore, pReq);		}		case (CC_CSMI_SAS_SMP_PASSTHRU & 0xFF):		{			MV_U8 portId = MapPortId(pCore, pReq->Device_Id);			MV_U8 tgtId = (MV_U8)pReq->Device_Id;			PDomain_Port	pPort = &pCore->Ports[MapPortEntry(pCore,portId)];			PDomain_Expander pExpander =  &pCore->Expanders[MapDeviceId(pCore, pReq->Device_Id)];			if (!((portId < MAX_PORT_ID) && (portId != ID_NOT_MAPPED) &&				(tgtId < pCore->Expander_Count_Supported+MIN_EXPANDER_ID) && (tgtId != ID_NOT_MAPPED))){				return MV_FALSE;			}			if(pReq->Cdb[2] == REPORT_GENERAL){					Core_CSMI_SMPRequest_ReportGeneral((MV_PVOID)pReq, pPort, pExpander);					return MV_TRUE;			}			else if((pReq->Cdb[2] == DISCOVER)||(pReq->Cdb[2] == PHY_CONTROL)){				MV_U8 i;				for(i=0;i<MAX_PHY_NUM;i++){					if(&pCore->Phy[i] == pPort->pPhy){						break;					}				}				if(i >= MAX_PHY_NUM)					return MV_FALSE;				if(pReq->Cdb[2] == DISCOVER)					Core_CSMI_SMPRequest_Discover((MV_PVOID)pReq, pPort, pExpander, i);				else//PHY_CONTROL					Core_CSMI_SMPRequest_PhyControl((MV_PVOID)pReq, pPort, pExpander, i);				return MV_TRUE;			}		}		case (CC_CSMI_SAS_TASK_MANAGEMENT & 0xFF):		{			Core_CSMI_Device_MakeRequestTask(pCore,pReq);			return MV_TRUE;		}		case (CC_CSMI_SAS_PHY_CONTROL & 0xFF):		case (CC_CSMI_SAS_SET_PHY_INFO & 0xFF):		{			MV_U8 portId = MapPortId(pCore, pReq->Device_Id);			MV_U8 tgtId = (MV_U8)pReq->Device_Id;			PDomain_Port	pPort = &pCore->Ports[MapPortEntry(pCore,portId)];			PDomain_Expander pExpander =  &pCore->Expanders[MapDeviceId(pCore, pReq->Device_Id)];			if (!((portId < MAX_PORT_ID) && (portId != ID_NOT_MAPPED) &&				(tgtId < pCore->Expander_Count_Supported+MIN_EXPANDER_ID) && (tgtId != ID_NOT_MAPPED))){				return MV_FALSE;			}			{				MV_U8 i;				for(i=0;i<MAX_PHY_NUM;i++){					if(&pCore->Phy[i] == pPort->pPhy){						break;					}				}				if(i >= MAX_PHY_NUM)					return MV_FALSE;				Core_CSMI_SMPRequest_PhyControl((MV_PVOID)pReq, pPort, pExpander, i);			}			return MV_TRUE;		}#if 0		case (CC_CSMI_SAS_SSP_PASSTHRU & 0xFF):		{			PCore_Driver_Extension pCore = pDevice->pPort->Core_Extension;			PMV_Request pReq = GetInternalReqFromPool(pCore);			PSATA_Scratch_Buffer pSATASB;			PMV_SG_Table pSGTable;			if( pReq == NULL ) 			{				// no internal requests available - wait for now 				pDevice->Is_Waiting = MV_TRUE;				return;			}			pSATASB = GetSATAScratchFromPool(pCore);			if( pSATASB == NULL )			{				FreeInternalReqToPool(pCore, pReq);				MV_DPRINT(("ERROR: No more free SATA scratch buffer. Request aborted.\n"));				return;			}			pSGTable = &pReq->SG_Table;			/* Prepare read capacity */			pReq->Cdb[0] = SCSI_CMD_READ_CAPACITY_10;			pReq->Tag = 0xab;			pReq->Device_Id = pDevice->Id;			//pReq->Req_Flag;			pReq->Cmd_Initiator = pCore;			pReq->Data_Transfer_Length = 8;			pReq->Cmd_Flag = CMD_FLAG_DATA_IN;			pReq->Data_Buffer = pSATASB->Scratch_Vir;			pReq->Sense_Info_Buffer =(MV_PVOID)( (MV_PTR_INTEGER)pReq->Data_Buffer+pReq->Data_Transfer_Length);			pReq->Sense_Info_Buffer_Length = 0x24;			pReq->Scratch_Buffer = pSATASB;			pReq->Completion = (void(*)(MV_PVOID,PMV_Request))SAS_InternalReqCallback;			/* Make the SG table. */			SGTable_Init(pSGTable, 0);			SGTable_Append(				pSGTable, 				pSATASB->Scratch_DMA.parts.low,				pSATASB->Scratch_DMA.parts.high,				8				);			/* Send this internal request */			Core_ModuleSendRequest(pCore, pReq);			return MV_TRUE;		}#endif		default:	        break;	}	pReq->Scsi_Status = REQ_STATUS_INVALID_PARAMETER;	return MV_TRUE;}#endif#ifdef SUPPORT_PASS_THROUGH_DIRECTPPassThorugh_Config pConfig;MV_U32 Data_Length;void Core_pass_thru_remove_CDB_header(	IN PMV_Request pReq	){	int i = 0;	for( i=0; i<MAX_CDB_SIZE; i++)	{		if( i < 12){			pReq->Cdb[i] = pReq->Cdb[i+4];		} else {			// Zero the last 4 cdb slots			pReq->Cdb[i] = 0;		}			}}MV_U32 Core_pass_thru_cal_correct_length (	MV_U32 length){		if( length & 0x80000000)		return (0xFFFFFFFF - length )+2;	else		return 0;}voidCore_pass_thru_callback(	MV_PVOID This,	PMV_Request pReq){	PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK)pReq->Org_Req;	PHBA_Extension pHBA = (PHBA_Extension)This;	PModule_Manage module_manage = &pHBA->Module_Manage;	PCore_Driver_Extension pCore = (PCore_Driver_Extension)module_manage->resource[MODULE_CORE].module_extension;	MV_U32 length;	MV_U32 reg[3];	MV_U16 deviceId;	MV_U8 testsize;	if( pReq->Scsi_Status == REQ_STATUS_PENDING )	{		return;	}	// SCSI Pass Through	if( pReq->Cmd_Flag & CMD_FLAG_SCSI_PASS_THRU )	{			if( pReq->Cdb[0] == SCSI_CMD_READ_LONG_10 )		{			// copy result data back into PassThrough_Config Struct			MV_CopyMemory(pConfig->Data_Buffer, pReq->Data_Buffer, Data_Length);			// return pReq->Data_Buffer pointer to pConfig			pReq->Data_Buffer = pConfig;			((MV_PU8)pReq->Sense_Info_Buffer)[0] = 0;			// Find the sense buffer return info			length = (((MV_PU8)pReq->Sense_Info_Buffer)[3] << 24)|				(((MV_PU8)pReq->Sense_Info_Buffer)[4] << 16)|				(((MV_PU8)pReq->Sense_Info_Buffer)[5] << 8)|				((MV_PU8)pReq->Sense_Info_Buffer)[6];			// Calculate the correct length for ECC			if( ((MV_PU8)pReq->Sense_Info_Buffer)[2] == 0x25 ) {				length = Core_pass_thru_cal_correct_length(length);				pConfig->Data_Length= length;				goto HBACallback;			}		}		MV_CopyMemory(Srb->DataBuffer, pReq->Data_Buffer, Data_Length);	}	// ATA Pass Through	if( pReq->Cmd_Flag & CMD_FLAG_ATA_PASS_THRU )	{		reg[0] = MV_REG_READ_DWORD( pCore->RX_FIS, 				SATA_RECEIVED_D2H_FIS(pReq->Cdb[15]) );			reg[1] = MV_REG_READ_DWORD( pCore->RX_FIS, 				(SATA_RECEIVED_D2H_FIS(pReq->Cdb[15]+4)) );		reg[2] = MV_REG_READ_DWORD( pCore->RX_FIS,				(SATA_RECEIVED_D2H_FIS(pReq->Cdb[15]+8)) );		testsize = sizeof(reg);		MV_CopyMemory(((MV_PU8)(pReq->Data_Buffer)+pReq->Data_Transfer_Length-sizeof(reg)), 				reg, sizeof(reg));		MV_CopyMemory(Srb->DataBuffer, pReq->Data_Buffer, pReq->Data_Transfer_Length);	}HBACallback:	HBARequestCallback(This, pReq);}voidCore_pass_thru_send_SCSI_command(	IN PCore_Driver_Extension pCore,	IN PMV_Request pReq){	PSATA_Scratch_Buffer pSATASB;	PMV_SG_Table pSGTable;	MV_U32 lengthLocation;	if( pReq == NULL ) 	{		return;	}		pConfig = (PPassThorugh_Config)pReq->Data_Buffer;		pSATASB = GetSATAScratchFromPool(pCore);	if( pSATASB == NULL )	{		FreeInternalReqToPool(pCore, pReq);		MV_DPRINT(("ERROR: No more free SATA scratch buffer. Request aborted.\n"));		return;	}	pSGTable = &pReq->SG_Table;	if( pReq->Data_Transfer_Length< MAX_PASS_THRU_DATA_BUFFER_SIZE )	{		// from SCSI commander application		Data_Length = pReq->Data_Transfer_Length;	} else {		// from CLI application		Data_Length = pConfig->Data_Length;	}			switch( pReq->Cdb[1] )	{		case APICDB1_SCSI_NON_DATA:			pReq->Cmd_Flag = CMD_FLAG_NON_DATA;			break;		case APICDB1_SCSI_PIO_IN:			pReq->Cmd_Flag = CMD_FLAG_PIO | CMD_FLAG_DATA_IN;			pReq->Data_Buffer= pSATASB->Scratch_Vir;			break;		case APICDB1_SCSI_PIO_OUT:			pReq->Cmd_Flag = CMD_FLAG_PIO | CMD_FLAG_DATA_OUT;			MV_CopyMemory( pSATASB->Scratch_Vir, pReq->Data_Buffer, Data_Length);			break;		default:			break;	}	pReq->Cmd_Flag |= CMD_FLAG_SCSI_PASS_THRU;	pReq->Device_Id = (pReq->Cdb[2]<<8)|pReq->Cdb[3]; // targetID	Core_pass_thru_remove_CDB_header( pReq );	pReq->Scsi_Status = REQ_STATUS_PENDING;	pReq->Completion = Core_pass_thru_callback;	SGTable_Init(pSGTable, 0);	SGTable_Append(		pSGTable, 		pSATASB->Scratch_DMA.parts.low,		pSATASB->Scratch_DMA.parts.high,		pReq->Data_Transfer_Length	);	/* Send this internal request */	Core_ModuleSendRequest(pCore, pReq);}voidCore_pass_thru_send_ATA_command(	IN PCore_Driver_Extension pCore,	IN PMV_Request pReq){	PSATA_Scratch_Buffer pSATASB = GetSATAScratchFromPool(pCore);	PMV_SG_Table pSGTable;	MV_U32 length;	pSGTable = &pReq->SG_Table;	switch( pReq->Cdb[1] )	{		case APICDB1_ATA_NON_DATA:			pReq->Cmd_Flag = CMD_FLAG_NON_DATA;			break;		case APICDB1_ATA_PIO_IN:			pReq->Cmd_Flag = CMD_FLAG_PIO | CMD_FLAG_DATA_IN;			break;		case APICDB1_ATA_PIO_OUT:			pReq->Cmd_Flag = CMD_FLAG_PIO | CMD_FLAG_DATA_OUT;			break;		default:			break;	}	pReq->Cmd_Flag |= CMD_FLAG_ATA_PASS_THRU;	pReq->Device_Id = (pReq->Cdb[2]<<8)|pReq->Cdb[3]; // targetID	Core_pass_thru_remove_CDB_header( pReq );	pReq->Scsi_Status = REQ_STATUS_PENDING;	pReq->Data_Buffer = pSATASB->Scratch_Vir;	pReq->Scratch_Buffer = pSATASB;	pReq->Completion = Core_pass_thru_callback;	SGTable_Init(pSGTable, 0);	SGTable_Append(		pSGTable, 		pSATASB->Scratch_DMA.parts.low,		pSATASB->Scratch_DMA.parts.high,		pReq->Data_Transfer_Length	);	/* Send this internal request */	Core_ModuleSendRequest(pCore, pReq);}MV_BOOLEANCore_pass_thru_fill_taskfile(	IN PMV_Request pReq,	OUT PATA_TaskFile pTaskFile	){	MV_ZeroMemory(pTaskFile, sizeof(ATA_TaskFile));	pTaskFile->Features = pReq->Cdb[0];	pTaskFile->Sector_Count = pReq->Cdb[1];	pTaskFile->LBA_Low = pReq->Cdb[2];	pTaskFile->LBA_Mid = pReq->Cdb[3];	pTaskFile->LBA_High = pReq->Cdb[4];	pTaskFile->Device = pReq->Cdb[5];	pTaskFile->Command = pReq->Cdb[6];	if( pReq->Cmd_Flag & CMD_FLAG_48BIT )	{		pTaskFile->Feature_Exp = pReq->Cdb[7];		pTaskFile->Sector_Count_Exp = pReq->Cdb[8];		pTaskFile->LBA_Low_Exp = pReq->Cdb[9];		pTaskFile->LBA_Mid_Exp = pReq->Cdb[10];		pTaskFile->LBA_High_Exp = pReq->Cdb[11];	}	return MV_TRUE;}MV_BOOLEANCore_pass_thru_send_command(	IN PCore_Driver_Extension pCore,	IN PMV_Request pReq	){	MV_BOOLEAN status = MV_FALSE;	switch(pReq->Cdb[0])	{		case APICDB0_PASS_THRU_CMD_SCSI:			Core_pass_thru_send_SCSI_command( pCore, pReq );			status = MV_TRUE;			break;		case APICDB0_PASS_THRU_CMD_ATA:			Core_pass_thru_send_ATA_command( pCore, pReq );			status = MV_TRUE;			break;		default:			pReq->Scsi_Status = REQ_STATUS_INVALID_PARAMETER;			status = MV_FALSE;			break;	}	return status;}#else /* SUPPORT_PASS_THROUGH_DIRECT */MV_BOOLEAN Core_pass_thru_fill_taskfile(IN PMV_Request pReq,					OUT PATA_TaskFile pTaskFile){	return MV_TRUE;}#endif /* SUPPORT_PASS_THROUGH_DIRECT */#endif

⌨️ 快捷键说明

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