📄 core_api.c
字号:
} } else { status = ERR_INVALID_REQUEST; } } if (status == REQ_STATUS_SUCCESS) { // Convert it into SCSI_CMD_MARVELL_SPECIFIC request. pMvReq->Cdb[0] = SCSI_CMD_MARVELL_SPECIFIC; pMvReq->Cdb[1] = CDB_CORE_MODULE; pMvReq->Cdb[2] = cacheMode; pMvReq->Device_Id = pDevice->Id; } } else { status = ERR_INVALID_HD_ID; } if (status != REQ_STATUS_SUCCESS) { if (pMvReq->Sense_Info_Buffer != NULL) ((MV_PU8)pMvReq->Sense_Info_Buffer)[0] = status; pMvReq->Scsi_Status = REQ_STATUS_ERROR_WITH_SENSE; return MV_TRUE; } else { pMvReq->Scsi_Status = REQ_STATUS_SUCCESS; return MV_FALSE; // Need to access hardware. }}MV_BOOLEAN core_pd_request_BSL_dump( PCore_Driver_Extension pCore, PMV_Request pMvReq ){ // TBD pMvReq->Scsi_Status = REQ_STATUS_ERROR; return MV_TRUE;}#endif /* #ifndef BIOS_NOT_SUPPORT */CORE_Management_Command_Handler BASEATTR core_pd_cmd_handler[APICDB1_PD_MAX] = { core_pd_request_get_HD_info, core_pd_request_get_expander_info,#ifdef SUPPORT_PM core_pd_request_get_PM_info,#endif#ifndef BIOS_NOT_SUPPORT core_pd_request_get_HD_config, core_pd_request_set_HD_config, core_pd_request_BSL_dump, NULL, NULL, core_pd_request_get_HD_status, core_pd_request_get_HD_info_ext#else NULL, NULL, NULL, NULL, NULL, NULL, NULL#endif};MV_BOOLEAN Core_pd_command( IN MV_PVOID extension, IN PMV_Request pReq ){ PCore_Driver_Extension pCore = (PCore_Driver_Extension)extension; if ( pReq->Cdb[1] >= APICDB1_PD_MAX ) { pReq->Scsi_Status = REQ_STATUS_INVALID_PARAMETER; return MV_TRUE; } if (core_pd_cmd_handler[pReq->Cdb[1]] == NULL) { pReq->Scsi_Status = REQ_STATUS_INVALID_PARAMETER; return MV_TRUE; } return core_pd_cmd_handler[pReq->Cdb[1]](pCore, pReq);}#if defined(SUPPORT_CSMI)MV_BOOLEAN Core_CSMI_Request_FirmwareDownload( PCore_Driver_Extension pCore, PMV_Request pMvReq ){ PCSMI_SAS_FIRMWARE_DOWNLOAD pcsmiFwDl = (PCSMI_SAS_FIRMWARE_DOWNLOAD)pMvReq->Data_Buffer; AdapterInfo AI; MV_U32 i, tmp; MV_U8 *pImage = (MV_U8*)&pcsmiFwDl[1]; AI.bar[2] = pCore->Base_Address[2]; if( -1==OdinSPI_Init( &AI ) ) return MV_FALSE; if( -1==OdinSPI_ChipErase( &AI ) ) return MV_FALSE; for( i=0; i<pcsmiFwDl->uBufferLength; i+=4 ) { if( -1 == OdinSPI_Write( &AI, i, *(MV_U32*)&pImage[i] ) ) { MV_DPRINT( ( "Write failed at %5.5lX\n", (unsigned long) i ) ); pMvReq->Scsi_Status = REQ_STATUS_ERROR; return MV_FALSE; } } for( i=0; i<pcsmiFwDl->uBufferLength; i+=4 ) { if( -1 == OdinSPI_Read( &AI, i, (MV_U8*)&tmp, 4 )|| tmp != *(MV_U32*)&pImage[i] ) { MV_DPRINT( ( "Verify failed at %5.5lX\n", (unsigned long) i ) ); pMvReq->Scsi_Status = REQ_STATUS_ERROR; return MV_FALSE; } } pMvReq->Scsi_Status = REQ_STATUS_SUCCESS; pMvReq->Completion(pMvReq->Cmd_Initiator, pMvReq); return MV_TRUE;}void Core_CSMI_SMPRequest_ReportGeneral( IN MV_PVOID pUpperReq, IN PDomain_Port pPort, IN PDomain_Expander pExpander );void Core_CSMI_SMPRequest_Discover( IN MV_PVOID pUpperReq, IN PDomain_Port pPort, IN PDomain_Expander pExpander, IN MV_U8 PhyId );void Core_CSMI_SMPRequest_PhyControl( IN PMV_Request pOrgReq, IN PDomain_Port pPort, IN PDomain_Expander pTgt, IN MV_U8 PhyId );void Core_CSMI_Device_MakeRequestTask( IN PCore_Driver_Extension pCore, IN PMV_Request pOrgReq );MV_BOOLEAN Core_CSMI_Command( IN MV_PVOID extension, IN PMV_Request pReq ){ PCore_Driver_Extension pCore = (PCore_Driver_Extension)extension; switch( pReq->Cdb[1] ) { /* FIXME : this constant is TOO large in linux */ case (CC_CSMI_SAS_FIRMWARE_DOWNLOAD & 0xFF): { return Core_CSMI_Request_FirmwareDownload(pCore, pReq); } case (CC_CSMI_SAS_SMP_PASSTHRU & 0xFF): { MV_U8 portId = MapPortId(pCore, pReq->Device_Id); MV_U8 tgtId = (MV_U8)pReq->Device_Id; PDomain_Port pPort = &pCore->Ports[MapPortEntry(pCore,portId)]; PDomain_Expander pExpander = &pCore->Expanders[MapDeviceId(pCore, pReq->Device_Id)]; if (!((portId < MAX_PORT_ID) && (portId != ID_NOT_MAPPED) && (tgtId < pCore->Expander_Count_Supported+MIN_EXPANDER_ID) && (tgtId != ID_NOT_MAPPED))){ return MV_FALSE; } if(pReq->Cdb[2] == REPORT_GENERAL){ Core_CSMI_SMPRequest_ReportGeneral((MV_PVOID)pReq, pPort, pExpander); return MV_TRUE; } else if((pReq->Cdb[2] == DISCOVER)||(pReq->Cdb[2] == PHY_CONTROL)){ MV_U8 i; for(i=0;i<MAX_PHY_NUM;i++){ if(&pCore->Phy[i] == pPort->pPhy){ break; } } if(i >= MAX_PHY_NUM) return MV_FALSE; if(pReq->Cdb[2] == DISCOVER) Core_CSMI_SMPRequest_Discover((MV_PVOID)pReq, pPort, pExpander, i); else//PHY_CONTROL Core_CSMI_SMPRequest_PhyControl((MV_PVOID)pReq, pPort, pExpander, i); return MV_TRUE; } } case (CC_CSMI_SAS_TASK_MANAGEMENT & 0xFF): { Core_CSMI_Device_MakeRequestTask(pCore,pReq); return MV_TRUE; } case (CC_CSMI_SAS_PHY_CONTROL & 0xFF): case (CC_CSMI_SAS_SET_PHY_INFO & 0xFF): { MV_U8 portId = MapPortId(pCore, pReq->Device_Id); MV_U8 tgtId = (MV_U8)pReq->Device_Id; PDomain_Port pPort = &pCore->Ports[MapPortEntry(pCore,portId)]; PDomain_Expander pExpander = &pCore->Expanders[MapDeviceId(pCore, pReq->Device_Id)]; if (!((portId < MAX_PORT_ID) && (portId != ID_NOT_MAPPED) && (tgtId < pCore->Expander_Count_Supported+MIN_EXPANDER_ID) && (tgtId != ID_NOT_MAPPED))){ return MV_FALSE; } { MV_U8 i; for(i=0;i<MAX_PHY_NUM;i++){ if(&pCore->Phy[i] == pPort->pPhy){ break; } } if(i >= MAX_PHY_NUM) return MV_FALSE; Core_CSMI_SMPRequest_PhyControl((MV_PVOID)pReq, pPort, pExpander, i); } return MV_TRUE; }#if 0 case (CC_CSMI_SAS_SSP_PASSTHRU & 0xFF): { PCore_Driver_Extension pCore = pDevice->pPort->Core_Extension; PMV_Request pReq = GetInternalReqFromPool(pCore); PSATA_Scratch_Buffer pSATASB; PMV_SG_Table pSGTable; if( pReq == NULL ) { // no internal requests available - wait for now pDevice->Is_Waiting = MV_TRUE; return; } pSATASB = GetSATAScratchFromPool(pCore); if( pSATASB == NULL ) { FreeInternalReqToPool(pCore, pReq); MV_DPRINT(("ERROR: No more free SATA scratch buffer. Request aborted.\n")); return; } pSGTable = &pReq->SG_Table; /* Prepare read capacity */ pReq->Cdb[0] = SCSI_CMD_READ_CAPACITY_10; pReq->Tag = 0xab; pReq->Device_Id = pDevice->Id; //pReq->Req_Flag; pReq->Cmd_Initiator = pCore; pReq->Data_Transfer_Length = 8; pReq->Cmd_Flag = CMD_FLAG_DATA_IN; pReq->Data_Buffer = pSATASB->Scratch_Vir; pReq->Sense_Info_Buffer =(MV_PVOID)( (MV_PTR_INTEGER)pReq->Data_Buffer+pReq->Data_Transfer_Length); pReq->Sense_Info_Buffer_Length = 0x24; pReq->Scratch_Buffer = pSATASB; pReq->Completion = (void(*)(MV_PVOID,PMV_Request))SAS_InternalReqCallback; /* Make the SG table. */ SGTable_Init(pSGTable, 0); SGTable_Append( pSGTable, pSATASB->Scratch_DMA.parts.low, pSATASB->Scratch_DMA.parts.high, 8 ); /* Send this internal request */ Core_ModuleSendRequest(pCore, pReq); return MV_TRUE; }#endif default: break; } pReq->Scsi_Status = REQ_STATUS_INVALID_PARAMETER; return MV_TRUE;}#endif#ifdef SUPPORT_PASS_THROUGH_DIRECTPPassThorugh_Config pConfig;MV_U32 Data_Length;void Core_pass_thru_remove_CDB_header( IN PMV_Request pReq ){ int i = 0; for( i=0; i<MAX_CDB_SIZE; i++) { if( i < 12){ pReq->Cdb[i] = pReq->Cdb[i+4]; } else { // Zero the last 4 cdb slots pReq->Cdb[i] = 0; } }}MV_U32 Core_pass_thru_cal_correct_length ( MV_U32 length){ if( length & 0x80000000) return (0xFFFFFFFF - length )+2; else return 0;}voidCore_pass_thru_callback( MV_PVOID This, PMV_Request pReq){ PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK)pReq->Org_Req; PHBA_Extension pHBA = (PHBA_Extension)This; PModule_Manage module_manage = &pHBA->Module_Manage; PCore_Driver_Extension pCore = (PCore_Driver_Extension)module_manage->resource[MODULE_CORE].module_extension; MV_U32 length; MV_U32 reg[3]; MV_U16 deviceId; MV_U8 testsize; if( pReq->Scsi_Status == REQ_STATUS_PENDING ) { return; } // SCSI Pass Through if( pReq->Cmd_Flag & CMD_FLAG_SCSI_PASS_THRU ) { if( pReq->Cdb[0] == SCSI_CMD_READ_LONG_10 ) { // copy result data back into PassThrough_Config Struct MV_CopyMemory(pConfig->Data_Buffer, pReq->Data_Buffer, Data_Length); // return pReq->Data_Buffer pointer to pConfig pReq->Data_Buffer = pConfig; ((MV_PU8)pReq->Sense_Info_Buffer)[0] = 0; // Find the sense buffer return info length = (((MV_PU8)pReq->Sense_Info_Buffer)[3] << 24)| (((MV_PU8)pReq->Sense_Info_Buffer)[4] << 16)| (((MV_PU8)pReq->Sense_Info_Buffer)[5] << 8)| ((MV_PU8)pReq->Sense_Info_Buffer)[6]; // Calculate the correct length for ECC if( ((MV_PU8)pReq->Sense_Info_Buffer)[2] == 0x25 ) { length = Core_pass_thru_cal_correct_length(length); pConfig->Data_Length= length; goto HBACallback; } } MV_CopyMemory(Srb->DataBuffer, pReq->Data_Buffer, Data_Length); } // ATA Pass Through if( pReq->Cmd_Flag & CMD_FLAG_ATA_PASS_THRU ) { reg[0] = MV_REG_READ_DWORD( pCore->RX_FIS, SATA_RECEIVED_D2H_FIS(pReq->Cdb[15]) ); reg[1] = MV_REG_READ_DWORD( pCore->RX_FIS, (SATA_RECEIVED_D2H_FIS(pReq->Cdb[15]+4)) ); reg[2] = MV_REG_READ_DWORD( pCore->RX_FIS, (SATA_RECEIVED_D2H_FIS(pReq->Cdb[15]+8)) ); testsize = sizeof(reg); MV_CopyMemory(((MV_PU8)(pReq->Data_Buffer)+pReq->Data_Transfer_Length-sizeof(reg)), reg, sizeof(reg)); MV_CopyMemory(Srb->DataBuffer, pReq->Data_Buffer, pReq->Data_Transfer_Length); }HBACallback: HBARequestCallback(This, pReq);}voidCore_pass_thru_send_SCSI_command( IN PCore_Driver_Extension pCore, IN PMV_Request pReq){ PSATA_Scratch_Buffer pSATASB; PMV_SG_Table pSGTable; MV_U32 lengthLocation; if( pReq == NULL ) { return; } pConfig = (PPassThorugh_Config)pReq->Data_Buffer; pSATASB = GetSATAScratchFromPool(pCore); if( pSATASB == NULL ) { FreeInternalReqToPool(pCore, pReq); MV_DPRINT(("ERROR: No more free SATA scratch buffer. Request aborted.\n")); return; } pSGTable = &pReq->SG_Table; if( pReq->Data_Transfer_Length< MAX_PASS_THRU_DATA_BUFFER_SIZE ) { // from SCSI commander application Data_Length = pReq->Data_Transfer_Length; } else { // from CLI application Data_Length = pConfig->Data_Length; } switch( pReq->Cdb[1] ) { case APICDB1_SCSI_NON_DATA: pReq->Cmd_Flag = CMD_FLAG_NON_DATA; break; case APICDB1_SCSI_PIO_IN: pReq->Cmd_Flag = CMD_FLAG_PIO | CMD_FLAG_DATA_IN; pReq->Data_Buffer= pSATASB->Scratch_Vir; break; case APICDB1_SCSI_PIO_OUT: pReq->Cmd_Flag = CMD_FLAG_PIO | CMD_FLAG_DATA_OUT; MV_CopyMemory( pSATASB->Scratch_Vir, pReq->Data_Buffer, Data_Length); break; default: break; } pReq->Cmd_Flag |= CMD_FLAG_SCSI_PASS_THRU; pReq->Device_Id = (pReq->Cdb[2]<<8)|pReq->Cdb[3]; // targetID Core_pass_thru_remove_CDB_header( pReq ); pReq->Scsi_Status = REQ_STATUS_PENDING; pReq->Completion = Core_pass_thru_callback; SGTable_Init(pSGTable, 0); SGTable_Append( pSGTable, pSATASB->Scratch_DMA.parts.low, pSATASB->Scratch_DMA.parts.high, pReq->Data_Transfer_Length ); /* Send this internal request */ Core_ModuleSendRequest(pCore, pReq);}voidCore_pass_thru_send_ATA_command( IN PCore_Driver_Extension pCore, IN PMV_Request pReq){ PSATA_Scratch_Buffer pSATASB = GetSATAScratchFromPool(pCore); PMV_SG_Table pSGTable; MV_U32 length; pSGTable = &pReq->SG_Table; switch( pReq->Cdb[1] ) { case APICDB1_ATA_NON_DATA: pReq->Cmd_Flag = CMD_FLAG_NON_DATA; break; case APICDB1_ATA_PIO_IN: pReq->Cmd_Flag = CMD_FLAG_PIO | CMD_FLAG_DATA_IN; break; case APICDB1_ATA_PIO_OUT: pReq->Cmd_Flag = CMD_FLAG_PIO | CMD_FLAG_DATA_OUT; break; default: break; } pReq->Cmd_Flag |= CMD_FLAG_ATA_PASS_THRU; pReq->Device_Id = (pReq->Cdb[2]<<8)|pReq->Cdb[3]; // targetID Core_pass_thru_remove_CDB_header( pReq ); pReq->Scsi_Status = REQ_STATUS_PENDING; pReq->Data_Buffer = pSATASB->Scratch_Vir; pReq->Scratch_Buffer = pSATASB; pReq->Completion = Core_pass_thru_callback; SGTable_Init(pSGTable, 0); SGTable_Append( pSGTable, pSATASB->Scratch_DMA.parts.low, pSATASB->Scratch_DMA.parts.high, pReq->Data_Transfer_Length ); /* Send this internal request */ Core_ModuleSendRequest(pCore, pReq);}MV_BOOLEANCore_pass_thru_fill_taskfile( IN PMV_Request pReq, OUT PATA_TaskFile pTaskFile ){ MV_ZeroMemory(pTaskFile, sizeof(ATA_TaskFile)); pTaskFile->Features = pReq->Cdb[0]; pTaskFile->Sector_Count = pReq->Cdb[1]; pTaskFile->LBA_Low = pReq->Cdb[2]; pTaskFile->LBA_Mid = pReq->Cdb[3]; pTaskFile->LBA_High = pReq->Cdb[4]; pTaskFile->Device = pReq->Cdb[5]; pTaskFile->Command = pReq->Cdb[6]; if( pReq->Cmd_Flag & CMD_FLAG_48BIT ) { pTaskFile->Feature_Exp = pReq->Cdb[7]; pTaskFile->Sector_Count_Exp = pReq->Cdb[8]; pTaskFile->LBA_Low_Exp = pReq->Cdb[9]; pTaskFile->LBA_Mid_Exp = pReq->Cdb[10]; pTaskFile->LBA_High_Exp = pReq->Cdb[11]; } return MV_TRUE;}MV_BOOLEANCore_pass_thru_send_command( IN PCore_Driver_Extension pCore, IN PMV_Request pReq ){ MV_BOOLEAN status = MV_FALSE; switch(pReq->Cdb[0]) { case APICDB0_PASS_THRU_CMD_SCSI: Core_pass_thru_send_SCSI_command( pCore, pReq ); status = MV_TRUE; break; case APICDB0_PASS_THRU_CMD_ATA: Core_pass_thru_send_ATA_command( pCore, pReq ); status = MV_TRUE; break; default: pReq->Scsi_Status = REQ_STATUS_INVALID_PARAMETER; status = MV_FALSE; break; } return status;}#else /* SUPPORT_PASS_THROUGH_DIRECT */MV_BOOLEAN Core_pass_thru_fill_taskfile(IN PMV_Request pReq, OUT PATA_TaskFile pTaskFile){ return MV_TRUE;}#endif /* SUPPORT_PASS_THROUGH_DIRECT */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -