X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=KernelLand%2FModules%2FInterfaces%2FUDI%2Fmain.c;h=4a655f0c34ce64b0f05c448039ce405e47239723;hb=845b6f9d90bb87b5e760e4d49aa93b0e003ab750;hp=1d76678eb285bf4cbe308d39ada1ea9697778954;hpb=fb13a50bc14688a20dc37acbbbbe23f56bf63c41;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/Interfaces/UDI/main.c b/KernelLand/Modules/Interfaces/UDI/main.c index 1d76678e..4a655f0c 100644 --- a/KernelLand/Modules/Interfaces/UDI/main.c +++ b/KernelLand/Modules/Interfaces/UDI/main.c @@ -13,12 +13,14 @@ #include #include #include +#include +#include // === 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 === @@ -35,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; } @@ -69,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; @@ -86,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; } @@ -114,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; } @@ -138,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; } @@ -318,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); @@ -404,6 +415,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 +423,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 +473,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 +522,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 +530,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 +548,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 +576,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 +590,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 +615,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 +643,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 +657,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 +671,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 +683,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 +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 { @@ -770,15 +808,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 +825,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 ++ )