Modules/UDI - Cleaned up source layout, implemented PCI IRQs
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / management_agent.c
index 38a6a12..0e1c87e 100644 (file)
@@ -5,10 +5,11 @@
  * management_agent.c
  * - Managment Agent
  */
-#include <acess.h>
+#define DEBUG  1
 #include <udi.h>
-#include "udi_internal.h"
-#include "udi_ma.h"
+#include <acess.h>
+#include <udi_internal.h>
+#include <udi_internal_ma.h>
 
 // === CONSTANTS ===
 enum {
@@ -45,7 +46,7 @@ tUDI_DriverInstance *UDI_MA_CreateInstance(tUDI_DriverModule *DriverModule)
 
        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?
 
@@ -110,6 +111,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 +126,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 +140,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 +176,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;
@@ -211,7 +220,29 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx)
 
 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 ;
+                               // 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 ;
+                               UDI_MA_CreateChildInstance(Module, inst, child);
+                       }
+               }
+       }
 }
 
 tUDI_DriverInstance *UDI_MA_CreateChildInstance(tUDI_DriverModule *Module,
@@ -220,6 +251,8 @@ tUDI_DriverInstance *UDI_MA_CreateChildInstance(tUDI_DriverModule *Module,
        // 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);
@@ -228,23 +261,28 @@ tUDI_DriverInstance *UDI_MA_CreateChildInstance(tUDI_DriverModule *Module,
        tUDI_BindOps    *parent = &Module->Parents[0];
        udi_channel_t channel = UDI_CreateChannel_Blank( UDI_int_GetMetaLang(inst, parent->meta_idx) );
        
-       UDI_BindChannel(channel,true,  inst, parent->ops_idx, parent->region_idx);
+       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);
-       
-       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;
-       }
+               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];
-       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;
+       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;
+               }
+               UDI_int_ChannelFlip( ev_cb.params.parent_bound.bind_cb );
+       }
+
        ev_cb.params.parent_bound.parent_ID = 1;
        ev_cb.params.parent_bound.path_handles = handles;
        

UCC git Repository :: git.ucc.asn.au