X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FInterfaces%2FUDI%2Fmanagement_agent.c;h=536c28ffaa63763c4e7888f3edf9d29f358c7b03;hb=e2ff5722101ae7dbb10f51f1477eac625fa30c1e;hp=0e1c87e798e306a60a06d5c672d6819e6e27718e;hpb=fb13a50bc14688a20dc37acbbbbe23f56bf63c41;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Interfaces/UDI/management_agent.c b/KernelLand/Modules/Interfaces/UDI/management_agent.c index 0e1c87e7..536c28ff 100644 --- a/KernelLand/Modules/Interfaces/UDI/management_agent.c +++ b/KernelLand/Modules/Interfaces/UDI/management_agent.c @@ -12,23 +12,15 @@ #include // === CONSTANTS === -enum { - MGMT_CB_ENUM = 1, -}; -const udi_cb_init_t cUDI_MgmtCbInitList[] = { - {MGMT_CB_ENUM,0,0, 0,0,NULL}, - {0} -}; // === PROTOTYPES === -tUDI_DriverInstance *UDI_MA_CreateChildInstance(tUDI_DriverModule *Module, - tUDI_DriverInstance *ParentInstance, tUDI_ChildBinding *ChildBinding); // === GLOBALS === tUDI_DriverInstance *gpUDI_ActiveInstances; // === CODE === -tUDI_DriverInstance *UDI_MA_CreateInstance(tUDI_DriverModule *DriverModule) +tUDI_DriverInstance *UDI_MA_CreateInstance(tUDI_DriverModule *DriverModule, + tUDI_DriverInstance *ParentInstance, tUDI_ChildBinding *ChildBinding) { tUDI_DriverInstance *inst = NEW_wA(tUDI_DriverInstance, Regions, DriverModule->nRegions); udi_primary_init_t *pri_init = DriverModule->InitInfo->primary_init_info; @@ -44,36 +36,38 @@ tUDI_DriverInstance *UDI_MA_CreateInstance(tUDI_DriverModule *DriverModule) } } + if( ParentInstance ) { + ASSERT(ChildBinding); + ChildBinding->BoundInstance = inst; + } + inst->Parent = ParentInstance; + inst->ParentChildBinding = ChildBinding; + inst->ManagementChannel = UDI_CreateChannel_Blank(&cMetaLang_Management); UDI_BindChannel_Raw(inst->ManagementChannel, true, inst, 0, 0, inst->Regions[0]->InitContext, pri_init->mgmt_ops); // UDI_BindChannel_Raw(inst->ManagementChannel, false, // NULL, 1, inst, &cUDI_MgmtOpsList); // TODO: ops list for management agent? - for( int i = 0; i < DriverModule->nRegions; i ++ ) - Log("Rgn %i: %p", i, inst->Regions[i]); +// for( int i = 0; i < DriverModule->nRegions; i ++ ) +// Log("Rgn %i: %p", i, inst->Regions[i]); - // Send usage indication - char scratch[pri_init->mgmt_scratch_requirement]; - { - udi_usage_cb_t ucb; - memset(&ucb, 0, sizeof(ucb)); - ucb.gcb.scratch = scratch; - ucb.gcb.channel = inst->ManagementChannel; - udi_usage_ind(&ucb, UDI_RESOURCES_NORMAL); - // TODO: Ensure that udi_usage_res is called - } - - for( int i = 1; i < DriverModule->nRegions; i ++ ) - { - // TODO: Bind secondaries to primary - Log_Warning("UDI", "TODO: Bind secondary channels"); - //inst->Regions[i]->PriChannel = UDI_CreateChannel_Blank( - } + LOG("Inst %s %p MA state =%i", + inst->Module->ModuleName, inst, UDI_MASTATE_USAGEIND); + inst->CurState = UDI_MASTATE_USAGEIND; + // Next State: _SECBIND // Add to global list of active instances inst->Next = gpUDI_ActiveInstances; gpUDI_ActiveInstances = inst; + + // Send usage indication + udi_usage_cb_t *cb = (void*)udi_cb_alloc_internal_v(&cMetaLang_Management, UDI_MGMT_USAGE_CB_NUM, + 0, pri_init->mgmt_scratch_requirement, inst->ManagementChannel + ); + UDI_GCB(cb)->initiator_context = inst; + udi_usage_ind(cb, UDI_RESOURCES_NORMAL); + // udi_usage_res causes next state transition return inst; } @@ -93,10 +87,10 @@ tUDI_DriverRegion *UDI_MA_InitRegion(tUDI_DriverInstance *Inst, void UDI_MA_BeginEnumeration(tUDI_DriverInstance *Inst) { udi_primary_init_t *pri_init = Inst->Module->InitInfo->primary_init_info; - udi_enumerate_cb_t *ecb = udi_cb_alloc_internal(NULL, MGMT_CB_ENUM, Inst->ManagementChannel); - memset(ecb, 0, sizeof(ecb)); - ecb->gcb.scratch = malloc(pri_init->mgmt_scratch_requirement); - ecb->gcb.channel = Inst->ManagementChannel; + udi_enumerate_cb_t *ecb = (void*)udi_cb_alloc_internal_v( + &cMetaLang_Management, UDI_MGMT_ENUMERATE_CB_NUM, + 0, pri_init->mgmt_scratch_requirement, Inst->ManagementChannel); + UDI_GCB(ecb)->initiator_context = Inst; ecb->child_data = malloc(pri_init->child_data_size); ecb->attr_list = NEW(udi_instance_attr_list_t, *pri_init->enumeration_attr_list_length); ecb->attr_valid_length = 0; @@ -140,7 +134,7 @@ int UDI_MA_CheckDeviceMatch(int nDevAttr, udi_instance_attr_list_t *DevAttrs, else { // Attribute desired is missing, error? - //LOG("attr '%s' missing", dev_attr->attr_name); + LOG("attr '%s' missing", dev_attr->attr_name); } } //LOG("n_matches = %i", n_matches); @@ -192,13 +186,16 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx) inst->FirstChild = child; // and search for a handler - tUDI_MetaLang *metalang = UDI_int_GetMetaLang(inst, child->Ops->meta_idx); + tUDI_MetaLang *metalang = UDI_int_GetMetaLang(inst->Module, child->Ops->meta_idx); int best_level = 0; tUDI_DriverModule *best_module = NULL; for( tUDI_DriverModule *module = gpUDI_LoadedModules; module; module = module->Next ) { for( int i = 0; i < module->nDevices; i ++ ) { + //LOG("%s:%i %p ?== %p", + // module->ModuleName, i, + // module->Devices[i]->Metalang, metalang); if( module->Devices[i]->Metalang != metalang ) continue ; @@ -214,7 +211,7 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx) } if( best_module != NULL ) { - UDI_MA_CreateChildInstance(best_module, inst, child); + UDI_MA_CreateInstance(best_module, inst, child); } } @@ -231,6 +228,7 @@ void UDI_MA_BindParents(tUDI_DriverModule *Module) { if( child->BoundInstance ) continue ; + // TODO: Check metalangs // Check for match int level = UDI_MA_CheckDeviceMatch( Module->Devices[i]->nAttribs, Module->Devices[i]->Attribs, @@ -239,59 +237,96 @@ void UDI_MA_BindParents(tUDI_DriverModule *Module) // No match: Continue if( level == 0 ) continue ; - UDI_MA_CreateChildInstance(Module, inst, child); + // Found a match, so create an instance (binding happens async) + UDI_MA_CreateInstance(Module, inst, child); } } } } -tUDI_DriverInstance *UDI_MA_CreateChildInstance(tUDI_DriverModule *Module, - tUDI_DriverInstance *ParentInstance, tUDI_ChildBinding *ChildBinding) +void UDI_MA_TransitionState(tUDI_DriverInstance *Inst, enum eUDI_MAState Src, enum eUDI_MAState Dst) { - // Found a match, so create an instance and bind it - tUDI_DriverInstance *inst = UDI_MA_CreateInstance(Module); - ChildBinding->BoundInstance = inst; - inst->Parent = ParentInstance; - inst->ParentChildBinding = ChildBinding; - - // TODO: Handle multi-parent drivers - ASSERTC(Module->nParents, ==, 1); + ASSERT(Inst); + if( Inst->CurState != Src ) + return ; - // Bind to parent - tUDI_BindOps *parent = &Module->Parents[0]; - udi_channel_t channel = UDI_CreateChannel_Blank( UDI_int_GetMetaLang(inst, parent->meta_idx) ); + LOG("Inst %s %p MA state %i->%i", + Inst->Module->ModuleName, Inst, Src, Dst); - UDI_BindChannel(channel,true, inst, parent->ops_idx, parent->region_idx, NULL,false,0); - UDI_BindChannel(channel,false, - ParentInstance, ChildBinding->Ops->ops_idx, ChildBinding->BindOps->region_idx, - NULL, true, ChildBinding->ChildID); - - udi_channel_event_cb_t ev_cb; - memset(&ev_cb, 0, sizeof(ev_cb)); - int n_handles = Module->InitInfo->primary_init_info->per_parent_paths; - udi_buf_path_t handles[n_handles]; - ev_cb.gcb.channel = channel; - ev_cb.event = UDI_CHANNEL_BOUND; - if( parent->bind_cb_idx == 0 ) - ev_cb.params.parent_bound.bind_cb = NULL; - else { - ev_cb.params.parent_bound.bind_cb = udi_cb_alloc_internal(inst, parent->bind_cb_idx, channel); - if( !ev_cb.params.parent_bound.bind_cb ) { - Log_Warning("UDI", "Bind CB index is invalid"); - return NULL; + switch(Dst) + { + case UDI_MASTATE_USAGEIND: + ASSERT(Dst != UDI_MASTATE_USAGEIND); + break; + case UDI_MASTATE_SECBIND: + Inst->CurState = UDI_MASTATE_SECBIND; + for( int i = 1; i < Inst->Module->nRegions; i ++ ) + { + // TODO: Bind secondaries to primary + Log_Warning("UDI", "TODO: Bind secondary channels"); + //inst->Regions[i]->PriChannel = UDI_CreateChannel_Blank( } - UDI_int_ChannelFlip( ev_cb.params.parent_bound.bind_cb ); - } + //UDI_MA_TransitionState(Inst, UDI_MASTATE_SECBIND, UDI_MASTATE_PARENTBIND); + //break; + case UDI_MASTATE_PARENTBIND: + Inst->CurState = UDI_MASTATE_PARENTBIND; + if( Inst->Parent ) + { + tUDI_DriverModule *Module = Inst->Module; + tUDI_ChildBinding *parent_bind = Inst->ParentChildBinding; + // TODO: Handle multi-parent drivers + ASSERTC(Module->nParents, ==, 1); + + // Bind to parent + tUDI_BindOps *parent = &Module->Parents[0]; + udi_channel_t channel = UDI_CreateChannel_Blank(UDI_int_GetMetaLang(Inst->Module, parent->meta_idx)); + + UDI_BindChannel(channel,true, Inst, parent->ops_idx, parent->region_idx, NULL,false,0); + UDI_BindChannel(channel,false, + Inst->Parent, parent_bind->Ops->ops_idx, parent_bind->BindOps->region_idx, + NULL, true, parent_bind->ChildID); - ev_cb.params.parent_bound.parent_ID = 1; - ev_cb.params.parent_bound.path_handles = handles; - - for( int i = 0; i < n_handles; i ++ ) { - //handles[i] = udi_buf_path_alloc_internal(inst); - handles[i] = 0; + udi_cb_t *bind_cb; + if( parent->bind_cb_idx == 0 ) + bind_cb = NULL; + else { + bind_cb = udi_cb_alloc_internal(Inst, parent->bind_cb_idx, channel); + if( !bind_cb ) { + Log_Warning("UDI", "Bind CB index is invalid"); + break; + } + UDI_int_ChannelFlip( bind_cb ); + } + + int n_handles = Module->InitInfo->primary_init_info->per_parent_paths; + udi_buf_path_t handles[n_handles]; + for( int i = 0; i < n_handles; i ++ ) { + //handles[i] = udi_buf_path_alloc_internal(Inst); + handles[i] = 0; + } + + udi_channel_event_cb_t *ev_cb = (void*)udi_cb_alloc_internal_v(&cMetaLang_Management, + UDI_MGMT_CHANNEL_EVENT_CB_NUM, 0, 0, channel); + UDI_GCB(ev_cb)->initiator_context = Inst; + ev_cb->event = UDI_CHANNEL_BOUND; + ev_cb->params.parent_bound.bind_cb = bind_cb; + ev_cb->params.parent_bound.parent_ID = 1; + ev_cb->params.parent_bound.path_handles = handles; + + udi_channel_event_ind(ev_cb); + break; + } + //UDI_MA_TransitionState(Inst, UDI_MASTATE_PARENTBIND, UDI_MASTATE_ENUMCHILDREN); + //break; + case UDI_MASTATE_ENUMCHILDREN: + Inst->CurState = UDI_MASTATE_ENUMCHILDREN; + UDI_MA_BeginEnumeration(Inst); + break; + case UDI_MASTATE_ACTIVE: + Inst->CurState = UDI_MASTATE_ACTIVE; + Log_Log("UDI", "Driver instance %s %p entered active state", + Inst->Module->ModuleName, Inst); + break; } - - udi_channel_event_ind(&ev_cb); - return inst; }