scsi2sata.c

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

C
1,717
字号
	}}/**************************************************************************** SCSI_ATA_FillSelfTestLogPage* Purpose: Fill the right values for Caching Mode page ****************************************************************************/void SCSI_ATA_FillSelfTestLogPage(	MV_PU8 pBuf, 	PDomain_Device pDevice,		int pageNum	){	// Parameter Code	pBuf[0] = 0;	pBuf[1] = pageNum+1;	// DU, DS, TSD, ETC, TMC, LBIN, LP set to 0	pBuf[2] = 0;	// Parameter length	pBuf[3] = 0x10;	// Self-test code }/**************************************************************************** SCSI_ATA_FormatUnit* Purpose: Format Unit cmd translation****************************************************************************/void SCSI_ATA_FillFormatTaskFile(	MV_U8 ataCmd,	MV_U32 lbaCount,	MV_U32 lbaLow,	MV_U32 lbaHigh,	OUT PATA_TaskFile pTaskFile	){	pTaskFile->Command = ataCmd;	pTaskFile->Features = 0;	pTaskFile->Feature_Exp = 0;	if(ataCmd==ATA_CMD_WRITE_DMA || ataCmd==ATA_CMD_VERIFY) {		pTaskFile->Sector_Count = (MV_U8)(lbaCount & 0xFF);		pTaskFile->LBA_Low = (MV_U8)(lbaLow&0xFF);		pTaskFile->LBA_Mid = (MV_U8)(lbaLow>>8) & 0xFF;		pTaskFile->LBA_High = (MV_U8)(lbaLow>>16) & 0xFF;		pTaskFile->Device = ((MV_U8)(lbaLow>>24) & 0xF ) | 0x40;	} else if (ataCmd==ATA_CMD_WRITE_DMA_EXT || ataCmd==ATA_CMD_VERIFY_EXT) {		pTaskFile->Sector_Count = (MV_U8)(lbaCount & 0xFF);		pTaskFile->Sector_Count_Exp = (MV_U8)((lbaCount >> 8) & 0xFF);		pTaskFile->LBA_Low = (MV_U8)(lbaLow&0xFF);		pTaskFile->LBA_Mid = (MV_U8)(lbaLow>>8) & 0xFF;		pTaskFile->LBA_High = (MV_U8)(lbaLow>>16) & 0xFF;		pTaskFile->LBA_Low_Exp = (MV_U8)(lbaLow>>24) & 0xFF;		pTaskFile->LBA_Mid_Exp = (MV_U8)(lbaHigh&0xFF);		pTaskFile->LBA_High_Exp = (MV_U8)((lbaHigh>>8)&0xFF);		pTaskFile->Device = 0x40;	}	TotalFormattedLbaCount += lbaCount;}/**************************************************************************** SCSI_ATA_FormatUnitTranslationCallback* Purpose: Format Unit cmd translation****************************************************************************/void SCSI_ATA_FormatUnitTranslationCallback(	IN MV_PVOID This,	IN PMV_Request pReq	){	PCore_Driver_Extension pCore = (PCore_Driver_Extension)This;	PDomain_Device pDevice = pCore->Devices;	ATA_TaskFile taskFile;	switch(pDevice->State)	{		case DEVICE_STATE_FORMAT_WRITE:			if( TotalLbaCount!=TotalFormattedLbaCount )			{				SCSI_ATA_FormatUnitTranslation( pDevice, pReq, &taskFile );			} else {				pDevice->State = DEVICE_STATE_FORMAT_VERIFY;				TotalFormattedLbaCount = 0;				SCSI_ATA_FormatUnitTranslation( pDevice, pReq, &taskFile );			}			break;		case DEVICE_STATE_FORMAT_VERIFY:			if( TotalLbaCount!=TotalFormattedLbaCount )			{				SCSI_ATA_FormatUnitTranslation( pDevice, pReq, &taskFile );				break;			}			pDevice->State = DEVICE_STATE_FORMAT_DONE;		case DEVICE_STATE_FORMAT_DONE:		default:			return;			}	/* Send this internal request */	Core_ModuleSendRequest(pCore, pReq);}/**************************************************************************** SCSI_ATA_FormatUnitTranslation* Purpose: Format Unit cmd translation****************************************************************************/void SCSI_ATA_FormatUnitTranslation(	PDomain_Device pDevice,	IN PMV_Request pReq, 	OUT PATA_TaskFile pTaskFile	){	MV_U8 defectList=0;	MV_U8 cmpList = 0;	MV_U8 fmtData = 0;	MV_U8 ataCmd =0;	MV_U32 lbaCount = 0;	defectList = pReq->Cdb[1]&0x7; // Defect list format checking	cmpList = pReq->Cdb[1]&0x8; // complete list bit checking	if( defectList != 0 || defectList != 0x6 || 		(cmpList != 0 && fmtData != 0 ) || pReq->Cdb[2] != 0 ||		pReq->Cdb[3] != 0 || pReq->Cdb[4] != 0 )	{		SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 				SCSI_ASC_INVALID_FEILD_IN_CDB );		return;	}	if ( pDevice->Capacity&DEVICE_CAPACITY_48BIT_SUPPORTED )	{		ataCmd = (pDevice->State == DEVICE_STATE_FORMAT_WRITE) ? ATA_CMD_WRITE_DMA_EXT : ATA_CMD_VERIFY_EXT;	} else {		ataCmd = (pDevice->State == DEVICE_STATE_FORMAT_WRITE) ? ATA_CMD_WRITE_DMA : ATA_CMD_VERIFY;	}//	TotalLbaCount = pDevice->Max_LBA.parts.low;	TotalLbaCount = pDevice->Max_LBA.parts.low + 1;	pReq->Completion = SCSI_ATA_FormatUnitTranslationCallback;	lbaCount = (LBA_BLOCK_COUNT < (TotalLbaCount-TotalFormattedLbaCount)) ?  			LBA_BLOCK_COUNT : (TotalLbaCount-TotalFormattedLbaCount);	SCSI_ATA_FillFormatTaskFile(ataCmd, 0, 0, lbaCount, pTaskFile);	TotalFormattedLbaCount += lbaCount;}/**************************************************************************** SCSI_ATA_InquiryTranslationCallback* Purpose: Handles the Inquiry data after ATA_CMD_IDENTIFY is sent****************************************************************************/#ifdef _OS_WINDOWSvoid SCSI_ATA_InquiryTranslationCallback(	IN MV_PVOID This,	IN PMV_Request pReq	){	MV_U8 MV_T10_ATA_VENDOR_ID[8] = { 0x41, 0x54, 0x41, 0x20, 0x20, 0x20, 0x20, 0x20 }; //'ATA     '	MV_U8 MV_T10_SAT_VENDOR_ID[8] = {'M','A','R','V','E','L','L'};	MV_U8 MV_INQUIRY_STANDARD_DATA[36] = {0};	MV_U8 MV_INQUIRY_VPD_PAGE0_DATA[9] = {0x00, 0x00, 0x00, 0x05,0x00, 0x80, 0x83, 0x87, 0x89};	MV_U8 MV_INQUIRY_VPD_PAGE80_DATA[24] = {0};	MV_U8 MV_INQUIRY_VPD_PAGE83_DATA[88] = {0};	MV_U8 MV_INQUIRY_VPD_PAGE87_DATA[36] = {0};	MV_U8 MV_INQUIRY_VPD_PAGE89_DATA[572] = {0};	PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK) pReq->Org_Req;	PCore_Driver_Extension pCore = (PCore_Driver_Extension)This;	PSATA_FIS_REG_H2D pFIS = (PSATA_FIS_REG_H2D)pCore->RX_FIS;	PATA_Identify_Data pATAIdentify;	int i = 0;	pATAIdentify = (PATA_Identify_Data)pReq->Data_Buffer;	if( pReq->Cdb[1]&0x01 )	{		 // EVPD is 1		switch(pReq->Cdb[2])		{			// Page Code is set as follows			case 0x00:				MV_CopyMemory( pReq->Data_Buffer, MV_INQUIRY_VPD_PAGE0_DATA, 						sizeof(MV_INQUIRY_VPD_PAGE0_DATA) );				break;			case 0x80:				MV_INQUIRY_VPD_PAGE80_DATA[1] = 0x80;	// Page Code				MV_INQUIRY_VPD_PAGE80_DATA[3] = 0x14;	// Page Length								// 4-23 bytes hold the serial number of the device				SCSI_ATA_FillDataField( &MV_INQUIRY_VPD_PAGE80_DATA[4], 						pATAIdentify->Serial_Number, 						sizeof(MV_INQUIRY_VPD_PAGE80_DATA));// len 20bytes				MV_CopyMemory( pReq->Data_Buffer, MV_INQUIRY_VPD_PAGE80_DATA, 						sizeof(MV_INQUIRY_VPD_PAGE80_DATA));			break;			case 0x83:				MV_INQUIRY_VPD_PAGE83_DATA[1] = 0x83;	// Page Code				MV_INQUIRY_VPD_PAGE83_DATA[3] = 88;	// Page Length				if( pATAIdentify->Command_Set_Default & 0x100 )				{					//Support World wide name					MV_INQUIRY_VPD_PAGE83_DATA[4] = 0x1;					MV_INQUIRY_VPD_PAGE83_DATA[5] = 0x3;					// MV_INQUIRY_VPD_PAGE83_DATA[6] is reserved					MV_INQUIRY_VPD_PAGE83_DATA[7] = 0x8;					MV_INQUIRY_VPD_PAGE83_DATA[8] = 							SCSI_ATA_UpperWord(pATAIdentify->NAA);					MV_INQUIRY_VPD_PAGE83_DATA[9] = 							SCSI_ATA_LowerWord(pATAIdentify->NAA);					MV_INQUIRY_VPD_PAGE83_DATA[10]= 							SCSI_ATA_UpperWord(pATAIdentify->Unique_ID1);					MV_INQUIRY_VPD_PAGE83_DATA[11]= 							SCSI_ATA_LowerWord(pATAIdentify->Unique_ID1);					MV_INQUIRY_VPD_PAGE83_DATA[12]= 							SCSI_ATA_UpperWord(pATAIdentify->Unique_ID2);					MV_INQUIRY_VPD_PAGE83_DATA[13]= 							SCSI_ATA_LowerWord(pATAIdentify->Unique_ID2);					MV_INQUIRY_VPD_PAGE83_DATA[14]= 							SCSI_ATA_UpperWord(pATAIdentify->Unique_ID3);					MV_INQUIRY_VPD_PAGE83_DATA[15]= 							SCSI_ATA_LowerWord(pATAIdentify->Unique_ID3);				} else {					//Logical Unit name					MV_INQUIRY_VPD_PAGE83_DATA[4] = 0x2;					MV_INQUIRY_VPD_PAGE83_DATA[5] = 0x1;					// MV_INQUIRY_VPD_PAGE83_DATA[6] is reserved					MV_INQUIRY_VPD_PAGE83_DATA[7] = 68;					MV_CopyMemory( &MV_INQUIRY_VPD_PAGE83_DATA[8], 							MV_T10_ATA_VENDOR_ID, 							sizeof(MV_T10_ATA_VENDOR_ID) );										// Fill Model Number					SCSI_ATA_FillDataField( &MV_INQUIRY_VPD_PAGE83_DATA[16], 							pATAIdentify->Model_Number, 							sizeof(pATAIdentify->Model_Number) );					// Fill Serial Number					SCSI_ATA_FillDataField( &MV_INQUIRY_VPD_PAGE83_DATA[46], 							pATAIdentify->Serial_Number, 							sizeof(pATAIdentify->Serial_Number) );				}				MV_CopyMemory(pReq->Data_Buffer, MV_INQUIRY_VPD_PAGE83_DATA, 						sizeof(MV_INQUIRY_VPD_PAGE83_DATA) );				break;			case 0x87:				MV_INQUIRY_VPD_PAGE87_DATA[1] = 0x87;  // Page Code				MV_INQUIRY_VPD_PAGE87_DATA[3] = Srb->Lun*4;				MV_CopyMemory(pReq->Data_Buffer, MV_INQUIRY_VPD_PAGE87_DATA,						sizeof(MV_INQUIRY_VPD_PAGE87_DATA) );				break;			case 0x89:				MV_INQUIRY_VPD_PAGE89_DATA[1] = 0x89;	// Page Code				MV_INQUIRY_VPD_PAGE89_DATA[2] = 0x2;	// Page Length				MV_INQUIRY_VPD_PAGE89_DATA[3] = 0x38;				MV_INQUIRY_VPD_PAGE89_DATA[56] = ATA_CMD_IDENTIFY_ATA;				// Fill SAT Vendor ID				MV_CopyMemory(&MV_INQUIRY_VPD_PAGE89_DATA[8], MV_T10_SAT_VENDOR_ID, 						sizeof(MV_T10_SAT_VENDOR_ID) );				// Fill ATA Signature				MV_CopyMemory(&MV_INQUIRY_VPD_PAGE89_DATA[36], pFIS,						sizeof(pFIS));				SCSI_ATA_FillDataField( &MV_INQUIRY_VPD_PAGE89_DATA[60], 						(char*)pATAIdentify,						sizeof(pATAIdentify) );				MV_CopyMemory( pReq->Data_Buffer, MV_INQUIRY_VPD_PAGE89_DATA,						sizeof(MV_INQUIRY_VPD_PAGE89_DATA) );				break;			default:				SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 						SCSI_ASC_INVALID_FEILD_IN_CDB );				return;		}	} else {		// Standard inquiry return data		MV_INQUIRY_STANDARD_DATA[1] = 0x80;  // Removable Medium		MV_INQUIRY_STANDARD_DATA[2] = 0x05;  // Version Supported		MV_INQUIRY_STANDARD_DATA[3] |= 0x2;  // Response Data Format based on Spec		MV_INQUIRY_STANDARD_DATA[4] = 0x20;  // 32 bytes left		// Fill with Generic T10 (ATA) Vendor Identification		MV_CopyMemory(&MV_INQUIRY_STANDARD_DATA[8], MV_T10_ATA_VENDOR_ID, 				sizeof(MV_T10_ATA_VENDOR_ID));		// Product Identification(SCSI)/Model Number(ATA)		SCSI_ATA_FillDataField( &MV_INQUIRY_STANDARD_DATA[16], pATAIdentify->Model_Number,				sizeof(pATAIdentify->Model_Number) );		// Product Revision Level(SCSI)/Firmware Revision(ATA)		if( pATAIdentify->Firmware_Revision[5] == 0x20 &&			pATAIdentify->Firmware_Revision[4] == 0x20 &&			pATAIdentify->Firmware_Revision[7] == 0x20 &&			pATAIdentify->Firmware_Revision[6] == 0x20)		{			SCSI_ATA_FillDataField( &MV_INQUIRY_STANDARD_DATA[32], pATAIdentify->Firmware_Revision,					4 );		} else {			SCSI_ATA_FillDataField( &MV_INQUIRY_STANDARD_DATA[32], &pATAIdentify->Firmware_Revision[5],					4 );				}		MV_CopyMemory(pReq->Data_Buffer, MV_INQUIRY_STANDARD_DATA, sizeof(MV_INQUIRY_STANDARD_DATA));	}}#else /* _OS_WINDOWS */inline void SCSI_ATA_InquiryTranslationCallback(IN MV_PVOID This,					 IN PMV_Request pReq){}#endif /* _OS_WINDOWS *//**************************************************************************** SCSI_ATA_InquiryTranslation* Purpose: Translate Inquiry SCSI command and send ATA_CMD_IDENTIFY ****************************************************************************/void SCSI_ATA_InquiryTranslation(	IN PMV_Request pReq, 	OUT PATA_TaskFile pTaskFile	){	if ( ( (pReq->Cdb[1]&0x1 ) == 0 )&&		 (pReq->Cdb[2] != 0)) {		SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 				SCSI_ASC_INVALID_FEILD_IN_CDB );		return;	}	// determine the allocation length	switch( pReq->Cdb[2] )	{		case 0x00:			pReq->Cdb[4] = 9;			break;		case 0x80:			pReq->Cdb[4] = 24;			break;		case 0x83:			pReq->Cdb[4] = 88;			break;		case 0x87:			pReq->Cdb[4] = 36;			break;		case 0x89:			/* FIXME : 572, for a u8? */			MV_DASSERT(MV_FALSE);//			pReq->Cdb[4] = 572;			break;		default:			pReq->Cdb[4] = 36;			break;	}		pReq->Completion = SCSI_ATA_InquiryTranslationCallback;	pTaskFile->Command = ATA_CMD_IDENTIFY_ATA;}/**************************************************************************** SCSI_ATA_LogSenseTranslation* Purpose: Translate Mode Sense SCSI command ****************************************************************************/void SCSI_ATA_LogSenseTranslation(	IN PDomain_Device pDevice,	IN PMV_Request pReq, 	OUT PATA_TaskFile pTaskFile	){	int i = 0;	MV_U8 length = 0;	MV_U8 MV_LOG_PAGE0_DATA[6]={0};	MV_U8 MV_LOG_PAGE10_DATA[194]={0};			// Check page control (PC) settings	if( pReq->Cdb[2] != 0x40 )	{		SCSI_ATA_CheckCondition( pReq, SCSI_SK_ILLEGAL_REQUEST, 				SCSI_ASC_INVALID_FEILD_IN_CDB );		}	// Report log depending on page code 	switch( pReq->Cdb[2] & 0x3F )	{		case SUPPORTED_LOG_PAGES_LOG_PAGE:			length = 4; // Header length			if( pDevice->Capacity & DEVICE_CAPACITY_SMART_SUPPORTED )			{				/*	MV_LOG_PAGE0_DATA[0]-[2] are all zero					MV_LOG_PAGE0_DATA[0] = 0x00; page code					MV_LOG_PAGE0_DATA[1] = reserved					MV_LOG_PAGE0_DATA[2] = unspecified; page length					MV_LOG_PAGE0_DATA[3] = 0x00; page0 supported */				MV_LOG_PAGE0_DATA[length]=0x10;				length++;			}						if( pDevice->Capacity & DEVICE_CAPACITY_SMART_SELF_TEST_SUPPORTED )			{				/*	MV_LOG_PAGE0_DATA[0]-[2] are all zero					MV_LOG_PAGE0_DATA[0] = 0x00; page code					MV_LOG_PAGE0_DATA[1] = reserved					MV_LOG_PAGE0_DATA[2] = unspecified; page length					MV_LOG_PAGE0_DATA[3] = 0x00; page0 supported 					MV_LOG_PAGE0_DATA[4] = could be filled or empty*/				MV_LOG_PAGE0_DATA[length]=0x2F;				length++;			}			MV_CopyMemory(pReq->Data_Buffer, MV_LOG_PAGE0_DATA, length);			break;		case SELF_TEST_RESULTS_LOG_PAGE:			MV_LOG_PAGE10_DATA[0] = 0x10; // Page Code			MV_LOG_PAGE10_DATA[2] = 0x1;			MV_LOG_PAGE10_DATA[3] = 0x90;			// Self-test Results log parameter			for(i=0; i<20; i++)			{				SCSI_ATA_FillSelfTestLogPage(&MV_LOG_PAGE10_DATA[4+(i*20)], 						pDevice ,i);			}			break;		case INFORMATIONAL_EXCEPTIONS_LOG_PAGE:			break;		default:

⌨️ 快捷键说明

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