Modules/UDI - Enumeration working, ne2000 starting to bind to PCI
authorJohn Hodge <[email protected]>
Fri, 4 Oct 2013 13:14:56 +0000 (21:14 +0800)
committerJohn Hodge <[email protected]>
Fri, 4 Oct 2013 13:14:56 +0000 (21:14 +0800)
KernelLand/Modules/Interfaces/UDI/main.c
KernelLand/Modules/Interfaces/UDI/management_agent.c
KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c
KernelLand/Modules/Interfaces/UDI/udi_internal.h
KernelLand/Modules/Interfaces/UDI/udi_lib/imc.c
KernelLand/Modules/Interfaces/UDI/udi_lib/meta_mgmt.c
KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c
KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c

index 1d1b28c..e9dffc5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Acess2 UDI Layer
  */
-#define DEBUG  0
+#define DEBUG  1
 #define VERSION        ((0<<8)|1)
 #include <acess.h>
 #include <modules.h>
@@ -19,6 +19,7 @@ extern size_t pci_udiprops_size;
  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);
+const tUDI_MetaLang    *UDI_int_GetMetaLangByName(const char *Name);
 
 // === GLOBALS ===
 MODULE_DEFINE(0, VERSION, UDI, UDI_Install, NULL, NULL);
@@ -326,333 +327,346 @@ 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 ++;
+               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];
                }
-               
-               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(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)
                {
-                       if( udiprops[i] == '\0' ) {
-                               udipropsptrs[line++] = &udiprops[i+1];
-                       }
+               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;
                }
-               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 ++ )
+       }
+
+       // 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    device_index = 0;
+        int    next_unpop_region = 1;
+       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);
+               switch(sym)
                {
-                       const char *str = udipropsptrs[i];
-                        int    sym = _get_token_sym_v(str, &str, false, caUDI_UdipropsNames);
-                       switch(sym)
+               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:
                        {
-                       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;
+                       tUDI_MetaLangRef *ml = &driver_module->MetaLangs[ml_index++];
+                       ml->meta_idx = _get_token_idx(str, &str);
+                       if( !str )      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);
                        }
-               }
-
-               // 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);
-
-               // 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 ++ )
-               {
-                       const char *str = udipropsptrs[i];
-                       if( !*str )
-                               continue ;
-                        int    sym = _get_token_sym_v(str, &str, true, caUDI_UdipropsNames);
-                       switch(sym)
+                       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( !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( !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( !str )      break ;
+                       }
+                       break;
+                       }
+               case UDIPROPS__parent_bind_ops:
+                       {
+                       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 :(
+                       }
+                       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( !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;
                                }
-                       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 ;
                                        }
-                                       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 :(
+                                       next_unpop_region ++;
+                                       rgn->RegionIdx = rgn_idx;
                                }
-                               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( !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 )
+                       {
+                               _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);
+                       driver_module->Devices[device_index++] = dev;;
+                       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;
+                               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 ++;
+                                       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( !str )      break;
+                               n_attr ++;
                        }
+                       
+                       break;
+                       }
+               default:
+                       Log_Debug("UDI", "udipropsptrs[%i] = '%s'", i, udipropsptrs[i]);
+                       break;
                }
-               
-               // Sort message list
-               // TODO: Sort message list
        }
+       free(udipropsptrs);
+       
+       // 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 ++ )
@@ -772,6 +786,12 @@ tUDI_MetaLang *UDI_int_GetMetaLang(tUDI_DriverInstance *Inst, udi_index_t index)
 void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, udi_channel_t channel)
 {
        const udi_cb_init_t     *cb_init;
+       LOG("Inst=%p, bind_cb_idx=%i, channel=%p", Inst, bind_cb_idx, channel);
+       if(Inst) {
+               ASSERT(Inst->Module);
+               ASSERT(Inst->Module->InitInfo);
+               ASSERT(Inst->Module->InitInfo->cb_init_list);
+       }
        cb_init = Inst ? Inst->Module->InitInfo->cb_init_list : cUDI_MgmtCbInitList;
        for( ; cb_init->cb_idx; cb_init ++ )
        {
@@ -779,10 +799,18 @@ void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx,
                {
                        // TODO: Get base size using meta/cbnum
                        tUDI_MetaLang *metalang = UDI_int_GetMetaLang(Inst, cb_init->meta_idx);
-                       ASSERT(metalang);
+                       if( !metalang ) {
+                               Log_Warning("UDI", "Metalang referenced in %s CB %i is invalid (%i)",
+                                       Inst->Module->ModuleName, bind_cb_idx, cb_init->meta_idx);
+                               return NULL;
+                       }
                        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);
+                       ASSERTC(base, >=, sizeof(udi_cb_t));
+                       base -= sizeof(udi_cb_t);
+                       LOG("+ %i + %i + %i", base, cb_init->inline_size, cb_init->scratch_requirement);
+                       udi_cb_t *ret = NEW(udi_cb_t, + base
+                               + cb_init->inline_size + cb_init->scratch_requirement);
                        ret->channel = channel;
                        return ret;
                }
@@ -793,3 +821,19 @@ void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx,
        
 }
 
+const tUDI_MetaLang *UDI_int_GetMetaLangByName(const char *Name)
+{
+       //extern tUDI_MetaLang  cMetaLang_Management;
+       extern tUDI_MetaLang    cMetaLang_BusBridge;
+       const tUDI_MetaLang     *langs[] = {
+               &cMetaLang_BusBridge,
+               NULL
+       };
+       for( int i = 0; langs[i]; i ++ )
+       {
+               if( strcmp(Name, langs[i]->Name) == 0 )
+                       return langs[i];
+       }
+       return NULL;
+}
+
index 38a6a12..eb441aa 100644 (file)
@@ -5,6 +5,7 @@
  * management_agent.c
  * - Managment Agent
  */
+#define DEBUG  1
 #include <acess.h>
 #include <udi.h>
 #include "udi_internal.h"
@@ -124,6 +125,11 @@ int UDI_MA_CheckDeviceMatch(int nDevAttr, udi_instance_attr_list_t *DevAttrs,
                }
                if( enum_attr )
                {
+                       //LOG("Match = '%s' (%i %x == %i %x)",
+                       //      dev_attr->attr_name,
+                       //      dev_attr->attr_length, UDI_ATTR32_GET(dev_attr->attr_value),
+                       //      enum_attr->attr_length, UDI_ATTR32_GET(enum_attr->attr_value)
+                       //      );
                        if( enum_attr->attr_length != dev_attr->attr_length )
                                return 0;
                        if( memcmp(enum_attr->attr_value, dev_attr->attr_value, dev_attr->attr_length) != 0 )
@@ -133,8 +139,10 @@ int UDI_MA_CheckDeviceMatch(int nDevAttr, udi_instance_attr_list_t *DevAttrs,
                else
                {
                        // Attribute desired is missing, error?
+                       //LOG("attr '%s' missing", dev_attr->attr_name);
                }
        }
+       //LOG("n_matches = %i", n_matches);
        return n_matches;
 }
 
@@ -142,7 +150,7 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx)
 {
        // Current side is MA, other is instance
        tUDI_DriverInstance *inst = UDI_int_ChannelGetInstance( UDI_GCB(cb), true );
-       LOG("inst = %p", inst);
+       //LOG("inst = %p", inst);
        
        // Search for existing child with same child_ID and ops
        for( tUDI_ChildBinding *child = inst->FirstChild; child; child = child->Next )
@@ -166,7 +174,6 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx)
        // - Locate child_bind_ops definition
        for( int i = 0; i < inst->Module->nChildBindOps; i ++ )
        {
-               LOG(" %i == %i?", inst->Module->ChildBindOps[i].ops_idx, ops_idx);
                if( inst->Module->ChildBindOps[i].ops_idx == ops_idx ) {
                        child->BindOps = &inst->Module->ChildBindOps[i];
                        break;
@@ -211,7 +218,29 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx)
 
 void UDI_MA_BindParents(tUDI_DriverModule *Module)
 {
-       UNIMPLEMENTED();
+       // Scan active instances for enumerated children that can be handled by this module
+       for( int i = 0; i < Module->nDevices; i ++ )
+       {
+               // TODO: Have list of unbound enumerated children
+               for( tUDI_DriverInstance *inst = gpUDI_ActiveInstances; inst; inst = inst->Next )
+               {
+                       // Loop children
+                       for( tUDI_ChildBinding *child = inst->FirstChild; child; child = child->Next )
+                       {
+                               if( child->BoundInstance )
+                                       continue ;
+                               // Check for match
+                               int level = UDI_MA_CheckDeviceMatch(
+                                       Module->Devices[i]->nAttribs, Module->Devices[i]->Attribs,
+                                       child->nAttribs, child->Attribs
+                                       );
+                               // No match: Continue
+                               if( level == 0 )
+                                       continue ;
+                               UDI_MA_CreateChildInstance(Module, inst, child);
+                       }
+               }
+       }
 }
 
 tUDI_DriverInstance *UDI_MA_CreateChildInstance(tUDI_DriverModule *Module,
@@ -231,20 +260,24 @@ tUDI_DriverInstance *UDI_MA_CreateChildInstance(tUDI_DriverModule *Module,
        UDI_BindChannel(channel,true,  inst, parent->ops_idx, parent->region_idx);
        UDI_BindChannel(channel,false,
                ParentInstance, ChildBinding->Ops->ops_idx, ChildBinding->BindOps->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");
-               return NULL;
-       }
 
        udi_channel_event_cb_t  ev_cb;
+       memset(&ev_cb, 0, sizeof(ev_cb));
         int    n_handles = 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;
+       if( parent->bind_cb_idx == 0 )
+               ev_cb.params.parent_bound.bind_cb = NULL;
+       else {
+               ev_cb.params.parent_bound.bind_cb = udi_cb_alloc_internal(inst, parent->bind_cb_idx, channel);
+               if( !ev_cb.params.parent_bound.bind_cb ) {
+                       Log_Warning("UDI", "Bind CB index is invalid");
+                       return NULL;
+               }
+               UDI_int_ChannelFlip( ev_cb.params.parent_bound.bind_cb );
+       }
+
        ev_cb.params.parent_bound.parent_ID = 1;
        ev_cb.params.parent_bound.path_handles = handles;
        
index 394ae39..0dac0c2 100644 (file)
@@ -131,11 +131,12 @@ void pci_bridge_ch_event_ind(udi_channel_event_cb_t *cb)
 {
        UNIMPLEMENTED();
 }
-void pci_unbind_req(udi_bus_bind_cb_t *cb)
+void pci_bind_req(udi_bus_bind_cb_t *cb)
 {
-       UNIMPLEMENTED();
+       // TODO: DMA constraints
+       udi_bus_bind_ack(cb, 0, UDI_DMA_LITTLE_ENDIAN, UDI_OK);
 }
-void pci_bind_req_op(udi_bus_bind_cb_t *cb)
+void pci_unbind_req(udi_bus_bind_cb_t *cb)
 {
        UNIMPLEMENTED();
 }
@@ -158,8 +159,8 @@ udi_mgmt_ops_t      pci_mgmt_ops = {
 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_bind_req,
        pci_unbind_req,
-       pci_bind_req_op,
        pci_intr_attach_req,
        pci_intr_detach_req
 };
index 2d298ca..b208930 100644 (file)
@@ -70,10 +70,6 @@ struct sUDI_PropRegion
 struct sUDI_MetaLang
 {
        const char *Name;
-        int    nOpGroups;
-       struct {
-               void    *OpList;
-       } OpGroups;
         int    nCbTypes;
        struct {
                size_t  Size;
index 2f9f3fe..ce646df 100644 (file)
@@ -80,5 +80,5 @@ void udi_channel_event_ind(udi_channel_event_cb_t *cb)
 
 void udi_channel_event_complete(udi_channel_event_cb_t *cb, udi_status_t status)
 {
-       Warning("%s Unimplemented", __func__);
+       UNIMPLEMENTED();
 }
index 87a54fd..6a80292 100644 (file)
@@ -22,12 +22,10 @@ EXPORT(udi_final_cleanup_ack);
 
 tUDI_MetaLang  cMetaLang_Management = {
        "udi_mgmt",
-       1,
-       {NULL},
        
        1,
        {
-               {sizeof(udi_enumerate_cb_t)-sizeof(udi_cb_t), NULL}
+               {sizeof(udi_enumerate_cb_t), NULL}
        }
 };
 
@@ -40,7 +38,8 @@ void udi_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
                Log_Warning("UDI", "%s on wrong channel type", __func__);
                return ;
        }
-       
+
+       // Non-deferred because it's usually called with a stack allocated cb   
        UDI_int_ChannelReleaseFromCall( UDI_GCB(cb) );
        ops->usage_ind_op(cb, resource_level);
 }
@@ -67,8 +66,6 @@ void udi_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
        }
        
        UDI_int_MakeDeferredCbU8( UDI_GCB(cb), (udi_op_t*)ops->enumerate_req_op, enumeration_level );
-//     UDI_int_ChannelReleaseFromCall( UDI_GCB(cb) );
-//     ops->enumerate_req_op(cb, enumeration_level);
 }
 
 void udi_enumerate_no_children(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
@@ -83,7 +80,7 @@ void udi_enumerate_ack(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_result, u
        switch( enumeration_result )
        {
        case UDI_ENUMERATE_OK:
-               #if DEBUG
+               #if DEBUG && 0
                for( int i = 0; i < cb->attr_valid_length; i ++ )
                {
                        udi_instance_attr_list_t        *at = &cb->attr_list[i];
index e1e6a47..dadb442 100644 (file)
@@ -1,10 +1,35 @@
 /**
- * \file physio/meta_bus.c
- * \author John Hodge (thePowersGang)
+ * Acess2 UDI Layer
+ * - By John Hodge (thePowersGang)
+ *
+ * udi_lib/physio/meta_bus.c
+ * - Bus Bridge Metalanguage
  */
+#define DEBUG  1
 #include <acess.h>
 #include <udi.h>
 #include <udi_physio.h>
+#include "../../udi_internal.h"
+
+// === GLOBALS ==
+udi_layout_t   cMetaLang_BusBridge_IntrAttachCbLayout[] = {
+       UDI_DL_STATUS_T,
+       UDI_DL_UBIT8_T,
+       UDI_DL_ORIGIN_T,        // TODO: handle
+       0
+};
+tUDI_MetaLang  cMetaLang_BusBridge = {
+       "udi_bridge",
+       // CB Types
+       5,
+       {
+               {0},    // 0: Empty
+               {sizeof(udi_bus_bind_cb_t), NULL},      // Defined, but is just a gcb
+               {sizeof(udi_intr_attach_cb_t), NULL},
+               {sizeof(udi_intr_detach_cb_t), NULL},
+               {sizeof(udi_intr_event_cb_t), NULL}
+       }
+};
 
 // === EXPORTS ===
 EXPORT(udi_bus_unbind_req);
@@ -12,6 +37,12 @@ EXPORT(udi_bus_unbind_ack);
 EXPORT(udi_bus_bind_req);
 EXPORT(udi_bus_bind_ack);
 
+#define PREP_OPS(type,ml,num)  const type *ops = UDI_int_ChannelPrepForCall(UDI_GCB(cb), ml, num); \
+       if(!ops) { Log_Warning("UDI", "%s on wrong channel type", __func__); return ; }
+
+#define PREP_OPS_DEVICE        const udi_bus_device_ops_t *ops = UDI_int_ChannelPrepForCall( UDI_GCB(cb), &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM ); \
+       if(!ops) { Log_Warning("UDI", "%s on wrong channel type", __func__); return ; }
+
 // === CODE ===
 void udi_bus_unbind_req(udi_bus_bind_cb_t *cb)
 {
@@ -24,7 +55,29 @@ void udi_bus_unbind_ack(udi_bus_bind_cb_t *cb)
 
 void udi_bus_bind_req(udi_bus_bind_cb_t *cb)
 {
-       UNIMPLEMENTED();
+       LOG("cb=%p{...}", cb);
+       PREP_OPS(udi_bus_bridge_ops_t, &cMetaLang_BusBridge, UDI_BUS_BRIDGE_OPS_NUM)
+       
+       UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->bus_bind_req_op );
+}
+
+struct marshalled_bus_bind_ack
+{
+       tUDI_DeferredCall       Call;
+       udi_dma_constraints_t   dma_constraints;
+       udi_ubit8_t     preferred_endianness;
+       udi_status_t    status;
+};
+
+static void _unmarshal_bus_bind_ack(tUDI_DeferredCall *Call)
+{
+       struct marshalled_bus_bind_ack *info = (void*)Call;
+       ((udi_bus_bind_ack_op_t*)Call->Handler)(
+               UDI_MCB(Call->cb, udi_bus_bind_cb_t),
+               info->dma_constraints,
+               info->preferred_endianness,
+               info->status);
+       free(info);
 }
 
 void udi_bus_bind_ack(
@@ -34,5 +87,16 @@ void udi_bus_bind_ack(
        udi_status_t    status
        )
 {
-       UNIMPLEMENTED();
+       LOG("cb=%p{...}, dma_constraints=%p, preferred_endianness=%i,status=%i",
+               cb, dma_constraints, preferred_endianness, status);
+       PREP_OPS(udi_bus_device_ops_t, &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM)
+       
+       struct marshalled_bus_bind_ack *call = NEW(struct marshalled_bus_bind_ack,);
+       call->Call.Unmarshal = _unmarshal_bus_bind_ack;
+       call->Call.cb = UDI_GCB(cb);
+       call->Call.Handler = (udi_op_t*)ops->bus_bind_ack_op;
+       call->dma_constraints = dma_constraints;
+       call->preferred_endianness = preferred_endianness;
+       call->status = status;
+       UDI_int_AddDeferred(&call->Call);
 }
index 03849ae..a482590 100644 (file)
@@ -20,7 +20,22 @@ void udi_pio_map(udi_pio_map_call_t *callback, udi_cb_t *gcb,
        udi_pio_trans_t *trans_list, udi_ubit16_t list_length,
        udi_ubit16_t pio_attributes, udi_ubit32_t pace, udi_index_t serialization_domain)
 {
-       UNIMPLEMENTED();
+       char bus_type[16];
+       udi_instance_attr_type_t        type;
+       type = udi_instance_attr_get_internal(gcb, "bus_type", 0, bus_type, sizeof(bus_type), NULL);
+       if(type != UDI_ATTR_STRING) {
+               callback(gcb, UDI_NULL_HANDLE);
+               return ;
+       }
+       
+       if( strcmp(bus_type, "pci") == 0 ) {
+               // Ask PCI binding
+       }
+       else {
+               // Oops, unknown
+               callback(gcb, UDI_NULL_HANDLE);
+               return ;
+       }
 }
 
 void udi_pio_unmap(udi_pio_handle_t pio_handle)

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