From c0f20e1d9a03ae5026b345748d1e30b7dc142596 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 17 Sep 2013 22:47:31 +0800 Subject: [PATCH] Modules/UDI - Working on more framework and PCI bus - No longer crashes on boot, so that's a plus - Working on deferred call framework to avoid huge stack chaining --- KernelLand/Modules/Interfaces/UDI/Makefile | 2 +- KernelLand/Modules/Interfaces/UDI/channels.c | 143 ++++++-- .../Interfaces/UDI/include/physio/meta_bus.h | 2 +- .../Interfaces/UDI/include/udi/arch/x86.h | 2 +- .../Modules/Interfaces/UDI/include/udi/attr.h | 13 + .../Modules/Interfaces/UDI/include/udi/init.h | 4 +- KernelLand/Modules/Interfaces/UDI/main.c | 344 ++++++++++++++---- .../Modules/Interfaces/UDI/trans/bus_pci.c | 183 ++++++++++ .../Modules/Interfaces/UDI/udi_internal.h | 80 +++- .../Modules/Interfaces/UDI/udi_lib/imc.c | 17 +- .../Modules/Interfaces/UDI/udi_lib/logging.c | 1 + .../Interfaces/UDI/udi_lib/meta_mgmt.c | 25 +- .../Modules/Interfaces/UDI/udi_lib/strmem.c | 4 + 13 files changed, 686 insertions(+), 134 deletions(-) create mode 100644 KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c diff --git a/KernelLand/Modules/Interfaces/UDI/Makefile b/KernelLand/Modules/Interfaces/UDI/Makefile index 9613127c..dde172c3 100644 --- a/KernelLand/Modules/Interfaces/UDI/Makefile +++ b/KernelLand/Modules/Interfaces/UDI/Makefile @@ -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/%) diff --git a/KernelLand/Modules/Interfaces/UDI/channels.c b/KernelLand/Modules/Interfaces/UDI/channels.c index d232e034..8f96d341 100644 --- a/KernelLand/Modules/Interfaces/UDI/channels.c +++ b/KernelLand/Modules/Interfaces/UDI/channels.c @@ -9,57 +9,85 @@ #include #include #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 +} + diff --git a/KernelLand/Modules/Interfaces/UDI/include/physio/meta_bus.h b/KernelLand/Modules/Interfaces/UDI/include/physio/meta_bus.h index 7b88ece8..f1af116f 100644 --- a/KernelLand/Modules/Interfaces/UDI/include/physio/meta_bus.h +++ b/KernelLand/Modules/Interfaces/UDI/include/physio/meta_bus.h @@ -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 { diff --git a/KernelLand/Modules/Interfaces/UDI/include/udi/arch/x86.h b/KernelLand/Modules/Interfaces/UDI/include/udi/arch/x86.h index 9c505d33..e81b29ca 100644 --- a/KernelLand/Modules/Interfaces/UDI/include/udi/arch/x86.h +++ b/KernelLand/Modules/Interfaces/UDI/include/udi/arch/x86.h @@ -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 diff --git a/KernelLand/Modules/Interfaces/UDI/include/udi/attr.h b/KernelLand/Modules/Interfaces/UDI/include/udi/attr.h index a63ce8a7..729f4698 100644 --- a/KernelLand/Modules/Interfaces/UDI/include/udi/attr.h +++ b/KernelLand/Modules/Interfaces/UDI/include/udi/attr.h @@ -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 */ diff --git a/KernelLand/Modules/Interfaces/UDI/include/udi/init.h b/KernelLand/Modules/Interfaces/UDI/include/udi/init.h index 6189e8dc..177e989d 100644 --- a/KernelLand/Modules/Interfaces/UDI/include/udi/init.h +++ b/KernelLand/Modules/Interfaces/UDI/include/udi/init.h @@ -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; }; /** diff --git a/KernelLand/Modules/Interfaces/UDI/main.c b/KernelLand/Modules/Interfaces/UDI/main.c index 7b36de96..9a7438a2 100644 --- a/KernelLand/Modules/Interfaces/UDI/main.c +++ b/KernelLand/Modules/Interfaces/UDI/main.c @@ -8,13 +8,21 @@ #include #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 index 00000000..96e1462e --- /dev/null +++ b/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c @@ -0,0 +1,183 @@ +/* + * Acess2 UDI Layer + * - By John Hodge (thePowersGang) + * + * trans/bus_pci.c + * - PCI Bus Driver + */ +#include +#include +#include // 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 (acess@mutabah.net)\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); diff --git a/KernelLand/Modules/Interfaces/UDI/udi_internal.h b/KernelLand/Modules/Interfaces/UDI/udi_internal.h index d9a5c001..be9f5bc3 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_internal.h +++ b/KernelLand/Modules/Interfaces/UDI/udi_internal.h @@ -8,12 +8,19 @@ #ifndef _UDI_INTERNAL_H_ #define _UDI_INTERNAL_H_ +#include + #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 diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/imc.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/imc.c index cd15e070..2f9f3fe6 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/imc.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/imc.c @@ -2,8 +2,11 @@ * \file imc.c * \author John Hodge (thePowersGang) */ +#define DEBUG 1 #include #include +//#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) diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/logging.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/logging.c index 4d91c624..eef10709 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/logging.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/logging.c @@ -4,6 +4,7 @@ * * \brief UDI Tracing, Logging and Debug */ +#define DEBUG 1 #include #include diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/meta_mgmt.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/meta_mgmt.c index 3156ce96..11d35a2c 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/meta_mgmt.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/meta_mgmt.c @@ -2,6 +2,7 @@ * \file meta_mgmt.c * \author John Hodge (thePowersGang) */ +#define DEBUG 1 #include #include #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) diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/strmem.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/strmem.c index 870191d7..3f08ca99 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/strmem.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/strmem.c @@ -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; -- 2.20.1