Modules/UDI - Working on more framework and PCI bus
authorJohn Hodge <[email protected]>
Tue, 17 Sep 2013 14:47:31 +0000 (22:47 +0800)
committerJohn Hodge <[email protected]>
Tue, 17 Sep 2013 14:47:31 +0000 (22:47 +0800)
- No longer crashes on boot, so that's a plus
- Working on deferred call framework to avoid huge stack chaining

13 files changed:
KernelLand/Modules/Interfaces/UDI/Makefile
KernelLand/Modules/Interfaces/UDI/channels.c
KernelLand/Modules/Interfaces/UDI/include/physio/meta_bus.h
KernelLand/Modules/Interfaces/UDI/include/udi/arch/x86.h
KernelLand/Modules/Interfaces/UDI/include/udi/attr.h
KernelLand/Modules/Interfaces/UDI/include/udi/init.h
KernelLand/Modules/Interfaces/UDI/main.c
KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c [new file with mode: 0644]
KernelLand/Modules/Interfaces/UDI/udi_internal.h
KernelLand/Modules/Interfaces/UDI/udi_lib/imc.c
KernelLand/Modules/Interfaces/UDI/udi_lib/logging.c
KernelLand/Modules/Interfaces/UDI/udi_lib/meta_mgmt.c
KernelLand/Modules/Interfaces/UDI/udi_lib/strmem.c

index 9613127..dde172c 100644 (file)
@@ -10,7 +10,7 @@ LIB_OBJS += meta_mgmt.o meta_gio.o
 LIB_OBJS += physio.o physio/meta_bus.o physio/meta_intr.o physio/pio.o physio/dma.o
 LIB_OBJS += scsi.o
 # - UDI->Acess Translation Layer
-TRANS_OBJS := 
+TRANS_OBJS := bus_pci.o
 
 OBJ  = main.o channels.o
 OBJ += $(LIB_OBJS:%=udi_lib/%) $(TRANS_OBJS:%=trans/%)
index d232e03..8f96d34 100644 (file)
@@ -9,57 +9,85 @@
 #include <acess.h>
 #include <udi.h>
 #include "udi_internal.h"
+#define LOCK_CHANNELS  1
 
 struct sUDI_ChannelSide {
        struct sUDI_Channel     *BackPtr;
+       udi_index_t     MetaOpsNum;
        const void      *Ops;
        void    *Context;
 };
 
 typedef struct sUDI_Channel
 {
-       enum eUDI_MetaLang      MetaLang;
-       udi_index_t     MetaOpsNum;
+       tUDI_MetaLang   *MetaLang;
+       bool    Locked;
        struct sUDI_ChannelSide  Side[2];
 } tUDI_Channel;
 
 // === CODE ===
-udi_channel_t UDI_CreateChannel(enum eUDI_MetaLang metalang, udi_index_t meta_ops_num,
-       tUDI_DriverInstance *ThisEnd, udi_index_t ThisOpsIndex,
-       tUDI_DriverInstance *OtherEnd, udi_index_t OtherOpsIndex)
+udi_channel_t UDI_CreateChannel_Blank(tUDI_MetaLang *metalang)
 {
        tUDI_Channel    *ret = NEW(tUDI_Channel,);
-       struct {
-               tUDI_DriverInstance     *inst;
-               udi_index_t     ops_index;
-       } ends[2] = {
-               {ThisEnd, ThisOpsIndex},
-               {OtherEnd, OtherOpsIndex}
-       };
+
        ret->MetaLang = metalang;
-       ret->MetaOpsNum = meta_ops_num;
-       for( int i = 0; i < 2; i ++ )
-       {
-               if( !ends[i].inst ) {
-                       continue ;
-               }
-               tUDI_DriverModule       *mod = ends[i].inst->Module;
-               ret->Side[i].BackPtr = ret;
-               udi_ops_init_t  *ops = mod->InitInfo->ops_init_list;;
-               while( ops->ops_idx && ops->ops_idx != ends[i].ops_index )
-                       ops++;
-               ASSERTR(ops->ops_idx, NULL);    // TODO: Pretty error
-               ASSERTCR(ops->meta_idx, <, mod->nMetaLangs, NULL);
-               ASSERTCR(mod->MetaLangs[ops->meta_idx], ==, metalang, NULL);
-               ASSERTCR(ops->meta_ops_num, ==, meta_ops_num, NULL);
-               if( ops->chan_context_size ) {
-                       ret->Side[i].Context = malloc(ops->chan_context_size);
-               }
-               ret->Side[i].Ops = ops->ops_vector;
-       }
+       ret->Side[0].BackPtr = ret;     
+       ret->Side[1].BackPtr = ret;     
+
        return (udi_channel_t)&ret->Side[0].BackPtr;
 }
 
+struct sUDI_ChannelSide *UDI_int_ChannelGetSide(udi_channel_t channel, bool other_side)
+{
+       tUDI_Channel *ch = *(tUDI_Channel**)channel;
+       if(!ch) return NULL;
+       
+       int side_idx = (channel == (udi_channel_t)&ch->Side[0].BackPtr) != other_side;
+
+       return &ch->Side[side_idx];
+}
+
+int UDI_BindChannel_Raw(udi_channel_t channel, bool other_side, udi_index_t meta_ops_num,  void *context, const void *ops)
+{
+       struct sUDI_ChannelSide *side = UDI_int_ChannelGetSide(channel, other_side);
+       side->Context = context;
+       side->MetaOpsNum = meta_ops_num;
+       side->Ops = ops;
+       return 0;
+}
+
+int UDI_BindChannel(udi_channel_t channel, bool other_side, tUDI_DriverInstance *inst, udi_index_t ops_idx, udi_index_t region)
+{
+       tUDI_Channel *ch = *(tUDI_Channel**)channel;
+       
+       tUDI_DriverRegion       *rgn = inst->Regions[region];
+       
+       udi_ops_init_t *ops = UDI_int_GetOps(inst, ops_idx);
+       if( !ops ) {
+               Log_Warning("UDI", "Ops ID invalid for '%s' (%i)", inst->Module, ops_idx);
+               return 1;
+       }
+
+       tUDI_MetaLang *ops_ml = UDI_int_GetMetaLang(inst, ops->meta_idx);
+       if( ops_ml != ch->MetaLang ) {
+               Log_Warning("UDI", "Attempt by %s to bind with mismatched channel '%s' op '%s' channel",
+                       inst->Module, ops_ml->Name, ch->MetaLang->Name);
+               return 3;
+       }
+
+       void *context;
+       if( ops->chan_context_size ) {
+               context = malloc( ops->chan_context_size );
+               ((udi_chan_context_t*)context)->rdata = rgn->InitContext;
+       }
+       else {
+               context = rgn->InitContext;
+       }
+       
+       UDI_BindChannel_Raw(channel, other_side, ops->meta_ops_num, context, ops->ops_vector);
+       return 0;
+}
+
 /**
  * \brief Prepare a cb for a channel call
  * \param gcb  Generic control block for this request
@@ -70,16 +98,59 @@ udi_channel_t UDI_CreateChannel(enum eUDI_MetaLang metalang, udi_index_t meta_op
  * Updates the channel and context fields of the gcb, checks the metalanguage and returns
  * the handler list for the other end of the channel.
  */
-const void *UDI_int_ChannelPrepForCall(udi_cb_t *gcb, enum eUDI_MetaLang metalang, udi_index_t meta_ops_num)
+const void *UDI_int_ChannelPrepForCall(udi_cb_t *gcb, tUDI_MetaLang *metalang, udi_index_t meta_ops_num)
 {
+       ASSERT(gcb);
+       ASSERT(gcb->channel);
        tUDI_Channel *ch = *(tUDI_Channel**)(gcb->channel);
-       ASSERTCR(ch->MetaLang, ==, metalang, NULL);
+       ASSERT(ch);
 
-       struct sUDI_ChannelSide *newside = (gcb->channel == (udi_channel_t)&ch->Side[0].BackPtr ? &ch->Side[1] : &ch->Side[0]);
+       // TODO: Allow calls without auto-lock
+       #if LOCK_CHANNELS
+       if( ch->Locked ) {
+               Log_Warning("UDI", "Channel %s:%i used while blocked (before handler was fired)",
+                       ch->MetaLang->Name, meta_ops_num);
+               return NULL;
+       }       
+       ch->Locked = true;
+       #endif
+       
+       struct sUDI_ChannelSide *newside = UDI_int_ChannelGetSide(gcb->channel, true);
+       if( metalang == NULL )
+       {
+               if( ch->MetaLang == &cMetaLang_Management ) {
+                       Log_Warning("UDI", "Invalid udi_channel_event_ind on Management metalang");
+                       return NULL;
+               }
+       }
+       else
+       {
+               if( ch->MetaLang != metalang || newside->MetaOpsNum != meta_ops_num ) {
+                       Log_Warning("UDI", "Metalanguage mismatch %s:%i req != %s:%i ch",
+                               metalang->Name, meta_ops_num,
+                               ch->MetaLang->Name, newside->MetaOpsNum);
+                       return NULL;
+               }
+       }
 
-//     gcb->initiator_context = gcb->context;
        gcb->channel = (udi_channel_t)&newside->BackPtr;
        gcb->context = newside->Context;
+       if( !newside->Ops ) {
+               Log_Warning("UDI", "Target end of %p(%s:%i) is unbound",
+                       ch, ch->MetaLang->Name, newside->MetaOpsNum);
+       }
        return newside->Ops;
 }
 
+void UDI_int_ChannelReleaseFromCall(udi_cb_t *gcb)
+{
+       #if LOCK_CHANNELS
+       ASSERT(gcb);
+       ASSERT(gcb->channel);
+       tUDI_Channel *ch = *(tUDI_Channel**)(gcb->channel);
+       ASSERT(ch);
+       
+       ch->Locked = false;
+       #endif
+}
+
index 7b88ece..f1af116 100644 (file)
@@ -41,7 +41,7 @@ struct udi_bus_bridge_ops_s
      udi_intr_detach_req_op_t  *intr_detach_req_op;
 };
 /* Bus Bridge Ops Vector Number */
-#define UDI_BUS_BRIDGE_OPS_NUM
+#define UDI_BUS_BRIDGE_OPS_NUM 2
 
 struct udi_bus_bind_cb_s
 {
index 9c505d3..e81b29c 100644 (file)
@@ -14,7 +14,7 @@ typedef udi_ubit8_t   udi_boolean_t;  /* 0=False; 1..28-1=True */
 #define TRUE   1
 
 typedef size_t udi_size_t;     /* buffer size */
-typedef size_t udi_index_t;    /* zero-based index type */
+typedef udi_ubit8_t    udi_index_t;    /* zero-based index type */
 
 typedef void   *_udi_handle_t;
 #define        _NULL_HANDLE    NULL
index a63ce8a..729f469 100644 (file)
@@ -11,6 +11,19 @@ typedef udi_ubit8_t  udi_instance_attr_type_t;
 #define UDI_MAX_ATTR_NAMELEN   32
 #define UDI_MAX_ATTR_SIZE              64
 
+#define UDI_ATTR32_SET(aval, v) \
+       { udi_ubit32_t vtmp = (v); \
+       (aval)[0] = (vtmp) & 0xff; \
+       (aval)[1] = ((vtmp) >> 8) & 0xff; \
+       (aval)[2] = ((vtmp) >> 16) & 0xff; \
+       (aval)[3] = ((vtmp) >> 24) & 0xff; }
+#define UDI_ATTR32_GET(aval) \
+       ((aval)[0] + ((aval)[1] << 8) + \
+       ((aval)[2] << 16) + ((aval)[3] << 24))
+#define UDI_ATTR32_INIT(v) \
+       { (v) & 0xff, ((v) >> 8) & 0xff, \
+       ((v) >> 16) & 0xff, ((v) >> 24) & 0xff }
+
 /**
  * \brief Instance Attribute
  */
index 6189e8d..177e989 100644 (file)
@@ -51,7 +51,7 @@ struct udi_init_s
         * gets for a specific ops vector.
         */
        udi_cb_select_t *cb_select_list;
-};
+} __attribute__((packed));
 
 
 /**
@@ -180,7 +180,7 @@ struct udi_ops_init_s
        /**
         * \brief Flags for each entry in \a ops_vector
         */
-       //const udi_ubit8_t     *op_flags;
+       const udi_ubit8_t       *op_flags;
 };
 
 /**
index 7b36de9..9a7438a 100644 (file)
@@ -8,13 +8,21 @@
 #include <udi.h>
 #include "udi_internal.h"
 
+// === IMPORTS ===
+extern udi_init_t      pci_init;
+extern char    pci_udiprops[];
+extern size_t  pci_udiprops_size;
+
 // === PROTOTYPES ===
  int   UDI_Install(char **Arguments);
  int   UDI_DetectDriver(void *Base);
  int   UDI_LoadDriver(void *Base);
 
+tUDI_DriverModule      *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const char *udiprops, size_t udiprops_size);
+
 tUDI_DriverInstance    *UDI_CreateInstance(tUDI_DriverModule *DriverModule);
 tUDI_DriverRegion      *UDI_InitRegion(tUDI_DriverInstance *Inst, udi_ubit16_t Index, udi_ubit16_t Type, size_t RDataSize);
+void   UDI_int_BeginEnumeration(tUDI_DriverInstance *Inst);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, UDI, UDI_Install, NULL, NULL);
@@ -30,6 +38,9 @@ tModuleLoader gUDI_Loader = {
 int UDI_Install(char **Arguments)
 {
        Module_RegisterLoader( &gUDI_Loader );
+
+       UDI_int_LoadDriver(NULL, &pci_init, pci_udiprops, pci_udiprops_size);
+
        return MODULE_ERR_OK;
 }
 
@@ -64,67 +75,64 @@ int UDI_LoadDriver(void *Base)
        char    *udiprops = NULL;
        char    *udiprops_end = 0;
        
-       ENTER("pBase", Base);
-       
        if( Binary_FindSymbol(Base, "udi_init_info", (Uint*)&info) == 0) {
                Binary_Unload(Base);
-               LEAVE('i', 0);
                return 0;
        }
        
        Binary_FindSymbol(Base, "_udiprops", (Uint*)&udiprops);
        Binary_FindSymbol(Base, "_udiprops_end", (Uint*)&udiprops_end);
+       Log_Debug("UDI", "udiprops = %p, udiprops_end = %p", udiprops, udiprops_end);
 
-       #if 0   
-       Log("primary_init_info = %p = {", info->primary_init_info);
-       {
-               Log(" .mgmt_ops = %p = {", info->primary_init_info->mgmt_ops);
-               Log("  .usage_ind_op: %p() - 0x%02x",
-                       info->primary_init_info->mgmt_ops->usage_ind_op,
-                       info->primary_init_info->mgmt_op_flags[0]
-                       );
-               Log("  .enumerate_req_op: %p() - 0x%02x",
-                       info->primary_init_info->mgmt_ops->enumerate_req_op,
-                       info->primary_init_info->mgmt_op_flags[1]
-                       );
-               Log("  .devmgmt_req_op: %p() - 0x%02x",
-                       info->primary_init_info->mgmt_ops->devmgmt_req_op,
-                       info->primary_init_info->mgmt_op_flags[2]
-                       );
-               Log("  .final_cleanup_req_op: %p() - 0x%02x",
-                       info->primary_init_info->mgmt_ops->final_cleanup_req_op,
-                       info->primary_init_info->mgmt_op_flags[3]
-                       );
-               Log(" }");
-               Log(" .mgmt_scratch_requirement = 0x%x", info->primary_init_info->mgmt_scratch_requirement);
-               Log(" .enumeration_attr_list_length = 0x%x", info->primary_init_info->enumeration_attr_list_length);
-               Log(" .rdata_size = 0x%x", info->primary_init_info->rdata_size);
-               Log(" .child_data_size = 0x%x", info->primary_init_info->child_data_size);
-               Log(" .per_parent_paths = 0x%x", info->primary_init_info->per_parent_paths);
-       }
-       Log("}");
-       Log("secondary_init_list = %p {", info->secondary_init_list);
-       for( int i = 0; info->secondary_init_list && info->secondary_init_list[i].region_idx; i ++ )
-       {
-               Log(" [%i] = { .region_idx=%i, .rdata_size=0x%x }",
-                       info->secondary_init_list[i].region_idx, info->secondary_init_list[i].rdata_size);
-       }
-       LOG("}");
-       Log("ops_init_list = %p", info->ops_init_list);
+       UDI_int_LoadDriver(Base, info, udiprops, udiprops_end - udiprops);
+
+       #if 0
+       // Create initial driver instance
+       tUDI_DriverInstance *inst = UDI_CreateInstance(driver_module);
        
-       for( int i = 0; info->ops_init_list[i].ops_idx; i++ )
+       // Bind to parent
+       // TODO: This will move to udi_enumerate_ack handling
+       for( int i = 0; i < driver_module->nParents; i ++ )
        {
-               Log("info->ops_init_list[%i] = {", i);
-               Log(" .ops_idx = 0x%x", info->ops_init_list[i].ops_idx);
-               Log(" .meta_idx = 0x%x", info->ops_init_list[i].meta_idx);
-               Log(" .meta_ops_num = 0x%x", info->ops_init_list[i].meta_ops_num);
-               Log(" .chan_context_size = 0x%x", info->ops_init_list[i].chan_context_size);
-               Log(" .ops_vector = %p", info->ops_init_list[i].ops_vector);
-//             Log(" .op_flags = %p", info->ops_init_list[i].op_flags);
-               Log("}");
+               tUDI_BindOps    *parent = &driver_module->Parents[i];
+               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,false, parent_inst, parent_chld->ops_idx, parent_chld->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");
+                       continue ;
+               }
+
+               udi_channel_event_cb_t  ev_cb;
+                int    n_handles = driver_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 = i+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_channel_event_ind(&ev_cb);
        }
+
+       // Send enumeraton request
        #endif
+       
+       return 0;
+}
 
+tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const char *udiprops, size_t udiprops_size)
+{
+       //UDI_int_DumpInitInfo(info);
        
        // TODO: Multiple modules?
        tUDI_DriverModule *driver_module = NEW(tUDI_DriverModule,);
@@ -132,10 +140,8 @@ int UDI_LoadDriver(void *Base)
 
        // - Parse udiprops
        {
-               char    **udipropsptrs;
+               const char      **udipropsptrs;
                
-               Log_Debug("UDI", "udiprops = %p, udiprops_end = %p", udiprops, udiprops_end);
-               size_t  udiprops_size = udiprops_end - udiprops;
                
                int nLines = 1;
                for( int i = 0; i < udiprops_size; i++ )
@@ -146,7 +152,7 @@ int UDI_LoadDriver(void *Base)
                
                Log_Debug("UDI", "nLines = %i", nLines);
                
-               udipropsptrs = NEW(char*,*nLines);
+               udipropsptrs = NEW(const char*,*nLines);
                int line = 0;
                udipropsptrs[line++] = udiprops;
                for( int i = 0; i < udiprops_size; i++ )
@@ -167,7 +173,6 @@ int UDI_LoadDriver(void *Base)
                // 'region' into driver_module->RegionTypes
                // 'module' into driver_module->ModuleName
                
-                int    nMessages = 0;
                 int    nLocales = 1;
                 int    nRegionTypes = 0;
                for( int i = 0; i < nLines; i ++ )
@@ -176,8 +181,11 @@ int UDI_LoadDriver(void *Base)
                        if( strncmp("module ", str, 7) == 0 ) {
                                driver_module->ModuleName = str + 7;
                        }
+                       else if( strncmp("meta ", str, 5) == 0 ) {
+                               driver_module->nMetaLangs ++;
+                       }
                        else if( strncmp("message ", str, 8) == 0 ) {
-                               nMessages ++;
+                               driver_module->nMessages ++;
                        }
                        else if( strncmp("locale ", str, 7) == 0 ) {
                                nLocales ++;
@@ -185,23 +193,41 @@ int UDI_LoadDriver(void *Base)
                        else if( strncmp("region ", str, 7) == 0 ) {
                                nRegionTypes ++;
                        }
+                       else if( strncmp("parent_bind_ops ", str, 16) == 0 ) {
+                               driver_module->nParents ++;
+                       }
                }
 
                // Allocate structures
-               driver_module->nMessages = nMessages;
-               driver_module->Messages = NEW(tUDI_PropMessage, *nMessages);
+               driver_module->Messages    = NEW(tUDI_PropMessage, * driver_module->nMessages);
                driver_module->nRegionTypes = nRegionTypes;
-               driver_module->RegionTypes = NEW(tUDI_PropRegion, *nRegionTypes);
+               driver_module->RegionTypes = NEW(tUDI_PropRegion,  * driver_module->nRegionTypes);
+               driver_module->MetaLangs   = NEW(tUDI_MetaLangRef, * driver_module->nMetaLangs);
+               driver_module->Parents     = NEW(tUDI_BindOps,     * driver_module->nParents);
 
                // Populate
                 int    cur_locale = 0;
                 int    msg_index = 0;
+                int    ml_index = 0;
+                int    parent_index = 0;
                for( int i = 0; i < nLines; i ++ )
                {
                        const char *str = udipropsptrs[i];
                        if( strncmp("module ", str, 7) == 0 ) {
                                driver_module->ModuleName = str + 7;
                        }
+                       else if( strncmp("meta ", str, 5) == 0 ) {
+                               tUDI_MetaLangRef *ml = &driver_module->MetaLangs[ml_index++];
+                               char    *end;
+                               ml->meta_idx = strtoul(str+5, &end, 10);
+                               if( *end != ' ' && !end != '\t' ) {
+                                       // TODO: handle 'meta' error
+                                       continue ;
+                               }
+                               while( isspace(*end) )
+                                       end ++;
+                               ml->interface_name = end;
+                       }
                        else if( strncmp("message ", str, 8) == 0 ) {
                                tUDI_PropMessage *msg = &driver_module->Messages[msg_index++];
                                char    *end;
@@ -215,15 +241,31 @@ int UDI_LoadDriver(void *Base)
                                        end ++;
                                msg->string = end;
                                
-                               Log_Debug("UDI", "Message %i/%i: '%s'", msg->locale, msg->index, msg->string);
+                               //Log_Debug("UDI", "Message %i/%i: '%s'", msg->locale, msg->index, msg->string);
                        }
                        else if( strncmp("locale ", str, 7) == 0 ) {
                                // TODO: Set locale
                                cur_locale = 1;
                        }
-                       else if( strncmp("region ", str, 7) == 0 ) {
-                               nRegionTypes ++;
+                       //else if( strncmp("region ", str, 7) == 0 ) {
+                       //      nRegionTypes ++;
+                       //}
+                       else if( strncmp("parent_bind_ops ", str, 16) == 0 ) {
+                               tUDI_BindOps    *bind = &driver_module->Parents[parent_index++];
+                               char *end;
+                               bind->meta_idx = strtoul(str+16, &end, 10);
+                               while(isspace(*end))    end++;
+                               bind->region_idx = strtoul(end, &end, 10);
+                               while(isspace(*end))    end++;
+                               bind->ops_idx = strtoul(end, &end, 10);
+                               while(isspace(*end))    end++;
+                               bind->bind_cb_idx = strtoul(end, &end, 10);
+                               Log_Debug("UDI", "Parent bind - meta:%i,rgn:%i,ops:%i,bind:%i",
+                                       bind->meta_idx, bind->region_idx, bind->ops_idx, bind->bind_cb_idx);
                        }
+                       //else if( strncmp("internal_bind_ops ", str, 18) == 0 ) {
+                       //      // Get region using index
+                       //}
                        else {
                                Log_Debug("UDI", "udipropsptrs[%i] = '%s'", i, udipropsptrs[i]);
                        }
@@ -236,38 +278,131 @@ int UDI_LoadDriver(void *Base)
         int    nSecondaryRgns = 0;
        for( int i = 0; info->secondary_init_list && info->secondary_init_list[i].region_idx; i ++ )
                nSecondaryRgns ++;
-       driver_module->nSecondaryRegions = nSecondaryRgns;
+       driver_module->nRegions = 1+nSecondaryRgns;
+
        
-       // Create initial driver instance
-       tUDI_DriverInstance *inst = UDI_CreateInstance(driver_module);
+       // Check for orphan drivers, and create an instance of them when loaded
+       if( driver_module->nParents == 0 )
+       {
+               tUDI_DriverInstance *inst = UDI_CreateInstance(driver_module);
+       
+               // Enumerate so any pre-loaded drivers are detected     
+               UDI_int_BeginEnumeration(inst);
+       }
+       else
+       {
+               // Send rescan requests to all loaded instances that support a parent metalang
+       }
 
-       for( int i = 0; i < 1+driver_module->nSecondaryRegions; i ++ )
-               Log("Rgn %i: %p", i, inst->Regions[i]);
+       return driver_module;
+}
 
-       // Send usage indication
-       udi_usage_cb_t ucb;
-       memset(&ucb, 0, sizeof(ucb));
-       ucb.gcb.channel = inst->ManagementChannel;
-       udi_usage_ind(&ucb, UDI_RESOURCES_NORMAL);
-       
-       return 0;
+void UDI_int_DumpInitInfo(udi_init_t *info)
+{
+       Log("primary_init_info = %p = {", info->primary_init_info);
+       {
+               Log(" .mgmt_ops = %p = {", info->primary_init_info->mgmt_ops);
+               Log("  .usage_ind_op: %p() - 0x%02x",
+                       info->primary_init_info->mgmt_ops->usage_ind_op,
+                       info->primary_init_info->mgmt_op_flags[0]
+                       );
+               Log("  .enumerate_req_op: %p() - 0x%02x",
+                       info->primary_init_info->mgmt_ops->enumerate_req_op,
+                       info->primary_init_info->mgmt_op_flags[1]
+                       );
+               Log("  .devmgmt_req_op: %p() - 0x%02x",
+                       info->primary_init_info->mgmt_ops->devmgmt_req_op,
+                       info->primary_init_info->mgmt_op_flags[2]
+                       );
+               Log("  .final_cleanup_req_op: %p() - 0x%02x",
+                       info->primary_init_info->mgmt_ops->final_cleanup_req_op,
+                       info->primary_init_info->mgmt_op_flags[3]
+                       );
+               Log(" }");
+               Log(" .mgmt_scratch_requirement = 0x%x", info->primary_init_info->mgmt_scratch_requirement);
+               Log(" .enumeration_attr_list_length = 0x%x", info->primary_init_info->enumeration_attr_list_length);
+               Log(" .rdata_size = 0x%x", info->primary_init_info->rdata_size);
+               Log(" .child_data_size = 0x%x", info->primary_init_info->child_data_size);
+               Log(" .per_parent_paths = 0x%x", info->primary_init_info->per_parent_paths);
+       }
+       Log("}");
+       Log("secondary_init_list = %p {", info->secondary_init_list);
+       for( int i = 0; info->secondary_init_list && info->secondary_init_list[i].region_idx; i ++ )
+       {
+               Log(" [%i] = { .region_idx=%i, .rdata_size=0x%x }",
+                       info->secondary_init_list[i].region_idx, info->secondary_init_list[i].rdata_size);
+       }
+       Log("}");
+       Log("ops_init_list = %p {", info->ops_init_list);
+       for( int i = 0; info->ops_init_list[i].ops_idx; i++ )
+       {
+               Log(" [%i] = {", i);
+               Log("  .ops_idx = 0x%x", info->ops_init_list[i].ops_idx);
+               Log("  .meta_idx = 0x%x", info->ops_init_list[i].meta_idx);
+               Log("  .meta_ops_num = 0x%x", info->ops_init_list[i].meta_ops_num);
+               Log("  .chan_context_size = 0x%x", info->ops_init_list[i].chan_context_size);
+               Log("  .ops_vector = %p", info->ops_init_list[i].ops_vector);
+//             Log("  .op_flags = %p", info->ops_init_list[i].op_flags);
+               Log(" }");
+       }
+       Log("}");
+       Log("cb_init_list = %p {", info->cb_init_list);
+       for( int i = 0; info->cb_init_list[i].cb_idx; i++ )
+       {
+               udi_cb_init_t   *ent = &info->cb_init_list[i];
+               Log(" [%i] = {", i);
+               Log("  .cbidx = %i", ent->cb_idx);
+               Log("  .meta_idx = %i", ent->meta_idx);
+               Log("  .meta_cb_num = %i", ent->meta_cb_num);
+               Log("  .scratch_requirement = 0x%x", ent->scratch_requirement);
+               Log("  .inline_size = 0x%x", ent->inline_size);
+               Log("  .inline_layout = %p", ent->inline_layout);
+               Log(" }");
+       }
 }
 
 tUDI_DriverInstance *UDI_CreateInstance(tUDI_DriverModule *DriverModule)
 {
-       tUDI_DriverInstance     *inst = NEW_wA(tUDI_DriverInstance, Regions, (1+DriverModule->nSecondaryRegions));
+       tUDI_DriverInstance     *inst = NEW_wA(tUDI_DriverInstance, Regions, DriverModule->nRegions);
+       udi_primary_init_t      *pri_init = DriverModule->InitInfo->primary_init_info;
        inst->Module = DriverModule;
-       inst->Regions[0] = UDI_InitRegion(inst, 0, 0, DriverModule->InitInfo->primary_init_info->rdata_size);
+       inst->Regions[0] = UDI_InitRegion(inst, 0, 0, pri_init->rdata_size);
        udi_secondary_init_t    *sec_init = DriverModule->InitInfo->secondary_init_list;
        if( sec_init )
        {
                for( int i = 0; sec_init[i].region_idx; i ++ )
                {
-                       inst->Regions[1+i] = UDI_InitRegion(inst, i, sec_init[i].region_idx, sec_init[i].rdata_size);
+                       inst->Regions[1+i] = UDI_InitRegion(inst, i,
+                               sec_init[i].region_idx, sec_init[i].rdata_size);
                }
        }
 
-       inst->ManagementChannel = UDI_CreateChannel(METALANG_MGMT, 0, NULL, 0, inst, 0);
+       //inst->ManagementChannel = UDI_CreateChannel(METALANG_MGMT, 0, NULL, 0, inst, 0);
+       inst->ManagementChannel = UDI_CreateChannel_Blank(&cMetaLang_Management);
+       UDI_BindChannel_Raw(inst->ManagementChannel, true,
+               0, inst->Regions[0]->InitContext, pri_init->mgmt_ops);
+//     UDI_BindChannel_Raw(inst->ManagementChannel, false,
+//             1, inst, NULL); // TODO: ops list for management
+
+       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 ++ )
+       {
+               //inst->Regions[i]->PriChannel = UDI_CreateChannel_Blank(
+               // TODO: Bind secondaries to primary
+       }
        
        return inst;
 }
@@ -275,7 +410,7 @@ tUDI_DriverInstance *UDI_CreateInstance(tUDI_DriverModule *DriverModule)
 tUDI_DriverRegion *UDI_InitRegion(tUDI_DriverInstance *Inst, udi_ubit16_t Index, udi_ubit16_t Type, size_t RDataSize)
 {
 //     ASSERTCR( RDataSize, <=, UDI_MIN_ALLOC_LIMIT, NULL );
-       ASSERTCR( RDataSize, >, sizeof(udi_init_context_t), NULL );
+       ASSERTCR( RDataSize, >=, sizeof(udi_init_context_t), NULL );
        tUDI_DriverRegion       *rgn = NEW(tUDI_DriverRegion,+RDataSize);
        rgn->InitContext = (void*)(rgn+1);
        rgn->InitContext->region_idx = Type;
@@ -283,3 +418,58 @@ tUDI_DriverRegion *UDI_InitRegion(tUDI_DriverInstance *Inst, udi_ubit16_t Index,
        return rgn;
 }
 
+void UDI_int_BeginEnumeration(tUDI_DriverInstance *Inst)
+{
+       udi_primary_init_t *pri_init = Inst->Module->InitInfo->primary_init_info;
+       char scratch[pri_init->mgmt_scratch_requirement];
+       udi_enumerate_cb_t      ecb;
+       memset(&ecb, 0, sizeof(ecb));
+       ecb.gcb.scratch = scratch;
+       ecb.gcb.channel = Inst->ManagementChannel;
+       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;
+       udi_enumerate_req(&ecb, UDI_ENUMERATE_START);
+}
+
+// TODO: Move this stuff out
+udi_ops_init_t *UDI_int_GetOps(tUDI_DriverInstance *Inst, udi_index_t index)
+{
+       udi_ops_init_t *ops = Inst->Module->InitInfo->ops_init_list;
+       while( ops->ops_idx && ops->ops_idx != index )
+               ops ++;
+       if(ops->ops_idx == 0)
+               return NULL;
+       return ops;
+}
+
+tUDI_MetaLang *UDI_int_GetMetaLang(tUDI_DriverInstance *Inst, udi_index_t index)
+{
+       if( index == 0 )
+               return &cMetaLang_Management;
+       for( int i = 0; i < Inst->Module->nMetaLangs; i ++ )
+       {
+               if( Inst->Module->MetaLangs[i].meta_idx == index )
+                       return Inst->Module->MetaLangs[i].metalang;
+       }
+       return NULL;
+}
+
+void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, udi_channel_t channel)
+{
+       udi_cb_init_t   *cb_init = NULL;
+       for( cb_init = Inst->Module->InitInfo->cb_init_list; cb_init->cb_idx; cb_init ++ )
+       {
+               if( cb_init->cb_idx == bind_cb_idx )
+               {
+                       udi_cb_t *ret = NEW(udi_cb_t, + cb_init->inline_size + cb_init->scratch_requirement);
+                       ret->channel = channel;
+                       return ret;
+               }
+       }
+       Log_Warning("UDI", "Cannot find CB init def %i for '%s'",
+               bind_cb_idx, Inst->Module->ModuleName);
+       return NULL;
+       
+}
+
diff --git a/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c b/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c
new file mode 100644 (file)
index 0000000..96e1462
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Acess2 UDI Layer
+ * - By John Hodge (thePowersGang)
+ *
+ * trans/bus_pci.c
+ * - PCI Bus Driver
+ */
+#include <udi.h>
+#include <udi_physio.h>
+#include <drv_pci.h>   // acess
+
+// === MACROS ===
+/* Copied from http://projectudi.cvs.sourceforge.net/viewvc/projectudi/udiref/driver/udi_dpt/udi_dpt.h */
+#define DPT_SET_ATTR_BOOLEAN(attr, name, val)  \
+               udi_strcpy((attr)->attr_name, (name)); \
+               (attr)->attr_type = UDI_ATTR_BOOLEAN; \
+               (attr)->attr_length = sizeof(udi_boolean_t); \
+               UDI_ATTR32_SET((attr)->attr_value, (val))
+
+#define DPT_SET_ATTR32(attr, name, val)        \
+               udi_strcpy((attr)->attr_name, (name)); \
+               (attr)->attr_type = UDI_ATTR_UBIT32; \
+               (attr)->attr_length = sizeof(udi_ubit32_t); \
+               UDI_ATTR32_SET((attr)->attr_value, (val))
+
+#define DPT_SET_ATTR_ARRAY8(attr, name, val, len) \
+               udi_strcpy((attr)->attr_name, (name)); \
+               (attr)->attr_type = UDI_ATTR_ARRAY8; \
+               (attr)->attr_length = (len); \
+               udi_memcpy((attr)->attr_value, (val), (len))
+
+#define DPT_SET_ATTR_STRING(attr, name, val, len) \
+               udi_strcpy((attr)->attr_name, (name)); \
+               (attr)->attr_type = UDI_ATTR_STRING; \
+               (attr)->attr_length = (len); \
+               udi_strncpy_rtrim((char *)(attr)->attr_value, (val), (len))
+
+
+// === TYPES ===
+typedef struct
+{
+       udi_init_context_t      init_context;
+       
+       tPCIDev cur_iter;
+} pci_rdata_t;
+
+// === PROTOTYPES ===
+void   pci_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level);
+void   pci_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level);
+void   pci_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID);
+void   pci_final_cleanup_req(udi_mgmt_cb_t *cb);
+
+void   pci_bridge_ch_event_ind(udi_channel_event_cb_t *cb);
+void   pci_unbind_req(udi_bus_bind_cb_t *cb);
+void   pci_bind_req_op(udi_bus_bind_cb_t *cb);
+void   pci_intr_attach_req(udi_intr_attach_cb_t *cb);
+void   pci_intr_detach_req(udi_intr_detach_cb_t *cb);
+
+
+// === CODE ===
+void pci_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
+{
+       UNIMPLEMENTED();
+}
+void pci_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
+{
+       pci_rdata_t     *rdata = UDI_GCB(cb)->context;
+       switch(enumeration_level)
+       {
+       case UDI_ENUMERATE_START:
+       case UDI_ENUMERATE_START_RESCAN:
+               rdata->cur_iter = -1;
+       case UDI_ENUMERATE_NEXT:
+               // TODO: Filters
+               if( (rdata->cur_iter = PCI_GetDeviceByClass(0,0, rdata->cur_iter)) == -1 )
+               {
+                       udi_enumerate_ack(cb, UDI_ENUMERATE_DONE, 0);
+               }
+               else
+               {
+                       udi_instance_attr_list_t *attr_list = cb->attr_list;
+                       Uint16  ven, dev;
+                       Uint32  class;
+                       PCI_GetDeviceInfo(rdata->cur_iter, &ven, &dev, &class);
+
+                       DPT_SET_ATTR_STRING(attr_list, "bus_type", "pci", 3);
+                       attr_list ++;
+                       DPT_SET_ATTR32(attr_list, "pci_vendor_id", ven);
+                       attr_list ++;
+                       DPT_SET_ATTR32(attr_list, "pci_device_id", dev);
+                       attr_list ++;
+
+                       cb->attr_valid_length = attr_list - cb->attr_list;
+                       udi_enumerate_ack(cb, UDI_ENUMERATE_OK, 0);
+               }
+               break;
+       }
+}
+void pci_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID)
+{
+       UNIMPLEMENTED();
+}
+void pci_final_cleanup_req(udi_mgmt_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+
+void pci_bridge_ch_event_ind(udi_channel_event_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void pci_unbind_req(udi_bus_bind_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void pci_bind_req_op(udi_bus_bind_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void pci_intr_attach_req(udi_intr_attach_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+void pci_intr_detach_req(udi_intr_detach_cb_t *cb)
+{
+       UNIMPLEMENTED();
+}
+
+// === UDI Functions ===
+udi_mgmt_ops_t pci_mgmt_ops = {
+       pci_usage_ind,
+       pci_enumerate_req,
+       pci_devmgmt_req,
+       pci_final_cleanup_req
+};
+udi_ubit8_t    pci_mgmt_op_flags[4] = {0,0,0,0};
+udi_bus_bridge_ops_t   pci_bridge_ops = {
+       pci_bridge_ch_event_ind,
+       pci_unbind_req,
+       pci_bind_req_op,
+       pci_intr_attach_req,
+       pci_intr_detach_req
+};
+udi_ubit8_t    pci_bridge_op_flags[5] = {0,0,0,0,0};
+udi_primary_init_t     pci_pri_init = {
+       .mgmt_ops = &pci_mgmt_ops,
+       .mgmt_op_flags = pci_mgmt_op_flags,
+       .mgmt_scratch_requirement = 0,
+       .enumeration_attr_list_length = 4,
+       .rdata_size = sizeof(pci_rdata_t),
+       .child_data_size = 0,
+       .per_parent_paths = 0
+};
+udi_ops_init_t pci_ops_list[] = {
+       {
+               1, 1, UDI_BUS_BRIDGE_OPS_NUM,
+               0,
+               (udi_ops_vector_t*)&pci_bridge_ops,
+               pci_bridge_op_flags
+       },
+       {0}
+};
+udi_init_t     pci_init = {
+       .primary_init_info = &pci_pri_init,
+       .ops_init_list = pci_ops_list
+};
+const char     pci_udiprops[] =
+       "properties_version 0x101\0"
+       "message 1 Acess2 Kernel\0"
+       "message 2 John Hodge ([email protected])\0"
+       "message 3 Acess2 PCI Bus\0"
+       "supplier 1\0"
+       "contact 2\0"
+       "name 3\0"
+       "module acess_pci\0"
+       "shortname acesspci\0"
+       "requires udi 0x101\0"
+       "provides udi_bridge 0x101\0"
+       "meta 1 udi_bridge\0"
+       "region 0\0"
+       "child_bind_ops 1 0 1\0"
+       "";
+size_t pci_udiprops_size = sizeof(pci_udiprops);
index d9a5c00..be9f5bc 100644 (file)
@@ -8,12 +8,19 @@
 #ifndef _UDI_INTERNAL_H_
 #define _UDI_INTERNAL_H_
 
+#include <stdbool.h>
+
 #define NEW(type,extra) (type*)calloc(sizeof(type)extra,1)
 #define NEW_wA(type,fld,cnt)   NEW(type,+(sizeof(((type*)NULL)->fld[0])*cnt))
 
 typedef struct sUDI_PropMessage        tUDI_PropMessage;
 typedef struct sUDI_PropRegion         tUDI_PropRegion;
 
+typedef const struct sUDI_MetaLang     tUDI_MetaLang;
+
+typedef struct sUDI_MetaLangRef        tUDI_MetaLangRef;
+typedef struct sUDI_BindOps    tUDI_BindOps;
+
 typedef struct sUDI_DriverModule       tUDI_DriverModule;
 typedef struct sUDI_DriverInstance     tUDI_DriverInstance;
 typedef struct sUDI_DriverRegion       tUDI_DriverRegion;
@@ -53,12 +60,41 @@ struct sUDI_PropRegion
 
 };
 
+struct sUDI_MetaLang
+{
+       const char *Name;
+        int    nOpGroups;
+       struct {
+               void    *OpList;
+       } OpGroups;
+};
+
+struct sUDI_MetaLangRef
+{
+       udi_ubit8_t     meta_idx;
+       const char      *interface_name;
+       tUDI_MetaLang   *metalang;
+       // TODO: pointer to metalanguage structure
+};
+
+struct sUDI_BindOps
+{
+       udi_ubit8_t     meta_idx;
+       udi_ubit8_t     region_idx;
+       udi_ubit8_t     ops_idx;
+       udi_ubit8_t     bind_cb_idx;
+};
+
 struct sUDI_DriverModule
 {
        tUDI_DriverModule       *Next;
        void    *Base;
 
        udi_init_t      *InitInfo;
+
+       // Counts of arrays in InitInfo
+        int    nCBInit;
+        int    nOpsInit;
                
        const char      *ModuleName;
         int    nMessages;
@@ -68,9 +104,11 @@ struct sUDI_DriverModule
        tUDI_PropRegion *RegionTypes;
 
         int    nMetaLangs;
-       enum eUDI_MetaLang      *MetaLangs;
-       
-        int    nSecondaryRegions;
+       tUDI_MetaLangRef        *MetaLangs;
+
+        int    nParents;
+       tUDI_BindOps    *Parents;
+        int    nRegions;
 };
 
 struct sUDI_DriverInstance
@@ -85,17 +123,39 @@ struct sUDI_DriverRegion
        udi_init_context_t      *InitContext;
 };
 
-enum eUDI_MetaLang
+
+extern tUDI_MetaLang   cMetaLang_Management;
+
+
+// --- Index to pointer translation ---
+extern udi_ops_init_t  *UDI_int_GetOps(tUDI_DriverInstance *Inst, udi_index_t index);
+extern tUDI_MetaLang *UDI_int_GetMetaLang(tUDI_DriverInstance *Inst, udi_index_t meta_idx);
+
+// --- Channels ---
+extern udi_channel_t   UDI_CreateChannel_Blank(tUDI_MetaLang *metalang);
+extern int     UDI_BindChannel_Raw(udi_channel_t channel, bool other_side, udi_index_t meta_ops_num, void *context, const void *ops);
+extern int     UDI_BindChannel(udi_channel_t channel, bool other_side, tUDI_DriverInstance *inst, udi_index_t ops, udi_index_t region);
+extern const void      *UDI_int_ChannelPrepForCall(udi_cb_t *gcb, tUDI_MetaLang *metalang, udi_index_t meta_ops_num);
+extern void    UDI_int_ChannelReleaseFromCall(udi_cb_t *gcb);
+
+// --- Async Calls ---
+typedef struct sUDI_DeferredCall       tUDI_DeferredCall;
+typedef void   tUDI_DeferredUnmarshal(tUDI_DeferredCall *Call);
+struct sUDI_DeferredCall
 {
-       METALANG_MGMT,
-       METALANG_BUS
+       struct sUDI_DeferredCall        *Next;
+       tUDI_DeferredUnmarshal  *Unmarshal;
+       udi_op_t        *Handler;
+       // ...
 };
+extern void    UDI_int_AddDeferred(tUDI_DeferredCall *Call);
+extern void    UDI_int_MakeDeferredCb(udi_cb_t *cb, udi_op_t *handler);
+extern void    UDI_int_MakeDeferredCbU8(udi_cb_t *cb, udi_op_t *handler, udi_ubit8_t arg1);
+extern void    UDI_int_MakeDeferredCbS(udi_cb_t *cb, udi_op_t *handler, udi_status_t status);
 
-extern udi_channel_t   UDI_CreateChannel(enum eUDI_MetaLang metalang, udi_index_t meta_ops_num,
-       tUDI_DriverInstance *ThisEnd, udi_index_t ThisOpsIndex,
-       tUDI_DriverInstance *OtherEnd, udi_index_t OtherOpsIndex);
+// --- CBs ---
+extern void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, udi_channel_t channel);
 
-extern const void      *UDI_int_ChannelPrepForCall(udi_cb_t *gcb, enum eUDI_MetaLang metalang, udi_index_t meta_ops_num);
 
 #endif
 
index cd15e07..2f9f3fe 100644 (file)
@@ -2,8 +2,11 @@
  * \file imc.c
  * \author John Hodge (thePowersGang)
  */
+#define DEBUG  1
 #include <acess.h>
 #include <udi.h>
+//#include "internal/channels.h"
+#include "../udi_internal.h"
 
 // === EXPORTS ===
 EXPORT(udi_channel_anchor);
@@ -60,7 +63,19 @@ void udi_channel_close(udi_channel_t channel)
 
 void udi_channel_event_ind(udi_channel_event_cb_t *cb)
 {
-       udi_channel_event_complete(cb, UDI_OK);
+       LOG("cb=%p{...}", cb);
+       const struct {
+               udi_channel_event_ind_op_t *channel_event_ind_op;
+       } *ops = UDI_int_ChannelPrepForCall( UDI_GCB(cb), NULL, 0 );
+       if(!ops) {
+               Log_Warning("UDI", "udi_channel_event_ind on wrong channel type");
+               return ;
+       }
+
+       // UDI_int_MakeDeferredCb( UDI_GCB(cb), ops->channel_event_ind_op );
+
+       UDI_int_ChannelReleaseFromCall( UDI_GCB(cb) );  
+       ops->channel_event_ind_op(cb);
 }
 
 void udi_channel_event_complete(udi_channel_event_cb_t *cb, udi_status_t status)
index 4d91c62..eef1070 100644 (file)
@@ -4,6 +4,7 @@
  *
  * \brief UDI Tracing, Logging and Debug
  */
+#define DEBUG  1
 #include <acess.h>
 #include <udi.h>
 
index 3156ce9..11d35a2 100644 (file)
@@ -2,6 +2,7 @@
  * \file meta_mgmt.c
  * \author John Hodge (thePowersGang)
  */
+#define DEBUG  1
 #include <acess.h>
 #include <udi.h>
 #include "../udi_internal.h"
@@ -18,12 +19,19 @@ EXPORT(udi_devmgmt_ack);
 EXPORT(udi_final_cleanup_req);
 EXPORT(udi_final_cleanup_ack);
 
+tUDI_MetaLang  cMetaLang_Management = {
+       "udi_mgmt",
+       1,
+       {NULL}
+};
+
 // === CODE ===
 void udi_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
 {
-       const udi_mgmt_ops_t *ops;
-       if( !(ops = UDI_int_ChannelPrepForCall( UDI_GCB(cb), METALANG_MGMT, 0 )) ) {
-               Log_Warning("UDI", "udi_usage_ind on wrong channel type");
+       LOG("cb=%p{...}, resource_level=%i", cb, resource_level);
+       const udi_mgmt_ops_t *ops = UDI_int_ChannelPrepForCall( UDI_GCB(cb), &cMetaLang_Management, 0 );
+       if(!ops) {
+               Log_Warning("UDI", "%s on wrong channel type", __func__);
                return ;
        }
        
@@ -42,12 +50,19 @@ void udi_usage_res(udi_usage_cb_t *cb)
 
 void udi_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
 {
-       UNIMPLEMENTED();
+       LOG("cb=%p{...}, enumeration_level=%i", cb, enumeration_level);
+       const udi_mgmt_ops_t *ops = UDI_int_ChannelPrepForCall( UDI_GCB(cb), &cMetaLang_Management, 0 );
+       if(!ops) {
+               Log_Warning("UDI", "%s on wrong channel type", __func__);
+               return ;
+       }
+       
+       ops->enumerate_req_op(cb, enumeration_level);
 }
 
 void udi_enumerate_no_children(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
 {
-       UNIMPLEMENTED();
+       udi_enumerate_ack(cb, UDI_ENUMERATE_LEAF, 0);
 }
 
 void udi_enumerate_ack(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_result, udi_index_t ops_idx)
index 870191d..3f08ca9 100644 (file)
@@ -26,6 +26,10 @@ EXPORT(udi_snprintf);
 EXPORT(udi_vsnprintf);
 
 // === CODE ===
+char *udi_strcpy(char *s1, const char *s2)
+{
+       return strcpy(s1, s2);
+}
 char *udi_strncpy_rtrim(char *s1, const char *s2, udi_size_t n)
 {
        char *dst = s1;

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