Modules/UDI - Handle errors in udiprops more gracefully
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / main.c
index 1d76678..1c48008 100644 (file)
 #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 ===
@@ -40,6 +42,8 @@ int UDI_Install(char **Arguments)
        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;
 }
@@ -69,7 +73,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;
@@ -86,6 +90,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;
 }
 
@@ -114,10 +121,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;
        }
@@ -138,8 +145,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;
        }
@@ -318,7 +325,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);
        
@@ -404,6 +411,7 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
        driver_module->Devices      = NEW(tUDI_PropDevSpec*,* driver_module->nDevices);
 
        // Populate
+       bool    error_hit = false;
         int    cur_locale = 0;
         int    msg_index = 0;
         int    ml_index = 0;
@@ -411,42 +419,45 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
         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)
                {
                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:
-                       {
+               case UDIPROPS__meta: {
                        tUDI_MetaLangRef *ml = &driver_module->MetaLangs[ml_index++];
                        ml->meta_idx = _get_token_idx(str, &str);
-                       if( !str )      continue;
+                       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;
-                       }
+                       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 ;
+                       IF_ERROR(continue);
                        msg->string = str;
                        //Log_Debug("UDI", "Message %i/%i: '%s'", msg->locale, msg->index, msg->string);
                        break;
@@ -458,7 +469,7 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                case UDIPROPS__region:
                        {
                        udi_index_t rgn_idx = _get_token_idx(str, &str);
-                       if( !str )      continue ;
+                       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 )
@@ -507,7 +518,7 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                                        rgn->OverrunTime = _get_token_uint32(str, &str);
                                        break;
                                }
-                               if( !str )      break ;
+                               IF_ERROR(break);
                        }
                        break;
                        }
@@ -515,12 +526,13 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                        {
                        tUDI_BindOps    *bind = &driver_module->Parents[parent_index++];
                        bind->meta_idx = _get_token_idx(str, &str);
-                       if( !str )      continue ;
+                       IF_ERROR(continue);
                        bind->region_idx = _get_token_idx(str, &str);
-                       if( !str )      continue ;
+                       IF_ERROR(continue);
                        bind->ops_idx = _get_token_idx(str, &str);
-                       if( !str )      continue ;
+                       IF_ERROR(continue);
                        bind->bind_cb_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
                        if( *str ) {
                                // Expected EOL, didn't get it :(
                        }
@@ -532,9 +544,9 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                        {
                        // Get region using index
                        udi_index_t meta = _get_token_idx(str, &str);
-                       if( !str )      continue ;
+                       IF_ERROR(continue);
                        udi_index_t rgn_idx = _get_token_idx(str, &str);
-                       if( !str )      continue ;
+                       IF_ERROR(continue);
                        
                        // Search for region index (just in case the relevant 'region' comes after)
                        tUDI_PropRegion *rgn = &driver_module->RegionTypes[0];
@@ -560,11 +572,11 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                        rgn->BindMeta = meta;
                        
                        rgn->PriBindOps = _get_token_idx(str, &str);
-                       if( !str )      continue ;
+                       IF_ERROR(continue);
                        rgn->SecBindOps = _get_token_idx(str, &str);
-                       if( !str )      continue ;
+                       IF_ERROR(continue);
                        rgn->BindCb = _get_token_idx(str, &str);
-                       if( !str )      continue ;
+                       IF_ERROR(continue);
                        if( *str ) {
                                // TODO: Please sir, I want an EOL
                        }
@@ -574,10 +586,11 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                        {
                        tUDI_BindOps    *bind = &driver_module->ChildBindOps[child_bind_index++];
                        bind->meta_idx = _get_token_idx(str, &str);
-                       if( !str )      continue ;
+                       IF_ERROR(continue);
                        bind->region_idx = _get_token_idx(str, &str);
-                       if( !str )      continue ;
+                       IF_ERROR(continue);
                        bind->ops_idx = _get_token_idx(str, &str);
+                       IF_ERROR(continue);
                        if( *str ) {
                                // Expected EOL, didn't get it :(
                        }
@@ -598,26 +611,27 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                        {
                         int    n_attr = 0;
                        // Count properties (and validate)
-                       _get_token_idx(str, &str);      // message
-                       if( !str )      continue;
+                       _get_token_uint16(str, &str);   // message
+                       IF_ERROR(continue);
                        _get_token_idx(str, &str);      // meta
-                       if( !str )      continue;
+                       IF_ERROR(continue);
                        while( *str )
                        {
                                _get_token_str(str, &str, NULL);
-                               if( !str )      break;
+                               IF_ERROR(break);
                                _get_token_sym(str, &str, true, "string", "ubit32", "boolean", "array", NULL);
-                               if( !str )      break;
+                               IF_ERROR(break);
                                _get_token_str(str, &str, NULL);
-                               if( !str )      break;
+                               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_idx(str, &str);
+                       dev->MessageNum = _get_token_uint16(str, &str);
                        dev->MetaIdx = _get_token_idx(str, &str);
                        dev->nAttribs = n_attr;
                        n_attr = 0;
@@ -625,10 +639,10 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                        {
                                udi_instance_attr_list_t *at = &dev->Attribs[n_attr];
                                _get_token_str(str, &str, at->attr_name);
-                               if( !str )      break;
+                               IF_ERROR(break);
                                at->attr_type = _get_token_sym(str, &str, true,
                                        " ", "string", "array", "ubit32", "boolean", NULL);
-                               if( !str )      break;
+                               IF_ERROR(break);
                                udi_ubit32_t    val;
                                switch( dev->Attribs[n_attr].attr_type )
                                {
@@ -639,6 +653,7 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                                        // TODO: Array
                                        Log_Warning("UDI", "TODO: Parse 'array' attribute in 'device'");
                                        _get_token_str(str, &str, NULL);
+                                       error_hit = true;
                                        break;
                                case 3: // ubit32
                                        at->attr_length = sizeof(udi_ubit32_t);
@@ -652,7 +667,7 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                                        UDI_ATTR32_SET(at->attr_value, _get_token_bool(str, &str));
                                        break;
                                }
-                               if( !str )      break;
+                               IF_ERROR(break);
                                n_attr ++;
                        }
                        
@@ -664,6 +679,28 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                }
        }
        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
@@ -681,10 +718,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
        {
@@ -770,15 +804,15 @@ 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;
 }
@@ -787,8 +821,12 @@ const tUDI_MetaLang *UDI_int_GetMetaLangByName(const char *Name)
 {
        //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 ++ )

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