scsi2sata.c

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

C
1,717
字号
#include "core_header.h"#include "core_exp.h"#include "core_sata.h"#include "core_ata.h"#include "core_api.h"#include "scsi2sata.h"#include "core_helper.h"MV_U8 modePageBuf[28]={0};static MV_U32 TotalLbaCount;static MV_U32 TotalFormattedLbaCount;static MV_BOOLEAN FirstRun = MV_TRUE;void SCSI_ATA_FormatUnitTranslation(	PDomain_Device pDevice,	IN PMV_Request pReq, 	OUT PATA_TaskFile pTaskFile	);#ifdef _OS_WINDOWSextern void HBARequestCallback(MV_PVOID This,PMV_Request pReq);#define __callback_stud HBARequestCallback#else /* _OS_WINDOWS */static inline void __callback_stud(MV_PVOID this , PMV_Request req) {};#endif /* _OS_WINDOWS *//* * Translate SCSI command to SATA FIS * The following SCSI command set is the minimum required. *		Standard Inquiry *		Read Capacity *		Test Unit Ready *		Start/Stop Unit *		Read 10 *		Write 10 *		Request Sense *		Mode Sense/Select */MV_VOID SCSI_To_FIS(MV_PVOID This, PMV_Request pReq, PMV_Command_Table pCmdTable, PATA_TaskFile pTaskFile){#ifdef SUPPORT_PM	PCore_Driver_Extension pCore = (PCore_Driver_Extension)This;/*	PDomain_Port pPort = &pCore->Ports[MapPortEntry(pCore,MapPortId(pCore, pReq->Device_Id))];*/	PDomain_Device pDevice = &pCore->Devices[MapDeviceId(pCore, pReq->Device_Id)];#endif /* SUPPORT_PM */	PSATA_FIS_REG_H2D pFIS = (PSATA_FIS_REG_H2D) pCmdTable->table.STP_CMD_Table.FIS;	/* 	 * TBD	 * 1. SoftReset is not supported yet.	 * 2. PM_Port	 */	pFIS->FIS_Type = SATA_FIS_TYPE_REG_H2D;#ifdef SUPPORT_PM	pFIS->PM_Port = (IS_SOFT_RESET_REQ(pReq)) ? pReq->Cdb[3] : ((IS_PM_REQ(pReq) ? 0x0F : pDevice->PM_Number));#else	pFIS->PM_Port = 0;#endif /* SUPPORT_PM */	pFIS->C = !(IS_SOFT_RESET_REQ(pReq));	pFIS->Command = pTaskFile->Command;	pFIS->Features = pTaskFile->Features;	pFIS->Device = pTaskFile->Device;	pFIS->Control = pTaskFile->Control;	pFIS->LBA_Low = pTaskFile->LBA_Low;	pFIS->LBA_Mid = pTaskFile->LBA_Mid;		pFIS->LBA_High = pTaskFile->LBA_High;	pFIS->Sector_Count = pTaskFile->Sector_Count;		/* No matter it's 48bit or not, I've set the values. */	pFIS->LBA_Low_Exp = pTaskFile->LBA_Low_Exp;	pFIS->LBA_Mid_Exp = pTaskFile->LBA_Mid_Exp;	pFIS->LBA_High_Exp = pTaskFile->LBA_High_Exp;	pFIS->Features_Exp = pTaskFile->Feature_Exp;	pFIS->Sector_Count_Exp = pTaskFile->Sector_Count_Exp;#if 0//DEBUG_BIOS	MV_DUMPC32(0xCCCCEEA1);	MV_DUMP8(pFIS->FIS_Type);	MV_DUMP8(pFIS->Command);#endif}/* Set MV_Request.Cmd_Flag */MV_BOOLEAN Category_CDB_Type(	IN PDomain_Device pDevice,	IN PMV_Request pReq	){	//pReq->Cmd_Flag = 0;//TBD: Don't set. HBA has set some bits.	PDomain_Port pPort = pDevice->pPort;	PCore_Driver_Extension pCore = pPort->Core_Extension;    switch ( pReq->Cdb[0] )	{		case SCSI_CMD_READ_10:		case SCSI_CMD_READ_16:		case SCSI_CMD_WRITE_10:		case SCSI_CMD_VERIFY_10:		case SCSI_CMD_INQUIRY:			/* 			 * 			 * CMD_FLAG_DATA_IN			 * CMD_FLAG_NON_DATA			 * CMD_FLAG_DMA			 */			if ( IS_ATAPI(pDevice) )				pReq->Cmd_Flag |= CMD_FLAG_PACKET;			if ( pDevice->Capacity&DEVICE_CAPACITY_48BIT_SUPPORTED )				pReq->Cmd_Flag |= CMD_FLAG_48BIT;			if ( pDevice->Capacity&DEVICE_CAPACITY_NCQ_SUPPORTED )			{				// might be a PM - assert is no longer true				//MV_DASSERT( pPort->Type==PORT_TYPE_SATA );						if ( (pReq->Cdb[0]==SCSI_CMD_READ_10)					|| (pReq->Cdb[0]==SCSI_CMD_WRITE_10) )				{					if ( Port_IsRequestRunning( pCore, pPort->Id )						|| (pPort->Setting&PORT_SETTING_NCQ_RUNNING) )					{						if ( pReq->Scsi_Status!=REQ_STATUS_RETRY )							pReq->Cmd_Flag |= CMD_FLAG_NCQ;					}				}			}			break;		case SCSI_CMD_MARVELL_SPECIFIC:			{				/* This request should be for core module */				if ( pReq->Cdb[1]!=CDB_CORE_MODULE )					return MV_FALSE;				switch ( pReq->Cdb[2] )				{					case CDB_CORE_IDENTIFY:					case CDB_CORE_READ_LOG_EXT:					case CDB_CORE_PM_READ_REG:					case CDB_CORE_PM_WRITE_REG:						pReq->Cmd_Flag |= CMD_FLAG_DATA_IN;						break;										case CDB_CORE_SOFT_RESET_1:					case CDB_CORE_SOFT_RESET_0:					case CDB_CORE_SET_UDMA_MODE:					case CDB_CORE_SET_PIO_MODE:					case CDB_CORE_ENABLE_WRITE_CACHE:					case CDB_CORE_DISABLE_WRITE_CACHE:					case CDB_CORE_ENABLE_SMART:					case CDB_CORE_DISABLE_SMART:					case CDB_CORE_SMART_RETURN_STATUS:					case CDB_CORE_ENABLE_READ_AHEAD:					case CDB_CORE_DISABLE_READ_AHEAD:						pReq->Cmd_Flag |= CMD_FLAG_NON_DATA;						break;					case CDB_CORE_SHUTDOWN:						if (IS_ATAPI(pDevice))							return MV_FALSE;						pReq->Cmd_Flag |= CMD_FLAG_NON_DATA;						break;					case CDB_CORE_OS_SMART_CMD:						if  ((pReq->Cdb[3] != ATA_CMD_IDENTIFY_ATA) ||							(pReq->Cdb[3] != ATA_CMD_IDENTIY_ATAPI))							pReq->Cmd_Flag |= CMD_FLAG_SMART;						if (IS_ATAPI(pDevice))							pReq->Cmd_Flag |= CMD_FLAG_PACKET;						break;					default:						return MV_FALSE;				}				break;			}		case SCSI_CMD_START_STOP_UNIT:			case SCSI_CMD_SYNCHRONIZE_CACHE_10:			if (!IS_ATAPI(pDevice)) {				if ( pDevice->Capacity&DEVICE_CAPACITY_48BIT_SUPPORTED )					pReq->Cmd_Flag |= CMD_FLAG_48BIT;				pReq->Cmd_Flag |= CMD_FLAG_NON_DATA;				break;			}	//We will send this command to CD drive directly if it is ATAPI device.			case SCSI_CMD_READ_CAPACITY_10:		case SCSI_CMD_TEST_UNIT_READY:		case SCSI_CMD_MODE_SENSE_10:		case SCSI_CMD_MODE_SELECT_10:		case SCSI_CMD_PREVENT_MEDIUM_REMOVAL:		case SCSI_CMD_READ_TOC:		case SCSI_CMD_BLANK:		case SCSI_CMD_READ_DISC_INFO:		case SCSI_CMD_REQUEST_SENSE:		default:			if ( IS_ATAPI(pDevice) )			{				//MV_DPRINT(("Other requests: 0x%x.\n", pReq->Cdb[0]));				pReq->Cmd_Flag |= CMD_FLAG_PACKET;				break;			} else if( pReq->Cmd_Flag & CMD_FLAG_ATA_PASS_THRU ) {				break;			}			else			{#ifndef _OS_BIOS							MV_DPRINT(("Error: Unknown request: 0x%x.\n", pReq->Cdb[0]));#endif				return MV_FALSE;			}	}	return MV_TRUE;}/****************************************************************************                SAT - SCSI to ATA Translation Functions             ******                                                                    *****************************************************************************//**************************************************************************** SCSI_ATA_LowerWord* Purpose: Obtain the lower bytes of a word****************************************************************************/MV_U8 SCSI_ATA_LowerWord( MV_U16 target ){	return (target&0xFF);}/**************************************************************************** SCSI_ATA_UpperWord* Purpose: Obtain the upper bytes of a word****************************************************************************/MV_U8 SCSI_ATA_UpperWord( MV_U16 target ){	return (target&0xFF00)>>8;}/**************************************************************************** SCSI_ATA_CheckCondition* Purpose: Send Check Condition when request is illegal****************************************************************************/void SCSI_ATA_CheckCondition(	IN PMV_Request pReq,	IN MV_U8 senseKey,	IN MV_U8 senseCode	){	 pReq->Scsi_Status = SCSI_STATUS_CHECK_CONDITION;	((MV_PU8)pReq->Sense_Info_Buffer)[2] = senseKey;	((MV_PU8)pReq->Sense_Info_Buffer)[7] = 0;		// additional sense length 	((MV_PU8)pReq->Sense_Info_Buffer)[12] = senseCode; //additional sense code}/**************************************************************************** SCSI_ATA_FillLBACdb10* Purpose: Fill LBA Cdb (10) fields with the proper pReq->Cdb bytes****************************************************************************/void SCSI_ATA_FillLBACdb10(	IN PMV_Request pReq,	OUT PATA_TaskFile pTaskFile	){	pTaskFile->LBA_Low = pReq->Cdb[5];	pTaskFile->LBA_Mid = pReq->Cdb[4];	pTaskFile->LBA_High = pReq->Cdb[3];	pTaskFile->LBA_Low_Exp = pReq->Cdb[2];}/**************************************************************************** SCSI_ATA_FillLBACdb16* Purpose: Fill LBA Cdb (16) fields with the proper pReq->Cdb bytes****************************************************************************/void SCSI_ATA_FillLBACdb16(	IN PMV_Request pReq,	OUT PATA_TaskFile pTaskFile	){	pTaskFile->LBA_Low = pReq->Cdb[9];	pTaskFile->LBA_Mid = pReq->Cdb[8];	pTaskFile->LBA_High = pReq->Cdb[7];	pTaskFile->LBA_Low_Exp = pReq->Cdb[6];	pTaskFile->LBA_Mid_Exp = pReq->Cdb[5];	pTaskFile->LBA_High_Exp = pReq->Cdb[4];}/**************************************************************************** SCSI_ATA_FillDataField* Purpose: Fill data field with bytes that are swaped within a word****************************************************************************/void SCSI_ATA_FillDataField(	char* des,	char* src,	int len	){	int i = 0;	for( i=0; i<len; i++){		if( i & 1 ){			des = src+1;		} else {			des = src++;			des++;			des= src;		}		if( (len - i)>= 2)			i++;	}}/**************************************************************************** SCSI_ATA_FillCtrlModePage* Purpose: Fill the right values for Caching Mode page ****************************************************************************/void SCSI_ATA_FillCtrlModePage(MV_PU8 pBuf, PDomain_Device pDevice){	pBuf[0] = 0x0A;		/* Page Code, PS = 0; */	pBuf[1] = 0x0A;		/* Page Length */	pBuf[3] = 0x12;		/* Queue Algorithm Modifier = 0001b & QErr = 01b*/	pBuf[8] = 0xFF;		/* Busy Timeout Period (pBuf[8](MSB) & pBuf[9](LSB)) */	pBuf[9] = 0xFF;	// Setting Extended Self-test Completion time	if(pDevice->Capacity & DEVICE_CAPACITY_SMART_SELF_TEST_SUPPORTED)	{		// not yet supported	} else {		pBuf[10] = 0;		pBuf[11] = 0;	}}/**************************************************************************** SCSI_ATA_FillRWErrorRecoveryModePage* Purpose: Fill the right values for Caching Mode page ****************************************************************************/void SCSI_ATA_FillRWErrorRecoveryModePage(MV_PU8 pBuf ){	pBuf[0] = 0x01;		/* Page Code, PS = 0; */	pBuf[1] = 0x0A;		/* Page Length */	pBuf[2] = 0x80;		/* Set AWRE */}/**************************************************************************** SCSI_ATA_FillCachingModePage* Purpose: Fill the right values for Caching Mode page ****************************************************************************/void SCSI_ATA_FillCachingModePage(MV_PU8 pBuf, PDomain_Device pDevice){	pBuf[0] = 0x08;		/* Page Code, PS = 0; */	pBuf[1] = 0x12;		/* Page Length */		if( pDevice->Setting & DEVICE_SETTING_WRITECACHE_ENABLED )	{		pBuf[2] |= MV_BIT(2); // WCE	}		if( pDevice->Setting & DEVICE_SETTING_READ_LOOK_AHEAD )	{		pBuf[12] |= MV_BIT(5); // DRA	}	// 0x00 for everything else}/**************************************************************************** SCSI_ATA_FillInfoExcepCtrlModePage* Purpose: Fill the right values for Caching Mode page ****************************************************************************/void SCSI_ATA_FillInfoExcepCtrlModePage(MV_PU8 pBuf, PDomain_Device pDevice,	PMV_Request pReq){	pBuf[0] = 0x1C;		/* Page Code, PS = 0; */	pBuf[1] = 0x0A;		/* Page Length */	pBuf[3] = 0x6;		/* Set MRIE */	// Setting Extended Self-test Completion time	if(!(pDevice->Capacity & DEVICE_CAPACITY_SMART_SUPPORTED))		{		SCSI_ATA_CheckCondition(pReq, SCSI_SK_ILLEGAL_REQUEST, 				SCSI_ASC_INVALID_FEILD_IN_CDB);	}}/**************************************************************************** SCSI_ATA_EnableDisableFeature* Purpose: Enable and disable a certain feature ****************************************************************************/void SCSI_ATA_EnableDisableFeature(		IN PDomain_Port pPort,	IN PDomain_Device pDevice,	IN MV_U8 cdbCoreCmd	){		PCore_Driver_Extension pCore = pPort->Core_Extension;	PMV_Request pReq = GetInternalReqFromPool(pCore);	/* Prepare enable read ahead command */	pReq->Cdb[0] = SCSI_CMD_MARVELL_SPECIFIC;	pReq->Cdb[1] = CDB_CORE_MODULE;	pReq->Cdb[2] = cdbCoreCmd;	pReq->Device_Id = pDevice->Id;	//pReq->Req_Flag;	pReq->Cmd_Initiator = pPort->Core_Extension;	pReq->Data_Transfer_Length = 0;	pReq->Data_Buffer = NULL;	pReq->Completion = (void(*)(MV_PVOID,PMV_Request)) __callback_stud;	/* skip if this is ATAPI device */	if( IS_ATAPI(pDevice) )	{		pReq->Scsi_Status = REQ_STATUS_SUCCESS;		pReq->Completion(pCore, pReq);	}	else	{		/* Send this internal request */		Core_ModuleSendRequest(pCore, pReq);

⌨️ 快捷键说明

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