📄 core_init.c
字号:
MapDeviceId(pCore,MapIndexA) = MapDeviceId(pCore,MapIndexB); MapDeviceId(pCore,MapIndexB) = Index;}MV_VOID SwapExpID( IN PCore_Driver_Extension pCore, IN MV_U8 MapIndexA, IN MV_U8 MapIndexB){ MV_U8 Index; pCore->Expanders[MapDeviceId(pCore,MapIndexA)].ExpId=MapIndexB; pCore->Expanders[MapDeviceId(pCore,MapIndexB)].ExpId=MapIndexA; Index = MapDeviceId(pCore,MapIndexA); MapDeviceId(pCore,MapIndexA) = MapDeviceId(pCore,MapIndexB); MapDeviceId(pCore,MapIndexB) = Index;}MV_VOID SwapPortID( IN PCore_Driver_Extension pCore, IN MV_U8 MapIndexA, IN MV_U8 MapIndexB){ MV_U8 Index; pCore->Ports[MapPortEntry(pCore,MapIndexA)].Id=MapIndexB; pCore->Ports[MapPortEntry(pCore,MapIndexB)].Id=MapIndexA; Index = MapPortEntry(pCore,MapIndexA); MapPortEntry(pCore,MapIndexA) = MapPortEntry(pCore,MapIndexB); MapPortEntry(pCore,MapIndexB) = Index;}MV_U8 GetFirstPhy( IN PCore_Driver_Extension pCore, IN PDomain_Port pPort){ MV_U8 i; MV_U8 phyMap=pPort->MemberPhyMap; for(i=0; i<pCore->Phy_Num; i++) { if(phyMap>>i) break; } return i;}MV_VOID IDSorting( IN PCore_Driver_Extension pCore ){ PDomain_Device pDevice = NULL; MV_U8 IndexA, IndexB, MinIndex; MV_U32 WeightA, WeightB; MV_U8 i=0,j=0;/* This routine try to re-arrange only the order of port_map/device_map, but the ports[]/devices[]/expanders[] order should stay the same.*/// re-arrange the port_map order by their least phy number for( i=0; i<=pCore->Port_Num; i++ ) { if( pCore->Port_Map[i] == ID_NOT_MAPPED ) continue; IndexA=GetFirstPhy(pCore, &pCore->Ports[MapPortEntry(pCore,i)]); if(IndexA >= pCore->Phy_Num ) continue; // virtual MinIndex=i; for(j=i; j<=pCore->Port_Num; j++ ) { if( pCore->Port_Map[j] == ID_NOT_MAPPED ) continue; IndexB=GetFirstPhy(pCore, &pCore->Ports[MapPortEntry(pCore,j)]); if(IndexB >= pCore->Phy_Num ) continue; // virtual if(IndexA>IndexB) { MinIndex=j; IndexA=IndexB; } } if(MinIndex!=i) SwapPortID(pCore,i,MinIndex); }// re-arrange the expander_map order by their port ID for( i=MIN_EXPANDER_ID; i<=pCore->Current_Expander_Id; i++ ) { if( pCore->Device_Map[i] == ID_NOT_MAPPED ) continue; IndexA = pCore->Expanders[MapDeviceId(pCore,i)].pPort->Id; MinIndex=i; for(j=i; j<=pCore->Current_Expander_Id; j++ ) { if( pCore->Device_Map[j] == ID_NOT_MAPPED ) continue; IndexB = pCore->Expanders[MapDeviceId(pCore,j)].pPort->Id; if(IndexA>IndexB) { MinIndex=j; IndexA=IndexB; } } if(MinIndex!=i) SwapExpID(pCore,i,MinIndex); }// re-arrange the device_map order by their least phy number and port ID // portId.exp.phyId for( i=0; i<=pCore->Current_Device_Id; i++ ) { if( pCore->Device_Map[i] == ID_NOT_MAPPED ) continue; pDevice=&pCore->Devices[MapDeviceId(pCore,i)]; if(pDevice->pPort==NULL) continue; // virtual WeightA=pDevice->Phy_Id + (pDevice->pPort->Id <<16); if(pDevice->pExpander!=NULL) WeightA += pDevice->pExpander->ExpId <<8; MinIndex=i; for(j=i; j<=pCore->Current_Device_Id; j++ ) { if( pCore->Device_Map[j] == ID_NOT_MAPPED ) continue; pDevice=&pCore->Devices[MapDeviceId(pCore,j)]; if(pDevice->pPort==NULL) continue; // virtual WeightB=pDevice->Phy_Id + (pDevice->pPort->Id <<16); if(pDevice->pExpander!=NULL) WeightB += pDevice->pExpander->ExpId <<8; if(WeightA>WeightB) { MinIndex=j; WeightA=WeightB; } } if(MinIndex!=i) SwapDeviceID(pCore,i,MinIndex); }}MV_BOOLEAN mvChannelStateMachine( PCore_Driver_Extension pCore, PDomain_Port pPort ){ MV_U8 i,j; MV_U8 index; MV_U8 portState; PDomain_Device pDevice = NULL; if ( pPort==NULL ) portState = PORT_STATE_IDLE; else portState = pPort->Port_State; //Each step: if fail like no device, should go to the end. /* Channel state machine */ switch ( portState ) { case PORT_STATE_IDLE: /* To do reset */ /* if there are any SATA drives, need to wait sometime for signature FIS to come back NOTE: This is for certain models of Seagate drives which will hang if we send soft reset before the power-on signature FIS is received. To save time, we do a wait here for 5 seconds for all SATA drives instead of doing them in sequence later in SATA_PortReset */ for (i=0; i<MAX_PORT_ID; i++) { MV_U8 index=pCore->Port_Map[i]; if (index == ID_NOT_MAPPED) continue; pPort = &pCore->Ports[index]; if ( pPort->Type & PORT_TYPE_SATA ) { MV_DPRINT(("Waiting for 5 seconds before resetting SATA port\n")); HBA_SleepMillisecond(pCore, 5000); break; } } for( i=0; i<MAX_PORT_ID; i++ ) { MV_U8 index=pCore->Port_Map[i]; if (index == ID_NOT_MAPPED) continue; pPort = &pCore->Ports[index]; MV_DASSERT( pPort->Port_State==PORT_STATE_IDLE ); if ( pPort->Type&PORT_TYPE_SAS ) { SAS_PortReset( pPort, MV_FALSE ); } else { SATA_PortReset( pPort, MV_FALSE ); } }/* for no port case */ if(pCore->Port_Pool.Top==MAX_PORT_NUMBER) { if(pPort==NULL) { if ( pCore->State==CORE_STATE_IDLE ) { pCore->State = CORE_STATE_STARTED; /* The 1st time init */ core_start_cmpl_notify(pCore); } } else { pPort->Port_State=PORT_STATE_INIT_DONE; mvChannelStateMachine(pCore, pPort); } } break; /* * Each port will call mvDeviceStateMachine for its devices. * When all the devices for that port are done, will call mvChannelStateMachine. */ case PORT_STATE_INIT_DONE: /* Check whether all the ports are done. */ for ( j=0; j<MAX_PORT_ID; j++ ) { index=pCore->Port_Map[j]; if(index==ID_NOT_MAPPED) continue; pPort = &pCore->Ports[index]; if ( pPort->Port_State!=PORT_STATE_INIT_DONE ) { // hibernation: check if this port has devices // waiting to be initialized /* In case that another port is doing discovery (not finished yet), the device list could be empty */ /* MV_DASSERT( !List_Empty(&pPort->Device_List) ); */ 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; } } return MV_TRUE; } } /* Discovery procedure is finished. */ if (pCore->State == CORE_STATE_IDLE) { /* do a ID sorting */ IDSorting(pCore); pCore->State = CORE_STATE_STARTED;#ifdef SUPPORT_SGPIO SGPIO_Initialize(pCore);#endif#ifdef SUPPORT_I2C I2C_ModuleInitialize(pCore);#else core_start_cmpl_notify(pCore);#endif /* SUPPORT_I2C */ } else { for ( j=0; j<MAX_PORT_ID; j++ ) { index = pCore->Port_Map[j]; if (index == ID_NOT_MAPPED) continue; pPort = &pCore->Ports[index]; /* check which device on this port needs to be reported */ //MV_PRINT("pPort->Device_Number = %d\n", pPort->Device_Number); 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->Need_Notify ) { core_notify_device_hotplug(pCore, EVENT_DEVICE_ARRIVAL, pDevice->Id); pDevice->Need_Notify = MV_FALSE; #ifdef SUPPORT_PM /* if (pDevice->pPM) { pDevice->pPM->PluginNotify &= ~MV_BIT(pDevice->PM_Number); } */ #endif } } } } break; } return MV_TRUE;}static MV_BOOLEAN SAS_DeviceStateMachine( PCore_Driver_Extension pCore, PDomain_Device pDevice ){ MV_U8 i; PDomain_Port pPort = pDevice->pPort; /* prevent running recursive state machine like hotplug */ if(pCore->Device_Map[pDevice->Id] == ID_NOT_MAPPED) return MV_FALSE; switch ( pDevice->State ) { case DEVICE_STATE_RESET_DONE: MV_DPRINT(("Device %d DEVICE_STATE_RESET_DONE.\n", pDevice->Id)); /* To do inquiry */ Device_MakeInquiryTaskRequest( pDevice ); break; case DEVICE_STATE_INQUIRY_DONE: MV_DPRINT(("Device %d DEVICE_STATE_INQUIRY_DONE.\n", pDevice->Id)); /* To do read capacity */ Device_MakeReadCapacityTaskRequest( pDevice ); break; case DEVICE_STATE_INQUIRY_16_DONE: MV_DPRINT(("Device %d DEVICE_STATE_INQUIRY_16_DONE.\n", pDevice->Id)); /* To do read capacity 16 */ Device_MakeReadCapacity16TaskRequest( pDevice ); break; case DEVICE_STATE_READ_CAPACITY_DONE: MV_DPRINT(("Device %d DEVICE_STATE_READ_CAPACITY_DONE.\n", pDevice->Id)); /* To do read capacity */ Device_MakeStartStopUnitRequest( pDevice, 1 ); /* Start */ break; case DEVICE_STATE_STARTSTOP_DONE: MV_DPRINT(("Device %d DEVICE_STATE_STARTSTOP_DONE.\n", pDevice->Id)); #ifdef CORE_SAS_SUPPORT_ATA_COMMAND /* To do mode sense to get device parameter */ Device_MakeModeSenseRequest( pDevice ); break; case DEVICE_STATE_MODE_SENSE_DONE: MV_DPRINT(("Device %d DEVICE_STATE_MODE_SENSE_DONE.\n", pDevice->Id)); /* To enable pre-read and write cache.*/ Device_MakeModeSelectRequest( pDevice ); break; case DEVICE_STATE_MODE_SELECT_DONE: MV_DPRINT(("Device %d DEVICE_STATE_MODE_SELECT_DONE.\n", pDevice->Id)); #endif /* 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)); 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;}MV_BOOLEAN SATA_DeviceStateMachine( PCore_Driver_Extension pCore, PDomain_Device pDevice ){ MV_U8 i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -