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 + -
显示快捷键?