X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FInterfaces%2FUDI%2Fmanagement_agent.c;h=536c28ffaa63763c4e7888f3edf9d29f358c7b03;hb=e2ff5722101ae7dbb10f51f1477eac625fa30c1e;hp=38a6a12466e26b6704aaded9cac18bfdebfd4807;hpb=de9c4d3d52751c9d66c61c062b74b02f80c31bf3;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Interfaces/UDI/management_agent.c b/KernelLand/Modules/Interfaces/UDI/management_agent.c index 38a6a124..536c28ff 100644 --- a/KernelLand/Modules/Interfaces/UDI/management_agent.c +++ b/KernelLand/Modules/Interfaces/UDI/management_agent.c @@ -5,29 +5,22 @@ * management_agent.c * - Managment Agent */ -#include +#define DEBUG 1 #include -#include "udi_internal.h" -#include "udi_ma.h" +#include +#include +#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; @@ -43,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, inst->Regions[0]->InitContext, pri_init->mgmt_ops); + 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; } @@ -92,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; @@ -110,6 +105,7 @@ void UDI_MA_BeginEnumeration(tUDI_DriverInstance *Inst) int UDI_MA_CheckDeviceMatch(int nDevAttr, udi_instance_attr_list_t *DevAttrs, int nEnumAttr, udi_instance_attr_list_t *EnumAttrs) { + // TODO: Ask metalangauge instead int n_matches = 0; for( int i = 0; i < nDevAttr; i ++ ) { @@ -124,6 +120,11 @@ int UDI_MA_CheckDeviceMatch(int nDevAttr, udi_instance_attr_list_t *DevAttrs, } if( enum_attr ) { + //LOG("Match = '%s' (%i %x == %i %x)", + // dev_attr->attr_name, + // dev_attr->attr_length, UDI_ATTR32_GET(dev_attr->attr_value), + // enum_attr->attr_length, UDI_ATTR32_GET(enum_attr->attr_value) + // ); if( enum_attr->attr_length != dev_attr->attr_length ) return 0; if( memcmp(enum_attr->attr_value, dev_attr->attr_value, dev_attr->attr_length) != 0 ) @@ -133,16 +134,19 @@ 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("n_matches = %i", n_matches); return n_matches; } void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx) { // Current side is MA, other is instance - tUDI_DriverInstance *inst = UDI_int_ChannelGetInstance( UDI_GCB(cb), true ); - LOG("inst = %p", inst); + // TODO: Get region index too? + tUDI_DriverInstance *inst = UDI_int_ChannelGetInstance( UDI_GCB(cb), true, NULL ); + //LOG("inst = %p", inst); // Search for existing child with same child_ID and ops for( tUDI_ChildBinding *child = inst->FirstChild; child; child = child->Next ) @@ -166,7 +170,6 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx) // - Locate child_bind_ops definition for( int i = 0; i < inst->Module->nChildBindOps; i ++ ) { - LOG(" %i == %i?", inst->Module->ChildBindOps[i].ops_idx, ops_idx); if( inst->Module->ChildBindOps[i].ops_idx == ops_idx ) { child->BindOps = &inst->Module->ChildBindOps[i]; break; @@ -183,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 ; @@ -205,55 +211,122 @@ 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); } } void UDI_MA_BindParents(tUDI_DriverModule *Module) { - UNIMPLEMENTED(); + // Scan active instances for enumerated children that can be handled by this module + for( int i = 0; i < Module->nDevices; i ++ ) + { + // TODO: Have list of unbound enumerated children + for( tUDI_DriverInstance *inst = gpUDI_ActiveInstances; inst; inst = inst->Next ) + { + // Loop children + for( tUDI_ChildBinding *child = inst->FirstChild; child; child = child->Next ) + { + if( child->BoundInstance ) + continue ; + // TODO: Check metalangs + // Check for match + int level = UDI_MA_CheckDeviceMatch( + Module->Devices[i]->nAttribs, Module->Devices[i]->Attribs, + child->nAttribs, child->Attribs + ); + // No match: Continue + if( level == 0 ) + continue ; + // 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; - - // 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, parent->meta_idx) ); + ASSERT(Inst); + if( Inst->CurState != Src ) + return ; - UDI_BindChannel(channel,true, inst, parent->ops_idx, parent->region_idx); - UDI_BindChannel(channel,false, - ParentInstance, ChildBinding->Ops->ops_idx, ChildBinding->BindOps->region_idx); + LOG("Inst %s %p MA state %i->%i", + Inst->Module->ModuleName, Inst, Src, Dst); - udi_cb_t *bind_cb = udi_cb_alloc_internal(inst, parent->bind_cb_idx, channel); - if( !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_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); - udi_channel_event_cb_t ev_cb; - int n_handles = Module->InitInfo->primary_init_info->per_parent_paths; - udi_buf_path_t handles[n_handles]; - memset(&ev_cb, 0, sizeof(ev_cb)); - ev_cb.gcb.channel = channel; - 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; - - 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; }