📄 core_init.c
字号:
PDomain_Port pPort = pDevice->pPort; MV_U32 loop;#ifdef SUPPORT_PM PDomain_PM pPM;#endif /* prevent running recursive state machine like hotplug */ if(pCore->Device_Map[pDevice->Id] == ID_NOT_MAPPED) return MV_FALSE; switch ( pDevice->State ) { /* this state is for serial state machine (hibernation) - we must start from here if PM has not been initialized the first time due to no resource */ case DEVICE_STATE_PM_SOFTRESET: MV_DPRINT(("Device %d DEVICE_STATE_PM_SOFTRESET.\n", pDevice->Id)); /* To do first FIS of soft reset */ Device_IssueSoftReset( pDevice->pPort, pDevice, MV_TRUE, MV_TRUE); HBA_SleepMicrosecond(pCore, 5); break; case DEVICE_STATE_SRST_1: MV_DPRINT(("Device %d DEVICE_STATE_SRST_1.\n", pDevice->Id)); /* To do first FIS of soft reset */ Device_IssueSoftReset( pDevice->pPort, pDevice, MV_TRUE, MV_FALSE); HBA_SleepMicrosecond(pCore, 5); break; case DEVICE_STATE_SRST_0: MV_DPRINT(("Device %d DEVICE_STATE_SRST_0.\n", pDevice->Id)); #if 0 /* Disable Command Complete Interrupt Make sure after SoftReset will get signature interrupt */ tmp = MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_IRQ_MASK); tmp &= ~INT_CMD_CMPL; MV_REG_WRITE_DWORD(pCore->Mmio_Base, COMMON_IRQ_MASK, tmp); #endif /* To do second FIS of soft reset */ Device_IssueSoftReset( pDevice->pPort, pDevice, MV_FALSE, MV_FALSE); //Must have to avoid command active didn't clear when issuing identify. HBA_SleepMillisecond(pCore, 50); break; case DEVICE_STATE_RESET_DONE: #if 0 /* Enable Command Complete Interrupt */ tmp = MV_REG_READ_DWORD(pCore->Mmio_Base, COMMON_IRQ_MASK); tmp |= INT_CMD_CMPL; MV_REG_WRITE_DWORD(pCore->Mmio_Base, COMMON_IRQ_MASK, tmp); #endif MV_DPRINT(("Device %d DEVICE_STATE_RESET_DONE.\n", pDevice->Id)); //Must have to avoid command active didn't clear when issuing identify. for(i=0;i<pCore->Phy_Num;i++) { if(pPort->MemberPhyMap&MV_BIT(i)) break; } if (!IS_STP(pDevice)) { loop = 10000; while( loop > 0 ) { if (mv_is_sig_fis_received(pCore->Mmio_Base, i)) { MV_DPRINT(("SoftReset: got signature FIS\n")); break; } HBA_SleepMillisecond(pCore, 1); loop--; } if (loop == 0) MV_DPRINT(("SoftReset: signature FIS not received after 10 sec\n")); } /* SATA_PortDeviceReady() doesn't apply to STP */ if( (pPort->Type&PORT_TYPE_SATA)&&(!SATA_PortDeviceReady(pPort, pDevice)) ) { //Have device but not ready. #ifdef SUPPORT_PM loop = 5000; while ( loop>0 ) { if ( SATA_PortDeviceReady(pPort, pDevice) ) { MV_DPRINT(("Device %d is ready after %d millisecond.\n", pDevice->Id, 5000-loop)); break; } HBA_SleepMillisecond(pCore, 1); loop--; if ( loop==0 ) MV_DPRINT(("Device %d not ready\n", pDevice->Id)); }#else /* SUPPORT_PM */ MV_DPRINT(("Device %d not ready\n", pDevice->Id));#endif /* SUPPORT_PM */ } /* To do identify */ Device_IssueIdentify( pDevice->pPort, pDevice); break; case DEVICE_STATE_IDENTIFY_DONE: MV_DPRINT(("Device %d DEVICE_STATE_IDENTIFY_DONE.\n", pDevice->Id)); /* set PIO mode before UDMA mode - ATAPI */ Device_IssueSetPIOMode( pDevice->pPort, pDevice ); break; case DEVICE_STATE_SET_PIO_DONE: MV_DPRINT(("Device %d DEVICE_STATE_SET_PIO_DONE.\n", pDevice->Id)); /* To do set UDMA mode */ Device_IssueSetUDMAMode( pDevice->pPort, pDevice ); break; case DEVICE_STATE_SET_UDMA_DONE: MV_DPRINT(("Device %d DEVICE_STATE_SET_UDMA_DONE.\n", pDevice->Id)); /* To do enable write cache */ Device_EnableWriteCache( pDevice->pPort, pDevice ); break; case DEVICE_STATE_ENABLE_WRITE_CACHE_DONE: MV_DPRINT(("Device %d DEVICE_STATE_ENABLE_WRITE_CACHE_DONE.\n", pDevice->Id)); /* To do enable read ahead */ Device_EnableReadAhead( pDevice->pPort, pDevice ); break; case DEVICE_STATE_ENABLE_READ_AHEAD_DONE: MV_DPRINT(("Device %d DEVICE_STATE_ENABLE_READ_AHEAD_DONE.\n", pDevice->Id)); /* Initialization procedure is done. */ pDevice->State = DEVICE_STATE_INIT_DONE; /* No break here. */ case DEVICE_STATE_INIT_DONE: MV_DPRINT(("Device %d DEVICE_STATE_INIT_DONE.\n", pDevice->Id)); if(!IS_STP(pDevice)) pDevice->NegotiatedLinkRate = GetMinNegotiatedLinkRate(pPort);/* reminder: STP shares this state machine, please do not change *//* pPort->Device_Number pPort->Device_List, etc. *//* ref: wrong timer/outstanding_req/sent_req problem with expander*/ if( pPort->Setting & PORT_SETTING_PM_EXISTING ) {#ifdef SUPPORT_PM pPM = pPort->pPM; MV_PRINT("pPM->CheckedPort = %d, pPM->NumberOfPorts = %d\n", pPM->CheckedPort, pPM->NumberOfPorts); /* PM device is initialized sequentially Only initialiezed device will be added to Port */ pPort->Device_Number++; List_AddTail(&pDevice->Queue_Pointer, &pPort->Device_List); if (pPM->CheckedPort < (pPM->NumberOfPorts - 1)) { pPM->CheckedPort++; pPM->ActPortNumber++; pPM->State = PM_STATE_IDLE; pPM->Status &= ~PM_STATUS_INITIATING; pPM->Status |= PM_STATUS_DEVICES_INITIATING; SATA_PMStateMachine(pCore, pPM); } else { for( i=0; i<pPort->Device_Number; i++ ) { pDevice = (PDomain_Device)List_GetFirstEntry(&pPort->Device_List, Domain_Device, Queue_Pointer); List_AddTail( &pDevice->Queue_Pointer, &pPort->Device_List ); if( pDevice->State != DEVICE_STATE_INIT_DONE ) { // if this device is waiting, try sending request again if( pDevice->Is_Waiting ) { if( IS_STP_OR_SATA(pDevice) ) SATA_DeviceStateMachine( pCore, pDevice ); else if( IS_SSP(pDevice) ) SAS_DeviceStateMachine( pCore, pDevice ); } return MV_TRUE; } else pDevice->Is_Waiting = MV_FALSE; } if ((pPM->Status & PM_STATUS_GSCR_CHANGE) && (pPM->PlugStatus & (PM_DEVICE_PLUG_IN | PM_DEVICE_PLUG_OUT))) { pPM->State = PM_STATE_IDLE; SATA_PMStateMachine(pCore, pPM); } else { pPort->Port_State = PORT_STATE_INIT_DONE; pPM->State = PM_STATE_IDLE; pPM->Status &= ~(PM_STATUS_DEVICES_INITIATING | PM_STATUS_RESET); pPM->Status |= PM_STATUS_STARTED; pPM->PlugStatus &= ~(PM_DEVICE_PLUG_IN); mvChannelStateMachine(pCore, pPort); } }#endif } else { for( i=0; i<pPort->Device_Number; i++ ) { pDevice = (PDomain_Device)List_GetFirstEntry(&pPort->Device_List, Domain_Device, Queue_Pointer); List_AddTail( &pDevice->Queue_Pointer, &pPort->Device_List ); if( pDevice->State != DEVICE_STATE_INIT_DONE ) { // if this device is waiting, try sending request again if( pDevice->Is_Waiting ) { if( IS_STP_OR_SATA(pDevice) ) SATA_DeviceStateMachine( pCore, pDevice ); else if( IS_SSP(pDevice) ) SAS_DeviceStateMachine( pCore, pDevice ); } return MV_TRUE; } else pDevice->Is_Waiting = MV_FALSE; } pPort->Port_State = PORT_STATE_INIT_DONE; mvChannelStateMachine(pCore, pPort); } break; default: break; } return MV_TRUE;}#ifdef SUPPORT_PMMV_VOID mvTimer2WaitPHYReady( IN OUT MV_PVOID This, IN MV_PVOID temp ){ PDomain_PM pPM = (PDomain_PM)This; PDomain_Port pPort=pPM->pPort; PCore_Driver_Extension pCore = (PCore_Driver_Extension)pPort->Core_Extension; MV_DPRINT(("PM %d mvTimer2WaitPHYReady Timeout callback!\n", pPM->Id)); pPM->State = PM_STATE_PORT_SPIN_UP_DEVICE_DONE; SATA_PMStateMachine(pCore, pPM);}MV_BOOLEAN SATA_PMStateMachine( PCore_Driver_Extension pCore, PDomain_PM pPM ){ MV_LPVOID mmio = pCore->Mmio_Base; PDomain_Port pPort = pPM->pPort; PDomain_Device pDevice= NULL; MV_U32 temp; switch ( pPM->State ) { case PM_STATE_IDLE: MV_DPRINT(("PM %d PM_STATE_IDLE\n", pPM->Id)); if (pPM->Status & PM_STATUS_RESET) { pPM->Status = PM_STATUS_INITIATING; pPM->State = PM_STATE_INIT; } else if (pPM->Status == PM_STATUS_DEVICE_HOTPLUG) { pPM->Status &= ~PM_STATUS_DEVICE_HOTPLUG; pPM->Status |= PM_STATUS_DEVICES_INITIATING; pPM->State = PM_STATE_CHECK_HOTPLUG; } else if ((pPM->Status & PM_STATUS_GSCR_CHANGE) &&(pPM->PlugStatus & (PM_DEVICE_PLUG_IN | PM_DEVICE_PLUG_OUT))) { pPM->Status &= ~PM_STATUS_GSCR_CHANGE; pPM->Status |= PM_STATUS_DEVICES_INITIATING; pPM->State = PM_STATE_CHECK_HOTPLUG; } else if (pPM->Status & PM_STATUS_DEVICES_INITIATING) pPM->State = PM_STATE_PORT_ENABLE_1; SATA_PMStateMachine(pCore, pPM); break; case PM_STATE_INIT: MV_DPRINT(("PM %d PM_STATE_INIT\n", pPM->Id)); MV_DPRINT(("pPM->Status = 0x%X\n", pPM->Status)); /* Enable FIS Receive - for PM read/write requests Enable SATA retry - for PM read/write requests */ // TBD: Do we need to enable it for any other purposes? temp = MV_REG_READ_DWORD( mmio, COMMON_CONTROL ); MV_REG_WRITE_DWORD( mmio, COMMON_CONTROL, temp | FIS_RCV_EN | EN_SATA_RETRY); PM_IssueReadReg(pPM, MV_TRUE, MV_SATA_GSCR_INFO_REG_NUM, MV_TRUE); break; case PM_STATE_READ_INFO_DONE: MV_DPRINT(("PM %d PM_READ_INFO_DONE\n", pPM->Id)); PM_IssueReadReg(pPM, MV_TRUE, MV_SATA_GSCR_ID_REG_NUM, MV_TRUE); break; case PM_STATE_READ_ID_DONE: MV_DPRINT(("PM %d PM_READ_ID_DONE\n", pPM->Id)); PM_IssueReadReg(pPM, MV_TRUE, MV_SATA_GSCR_REVISION_REG_NUM, MV_TRUE); break; case PM_STATE_READ_REV_DONE: MV_DPRINT(("PM %d PM_READ_REV_DONE\n", pPM->Id)); PM_IssueReadReg(pPM, MV_TRUE, MV_SATA_GSCR_FEATURES_ENABLE_REG_NUM, MV_TRUE); break; case PM_STATE_ENABLE_ASYNOTIFY: MV_DPRINT(("PM %d PM_STATE_ENABLE_ASYNOTIFY\n", pPM->Id)); PM_IssueWriteReg(pPM, MV_TRUE, MV_SATA_GSCR_FEATURES_ENABLE_REG_NUM, pPM->Feature_Enabled, MV_TRUE); break; case PM_STATE_CLEAR_ERROR_INFO: MV_DPRINT(("PM %d PM_STATE_CLEAR_ERROR_INFO\n", pPM->Id)); temp = MV_BIT(16) | MV_BIT(26); PM_IssueWriteReg(pPM, MV_TRUE, MV_SATA_GSCR_ERROR_ENABLE_REG_NUM, temp, MV_TRUE ); break; case PM_STATE_PORT_SPIN_UP_DEVICE: MV_DPRINT(("PM %d PM_STATE_PORT_SPIN_UP_DEVICE.\n", pPM->Id)); PM_IssueWriteReg(pPM, MV_FALSE, MV_SATA_PSCR_SCONTROL_REG_NUM, 0x01, MV_TRUE); break; case PM_STATE_PORT_SPIN_UP_DEVICE_DONE: MV_DPRINT(("PM %d Port %d PM_STATE_PORT_SPIN_UP_DEVICE_DONE.\n", pPM->Id, pPM->ActPortNumber)); PM_IssueWriteReg(pPM, MV_FALSE, MV_SATA_PSCR_SCONTROL_REG_NUM, 0x00, MV_TRUE); break; case PM_STATE_PORT_ENABLE_1: MV_DPRINT(("PM %d PM_STATE_PORT_ENABLE_1.\n", pPM->Id)); PM_IssueWriteReg(pPM, MV_FALSE, MV_SATA_PSCR_SCONTROL_REG_NUM, 0x01, MV_TRUE); break; case PM_STATE_PORT_ENABLE_0: MV_DPRINT(("PM %d Port %d PM_STATE_PORT_ENABLE_0.\n", pPM->Id, pPM->ActPortNumber)); PM_IssueWriteReg(pPM, MV_FALSE, MV_SATA_PSCR_SCONTROL_REG_NUM, 0x00, MV_TRUE); break; case PM_STATE_PORT_ENABLE_FLUSHED: MV_DPRINT(("PM %d Port %d PM_STATE_PORT_ENABLE_FLUSHED\n", pPM->Id, pPM->ActPortNumber)); PM_IssueReadReg(pPM, MV_FALSE, MV_SATA_PSCR_SCONTROL_REG_NUM, MV_TRUE); break; case PM_STATE_PORT_WAITING_PHY_READY: MV_DPRINT(("PM %d Port %d PM_STATE_PORT_WAITING_PHY_READY\n", pPM->Id, pPM->ActPortNumber)); PM_IssueReadReg(pPM, MV_FALSE, MV_SATA_PSCR_SSTATUS_REG_NUM, MV_TRUE); break; case PM_STATE_READ_PORT_ERROR: MV_DPRINT(("PM %d Port %d PM_STATE_READ_PORT_ERROR\n", pPM->Id, pPM->ActPortNumber)); PM_IssueReadReg(pPM, MV_FALSE, MV_SATA_PSCR_SERROR_REG_NUM, MV_TRUE); break; case PM_STATE_CLEAR_PORT_ERROR: MV_DPRINT(("PM %d Port %d PM_STATE_CLEAR_PORT_ERROR\n", pPM->Id, pPM->ActPortNumber)); PM_IssueWriteReg(pPM, MV_FALSE, MV_SATA_PSCR_SERROR_REG_NUM, 0xFFFFFFFF, MV_TRUE); break; case PM_STATE_PORT_ENABLED: MV_DPRINT(("PM %d Port %d PM_STATE_PORT_ENABLED\n", pPM->Id, pPM->ActPortNumber)); PM_IssueReadReg(pPM, MV_FALSE, MV_SATA_PSCR_SSTATUS_REG_NUM, MV_TRUE); break; case PM_STATE_PORT_FINISHED: MV_DPRINT(("PM %d Port %d PM_STATE_PORT_FINISHED\n", pPM->Id, pPM->ActPortNumber)); pDevice = GetDeviceFromPool(pCore); if( pDevice == NULL ) { MV_PRINT("pDevice is NULL\n"); return MV_FALSE; } pDevice->pPort = pPort; pDevice->pPM = pPM; pDevice->PM_Number = pPM->ActPortNumber; #ifndef USE_DYN_REGISTER_SET pDevice->Register_Set = SATA_GetRegisterSet(pCore); #endif pPM->Devices[pPM->ActPortNumber] = pDevice; pDevice->State = DEVICE_STATE_SRST_1; pDevice->Dev_Type = DT_DIRECT_ACCESS_BLOCK; pDevice->Connection |= DC_SERIAL | DC_ATA; /* MV_DPRINT(("pPM->PluginNotify= 0x%X\n", pPM->PluginNotify)); if (pPM->PluginNotify) { for (i = 0; i < pPM->NumberOfPorts; i++) { if (pPM->PluginNotify & MV_BIT(pPM->ActPortNumber)) { pDevice->Need_Notify = MV_TRUE; } } } */ SATA_DeviceStateMachine(pCore, pDevice); break; case PM_STATE_CHECK_HOTPLUG: HBA_SleepMillisecond(pCore, 200); MV_DPRINT(("PM %d Check Hotplug\n", pPM->Id)); PM_IssueReadReg(pPM, MV_TRUE, MV_SATA_GSCR_ERROR_REG_NUM, MV_FALSE); HBA_SleepMillisecond(pCore, 10); break; case PM_STATE_READ_PERROR: MV_DPRINT(("PM %d Port %d Read Port Error\n", pPM->Id, pPM->ActPortNumber)); PM_IssueReadReg(pPM, MV_FALSE, MV_SATA_PSCR_SERROR_REG_NUM, MV_FALSE); HBA_SleepMillisecond(pCore, 10); break; case PM_STATE_CLEAR_PERROR: MV_DPRINT(("PM %d Port %d Clear Port Error\n", pPM->Id, pPM->ActPortNumber)); PM_IssueWriteReg(pPM, MV_FALSE, MV_SATA_PSCR_SERROR_REG_NUM, 0xFFFFFFFF, MV_FALSE); HBA_SleepMillisecond(pCore, 10); break; case PM_STATE_READ_PSTATUS: MV_DPRINT(("PM %d Port %d Read Port Status\n", pPM->Id, pPM->ActPortNumber)); PM_IssueReadReg(pPM, MV_FALSE, MV_SATA_PSCR_SSTATUS_REG_NUM, MV_FALSE); HBA_SleepMillisecond(pCore, 10); break; case PM_STATE_FLUSH_GERROR: MV_DPRINT(("PM %d PM_STATE_FLUSH_GERROR\n", pPM->Id)); PM_IssueReadReg(pPM, MV_TRUE, MV_SATA_GSCR_ERROR_REG_NUM, MV_FALSE); HBA_SleepMillisecond(pCore, 10); break; case PM_STATE_DEVICE_PLUG_IN: SATA_PM_HandleDevicePlugin(pCore, pPM); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -