📄 core_exp.c
字号:
(pReq->Cdb[1] == CDB_CORE_MODULE) && ((pReq->Cdb[2] == CDB_CORE_ENABLE_SMART) || (pReq->Cdb[2] == CDB_CORE_DISABLE_SMART) || (pReq->Cdb[2] == CDB_CORE_SMART_RETURN_STATUS) || (pReq->Cdb[2] == CDB_CORE_OS_SMART_CMD)) ) { // skip SMART commands pReq->Scsi_Status = REQ_STATUS_SUCCESS; return MV_TRUE; }#endif /* CORE_SAS_SUPPORT_ATA_COMMAND */ } if (pDevice && (IS_ATAPI(pDevice)) && (pDevice->Status & DEVICE_STATUS_FUNCTIONAL)) { if( (pReq->Cdb[0] == SCSI_CMD_MARVELL_SPECIFIC) && (pReq->Cdb[1] == CDB_CORE_MODULE) && (pReq->Cdb[2] == CDB_CORE_OS_SMART_CMD)) { // skip SMART commands pReq->Scsi_Status = REQ_STATUS_SUCCESS; return MV_TRUE; } switch (pReq->Cdb[0]) { case SCSI_CMD_MODE_SENSE_6: /* convert to atapi cdb12 */ pReq->Cdb[8] = pReq->Cdb[4]; pReq->Cdb[4] = 0; pReq->Cdb[0] = SCSI_CMD_MODE_SENSE_10; break; default: break; } return MV_FALSE; }#ifdef _OS_LINUX hba_map_sg_to_buffer(pReq);#endif /* _OS_LINUX */ ret = MV_TRUE; switch (pReq->Cdb[0]) { case SCSI_CMD_INQUIRY: mvScsiInquiry(pCore, pReq); break; case SCSI_CMD_READ_CAPACITY_10: mvScsiReadCapacity(pCore, pReq); break; case SCSI_CMD_SYNCHRONIZE_CACHE_10: ret = MV_FALSE; break; case SCSI_CMD_TEST_UNIT_READY: if( pReq->Cmd_Flag & CMD_FLAG_ATA_PASS_THRU ) { ret = MV_FALSE; // ATA PASS THRU CMD break; } case SCSI_CMD_REQUEST_SENSE: case SCSI_CMD_RESERVE_6: /* For Odin, just return good status */ case SCSI_CMD_RELEASE_6: pReq->Scsi_Status = REQ_STATUS_SUCCESS; break; case SCSI_CMD_REPORT_LUN: mvScsiReportLun(pCore, pReq); break; case SCSI_CMD_MODE_SENSE_6: case SCSI_CMD_MODE_SENSE_10: mvScsiModeSense(pCore, pReq); break; case SCSI_CMD_MODE_SELECT_6: case SCSI_CMD_MODE_SELECT_10: ret = mvScsiModeSelect(pCore, pReq); break; #ifdef CORE_SUPPORT_API case APICDB0_PD: ret = Core_pd_command(pCore, pReq); break;# ifdef SUPPORT_PASS_THROUGH_DIRECT case APICDB0_PASS_THRU_CMD_SCSI: case APICDB0_PASS_THRU_CMD_ATA: ret = Core_pass_thru_send_command(pCore, pReq); break;# endif /*SUPPORT_PASS_THROUGH_DIRECT*/# ifdef SUPPORT_CSMI case APICDB0_CSMI_CORE: ret = Core_CSMI_Command(pCore, pReq); break;# endif /* SUPPORT_CSMI */#endif /* CORE_SUPPORT_API */ default: ret = MV_FALSE; }#ifdef _OS_LINUX hba_unmap_sg_to_buffer(pReq);#endif /* _OS_LINUX */ return ret;}void SATA_PrepareCommandHeader(PDomain_Port pPort, PMV_Request pReq, PMV_Command_Header header, MV_U16 SlotNo){ PCore_Driver_Extension pCore; PDomain_Device pDevice = NULL;#ifdef DEBUG_BIOS MV_PU8 pHead; MV_U16 tmp;#endif if (!IS_PM_REQ(pReq)) { pCore = pPort->Core_Extension; pDevice = &pCore->Devices[MapDeviceId(pCore, pReq->Device_Id)]; } /* * Set up the command header. * TBD: Table_Address and Table_Address_High are fixed. Needn't set every time. */ header->FrameLength = MV_CPU_TO_LE16(FIS_REG_H2D_SIZE_IN_DWORD); header->ATAPI = (pReq->Cmd_Flag&CMD_FLAG_PACKET)?1:0; header->Reset = IS_SOFT_RESET_REQ(pReq); header->First_DMA = (pReq->Cmd_Flag&CMD_FLAG_NCQ)?1:0; if (IS_PM_REQ(pReq)) { header->Tag = MV_CPU_TO_LE16(SlotNo); } else { if (pReq->Cmd_Flag & CMD_FLAG_NCQ) header->Tag = MV_CPU_TO_LE16(GetNCQTag(pDevice)); else header->Tag = MV_CPU_TO_LE16(SlotNo); }#ifdef SUPPORT_PM header->PM_Port = (IS_SOFT_RESET_REQ(pReq)) ? pReq->Cdb[3] : ((IS_PM_REQ(pReq) ? 0x0F : pDevice->PM_Number));#else header->PM_Port = 0;#endif #ifdef DEBUG_BIOS pHead=(MV_PU8)header; MV_DUMPC32(pReq->Cmd_Flag); MV_DUMPC32(0xCCCCDDD2); MV_DUMPC32(pPort->Cmd_List_DMA.parts.low); MV_DUMPC32((MV_U32)(*(MV_PU32)&pHead[0])); MV_DUMPC32((MV_U32)(*(MV_PU32)&pHead[1])); MV_DUMPC32((MV_U32)(*(MV_PU32)&pHead[2])); MV_DUMPC32((MV_U32)(*(MV_PU32)&pHead[3]));#endif}/* * Fill SATA command table */MV_VOID SATA_PrepareCommandTable( PDomain_Port pPort, PMV_Request pReq, PMV_Command_Table pCmdTable, PATA_TaskFile pTaskFile ){#ifdef DEBUG_BIOS MV_PU8 pTable;#endif /* Step 1: fill the command FIS: MV_Command_Table */ SCSI_To_FIS(pPort->Core_Extension, pReq, pCmdTable, pTaskFile); /* Step 2. fill the ATAPI CDB - TBD*/ if ( pReq->Cmd_Flag&CMD_FLAG_PACKET ) { MV_CopyMemory(pCmdTable->table.STP_CMD_Table.ATAPI_CDB, pReq->Cdb, MAX_CDB_SIZE); } /* Step 3. Fill in SG table - already done earlier */#ifdef DEBUG_BIOS pTable = (MV_PU8) pPort->Cmd_Table; //MV_DUMPC32(0xCCCCEEE2); //MV_DUMPC16((MV_U16)pTable); //MV_DUMPC32(pPort->Cmd_Table_DMA.parts.low); MV_DUMPC32(0xCCCCEE21); MV_DUMPC32((MV_U32)(*(MV_PU32)&pCmdTable->FIS[0])); MV_DUMPC32(0xCCCCEE22); MV_DUMPC32((MV_U32)(*(MV_PU32)&pCmdTable->FIS[4])); MV_DUMPC32(0xCCCCEE23); MV_DUMPC32((MV_U32)(*(MV_PU32)&pCmdTable->FIS[8])); MV_DUMPC32(0xCCCCEE24); MV_DUMPC32((MV_U32)(*(MV_PU32)&pCmdTable->FIS[12]));#if 1 MV_DUMPC32(0xCCCCEEE3); //MV_DUMPC32((MV_U32)(*(MV_PU32)&pCmdTable->ATAPI_CDB[0])); //MV_DUMPC32((MV_U32)(*(MV_PU32)&pCmdTable->ATAPI_CDB[4])); //MV_DUMPC32((MV_U32)(*(MV_PU32)&pCmdTable->ATAPI_CDB[8])); //MV_DUMPC32((MV_U32)(*(MV_PU32)&pCmdTable->ATAPI_CDB[12])); //MV_DUMPC32(0xCCCCEEE4); //(MV_U32)(*(MV_PU32)&pTable[136]) =(MV_U32) 0; MV_DUMPC32((MV_U32)(*(MV_PU32)&pTable[128])); MV_DUMPC32((MV_U32)(*(MV_PU32)&pTable[132])); MV_DUMPC32((MV_U32)(*(MV_PU32)&pTable[136]));// MV_DUMPC32(pCmdTable->PRD_Entry[0].Size); MV_DUMPC32(0xCCCCEEE5); #ifdef DEBUG_BIOS if((MV_U32)(*(MV_PU32)&pTable[132]) != 0) { MV_DUMPC32(0xCCCC990D); MV_HALTKEY; } #endif //pSGEntry = &pCmdTable->PRD_Entry[0]; //MV_DUMPC32(pSGEntry->Base_Address); //MV_DUMPC32(pSGEntry->Base_Address_High); //MV_DUMPC32(pSGTable->Entry[0].Base_Address); //MV_DUMPC32(pSGTable->Entry[0].Base_Address_High); //MV_DUMPC8(pSGTable->Valid_Entry_Count); //MV_DPRINT("CmdTableAddr=0x%x,CmdTableAddrP=0x%x\n",(MV_U32)(MV_U16)pPort->Cmd_Table,(MV_U32)pPort->Cmd_Table_DMA.parts.low); //MV_DPRINT("CmdBlk0=0x%x,CmdBlk1=0x%x,CmdBlk2=0x%x,CmdBlk3=0x%x," // ,(MV_U32)(*(MV_PU32)&pCmdTable->FIS[0]) // ,(MV_U32)(*(MV_PU32)&pCmdTable->FIS[4]) // ,(MV_U32)(*(MV_PU32)&pCmdTable->FIS[8]) // ,(MV_U32)(*(MV_PU32)&pCmdTable->FIS[12])); //MV_DPRINT("ATAPI0=0x%x,ATAPI1=0x%x,ATAPI2=0x%x,ATAPI3=0x%x\n" // ,(MV_U32)(*(MV_PU32)&pCmdTable->ATAPI_CDB[0]) // ,(MV_U32)(*(MV_PU32)&pCmdTable->ATAPI_CDB[4]) // ,(MV_U32)(*(MV_PU32)&pCmdTable->ATAPI_CDB[8]) // ,(MV_U32)(*(MV_PU32)&pCmdTable->ATAPI_CDB[12])); //MV_DPRINT("SGAddr=0x%x,SGAddrH=0x%x,REV=0x%x,SGCnt=0x%x\n",(MV_U32)(*(MV_PU32)&pTable[128]),(MV_U32)(*(MV_PU32)&pTable[132]),(MV_U32)(*(MV_PU32)&pTable[136]),pCmdTable->PRD_Entry[0].Size);#endif MV_ENTERLINE;#endif}void WriteDELV_Q_Entry(MV_PVOID This, PDELIVERY_QUEUE_ENTRY pDELV_Q_Entry){ MV_U32 tmp; PCore_Driver_Extension pCore = (PCore_Driver_Extension) This; PDELIVERY_QUEUE_ENTRY pDELV_Q_List = (PDELIVERY_QUEUE_ENTRY) pCore->DELV_Q_; MV_LPVOID mmio = pCore->Mmio_Base; MV_CPU_TO_LE32_PTR(pDELV_Q_Entry); pCore->LastDELV_Q++; if (pCore->LastDELV_Q >= pCore->Slot_Count_Supported) pCore->LastDELV_Q = 0; tmp = (MV_U32) (pCore->LastDELV_Q); MV_CopyMemory(&pDELV_Q_List[tmp], pDELV_Q_Entry, sizeof(DELIVERY_QUEUE_ENTRY)); MV_REG_WRITE_DWORD(mmio, COMMON_DELV_Q_WR_PTR, tmp);}void ReadCMPL_QEntry(MV_PVOID This, MV_U16 SlotNo, PCOMPLETION_QUEUE_ENTRY *pCMPL_QEntry){ MV_U32 tmp; PCore_Driver_Extension pCore = (PCore_Driver_Extension)This; PCOMPLETION_QUEUE_ENTRY pCMPL_QList = (PCOMPLETION_QUEUE_ENTRY)pCore->CMPL_Q; COMPLETION_QUEUE_ENTRY entry; *pCMPL_QEntry = NULL; for(tmp=0;tmp<pCore->Slot_Count_Supported;tmp++) { entry = pCMPL_QList[tmp+1]; MV_LE32_TO_CPU_PTR(&entry); if (entry.SLOT_NM == SlotNo) { *pCMPL_QEntry = &pCMPL_QList[tmp+1]; break; } }}void PrepareDeliveryQueueEntry(MV_PVOID This, MV_U16 SlotNo, MV_U8 RegSet, DELIVERY_QUEUE_ENTRY *pDELV_Q_Entry){ struct _Domain_Port *pPort=(struct _Domain_Port *)This; MV_ZeroMemory(pDELV_Q_Entry, sizeof(DELIVERY_QUEUE_ENTRY)); pDELV_Q_Entry->SLOT_NM = SlotNo; pDELV_Q_Entry->PHY = pPort->MemberPhyMap; /* from Phy 0 */ pDELV_Q_Entry->CMD = (pPort->Type&PORT_TYPE_SAS)?CMD_SSP:CMD_STP; pDELV_Q_Entry->MODE = 1; /* Initiator */ pDELV_Q_Entry->PRIORITY = 0; /* Normal */ if( pPort->Type&PORT_TYPE_SATA ) pDELV_Q_Entry->SATA_REG_SET = RegSet;}MV_BOOLEANVerifyCommandBeforeSending( IN PCore_Driver_Extension pCore, IN PMV_Request pReq, OUT MV_QUEUE_COMMAND_RESULT * pCommandRet ){ struct _Domain_Port *pPort; struct _Domain_Device *pDevice = NULL; struct _Domain_Expander *pTgt = NULL; MV_U16 deviceId; MV_U8 portId; PMV_Request pOrgReq; MV_U16 Tag = 0;#ifdef CORE_SAS_SUPPORT_ATA_COMMAND MV_BOOLEAN orgWriteCache, orgPreread;#endif#ifdef SUPPORT_LARGE_REQUEST /* SG Buffer needed for sub MV_Request */ sgSize = sizeof(MV_SG_Entry) * sgEntryCount; tmpSG = temp; temp = temp + sgSize * subReqCount; /* sense buffer for sub MV_Request */ pSenseBuffer = (PMV_Sense_Data)temp; temp = temp + sizeof(MV_Sense_Data) * subReqCount; /* sub MV_Request */ for ( i=0; i<subReqCount; i++ ) { pReq = (PMV_Request)temp; pReq->SG_Table.Entry_Ptr = (PMV_SG_Entry)tmpSG; pReq->SG_Table.Max_Entry_Count = sgEntryCount; pReq->Sense_Info_Buffer = pSenseBuffer; pReq->Sense_Info_Buffer_Length = sizeof(MV_Sense_Data); List_AddTail(&pReq->Queue_Pointer, &pCore->Sub_Req_List); tmpSG += sgSize; temp += MV_REQUEST_SIZE; pSenseBuffer ++; } pCore->Sub_Req_Count = subReqCount;#endif if (IS_PM_REQ(pReq)) { pReq->Cmd_Flag |= CMD_FLAG_DATA_IN; return MV_FALSE; } if( IS_A_SMP_REQ(pReq) ) { portId = MapPortId(pCore, pReq->Device_Id); pPort=&pCore->Ports[MapPortEntry(pCore,portId)]; pTgt=&pCore->Expanders[MapDeviceId(pCore, pReq->Device_Id)]; if ( !pTgt->SMP_TRGT ) { pReq->Scsi_Status = REQ_STATUS_INVALID_REQUEST; *pCommandRet = MV_QUEUE_COMMAND_RESULT_FINISHED; return MV_TRUE; } } else { portId = MapPortId(pCore, pReq->Device_Id); deviceId = MapDeviceId(pCore, pReq->Device_Id); pPort=&pCore->Ports[MapPortEntry(pCore,portId)]; pDevice= &pCore->Devices[deviceId]; if (!IS_SOFT_RESET_REQ(pReq) && ((deviceId==ID_NOT_MAPPED)||(!(pDevice->Status&DEVICE_STATUS_FUNCTIONAL))) ) { pReq->Scsi_Status = REQ_STATUS_NO_DEVICE; *pCommandRet = MV_QUEUE_COMMAND_RESULT_FINISHED; return MV_TRUE; } } /* Set the Cmd_Flag to indicate which type of commmand it is. */ if( (pDevice != NULL) && IS_STP_OR_SATA(pDevice) ) { if ( !Category_CDB_Type(pDevice, pReq) ) { pReq->Scsi_Status = REQ_STATUS_INVALID_REQUEST; /* Invalid request and can be returned to OS now. */ *pCommandRet = MV_QUEUE_COMMAND_RESULT_FINISHED; return MV_TRUE; } if (pDevice->Outstanding_Req >= 32) { *pCommandRet = MV_QUEUE_COMMAND_RESULT_FULL; return MV_TRUE; } // make sure there is only one request running on the ATAPI device or timer could get messed up if( IS_ATAPI(pDevice) && pDevice->Outstanding_Req > 0 ) { *pCommandRet = MV_QUEUE_COMMAND_RESULT_FULL; return MV_TRUE; } if ( ( (pReq->Cmd_Flag&CMD_FLAG_NCQ) && !(pPort->Setting&PORT_SETTING_NCQ_RUNNING) ) || ( !(pReq->Cmd_Flag&CMD_FLAG_NCQ) && (pPort->Setting&PORT_SETTING_NCQ_RUNNING) ) || (pReq->Scsi_Status==REQ_STATUS_RETRY) || (pPort->Setting&PORT_SETTING_DURING_RETRY) ) { if ( Port_IsRequestRunning(pCore, portId) ) { *pCommandRet = MV_QUEUE_COMMAND_RESULT_FULL; return MV_TRUE; } } if((pReq->Cmd_Flag&CMD_FLAG_NCQ)&&(pPort->Setting&PORT_SETTING_NCQ_RUNNING)&&(GetNCQTag(pDevice)>=32)) { MV_PRINT("NCQ TAG is run out\n"); *pCommandRet = MV_QUEUE_COMMAND_RESULT_FULL; return MV_TRUE; } } else { if ((pPort->Type&PORT_TYPE_SAS) && (!IS_A_SMP_REQ(pReq))) { if (((IS_TAPE(pDevice)) && pDevice->Outstanding_Req > 0 ) || (pDevice->Outstanding_Req >= pDevice->Queue_Depth) ) { *pCommandRet = MV_QUEUE_COMMAND_RESULT_FULL; return MV_TRUE; } } /* SSP also needs finish MODULE special commands. */ #ifndef CORE_SAS_SUPPORT_ATA_COMMAND if( (pReq->Cdb[0]==SCSI_CMD_MARVELL_SPECIFIC )&& (pReq->Cdb[1]==CDB_CORE_MODULE)&& (pReq->Cdb[2]==CDB_CORE_SHUTDOWN) ) { pReq->Scsi_Status = REQ_STATUS_INVALID_REQUEST; /* Invalid request and can be returned to OS now. */ *pCommandRet = MV_QUEUE_COMMAND_RESULT_FINISHED; return MV_TRUE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -