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

📄 core_exp.c

📁 6440linuxDriver的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		#else		if( !IS_A_SMP_REQ(pReq) )		{			MV_DASSERT( pDevice!=NULL );			orgWriteCache = (pDevice->Setting&DEVICE_SETTING_WRITECACHE_ENABLED)?MV_TRUE:MV_FALSE;			orgPreread = MV_TRUE;	/* No control yet. */			if ( pReq->Cdb[0]==SCSI_CMD_MARVELL_SPECIFIC ) {				if ( pReq->Cdb[1]==CDB_CORE_MODULE ) {					switch ( pReq->Cdb[2] ) {						case CDB_CORE_ENABLE_SMART:							pDevice->Setting |= DEVICE_SETTING_SMART_ENABLED;							pReq->Scsi_Status = REQ_STATUS_SUCCESS;							*pCommandRet = MV_QUEUE_COMMAND_RESULT_FINISHED;							return MV_TRUE;						case CDB_CORE_DISABLE_SMART:							pDevice->Setting &= ~DEVICE_SETTING_SMART_ENABLED;							pReq->Scsi_Status = REQ_STATUS_SUCCESS;							*pCommandRet = MV_QUEUE_COMMAND_RESULT_FINISHED;							return MV_TRUE;						case CDB_CORE_SMART_RETURN_STATUS:							if ( !SCSI_MakeSMARTReturnStatusCommand(pCore, pReq) ) {								*pCommandRet = MV_QUEUE_COMMAND_RESULT_NO_RESOURCE;								return MV_TRUE;							}							break;						case CDB_CORE_OS_SMART_CMD:							pReq->Scsi_Status = REQ_STATUS_INVALID_REQUEST;							*pCommandRet = MV_QUEUE_COMMAND_RESULT_FINISHED;							return MV_TRUE;						case CDB_CORE_ENABLE_WRITE_CACHE:							if ( !SCSI_MakeCacheCommand(pCore, pReq, MV_TRUE, orgPreread) ) {								*pCommandRet = MV_QUEUE_COMMAND_RESULT_NO_RESOURCE;								return MV_TRUE;							}							break;						case CDB_CORE_DISABLE_WRITE_CACHE:							if ( !SCSI_MakeCacheCommand(pCore, pReq, MV_FALSE, orgPreread) ) {								*pCommandRet = MV_QUEUE_COMMAND_RESULT_NO_RESOURCE;								return MV_TRUE;							}							break;						case CDB_CORE_ENABLE_READ_AHEAD:							if ( !SCSI_MakeCacheCommand(pCore, pReq, orgWriteCache, MV_TRUE) ) {								*pCommandRet = MV_QUEUE_COMMAND_RESULT_NO_RESOURCE;								return MV_TRUE;							}							break;						case CDB_CORE_DISABLE_READ_AHEAD:							if ( !SCSI_MakeCacheCommand(pCore, pReq, orgWriteCache, MV_FALSE) ) {								*pCommandRet = MV_QUEUE_COMMAND_RESULT_NO_RESOURCE;								return MV_TRUE;							}							break;						case CDB_CORE_SHUTDOWN:							SCSI_MakeSynchronizeCacheCommmand(pCore, pReq);							break;						case CDB_CORE_TASK_MGMT:							break;						case CDB_CORE_IDENTIFY:						case CDB_CORE_SET_UDMA_MODE:						case CDB_CORE_SET_PIO_MODE:						case CDB_CORE_READ_LOG_EXT:						case CDB_CORE_SMP:						default:							/* We shouldn't receive these commands or haven't implemented yet. */							MV_DASSERT( MV_FALSE );							pReq->Scsi_Status = REQ_STATUS_INVALID_REQUEST;							*pCommandRet = MV_QUEUE_COMMAND_RESULT_FINISHED;							return MV_TRUE;					}				}			}			else if ( pReq->Cdb[0]==APICDB0_LD 					&& pReq->Cdb[1]==APICDB1_LD_SHUTDOWN ) {				MV_DPRINT( ("Got APICDB1_LD_SHUTDOWN\n") );				SCSI_MakeSynchronizeCacheCommmand(pCore, pReq);			}		}		#endif	}	if(Tag_IsEmpty(&pCore->Tag_Pool)) {		*pCommandRet = MV_QUEUE_COMMAND_RESULT_FULL;		return MV_TRUE;	}	if(pReq->Cdb[0]==SCSI_CMD_MARVELL_SPECIFIC)	{		if(pReq->Cdb[1]==CDB_CORE_MODULE)		{			switch(pReq->Cdb[2])			{			case CDB_CORE_TASK_MGMT:				if(pReq->Cdb[5]==ABORT_TASK_TMF)				{					Tag=(MV_U16)(pReq->Cdb[4]<<8) + (MV_U16)pReq->Cdb[3];					pOrgReq=FindRunningReqByTag(pCore, Tag);					if( (pOrgReq != pReq->Org_Req) ||(pOrgReq == NULL) )					{						pReq->Scsi_Status = REQ_STATUS_INVALID_REQUEST;						*pCommandRet = MV_QUEUE_COMMAND_RESULT_FINISHED;						return MV_TRUE;					}				}				break;			}		}	}	return MV_FALSE;}MV_QUEUE_COMMAND_RESULTPrepareAndSendCommand(	IN PCore_Driver_Extension pCore,	IN PMV_Request pReq	){	MV_U16 SlotNo;	MV_PHYSICAL_ADDR tmpPhyAddress;	PMV_Command_Header pCmdHeader;	PMV_Command_Table pCmdTbl = (PMV_Command_Table)pCore->Cmd_Table;	DELIVERY_QUEUE_ENTRY DELV_Q_Entry;	struct _Domain_Port *pPort = NULL;	struct _Domain_Device *pDevice = NULL;	ATA_TaskFile taskFile;	struct _Domain_Expander *pTgt = NULL;#ifdef SUPPORT_PM	PDomain_PM pPM = NULL;#endif	MV_U16 deviceId;	MV_U8 portId;	MV_U64 Val64;	MV_BOOLEAN ret;	MV_U16 Tag = 0;	MV_U32 ReqLen;	struct SMPRequest *pSMPReq;	MV_QUEUE_COMMAND_RESULT commandRet;	PSG_Buffer pSGBuf;		pReq->SlotNo=0xfff;	/* Verify this command. May can be finished now. 	 * Remove the verify code to this following function. */	if ( VerifyCommandBeforeSending(pCore, pReq, &commandRet) ) {		return commandRet;	}	if( IS_A_SMP_REQ(pReq) )	{/* workaround for a HW SMP bug, HW will return with old response and corrupt the command table if we issue SMP too soon */		HBA_SleepMillisecond(pCore, 5);		portId = MapPortId(pCore, pReq->Device_Id);		pPort=&pCore->Ports[MapPortEntry(pCore,portId)];		pTgt=&pCore->Expanders[MapDeviceId(pCore, pReq->Device_Id)];	}	else	{		if (!IS_PM_REQ(pReq))		{			portId = MapPortId(pCore, pReq->Device_Id);			deviceId = MapDeviceId(pCore, pReq->Device_Id);			pPort=&pCore->Ports[MapPortEntry(pCore,portId)];			pDevice= &pCore->Devices[deviceId];		}		else		{			deviceId = MapDeviceId(pCore, pReq->Device_Id);		#ifdef SUPPORT_PM			pPM = &(pCore->PMs[deviceId]);			pPort = pPM->pPort;		#endif		}				if ( !IS_PM_REQ(pReq) && !IS_SOFT_RESET_REQ(pReq) && 			 ((deviceId==ID_NOT_MAPPED)||(!(pDevice->Status&DEVICE_STATUS_FUNCTIONAL))) )		{			pReq->Scsi_Status = REQ_STATUS_NO_DEVICE;			return MV_QUEUE_COMMAND_RESULT_FINISHED;		}	}	SlotNo = GetOneCommandSlot(pCore, &pCmdHeader);	pReq->SlotNo = SlotNo;	pSGBuf = GetSGBufferFromPool(pCore);	if (pSGBuf == NULL)	{		MV_DPRINT(("Ran out of SG buffers!\n"));		return MV_QUEUE_COMMAND_RESULT_NO_RESOURCE;	}	pReq->SG_Buffer = pSGBuf;	tmpPhyAddress.value = pCore->Cmd_Table_DMA.value + 		((MV_PU8) &pCmdTbl[SlotNo].Status_Buff - 		 (MV_PU8) pCore->Cmd_Table);	pCmdHeader->StatusBuff_Address = MV_CPU_TO_LE32(tmpPhyAddress.parts.low);	pCmdHeader->StatusBuff_Address_High = MV_CPU_TO_LE32(tmpPhyAddress.parts.high);	U64_ASSIGN_U64(tmpPhyAddress, pSGBuf->Buffer_DMA);	pCmdHeader->PRD_Table_Address = MV_CPU_TO_LE32(tmpPhyAddress.parts.low);	pCmdHeader->PRD_Table_Address_High = MV_CPU_TO_LE32(tmpPhyAddress.parts.high);	pCmdHeader->Tag = MV_CPU_TO_LE16(SlotNo);	MV_ZeroMemory(&pCmdTbl[SlotNo], sizeof(MV_Command_Table));//	MV_ZeroMemory(&pCmdTbl[SlotNo].Status_Buff.Err_Info, 8);	if (IS_PM_REQ(pReq))	{		ret = ATA_CDB2TaskFile(pDevice, pReq,				       (MV_U8) pCmdHeader->Tag, 				       &taskFile);		if ( !ret )		{			// TBD: handle this			MV_DASSERT( MV_FALSE );			}						tmpPhyAddress.value = pCore->Cmd_Table_DMA.value + 			((MV_PU8) &pCmdTbl[SlotNo].table.STP_CMD_Table - 			 (MV_PU8)pCore->Cmd_Table);		pCmdHeader->Table_Address = MV_CPU_TO_LE32(tmpPhyAddress.parts.low);		pCmdHeader->Table_Address_High = MV_CPU_TO_LE32(tmpPhyAddress.parts.high);	}	else if (pPort->Type&PORT_TYPE_SATA		|| (!IS_A_SMP_REQ(pReq) && IS_STP_OR_SATA(pDevice)))	{		if (IS_ATAPI(pDevice))		{			ret = ATAPI_CDB2TaskFile(pDevice, pReq, &taskFile);		}		else		{			if (pReq->Cmd_Flag & CMD_FLAG_ATA_PASS_THRU)			{				ret = Core_pass_thru_fill_taskfile( pReq, &taskFile );			}			else			{				ret = ATA_CDB2TaskFile(pDevice, pReq,						       (MV_U8) pCmdHeader->Tag, 						       &taskFile);			}		}		if ( !ret )		{			// TBD: handle this			MV_DASSERT( MV_FALSE );			}						tmpPhyAddress.value = pCore->Cmd_Table_DMA.value + 			((MV_PU8) &pCmdTbl[SlotNo].table.STP_CMD_Table - 			 (MV_PU8)pCore->Cmd_Table);		pCmdHeader->Table_Address = MV_CPU_TO_LE32(tmpPhyAddress.parts.low);		pCmdHeader->Table_Address_High = MV_CPU_TO_LE32(tmpPhyAddress.parts.high);		if (!IS_PM_REQ(pReq)		    && IS_STP(pDevice))		{			tmpPhyAddress.value = pCore->Cmd_Table_DMA.value + 				((MV_PU8) &pCmdTbl[SlotNo].Open_Addr_Frame - 				 (MV_PU8) pCore->Cmd_Table);			pCmdHeader->OpenAddrFrame_Address = MV_CPU_TO_LE32(tmpPhyAddress.parts.low);			pCmdHeader->OpenAddrFrame_Address_High = MV_CPU_TO_LE32(tmpPhyAddress.parts.high);		}	}	else if( pPort->Type&PORT_TYPE_SAS )	{		tmpPhyAddress.value = pCore->Cmd_Table_DMA.value + 			((MV_PU8) &pCmdTbl[SlotNo].Open_Addr_Frame - 			 (MV_PU8)pCore->Cmd_Table);		pCmdHeader->OpenAddrFrame_Address = MV_CPU_TO_LE32(tmpPhyAddress.parts.low);		pCmdHeader->OpenAddrFrame_Address_High = MV_CPU_TO_LE32(tmpPhyAddress.parts.high);		tmpPhyAddress.value = pCore->Cmd_Table_DMA.value + 			((MV_PU8) &pCmdTbl[SlotNo].table.SSP_CMD_Table - 			 (MV_PU8)pCore->Cmd_Table);		pCmdHeader->Table_Address = MV_CPU_TO_LE32(tmpPhyAddress.parts.low);		pCmdHeader->Table_Address_High = MV_CPU_TO_LE32(tmpPhyAddress.parts.high);	}	pCmdHeader->SSP_Retry = 1;#ifdef USE_NEW_SGTABLE	if( pReq->SG_Table.Valid_Entry_Count )	{		MV_U16 consumed = (MV_U16) sgdt_prepare_hwprd( pCore, &pReq->SG_Table, pSGBuf->Buffer_Vir, HW_SG_ENTRY_MAX );		if( consumed == 0 ) 		{			// resource not enough...			MV_DPRINT( ("Run out of PRD entry.\n") );			if( pReq->Req_Flag & REQ_FLAG_CONSOLIDATE )			{				pReq->Scsi_Status = REQ_STATUS_BUSY;				Tag_ReleaseOne(&pCore->Tag_Pool, SlotNo);				return MV_QUEUE_COMMAND_RESULT_FINISHED;			}			else			{				/* check why upper layer send request with too many sg items... */				MV_DASSERT( MV_FALSE );			}		}		pCmdHeader->PRD_Entry_Count = consumed;	}	else		pCmdHeader->PRD_Entry_Count = 0;#else	pCmdHeader->PRD_Entry_Count = pReq->SG_Table.Valid_Entry_Count;	for (i=0; i<pReq->SG_Table.Valid_Entry_Count; i++)	{				PMV_SG_Entry pSGEntry = ((PMV_SG_Entry) pSGBuf->Buffer_Vir) + i;		pSGEntry->Base_Address = MV_CPU_TO_LE32(pReq->SG_Table.Entry_Ptr[i].Base_Address);		pSGEntry->Base_Address_High = MV_CPU_TO_LE32(pReq->SG_Table.Entry_Ptr[i].Base_Address_High);		pSGEntry->Size = MV_CPU_TO_LE32(pReq->SG_Table.Entry_Ptr[i].Size);	}#endif	pCmdHeader->DataXferLen = MV_CPU_TO_LE32(pReq->Data_Transfer_Length);	if (IS_PM_REQ(pReq))	{		SATA_PrepareCommandHeader(pPort, pReq, pCmdHeader, SlotNo);		SATA_PrepareCommandTable(pPort, pReq, &pCmdTbl[SlotNo], &taskFile);		pPort->Setting &= ~PORT_SETTING_NCQ_RUNNING;	}	else if(pPort->Type&PORT_TYPE_SAS)	{		if (sizeof(SSP_RESPONSE_IU) > MAX_SMP_RESP_SIZE) 			pCmdHeader->MaxRspFrameLength = (sizeof(SSP_RESPONSE_IU)>>2);		else			pCmdHeader->MaxRspFrameLength = (MAX_SMP_RESP_SIZE>>2);		if ((pDevice != NULL) && IS_STP(pDevice))		{			SATA_PrepareCommandHeader(pPort, pReq, pCmdHeader, SlotNo);			if ( (!IS_ATAPI(pDevice)) && (pReq->Cmd_Flag & CMD_FLAG_NCQ ))				taskFile.Sector_Count = (MV_U8) pCmdHeader->Tag<<3;			SATA_PrepareCommandTable(pPort, pReq, &pCmdTbl[SlotNo], &taskFile);			if (pReq->Cmd_Flag & CMD_FLAG_NCQ)				pPort->Setting |= PORT_SETTING_NCQ_RUNNING;			else				pPort->Setting &= ~PORT_SETTING_NCQ_RUNNING;						pCmdTbl[SlotNo].Open_Addr_Frame.Protocol     = PROTOCOL_STP;			pCmdTbl[SlotNo].Open_Addr_Frame.Frame_Type   = ADDRESS_OPEN_FRAME;			pCmdTbl[SlotNo].Open_Addr_Frame.Initiator    = 1;//		    pCmdTbl[SlotNo].Open_Addr_Frame.Connect_Rate=PHY_LINKRATE_3;			pCmdTbl[SlotNo].Open_Addr_Frame.Connect_Rate=pDevice->NegotiatedLinkRate;			*(MV_U16 *)(pCmdTbl[SlotNo].Open_Addr_Frame.Connect_Tag) = MV_CPU_TO_BE16(pDevice->Id+1);			U64_ASSIGN(Val64, MV_CPU_TO_BE64(pDevice->SASAddr));		}		else if ((pReq->Cdb[0] == SCSI_CMD_MARVELL_SPECIFIC) &&			 (pReq->Cdb[1] == CDB_CORE_MODULE))		{			switch (pReq->Cdb[2])			{			case CDB_CORE_TASK_MGMT:/*CDB[3..4]=tagCDB[5]=Task FunctionCDB[6..13]=Lun*/				Tag=(MV_U16)(pReq->Cdb[4]<<8) + (MV_U16)pReq->Cdb[3];				pCmdHeader->FrameLength = ((sizeof(SSP_TASK_IU) + 									sizeof(SSP_Frame_Header))/4);				DELV_Q_Entry.PRIORITY = 1;				pCmdHeader->Tag |= pReq->Tag <<pCore->MaxCmdSlotWidth;				pCmdHeader->SSP_SSPFrameType = FRAME_TYPE_TASK;				MV_CopyMemory(&pCmdTbl[SlotNo].table.SSP_CMD_Table.data.task.LUN, &pReq->Cdb[6], 8);				pCmdTbl[SlotNo].table.SSP_CMD_Table.data.task.Tag = MV_CPU_TO_BE16(Tag);				pCmdTbl[SlotNo].table.SSP_CMD_Table.data.task.TaskFunction = pReq->Cdb[5];				pCmdTbl[SlotNo].Open_Addr_Frame.Protocol   = PROTOCOL_SSP;				pCmdTbl[SlotNo].Open_Addr_Frame.Frame_Type = ADDRESS_OPEN_FRAME;				pCmdTbl[SlotNo].Open_Addr_Frame.Initiator  = 1;				*(MV_U16 *)(pCmdTbl[SlotNo].Open_Addr_Frame.Connect_Tag) = MV_CPU_TO_BE16(pDevice->Id+1);//				pCmdTbl[SlotNo].Open_Addr_Frame.Connect_Rate=PHY_LINKRATE_3;				pCmdTbl[SlotNo].Open_Addr_Frame.Connect_Rate=pDevice->NegotiatedLinkRate;				U64_ASSIGN(Val64, MV_CPU_TO_BE64(pDevice->SASAddr));				break;			case CDB_CORE_SMP:				pCmdHeader->Tag |= pReq->Tag <<pCore->MaxCmdSlotWidth;				pCmdTbl[SlotNo].Open_Addr_Frame.Protocol     = PROTOCOL_SMP;				pCmdTbl[SlotNo].Open_Addr_Frame.Frame_Type   = ADDRESS_OPEN_FRAME;				pCmdTbl[SlotNo].Open_Addr_Frame.Initiator    = 1;				*(MV_U16 *)(pCmdTbl[SlotNo].Open_Addr_Frame.Connect_Tag) = 0xffff;//				pCmdTbl[SlotNo].Open_Addr_Frame.Connect_Rate=PHY_LINKRATE_3;				pCmdTbl[SlotNo].Open_Addr_Frame.Connect_Rate=pTgt->NegotiatedLinkRate;				if (pReq->Data_Buffer == NULL)				{					pReq->Scsi_Status = REQ_STATUS_ERROR;					return MV_QUEUE_COMMAND_RESULT_FINISHED;				}				if ((pReq->Cdb[3] & SMP_CDB_USE_ADDRESS) &&				    (pReq->Sense_Info_Buffer != NULL))				{					MV_CopyMemory(&Val64, pReq->Sense_Info_Buffer, 8);					U64_ASSIGN(Val64, MV_CPU_TO_BE64(Val64));				}				else				{					U64_ASSIGN(Val64, MV_CPU_TO_BE64(pTgt->SASAddr));				}				ReqLen  = 4;				pSMPReq = (struct SMPRequest *) pReq->Data_Buffer;				switch (pSMPReq->Function)				{				case REPORT_GENERAL:					ReqLen += sizeof(pSMPReq->Request.ReportGeneral) - sizeof(MV_U32);					break;				case REPORT_MANUFACTURER_INFORMATION:					ReqLen+= sizeof(pSMPReq->Request.ReportManufacturerInformation)-sizeof(MV_U32);					break;//					case READ_GPIO_REGISTER://						break;				case REPORT_SELF_CONFGRIGRUATION_STATUS:					ReqLen+= sizeof(pSMPReq->Request.ReportSelfConfigurationStatus)-sizeof(MV_U32);					break;				case DISCOVER:					ReqLen+= sizeof(pSMPReq->Request.Discover)-sizeof(MV_U32);					break;				case REPORT_PHY_ERROR_LOG:					ReqLen+= sizeof(pSMPReq->

⌨️ 快捷键说明

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