Usermode/libc++ - Implement map::insert and map::erase
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / main.c
index 1d1b28c..4a655f0 100644 (file)
@@ -1,24 +1,27 @@
 /*
  * Acess2 UDI Layer
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - UDI Entrypoint and Module loading
  */
-#define DEBUG  0
+#define DEBUG  1
 #define VERSION        ((0<<8)|1)
 #include <acess.h>
 #include <modules.h>
 #include <udi.h>
-#include "udi_internal.h"
-#include "udi_ma.h"
-
-// === IMPORTS ===
-extern udi_init_t      pci_init;
-extern char    pci_udiprops[];
-extern size_t  pci_udiprops_size;
+#include <udi_internal.h>
+#include <udi_internal_ma.h>
+#include <trans_pci.h>
+#include <trans_nsr.h>
+#include <trans_uart.h>
 
 // === 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);
+ int   UDI_LoadDriver(void *Base, const char *ArgumentString);
+tUDI_DriverModule      *UDI_int_LoadDriver(void *LoadBase, const udi_init_t *info, const char *udiprops, size_t udiprops_size);
+const tUDI_MetaLang    *UDI_int_GetMetaLangByName(const char *Name);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, UDI, UDI_Install, NULL, NULL);
@@ -34,11 +37,17 @@ tUDI_DriverModule   *gpUDI_LoadedModules;
  */
 int UDI_Install(char **Arguments)
 {
+       if( Arguments && Arguments[0] && strcmp(Arguments[0], "disable") == 0 ) {
+               // Module disabled by user
+               return MODULE_ERR_NOTNEEDED;
+       }
        Module_RegisterLoader( &gUDI_Loader );
 
        Proc_SpawnWorker(UDI_int_DeferredThread, NULL);
 
        UDI_int_LoadDriver(NULL, &pci_init, pci_udiprops, pci_udiprops_size);
+       UDI_int_LoadDriver(NULL, &acessnsr_init, acessnsr_udiprops, acessnsr_udiprops_size);
+       UDI_int_LoadDriver(NULL, &acessuart_init, acessuart_udiprops, acessuart_udiprops_size);
 
        return MODULE_ERR_OK;
 }
@@ -68,7 +77,7 @@ int UDI_DetectDriver(void *Base)
 /**
  * \fn int UDI_LoadDriver(void *Base)
  */
-int UDI_LoadDriver(void *Base)
+int UDI_LoadDriver(void *Base, const char *ArgumentString)
 {
        udi_init_t      *info;
        char    *udiprops = NULL;
@@ -85,6 +94,9 @@ int UDI_LoadDriver(void *Base)
 
        UDI_int_LoadDriver(Base, info, udiprops, udiprops_end - udiprops);
        
+       // TODO: Parse 'ArgumentString' and extract properties for module/instances
+       // - Including debug flag
+       
        return 0;
 }
 
@@ -113,10 +125,10 @@ static udi_boolean_t _get_token_bool(const char *str, const char **outstr)
 static udi_index_t _get_token_idx(const char *str, const char **outstr)
 {
        char    *end;
-       int ret = strtol(str, &end, 10);
-       if( ret < 0 || ret > 255 ) {
-               Log_Notice("UDI", "Value '%.*s' out of range for udi_index_t",
-                       end-str, str);
+       unsigned long ret = strtoul(str, &end, 10);
+       if( ret > 255 ) {
+               Log_Notice("UDI", "Value '%.*s' (0x%lx) out of range for udi_index_t",
+                       end-str, str, ret);
                *outstr = NULL;
                return 0;
        }
@@ -137,8 +149,8 @@ static udi_ubit16_t _get_token_uint16(const char *str, const char **outstr)
        char    *end;
        unsigned long ret = strtoul(str, &end, 10);
        if( ret > 0xFFFF ) {
-               Log_Notice("UDI", "Value '%.*s' out of range for udi_ubit16_t",
-                       end-str, str);
+               Log_Notice("UDI", "Value '%.*s' (0x%lx) out of range for udi_ubit16_t",
+                       end-str, str, ret);
                *outstr = NULL;
                return 0;
        }
@@ -317,7 +329,7 @@ const char *caUDI_UdipropsNames[] = {
 };
 #undef _defpropname
 
-tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const char *udiprops, size_t udiprops_size)
+tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, const udi_init_t *info, const char *udiprops, size_t udiprops_size)
 {
        //UDI_int_DumpInitInfo(info);
        
@@ -326,333 +338,376 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
        driver_module->InitInfo = info;
 
        // - Parse udiprops
+       const char      **udipropsptrs;
+       
+       int nLines = 1;
+       for( int i = 0; i < udiprops_size; i++ )
        {
-               const char      **udipropsptrs;
-               
-               
-               int nLines = 1;
-               for( int i = 0; i < udiprops_size; i++ )
-               {
-                       if( udiprops[i] == '\0' )
-                               nLines ++;
-               }
-               
-               Log_Debug("UDI", "nLines = %i", nLines);
-               
-               udipropsptrs = NEW(const char*,*nLines);
-               int line = 0;
-               udipropsptrs[line++] = udiprops;
-               for( int i = 0; i < udiprops_size; i++ )
-               {
-                       if( udiprops[i] == '\0' ) {
-                               udipropsptrs[line++] = &udiprops[i+1];
-                       }
+               if( udiprops[i] == '\0' )
+                       nLines ++;
+       }
+       
+       Log_Debug("UDI", "nLines = %i", nLines);
+       
+       udipropsptrs = NEW(const char*,*nLines);
+       int line = 0;
+       udipropsptrs[line++] = udiprops;
+       for( int i = 0; i < udiprops_size; i++ )
+       {
+               if( udiprops[i] == '\0' ) {
+                       udipropsptrs[line++] = &udiprops[i+1];
                }
-               if(udipropsptrs[line-1] == &udiprops[udiprops_size])
-                       nLines --;
-               
-               // Parse out:
-               // 'message' into driver_module->Messages
-               // 'region' into driver_module->RegionTypes
-               // 'module' into driver_module->ModuleName
-               
-                int    nLocales = 1;
-               for( int i = 0; i < nLines; i ++ )
+       }
+       if(udipropsptrs[line-1] == &udiprops[udiprops_size])
+               nLines --;
+       
+       // Parse out:
+       // 'message' into driver_module->Messages
+       // 'region' into driver_module->RegionTypes
+       // 'module' into driver_module->ModuleName
+       
+        int    nLocales = 1;
+       for( int i = 0; i < nLines; i ++ )
+       {
+               const char *str = udipropsptrs[i];
+                int    sym = _get_token_sym_v(str, &str, false, caUDI_UdipropsNames);
+               switch(sym)
                {
-                       const char *str = udipropsptrs[i];
-                        int    sym = _get_token_sym_v(str, &str, false, caUDI_UdipropsNames);
-                       switch(sym)
-                       {
-                       case UDIPROPS__module:
-                               driver_module->ModuleName = str;
-                               break;
-                       case UDIPROPS__meta:
-                               driver_module->nMetaLangs ++;
-                               break;
-                       case UDIPROPS__message:
-                               driver_module->nMessages ++;
-                               break;
-                       case UDIPROPS__locale:
-                               nLocales ++;
-                               break;
-                       case UDIPROPS__region:
-                               driver_module->nRegionTypes ++;
-                               break;
-                       case UDIPROPS__device:
-                               driver_module->nDevices ++;
-                               break;
-                       case UDIPROPS__parent_bind_ops:
-                               driver_module->nParents ++;
-                               break;
-                       case UDIPROPS__child_bind_ops:
-                               driver_module->nChildBindOps ++;
-                               break;
-                       default:
-                               // quiet ignore
-                               break;
-                       }
+               case UDIPROPS__module:
+                       driver_module->ModuleName = str;
+                       break;
+               case UDIPROPS__meta:
+                       driver_module->nMetaLangs ++;
+                       break;
+               case UDIPROPS__message:
+                       driver_module->nMessages ++;
+                       break;
+               case UDIPROPS__locale:
+                       nLocales ++;
+                       break;
+               case UDIPROPS__region:
+                       driver_module->nRegionTypes ++;
+                       break;
+               case UDIPROPS__device:
+                       driver_module->nDevices ++;
+                       break;
+               case UDIPROPS__parent_bind_ops:
+                       driver_module->nParents ++;
+                       break;
+               case UDIPROPS__child_bind_ops:
+                       driver_module->nChildBindOps ++;
+                       break;
+               default:
+                       // quiet ignore
+                       break;
                }
+       }
 
-               // Allocate structures
-               driver_module->Messages     = NEW(tUDI_PropMessage, * driver_module->nMessages);
-               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);
-               driver_module->ChildBindOps = NEW(tUDI_BindOps,     * driver_module->nChildBindOps);
-               driver_module->Devices      = NEW(tUDI_PropDevSpec*,* driver_module->nDevices);
+       // Allocate structures
+       LOG("nMessages = %i, nMetaLangs = %i",
+               driver_module->nMessages,
+               driver_module->nMetaLangs);
+       driver_module->Messages     = NEW(tUDI_PropMessage, * driver_module->nMessages);
+       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);
+       driver_module->ChildBindOps = NEW(tUDI_BindOps,     * driver_module->nChildBindOps);
+       driver_module->Devices      = NEW(tUDI_PropDevSpec*,* driver_module->nDevices);
 
-               // Populate
-                int    cur_locale = 0;
-                int    msg_index = 0;
-                int    ml_index = 0;
-                int    parent_index = 0;
-                int    child_bind_index = 0;
-                int    next_unpop_region = 1;
-               for( int i = 0; i < nLines; i ++ )
+       // Populate
+       bool    error_hit = false;
+        int    cur_locale = 0;
+        int    msg_index = 0;
+        int    ml_index = 0;
+        int    parent_index = 0;
+        int    child_bind_index = 0;
+        int    device_index = 0;
+        int    next_unpop_region = 1;
+       #define IF_ERROR(op)    if(!str){error_hit=1;op;}
+       for( int i = 0; i < nLines; i ++ )
+       {
+               const char *str = udipropsptrs[i];
+               if( !*str )
+                       continue ;
+                int    sym = _get_token_sym_v(str, &str, true, caUDI_UdipropsNames);
+               //LOG("Processing option '%s'", (sym >= 0 ? caUDI_UdipropsNames[sym] : "ERR"));
+               switch(sym)
                {
-                       const char *str = udipropsptrs[i];
-                       if( !*str )
-                               continue ;
-                        int    sym = _get_token_sym_v(str, &str, true, caUDI_UdipropsNames);
-                       switch(sym)
+               case UDIPROPS__properties_version:
+                       if( _get_token_uint32(str, &str) != 0x101 ) {
+                               Log_Warning("UDI", "Properties version mismatch.");
+                               error_hit = true;
+                       }
+                       break;
+               case UDIPROPS__module:
+                       driver_module->ModuleName = str;
+                       break;
+               case UDIPROPS__meta: {
+                       tUDI_MetaLangRef *ml = &driver_module->MetaLangs[ml_index++];
+                       ml->meta_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       ml->interface_name = str;
+                       // TODO: May need to trim trailing spaces
+                       ml->metalang = UDI_int_GetMetaLangByName(ml->interface_name);
+                       if( !ml->metalang ) {
+                               Log_Error("UDI", "Module %s referenced unsupported metalang %s",
+                                       driver_module->ModuleName, ml->interface_name);
+                               error_hit = true;
+                               // TODO: error
+                       }
+                       break; }
+               case UDIPROPS__message:
                        {
-                       case UDIPROPS__properties_version:
-                               if( _get_token_uint32(str, &str) != 0x101 ) {
-                                       Log_Warning("UDI", "Properties version mismatch.");
-                               }
-                               break;
-                       case UDIPROPS__module:
-                               driver_module->ModuleName = str;
-                               break;
-                       case UDIPROPS__meta:
-                               {
-                               tUDI_MetaLangRef *ml = &driver_module->MetaLangs[ml_index++];
-                               ml->meta_idx = _get_token_idx(str, &str);
-                               if( !str )      continue;
-                               ml->interface_name = str;
-                               break;
-                               }
-                       case UDIPROPS__message:
-                               {
-                               tUDI_PropMessage *msg = &driver_module->Messages[msg_index++];
-                               msg->locale = cur_locale;
-                               msg->index = _get_token_uint16(str, &str);
-                               if( !str )      continue ;
-                               msg->string = str;
-                               //Log_Debug("UDI", "Message %i/%i: '%s'", msg->locale, msg->index, msg->string);
-                               break;
-                               }
-                       case UDIPROPS__locale:
-                               // TODO: Set locale
-                               cur_locale = 1;
-                               break;
-                       case UDIPROPS__region:
-                               {
-                               udi_index_t rgn_idx = _get_token_idx(str, &str);
-                               if( !str )      continue ;
-                               // Search for region index (just in case internal_bind_ops appears earlier)
-                               tUDI_PropRegion *rgn = &driver_module->RegionTypes[0];
-                               if( rgn_idx > 0 )
-                               {
-                                       rgn ++;
-                                       for( int i = 1; i < next_unpop_region; i ++, rgn ++ ) {
-                                               if( rgn->RegionIdx == rgn_idx )
-                                                       break;
-                                       }
-                                       if(i == next_unpop_region) {
-                                               if( next_unpop_region == driver_module->nRegionTypes ) {
-                                                       // TODO: warning if reigon types overflow
-                                                       continue ;
-                                               }
-                                               next_unpop_region ++;
-                                               rgn->RegionIdx = rgn_idx;
-                                       }
-                               }
-                               // Parse attributes
-                               while( *str )
-                               {
-                                       int sym = _get_token_sym(str, &str, true,
-                                               "type", "binding", "priority", "latency", "overrun_time", NULL
-                                               );
-                                       if( !str )      break ;
-                                       switch(sym)
-                                       {
-                                       case 0: // type
-                                               rgn->Type = _get_token_sym(str, &str, true,
-                                                       "normal", "fp", NULL);
-                                               break;
-                                       case 1: // binding
-                                               rgn->Binding = _get_token_sym(str, &str, true,
-                                                       "static", "dynamic", NULL);
-                                               break;
-                                       case 2: // priority
-                                               rgn->Priority = _get_token_sym(str, &str, true,
-                                                       "med", "lo", "hi", NULL);
-                                               break;
-                                       case 3: // latency
-                                               rgn->Latency = _get_token_sym(str, &str, true,
-                                                       "non_overrunable", "powerfail_warning", "overrunable",
-                                                       "retryable", "non_critical", NULL);
-                                               break;
-                                       case 4: // overrun_time
-                                               rgn->OverrunTime = _get_token_uint32(str, &str);
+                       tUDI_PropMessage *msg = &driver_module->Messages[msg_index++];
+                       msg->locale = cur_locale;
+                       msg->index = _get_token_uint16(str, &str);
+                       IF_ERROR(continue);
+                       msg->string = str;
+                       //Log_Debug("UDI", "Message %i/%i: '%s'", msg->locale, msg->index, msg->string);
+                       break;
+                       }
+               case UDIPROPS__locale:
+                       // TODO: Set locale
+                       cur_locale = 1;
+                       break;
+               case UDIPROPS__region:
+                       {
+                       udi_index_t rgn_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       // Search for region index (just in case internal_bind_ops appears earlier)
+                       tUDI_PropRegion *rgn = &driver_module->RegionTypes[0];
+                       if( rgn_idx > 0 )
+                       {
+                               rgn ++;
+                               for( int i = 1; i < next_unpop_region; i ++, rgn ++ ) {
+                                       if( rgn->RegionIdx == rgn_idx )
                                                break;
-                                       }
-                                       if( !str )      break ;
                                }
-                               break;
+                               if(i == next_unpop_region) {
+                                       if( next_unpop_region == driver_module->nRegionTypes ) {
+                                               // TODO: warning if reigon types overflow
+                                               continue ;
+                                       }
+                                       next_unpop_region ++;
+                                       rgn->RegionIdx = rgn_idx;
                                }
-                       case UDIPROPS__parent_bind_ops:
+                       }
+                       // Parse attributes
+                       while( *str )
+                       {
+                               int sym = _get_token_sym(str, &str, true,
+                                       "type", "binding", "priority", "latency", "overrun_time", NULL
+                                       );
+                               if( !str )      break ;
+                               switch(sym)
                                {
-                               tUDI_BindOps    *bind = &driver_module->Parents[parent_index++];
-                               bind->meta_idx = _get_token_idx(str, &str);
-                               if( !str )      continue ;
-                               bind->region_idx = _get_token_idx(str, &str);
-                               if( !str )      continue ;
-                               bind->ops_idx = _get_token_idx(str, &str);
-                               if( !str )      continue ;
-                               bind->bind_cb_idx = _get_token_idx(str, &str);
-                               if( *str ) {
-                                       // Expected EOL, didn't get it :(
+                               case 0: // type
+                                       rgn->Type = _get_token_sym(str, &str, true,
+                                               "normal", "fp", NULL);
+                                       break;
+                               case 1: // binding
+                                       rgn->Binding = _get_token_sym(str, &str, true,
+                                               "static", "dynamic", NULL);
+                                       break;
+                               case 2: // priority
+                                       rgn->Priority = _get_token_sym(str, &str, true,
+                                               "med", "lo", "hi", NULL);
+                                       break;
+                               case 3: // latency
+                                       rgn->Latency = _get_token_sym(str, &str, true,
+                                               "non_overrunable", "powerfail_warning", "overrunable",
+                                               "retryable", "non_critical", NULL);
+                                       break;
+                               case 4: // overrun_time
+                                       rgn->OverrunTime = _get_token_uint32(str, &str);
+                                       break;
                                }
-                               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);
-                               break;
+                               IF_ERROR(break);
+                       }
+                       break;
+                       }
+               case UDIPROPS__parent_bind_ops:
+                       {
+                       tUDI_BindOps    *bind = &driver_module->Parents[parent_index++];
+                       bind->meta_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       bind->region_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       bind->ops_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       bind->bind_cb_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       if( *str ) {
+                               // Expected EOL, didn't get it :(
+                       }
+                       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);
+                       break;
+                       }
+               case UDIPROPS__internal_bind_ops:
+                       {
+                       // Get region using index
+                       udi_index_t meta = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       udi_index_t rgn_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       
+                       // Search for region index (just in case the relevant 'region' comes after)
+                       tUDI_PropRegion *rgn = &driver_module->RegionTypes[0];
+                       if( rgn_idx > 0 )
+                       {
+                               rgn ++;
+                                int    j;
+                               for( j = 1; j < next_unpop_region; j ++, rgn ++ ) {
+                                       if( rgn->RegionIdx == rgn_idx )
+                                               break;
                                }
-                       case UDIPROPS__internal_bind_ops:
-                               {
-                               // Get region using index
-                               udi_index_t meta = _get_token_idx(str, &str);
-                               if( !str )      continue ;
-                               udi_index_t rgn_idx = _get_token_idx(str, &str);
-                               if( !str )      continue ;
-                               
-                               // Search for region index (just in case the relevant 'region' comes after)
-                               tUDI_PropRegion *rgn = &driver_module->RegionTypes[0];
-                               if( rgn_idx > 0 )
-                               {
-                                       rgn ++;
-                                        int    j;
-                                       for( j = 1; j < next_unpop_region; j ++, rgn ++ ) {
-                                               if( rgn->RegionIdx == rgn_idx )
-                                                       break;
-                                       }
-                                       if( j == next_unpop_region ) {
-                                               if( next_unpop_region == driver_module->nRegionTypes ) {
-                                                       // TODO: warning if reigon types overflow
-                                                       continue ;
-                                               }
-                                               next_unpop_region ++;
-                                               rgn->RegionIdx = rgn_idx;
+                               if( j == next_unpop_region ) {
+                                       if( next_unpop_region == driver_module->nRegionTypes ) {
+                                               // TODO: warning if reigon types overflow
+                                               continue ;
                                        }
+                                       next_unpop_region ++;
+                                       rgn->RegionIdx = rgn_idx;
                                }
-               
-                               // Set properties
-                               rgn->BindMeta = meta;
-                               
-                               rgn->PriBindOps = _get_token_idx(str, &str);
-                               if( !str )      continue ;
-                               rgn->SecBindOps = _get_token_idx(str, &str);
-                               if( !str )      continue ;
-                               rgn->BindCb = _get_token_idx(str, &str);
-                               if( !str )      continue ;
-                               if( *str ) {
-                                       // TODO: Please sir, I want an EOL
-                               }
-                               break;
-                               }
-                       case UDIPROPS__child_bind_ops:
-                               {
-                               tUDI_BindOps    *bind = &driver_module->ChildBindOps[child_bind_index++];
-                               bind->meta_idx = _get_token_idx(str, &str);
-                               if( !str )      continue ;
-                               bind->region_idx = _get_token_idx(str, &str);
-                               if( !str )      continue ;
-                               bind->ops_idx = _get_token_idx(str, &str);
-                               if( *str ) {
-                                       // Expected EOL, didn't get it :(
-                               }
-                               Log_Debug("UDI", "Child bind - meta:%i,rgn:%i,ops:%i",
-                                       bind->meta_idx, bind->region_idx, bind->ops_idx);
-                               break;
-                               }
-                       case UDIPROPS__supplier:
-                       case UDIPROPS__contact:
-                       case UDIPROPS__name:
-                       case UDIPROPS__shortname:
-                       case UDIPROPS__release:
-                               break;
-                       //case UDIPROPS__requires:
-                       //      // TODO: Requires
-                       //      break;
-                       case UDIPROPS__device:
-                               {
-                                int    n_attr = 0;
-                               // Count properties (and validate)
-                               _get_token_idx(str, &str);      // message
-                               if( !str )      continue;
-                               _get_token_idx(str, &str);      // meta
-                               if( !str )      continue;
-                               while( *str )
+                       }
+       
+                       // Set properties
+                       rgn->BindMeta = meta;
+                       
+                       rgn->PriBindOps = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       rgn->SecBindOps = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       rgn->BindCb = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       if( *str ) {
+                               // TODO: Please sir, I want an EOL
+                       }
+                       break;
+                       }
+               case UDIPROPS__child_bind_ops:
+                       {
+                       tUDI_BindOps    *bind = &driver_module->ChildBindOps[child_bind_index++];
+                       bind->meta_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       bind->region_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       bind->ops_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
+                       if( *str ) {
+                               // Expected EOL, didn't get it :(
+                       }
+                       Log_Debug("UDI", "Child bind - meta:%i,rgn:%i,ops:%i",
+                               bind->meta_idx, bind->region_idx, bind->ops_idx);
+                       break;
+                       }
+               case UDIPROPS__supplier:
+               case UDIPROPS__contact:
+               case UDIPROPS__name:
+               case UDIPROPS__shortname:
+               case UDIPROPS__release:
+                       break;
+               //case UDIPROPS__requires:
+               //      // TODO: Requires
+               //      break;
+               case UDIPROPS__device:
+                       {
+                        int    n_attr = 0;
+                       // Count properties (and validate)
+                       _get_token_uint16(str, &str);   // message
+                       IF_ERROR(continue);
+                       _get_token_idx(str, &str);      // meta
+                       IF_ERROR(continue);
+                       while( *str )
+                       {
+                               _get_token_str(str, &str, NULL);
+                               IF_ERROR(break);
+                               _get_token_sym(str, &str, true, "string", "ubit32", "boolean", "array", NULL);
+                               IF_ERROR(break);
+                               _get_token_str(str, &str, NULL);
+                               IF_ERROR(break);
+                               n_attr ++;
+                       }
+                       // Rewind and actually parse
+                       // - Eat the 'device' token and hence reset 'str'
+                       _get_token_str(udipropsptrs[i], &str, NULL);
+                       
+                       tUDI_PropDevSpec *dev = NEW_wA(tUDI_PropDevSpec, Attribs, n_attr);
+                       driver_module->Devices[device_index++] = dev;;
+                       dev->MessageNum = _get_token_uint16(str, &str);
+                       dev->MetaIdx = _get_token_idx(str, &str);
+                       dev->nAttribs = n_attr;
+                       n_attr = 0;
+                       while( *str )
+                       {
+                               udi_instance_attr_list_t *at = &dev->Attribs[n_attr];
+                               _get_token_str(str, &str, at->attr_name);
+                               IF_ERROR(break);
+                               at->attr_type = _get_token_sym(str, &str, true,
+                                       " ", "string", "array", "ubit32", "boolean", NULL);
+                               IF_ERROR(break);
+                               udi_ubit32_t    val;
+                               switch( dev->Attribs[n_attr].attr_type )
                                {
+                               case 1: // String
+                                       at->attr_length = _get_token_str(str, &str, (char*)at->attr_value);
+                                       break;
+                               case 2: // Array
+                                       // TODO: Array
+                                       Log_Warning("UDI", "TODO: Parse 'array' attribute in 'device'");
                                        _get_token_str(str, &str, NULL);
-                                       if( !str )      break;
-                                       _get_token_sym(str, &str, true, "string", "ubit32", "boolean", "array", NULL);
-                                       if( !str )      break;
-                                       _get_token_str(str, &str, NULL);
-                                       if( !str )      break;
-                                       n_attr ++;
-                               }
-                               // Rewind and actually parse
-                               _get_token_str(udipropsptrs[i], &str, NULL);
-                               
-                               tUDI_PropDevSpec *dev = NEW_wA(tUDI_PropDevSpec, Attribs, n_attr);
-                               dev->MessageNum = _get_token_idx(str, &str);
-                               dev->MetaIdx = _get_token_idx(str, &str);
-                               dev->nAttribs = n_attr;
-                               n_attr = 0;
-                               while( *str )
-                               {
-                                       udi_instance_attr_list_t *at = &dev->Attribs[n_attr];
-                                       _get_token_str(str, &str, at->attr_name);
-                                       if( !str )      break;
-                                       at->attr_type = _get_token_sym(str, &str, true,
-                                               " ", "string", "array", "ubit32", "boolean", NULL);
-                                       if( !str )      break;
-                                       switch( dev->Attribs[n_attr].attr_type )
-                                       {
-                                       case 1: // String
-                                               at->attr_length = _get_token_str(str, &str, (char*)at->attr_value);
-                                               break;
-                                       case 2: // Array
-                                               // TODO: Array
-                                               Log_Warning("UDI", "TODO: Parse 'array' attribute in 'device'");
-                                               _get_token_str(str, &str, NULL);
-                                               break;
-                                       case 3: // ubit32
-                                               at->attr_length = sizeof(udi_ubit32_t);
-                                               UDI_ATTR32_SET(at->attr_value, _get_token_uint32(str, &str));
-                                               break;
-                                       case 4: // boolean
-                                               at->attr_length = sizeof(udi_boolean_t);
-                                               UDI_ATTR32_SET(at->attr_value, _get_token_bool(str, &str));
-                                               break;
-                                       }
-                                       if( !str )      break;
-                                       n_attr ++;
+                                       error_hit = true;
+                                       break;
+                               case 3: // ubit32
+                                       at->attr_length = sizeof(udi_ubit32_t);
+                                       val = _get_token_uint32(str, &str);
+                                       Log_Debug("UDI", "device %i: Value '%s'=%x", device_index,
+                                               at->attr_name, val);
+                                       UDI_ATTR32_SET(at->attr_value, val);
+                                       break;
+                               case 4: // boolean
+                                       at->attr_length = sizeof(udi_boolean_t);
+                                       UDI_ATTR32_SET(at->attr_value, _get_token_bool(str, &str));
+                                       break;
                                }
-                               
-                               break;
-                               }
-                       default:
-                               Log_Debug("UDI", "udipropsptrs[%i] = '%s'", i, udipropsptrs[i]);
-                               break;
+                               IF_ERROR(break);
+                               n_attr ++;
                        }
+                       
+                       break;
+                       }
+               default:
+                       Log_Debug("UDI", "udipropsptrs[%i] = '%s'", i, udipropsptrs[i]);
+                       break;
                }
-               
-               // Sort message list
-               // TODO: Sort message list
        }
+       free(udipropsptrs);
+       if( error_hit ) {
+               Log_Error("UDI", "Error encountered while parsing udiprops for '%s' (LoadBase=%p), bailing",
+                       driver_module->ModuleName, LoadBase);
+               for( int i = 0; i < device_index; i ++ )
+                       free(driver_module->Devices[i]);
+               free(driver_module->Messages);
+               free(driver_module->RegionTypes);
+               free(driver_module->MetaLangs);
+               free(driver_module->Parents);
+               free(driver_module->ChildBindOps);
+               free(driver_module->Devices);
+               free(driver_module);
+               return NULL;
+       }
+       ASSERTC(device_index, ==, driver_module->nDevices);
+
+       for( int i = 0; i < driver_module->nDevices; i ++ ) {
+               ASSERT(driver_module);
+               ASSERT(driver_module->Devices[i]);
+               driver_module->Devices[i]->Metalang = UDI_int_GetMetaLang(driver_module,
+                       driver_module->Devices[i]->MetaIdx);
+       }
+       
+       // Sort message list
+       // TODO: Sort message list
 
         int    nSecondaryRgns = 0;
        for( int i = 0; info->secondary_init_list && info->secondary_init_list[i].region_idx; i ++ )
@@ -667,10 +722,7 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
        // Check for orphan drivers, and create an instance of them when loaded
        if( driver_module->nParents == 0 )
        {
-               tUDI_DriverInstance *inst = UDI_MA_CreateInstance(driver_module);
-       
-               // Enumerate so any pre-loaded drivers are detected     
-               UDI_MA_BeginEnumeration(inst);
+               UDI_MA_CreateInstance(driver_module, NULL, NULL);
        }
        else
        {
@@ -756,40 +808,36 @@ udi_ops_init_t *UDI_int_GetOps(tUDI_DriverInstance *Inst, udi_index_t index)
        return ops;
 }
 
-tUDI_MetaLang *UDI_int_GetMetaLang(tUDI_DriverInstance *Inst, udi_index_t index)
+tUDI_MetaLang *UDI_int_GetMetaLang(tUDI_DriverModule *Module, udi_index_t index)
 {
        if( index == 0 )
                return &cMetaLang_Management;
-       ASSERT(Inst);
-       for( int i = 0; i < Inst->Module->nMetaLangs; i ++ )
+       ASSERT(Module);
+       for( int i = 0; i < Module->nMetaLangs; i ++ )
        {
-               if( Inst->Module->MetaLangs[i].meta_idx == index )
-                       return Inst->Module->MetaLangs[i].metalang;
+               if( Module->MetaLangs[i].meta_idx == index )
+                       return Module->MetaLangs[i].metalang;
        }
        return NULL;
 }
 
-void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, udi_channel_t channel)
+const tUDI_MetaLang *UDI_int_GetMetaLangByName(const char *Name)
 {
-       const udi_cb_init_t     *cb_init;
-       cb_init = Inst ? Inst->Module->InitInfo->cb_init_list : cUDI_MgmtCbInitList;
-       for( ; cb_init->cb_idx; cb_init ++ )
+       //extern tUDI_MetaLang  cMetaLang_Management;
+       extern tUDI_MetaLang    cMetaLang_BusBridge;
+       extern tUDI_MetaLang    cMetaLang_GIO;
+       extern tUDI_MetaLang    cMetaLang_NIC;
+       const tUDI_MetaLang     *langs[] = {
+               &cMetaLang_BusBridge,
+               &cMetaLang_GIO,
+               &cMetaLang_NIC,
+               NULL
+       };
+       for( int i = 0; langs[i]; i ++ )
        {
-               if( cb_init->cb_idx == bind_cb_idx )
-               {
-                       // TODO: Get base size using meta/cbnum
-                       tUDI_MetaLang *metalang = UDI_int_GetMetaLang(Inst, cb_init->meta_idx);
-                       ASSERT(metalang);
-                       ASSERTC(cb_init->meta_cb_num, <, metalang->nCbTypes);
-                       size_t  base = metalang->CbTypes[cb_init->meta_cb_num].Size;
-                       udi_cb_t *ret = NEW(udi_cb_t, + base + cb_init->inline_size + cb_init->scratch_requirement);
-                       ret->channel = channel;
-                       return ret;
-               }
+               if( strcmp(Name, langs[i]->Name) == 0 )
+                       return langs[i];
        }
-       Log_Warning("UDI", "Cannot find CB init def %i for '%s'",
-               bind_cb_idx, Inst->Module->ModuleName);
        return NULL;
-       
 }
 

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