scsi2sata.c

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

C
1,717
字号
			break;	}}/**************************************************************************** SCSI_ATA_ModeSenseTranslation* Purpose: Translate Mode Sense SCSI command ****************************************************************************/void SCSI_ATA_ModeSenseTranslation(	IN PDomain_Device pDevice,	IN PMV_Request pReq, 	OUT PATA_TaskFile pTaskFile	){	MV_PU8 pModePageBuf = NULL;//	PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK) pReq->Org_Req;	MV_U8 length = 0;		// DBD bit field	if( (pReq->Cdb[1] & 0x8) !=0 )	{		SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 				SCSI_ASC_INVALID_FEILD_IN_CDB|SCSI_ASC_INVALID_FIELD_IN_PARAMETER );	}	// PC bit field	if( (pReq->Cdb[2] & 0xC0) != 0)	{		SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 				SCSI_ASC_INVALID_FEILD_IN_CDB );			}	/*	* SAT translation for mode sense/select 6 from spec	* modePageBuf[0] = Mode Data length (Unspecified)	* modePageBuf[1] = Medium Type (support 00h only)	* modePageBuf[2] = Device Specific Parameter (Sense 0 only and select is unspecified)	* modePageBuf[3] = Block Descriptor length (00h)	*	* mode sense/select 8 is similar with extended fields of 0	*/	// Move pointer to the array location and find the size of the parameter header	if( pReq->Cdb[0] == SCSI_CMD_MODE_SELECT_6)	{		pModePageBuf = &modePageBuf[4];		length = 4; // size of header	} else if( pReq->Cdb[0] == SCSI_CMD_MODE_SELECT_10 ){		pModePageBuf = &modePageBuf[8];		length = 8; // size of header	}	// Page Code handling	switch(pReq->Cdb[2] & 0x3F)	{		case 0x0A:			SCSI_ATA_FillCtrlModePage(pModePageBuf, pDevice);			length += 12;			break;		case 0x01:			SCSI_ATA_FillRWErrorRecoveryModePage(pModePageBuf);			length += 12;			break;		case 0x08:			SCSI_ATA_FillCachingModePage(pModePageBuf, pDevice);			length += 20;			break;		case 0x1C:			SCSI_ATA_FillInfoExcepCtrlModePage(pModePageBuf, pDevice, pReq);			length += 12;			break;		default:			SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 					SCSI_ASC_INVALID_FEILD_IN_CDB );			return;	}	pReq->Cdb[4] = length; // allocation length	MV_CopyMemory(pReq->Data_Buffer, &modePageBuf, sizeof(modePageBuf));}/**************************************************************************** SCSI_ATA_ModeSelectTranslation* Purpose: Translate Mode Sense SCSI command ****************************************************************************/void SCSI_ATA_ModeSelectTranslation(	IN IN PDomain_Device pDevice,	IN PMV_Request pReq, 	OUT PATA_TaskFile pTaskFile	){		MV_PU8 pModePageBuf = NULL;	int length = 0;		if( (pReq->Cdb[1] & 0x10)==0)	{		SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 				SCSI_ASC_INVALID_FEILD_IN_CDB );	}	/*	* SAT translation for mode sense/select 6 from spec	* modePageBuf[0] = Mode Data length (Unspecified)	* modePageBuf[1] = Medium Type (support 00h only)	* modePageBuf[2] = Device Specific Parameter (Sense 0 only and select is unspecified)	* modePageBuf[3] = Block Descriptor length (00h)	*	* mode sense/select 8 is similar with extended fields of 0	*/	// Move pointer to the array location and find the size of the parameter header	if( pReq->Cdb[0] == SCSI_CMD_MODE_SENSE_6)	{		pModePageBuf = &modePageBuf[4];		length = 4; // size of header	} else if( pReq->Cdb[0] == SCSI_CMD_MODE_SENSE_10 ){		pModePageBuf = &modePageBuf[8];		length = 8; // size of header	}	// Page Code handling	switch(pReq->Cdb[2] & 0x3F)	{		case 0x0A:			break;		case 0x01:			break;		case 0x08:			if( pModePageBuf[2] & 0x4 )			{				SCSI_ATA_EnableDisableFeature(pDevice->pPort,pDevice, 						CDB_CORE_ENABLE_WRITE_CACHE);			} else {				SCSI_ATA_EnableDisableFeature(pDevice->pPort,pDevice, 						CDB_CORE_DISABLE_WRITE_CACHE);							}			if( pModePageBuf[2] & 0x20 )			{				SCSI_ATA_EnableDisableFeature(pDevice->pPort,pDevice, 						CDB_CORE_ENABLE_READ_AHEAD);			} else {				SCSI_ATA_EnableDisableFeature(pDevice->pPort,pDevice, 						CDB_CORE_DISABLE_READ_AHEAD);			}			break;		case 0x1C:			if(!(pDevice->Capacity & DEVICE_CAPACITY_SMART_SUPPORTED))			{				SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 					SCSI_ASC_INVALID_FEILD_IN_CDB );			}			break;		default:			SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 					SCSI_ASC_INVALID_FEILD_IN_CDB );			return;	}	if( modePageBuf[0] != 0 )	{		SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 			SCSI_ASC_INVALID_FEILD_IN_CDB );	}}/**************************************************************************** SCSI_ATA_ReadWriteTranslation* Purpose: Handles read/write SCSI commands ****************************************************************************/void SCSI_ATA_ReadWriteTranslation(	IN PMV_Request pReq, 	IN MV_U8 tag,	OUT PATA_TaskFile pTaskFile	){		MV_U8 tempSC, tempSC_exp; // temp sector count		switch(pReq->Cdb[0])	{		case SCSI_CMD_READ_10:		case SCSI_CMD_WRITE_10:			tempSC = pReq->Cdb[8];			tempSC_exp = pReq->Cdb[7];			SCSI_ATA_FillLBACdb10( pReq, pTaskFile );			break;		case SCSI_CMD_READ_16:		case SCSI_CMD_WRITE_16:			tempSC = pReq->Cdb[13];			tempSC_exp = pReq->Cdb[12];			SCSI_ATA_FillLBACdb16( pReq, pTaskFile );			break;		default:			return;	}		pTaskFile->Device = MV_BIT(6);	if ( pReq->Cmd_Flag&CMD_FLAG_NCQ )	{		pTaskFile->Features = tempSC;		pTaskFile->Feature_Exp = tempSC_exp;		pTaskFile->Sector_Count = tag<<3;		if ( pReq->Cdb[0]==SCSI_CMD_READ_10 || pReq->Cdb[0]==SCSI_CMD_READ_16 )			pTaskFile->Command = ATA_CMD_READ_FPDMA_QUEUED;		else			pTaskFile->Command = ATA_CMD_WRITE_FPDMA_QUEUED;			} else if ( pReq->Cmd_Flag&CMD_FLAG_48BIT ) {		pTaskFile->Sector_Count = tempSC;		pTaskFile->Sector_Count_Exp = tempSC_exp;		if ( pReq->Cdb[0]==SCSI_CMD_READ_10 || pReq->Cdb[0]==SCSI_CMD_READ_16 )			pTaskFile->Command = ATA_CMD_READ_DMA_EXT;		else			pTaskFile->Command = ATA_CMD_WRITE_DMA_EXT;			} else {		pTaskFile->Sector_Count = tempSC; 	/* Could be zero */				pTaskFile->Device |= (pReq->Cdb[2]&0xF);				MV_DASSERT( (pReq->Cdb[2]&0xF0)==0 );		if ( pReq->Cdb[0]==SCSI_CMD_READ_10 || pReq->Cdb[0]==SCSI_CMD_READ_16 )			pTaskFile->Command = ATA_CMD_READ_DMA;		else			pTaskFile->Command = ATA_CMD_WRITE_DMA;	}}/**************************************************************************** SCSI_ATA_ReadCapacityTranslationCallback* Purpose: Handles read capacity SCSI command callback data****************************************************************************/void SCSI_ATA_ReadCapacityTranslationCallback(		IN MV_PVOID This,		IN PMV_Request pReq		){	PCore_Driver_Extension pCore = (PCore_Driver_Extension)This;	PDomain_Device pDevice = pCore->Devices;	PATA_Identify_Data pATAIdentify = (PATA_Identify_Data)pReq->Data_Buffer;	/* Disk size */	if ( pDevice->Capacity&DEVICE_CAPACITY_48BIT_SUPPORTED )	{		pDevice->Max_LBA.parts.low = *((MV_PU32)&pATAIdentify->Max_LBA[0]);		pDevice->Max_LBA.parts.high = *((MV_PU32)&pATAIdentify->Max_LBA[2]);	}else 	{		pDevice->Max_LBA.parts.low = *((MV_PU32)&pATAIdentify->User_Addressable_Sectors[0]);		pDevice->Max_LBA.parts.high = 0;	}    /* 	 * The disk size as indicated by the ATA spec is the total addressable     * sectors on the drive ; while Max LBA is the LBA of the last logical block on the drive	 */	pDevice->Max_LBA = U64_SUBTRACT_U32(pDevice->Max_LBA, 1);	MV_CopyMemory(pReq->Data_Buffer, &pDevice->Max_LBA, sizeof(pDevice->Max_LBA) );}/**************************************************************************** SCSI_ATA_ReadCapacityTranslation* Purpose: Handles read capacity SCSI commands ****************************************************************************/void SCSI_ATA_ReadCapacityTranslation(	IN PMV_Request pReq, 	OUT PATA_TaskFile pTaskFile	){	if( (pReq->Cdb[2]|pReq->Cdb[3]|pReq->Cdb[4]|pReq->Cdb[5]|(pReq->Cdb[8]&0x1)) != 0)	{		SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 				SCSI_ASC_INVALID_FEILD_IN_CDB);		return;	}	pTaskFile->Command = ATA_CMD_IDENTIFY_ATA;	pReq->Completion = SCSI_ATA_ReadCapacityTranslationCallback;}/**************************************************************************** SCSI_ATA_VerifyTranslation* Purpose: Handles verify SCSI commands ****************************************************************************/void SCSI_ATA_VerifyTranslation(	IN PMV_Request pReq, 	OUT PATA_TaskFile pTaskFile	){	MV_U8 tempSC, tempSC_exp; // temp sector count		switch(pReq->Cdb[0])	{		case SCSI_CMD_VERIFY_10:			tempSC = pReq->Cdb[8];			tempSC_exp = pReq->Cdb[7];			SCSI_ATA_FillLBACdb10( pReq, pTaskFile );			break;		case SCSI_CMD_VERIFY_16:			tempSC = pReq->Cdb[13];			tempSC_exp = pReq->Cdb[12];			SCSI_ATA_FillLBACdb16( pReq, pTaskFile );			break;		default:			return;	}		pTaskFile->Device = MV_BIT(6);			if ( pReq->Cmd_Flag&CMD_FLAG_48BIT ) {		pTaskFile->Sector_Count = tempSC;		pTaskFile->Sector_Count_Exp = tempSC_exp;		pTaskFile->Command = ATA_CMD_VERIFY_EXT;	} else {		pTaskFile->Sector_Count = tempSC; 	/* Could be zero */		pTaskFile->Device |= (pReq->Cdb[2]&0xF);		MV_DASSERT( (pReq->Cdb[2]&0xF0)==0 );		pTaskFile->Command = ATA_CMD_VERIFY;	}}/**************************************************************************** SCSI_ATA_SyncCacheTranslation* Purpose: Syncronize cache 10/16****************************************************************************/void SCSI_ATA_SyncCacheTranslation(	IN PDomain_Device pDevice,	IN PMV_Request pReq, 	OUT PATA_TaskFile pTaskFile	){	pTaskFile->Device = MV_BIT(6);	switch(pReq->Cdb[0])	{		case SCSI_CMD_SYNCHRONIZE_CACHE_10:			if ( pDevice->Capacity&DEVICE_CAPACITY_48BIT_SUPPORTED )				pTaskFile->Command = ATA_CMD_FLUSH_EXT;			else				pTaskFile->Command = ATA_CMD_FLUSH;			break;		case SCSI_CMD_SYNCHRONIZE_CACHE_16:			pTaskFile->Command = ATA_CMD_FLUSH_EXT;			break;		default:			SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 					SCSI_ASC_INVALID_FEILD_IN_CDB );			return;	}	if( (pReq->Cdb[1]&0x2)!=0 )	{		pReq->Scsi_Status = SCSI_STATUS_GOOD;	}}/**************************************************************************** SCSI_ATA_SendDiagTranslationCallback* Purpose: handles callback****************************************************************************/void SCSI_ATA_SendDiagTraslationCallback(	IN MV_PVOID This,	IN PMV_Request pReq	){	}/**************************************************************************** SCSI_ATA_SendDiagTranslation* Purpose: Sends Diagnostic cmd ****************************************************************************/void SCSI_ATA_SendDiagTranslation(	IN PMV_Request pReq, 	OUT PATA_TaskFile pTaskFile	){	// CDB[1] checks if DevOffL and UnitOffL bits are set	// CDB[3] & CDB[4] checks for parameter list length equal to 0	if( ((pReq->Cdb[1]&0xFC)!=0) || (pReq->Cdb[3]!=0) || (pReq->Cdb[4]!=0) )	{		SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 				SCSI_ASC_INVALID_FEILD_IN_CDB );		return;	}	pTaskFile->Command = ATA_CMD_EXECUTE_DEVICE_DIAGNOSTIC;	switch(pReq->Cdb[1]&0xE0)	{		case DEFAULT_SELF_TEST:			break;		case BACKGROUND_SHORT_SELF_TEST:					break;		case BACKGROUND_EXTENDED_SELF_TEST:			break;		case ABORT_BACKGROUND_SELF_TEST:			break;		case FOREGROUND_SHORT_SELF_TEST:			break;		case FOREGROUND_EXTENDED_SELF_TEST:			break;		default:			break;	}}/**************************************************************************** SCSI_ATA_StartStopTranslation* Purpose: Start and Stop cmd translation****************************************************************************/void SCSI_ATA_StartStopTranslation(	IN PMV_Request pReq, 	OUT PATA_TaskFile pTaskFile

⌨️ 快捷键说明

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