1d76678eb285bf4cbe308d39ada1ea9697778954
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / main.c
1 /*
2  * Acess2 UDI Layer
3  * - By John Hodge (thePowersGang)
4  *
5  * main.c
6  * - UDI Entrypoint and Module loading
7  */
8 #define DEBUG   1
9 #define VERSION ((0<<8)|1)
10 #include <acess.h>
11 #include <modules.h>
12 #include <udi.h>
13 #include <udi_internal.h>
14 #include <udi_internal_ma.h>
15 #include <trans_pci.h>
16
17 // === PROTOTYPES ===
18  int    UDI_Install(char **Arguments);
19  int    UDI_DetectDriver(void *Base);
20  int    UDI_LoadDriver(void *Base);
21 tUDI_DriverModule       *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const char *udiprops, size_t udiprops_size);
22 const tUDI_MetaLang     *UDI_int_GetMetaLangByName(const char *Name);
23
24 // === GLOBALS ===
25 MODULE_DEFINE(0, VERSION, UDI, UDI_Install, NULL, NULL);
26 tModuleLoader   gUDI_Loader = {
27         NULL, "UDI", UDI_DetectDriver, UDI_LoadDriver, NULL
28 };
29 tUDI_DriverModule       *gpUDI_LoadedModules;
30
31 // === CODE ===
32 /**
33  * \fn int UDI_Install(char **Arguments)
34  * \brief Stub intialisation routine
35  */
36 int UDI_Install(char **Arguments)
37 {
38         Module_RegisterLoader( &gUDI_Loader );
39
40         Proc_SpawnWorker(UDI_int_DeferredThread, NULL);
41
42         UDI_int_LoadDriver(NULL, &pci_init, pci_udiprops, pci_udiprops_size);
43
44         return MODULE_ERR_OK;
45 }
46
47 /**
48  * \brief Detects if a driver should be loaded by the UDI subsystem
49  */
50 int UDI_DetectDriver(void *Base)
51 {
52         Uint    unused;
53         
54         if( Binary_FindSymbol(Base, "udi_init_info", &unused) == 0) {
55                 return 0;
56         }
57         if( Binary_FindSymbol(Base, "_udiprops", &unused) == 0 ) {
58                 Log_Warning("UDI", "Driver has udi_init_info, but no _udiprops symbol");
59                 return 0;
60         }
61         if( Binary_FindSymbol(Base, "_udiprops_end", &unused) == 0) {
62                 Log_Warning("UDI", "Driver has udi_init_info, but no _udiprops_end symbol");
63                 return 0;
64         }
65         
66         return 1;
67 }
68
69 /**
70  * \fn int UDI_LoadDriver(void *Base)
71  */
72 int UDI_LoadDriver(void *Base)
73 {
74         udi_init_t      *info;
75         char    *udiprops = NULL;
76         char    *udiprops_end = 0;
77         
78         if( Binary_FindSymbol(Base, "udi_init_info", (Uint*)&info) == 0) {
79                 Binary_Unload(Base);
80                 return 0;
81         }
82         
83         Binary_FindSymbol(Base, "_udiprops", (Uint*)&udiprops);
84         Binary_FindSymbol(Base, "_udiprops_end", (Uint*)&udiprops_end);
85         Log_Debug("UDI", "udiprops = %p, udiprops_end = %p", udiprops, udiprops_end);
86
87         UDI_int_LoadDriver(Base, info, udiprops, udiprops_end - udiprops);
88         
89         return 0;
90 }
91
92 static udi_boolean_t _get_token_bool(const char *str, const char **outstr)
93 {
94         udi_boolean_t   ret;
95         switch(*str++)
96         {
97         case 't':
98         case 'T':
99                 ret = 1;
100                 break;
101         case 'f':
102         case 'F':
103                 ret = 0;
104                 break;
105         default:
106                 *outstr = NULL;
107                 return 0;
108         }
109         while( isspace(*str) )
110                 str ++;
111         *outstr = str;
112         return ret;
113 }
114 static udi_index_t _get_token_idx(const char *str, const char **outstr)
115 {
116         char    *end;
117         int ret = strtol(str, &end, 10);
118         if( ret < 0 || ret > 255 ) {
119                 Log_Notice("UDI", "Value '%.*s' out of range for udi_index_t",
120                         end-str, str);
121                 *outstr = NULL;
122                 return 0;
123         }
124         if( *end && !isspace(*end) ) {
125                 Log_Notice("UDI", "No whitespace following '%.*s', got '%c'",
126                         end-str, str, *end);
127                 *outstr = NULL;
128                 return 0;
129         }
130         while( *end && isspace(*end) )
131                 end ++;
132         
133         *outstr = end;
134         return ret;
135 }
136 static udi_ubit16_t _get_token_uint16(const char *str, const char **outstr)
137 {
138         char    *end;
139         unsigned long ret = strtoul(str, &end, 10);
140         if( ret > 0xFFFF ) {
141                 Log_Notice("UDI", "Value '%.*s' out of range for udi_ubit16_t",
142                         end-str, str);
143                 *outstr = NULL;
144                 return 0;
145         }
146         if( *end && !isspace(*end) ) {
147                 Log_Notice("UDI", "No whitespace following '%.*s', got '%c'",
148                         end-str, str, *end);
149                 *outstr = NULL;
150                 return 0;
151         }
152         while( *end && isspace(*end) )
153                 end ++;
154         
155         *outstr = end;
156         return ret;
157 }
158 static udi_ubit32_t _get_token_uint32(const char *str, const char **outstr)
159 {
160         char    *end;
161         udi_ubit32_t ret = strtoul(str, &end, 0);
162         if( *end && !isspace(*end) ) {
163                 Log_Notice("UDI", "No whitespace following '%.*s', got '%c'",
164                         end-str, str, *end);
165                 *outstr = NULL;
166                 return 0;
167         }
168         while( *end && isspace(*end) )
169                 end ++;
170         
171         *outstr = end;
172         return ret;
173 }
174 static size_t _get_token_str(const char *str, const char **outstr, char *output)
175 {
176         size_t  ret = 0;
177         const char *pos = str;
178         while( *pos && !isspace(*pos) )
179         {
180                 if( *pos == '\\' )
181                 {
182                         pos ++;
183                         switch( *pos )
184                         {
185                         case '_':       // space
186                                 if(output)
187                                         output[ret] = ' ';
188                                 ret ++;
189                                 break;
190                         case 'H':       // hash
191                                 if(output)
192                                         output[ret] = '#';
193                                 ret ++;
194                                 break;
195                         case '\\':      // backslash
196                                 if(output)
197                                         output[ret] = '\\';
198                                 ret ++;
199                                 break;
200                         // TODO: \p and \m<msgnum> (for message/disaster_message only)
201                         default:
202                                 // Error
203                                 break;
204                         }
205                 }
206                 else {
207                         if(output)
208                                 output[ret] = *pos;
209                         ret ++;
210                 }
211                 pos ++;
212         }
213
214         while( isspace(*pos) )
215                 pos ++;
216         *outstr = pos;  
217
218         if(output)
219                 output[ret] = '\0';
220
221         return ret;
222 }
223 static int _get_token_sym_v(const char *str, const char **outstr, bool printError, const char **syms)
224 {
225         const char *sym;
226         for( int idx = 0; (sym = syms[idx]); idx ++ )
227         {
228                 size_t len = strlen(sym);
229                 if( memcmp(str, sym, len) != 0 )
230                         continue ;
231                 if( str[len] && !isspace(str[len]) )
232                         continue ;
233                 
234                 // Found it!
235                 str += len;
236                 while( isspace(*str) )
237                         str ++;
238                 *outstr = str;
239                 return idx;
240         }
241
242         // Unknown symbol, find the end of the symbol and error
243         const char *end = str;
244         while( !isspace(*end) )
245                 end ++;
246         
247         if( printError ) {
248                 Log_Notice("UDI", "Unknown token '%.*s'", end-str, str);
249         }
250
251         *outstr = NULL;
252         return -1;
253         
254 }
255 static int _get_token_sym(const char *str, const char **outstr, bool printError, ...)
256 {
257         va_list args;
258         const char *sym;
259          int    count = 0;
260         va_start(args, printError);
261         for( ; (sym = va_arg(args, const char *)); count ++ )
262                 ;
263         va_end(args);
264
265         const char      *symlist[count+1];      
266         va_start(args, printError);
267         for( int idx = 0; (sym = va_arg(args, const char *)); idx ++ )
268                 symlist[idx] = sym;
269         symlist[count] = NULL;
270         
271         return _get_token_sym_v(str, outstr, printError, symlist);
272 }
273
274 enum {
275         UDIPROPS__properties_version,
276         UDIPROPS__module,
277         UDIPROPS__meta,
278         UDIPROPS__message,
279         UDIPROPS__locale,
280         UDIPROPS__region,
281         UDIPROPS__parent_bind_ops,
282         UDIPROPS__internal_bind_ops,
283         UDIPROPS__child_bind_ops,
284         UDIPROPS__supplier,
285         UDIPROPS__contact,
286         UDIPROPS__name,
287         UDIPROPS__shortname,
288         UDIPROPS__release,
289         
290         UDIPROPS__requires,
291         UDIPROPS__device,
292         UDIPROPS__enumerates,
293
294         UDIPROPS_last
295 };
296 #define _defpropname(name)      [ UDIPROPS__##name ] = #name
297 const char *caUDI_UdipropsNames[] = {
298         _defpropname(properties_version),
299         _defpropname(module),
300         _defpropname(meta),
301         _defpropname(message),
302         _defpropname(locale),
303         _defpropname(region),
304         _defpropname(parent_bind_ops),
305         _defpropname(internal_bind_ops),
306         _defpropname(child_bind_ops),
307         _defpropname(supplier),
308         _defpropname(contact),
309         _defpropname(name),
310         _defpropname(shortname),
311         _defpropname(release),
312         _defpropname(requires),
313         
314         _defpropname(device),
315         _defpropname(enumerates),
316         
317         [UDIPROPS_last] = NULL
318 };
319 #undef _defpropname
320
321 tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const char *udiprops, size_t udiprops_size)
322 {
323         //UDI_int_DumpInitInfo(info);
324         
325         // TODO: Multiple modules?
326         tUDI_DriverModule *driver_module = NEW(tUDI_DriverModule,);
327         driver_module->InitInfo = info;
328
329         // - Parse udiprops
330         const char      **udipropsptrs;
331         
332         int nLines = 1;
333         for( int i = 0; i < udiprops_size; i++ )
334         {
335                 if( udiprops[i] == '\0' )
336                         nLines ++;
337         }
338         
339         Log_Debug("UDI", "nLines = %i", nLines);
340         
341         udipropsptrs = NEW(const char*,*nLines);
342         int line = 0;
343         udipropsptrs[line++] = udiprops;
344         for( int i = 0; i < udiprops_size; i++ )
345         {
346                 if( udiprops[i] == '\0' ) {
347                         udipropsptrs[line++] = &udiprops[i+1];
348                 }
349         }
350         if(udipropsptrs[line-1] == &udiprops[udiprops_size])
351                 nLines --;
352         
353         // Parse out:
354         // 'message' into driver_module->Messages
355         // 'region' into driver_module->RegionTypes
356         // 'module' into driver_module->ModuleName
357         
358          int    nLocales = 1;
359         for( int i = 0; i < nLines; i ++ )
360         {
361                 const char *str = udipropsptrs[i];
362                  int    sym = _get_token_sym_v(str, &str, false, caUDI_UdipropsNames);
363                 switch(sym)
364                 {
365                 case UDIPROPS__module:
366                         driver_module->ModuleName = str;
367                         break;
368                 case UDIPROPS__meta:
369                         driver_module->nMetaLangs ++;
370                         break;
371                 case UDIPROPS__message:
372                         driver_module->nMessages ++;
373                         break;
374                 case UDIPROPS__locale:
375                         nLocales ++;
376                         break;
377                 case UDIPROPS__region:
378                         driver_module->nRegionTypes ++;
379                         break;
380                 case UDIPROPS__device:
381                         driver_module->nDevices ++;
382                         break;
383                 case UDIPROPS__parent_bind_ops:
384                         driver_module->nParents ++;
385                         break;
386                 case UDIPROPS__child_bind_ops:
387                         driver_module->nChildBindOps ++;
388                         break;
389                 default:
390                         // quiet ignore
391                         break;
392                 }
393         }
394
395         // Allocate structures
396         LOG("nMessages = %i, nMetaLangs = %i",
397                 driver_module->nMessages,
398                 driver_module->nMetaLangs);
399         driver_module->Messages     = NEW(tUDI_PropMessage, * driver_module->nMessages);
400         driver_module->RegionTypes  = NEW(tUDI_PropRegion,  * driver_module->nRegionTypes);
401         driver_module->MetaLangs    = NEW(tUDI_MetaLangRef, * driver_module->nMetaLangs);
402         driver_module->Parents      = NEW(tUDI_BindOps,     * driver_module->nParents);
403         driver_module->ChildBindOps = NEW(tUDI_BindOps,     * driver_module->nChildBindOps);
404         driver_module->Devices      = NEW(tUDI_PropDevSpec*,* driver_module->nDevices);
405
406         // Populate
407          int    cur_locale = 0;
408          int    msg_index = 0;
409          int    ml_index = 0;
410          int    parent_index = 0;
411          int    child_bind_index = 0;
412          int    device_index = 0;
413          int    next_unpop_region = 1;
414         for( int i = 0; i < nLines; i ++ )
415         {
416                 const char *str = udipropsptrs[i];
417                 if( !*str )
418                         continue ;
419                  int    sym = _get_token_sym_v(str, &str, true, caUDI_UdipropsNames);
420                 switch(sym)
421                 {
422                 case UDIPROPS__properties_version:
423                         if( _get_token_uint32(str, &str) != 0x101 ) {
424                                 Log_Warning("UDI", "Properties version mismatch.");
425                         }
426                         break;
427                 case UDIPROPS__module:
428                         driver_module->ModuleName = str;
429                         break;
430                 case UDIPROPS__meta:
431                         {
432                         tUDI_MetaLangRef *ml = &driver_module->MetaLangs[ml_index++];
433                         ml->meta_idx = _get_token_idx(str, &str);
434                         if( !str )      continue;
435                         ml->interface_name = str;
436                         // TODO: May need to trim trailing spaces
437                         ml->metalang = UDI_int_GetMetaLangByName(ml->interface_name);
438                         if( !ml->metalang ) {
439                                 Log_Error("UDI", "Module %s referenced unsupported metalang %s",
440                                         driver_module->ModuleName, ml->interface_name);
441                         }
442                         break;
443                         }
444                 case UDIPROPS__message:
445                         {
446                         tUDI_PropMessage *msg = &driver_module->Messages[msg_index++];
447                         msg->locale = cur_locale;
448                         msg->index = _get_token_uint16(str, &str);
449                         if( !str )      continue ;
450                         msg->string = str;
451                         //Log_Debug("UDI", "Message %i/%i: '%s'", msg->locale, msg->index, msg->string);
452                         break;
453                         }
454                 case UDIPROPS__locale:
455                         // TODO: Set locale
456                         cur_locale = 1;
457                         break;
458                 case UDIPROPS__region:
459                         {
460                         udi_index_t rgn_idx = _get_token_idx(str, &str);
461                         if( !str )      continue ;
462                         // Search for region index (just in case internal_bind_ops appears earlier)
463                         tUDI_PropRegion *rgn = &driver_module->RegionTypes[0];
464                         if( rgn_idx > 0 )
465                         {
466                                 rgn ++;
467                                 for( int i = 1; i < next_unpop_region; i ++, rgn ++ ) {
468                                         if( rgn->RegionIdx == rgn_idx )
469                                                 break;
470                                 }
471                                 if(i == next_unpop_region) {
472                                         if( next_unpop_region == driver_module->nRegionTypes ) {
473                                                 // TODO: warning if reigon types overflow
474                                                 continue ;
475                                         }
476                                         next_unpop_region ++;
477                                         rgn->RegionIdx = rgn_idx;
478                                 }
479                         }
480                         // Parse attributes
481                         while( *str )
482                         {
483                                 int sym = _get_token_sym(str, &str, true,
484                                         "type", "binding", "priority", "latency", "overrun_time", NULL
485                                         );
486                                 if( !str )      break ;
487                                 switch(sym)
488                                 {
489                                 case 0: // type
490                                         rgn->Type = _get_token_sym(str, &str, true,
491                                                 "normal", "fp", NULL);
492                                         break;
493                                 case 1: // binding
494                                         rgn->Binding = _get_token_sym(str, &str, true,
495                                                 "static", "dynamic", NULL);
496                                         break;
497                                 case 2: // priority
498                                         rgn->Priority = _get_token_sym(str, &str, true,
499                                                 "med", "lo", "hi", NULL);
500                                         break;
501                                 case 3: // latency
502                                         rgn->Latency = _get_token_sym(str, &str, true,
503                                                 "non_overrunable", "powerfail_warning", "overrunable",
504                                                 "retryable", "non_critical", NULL);
505                                         break;
506                                 case 4: // overrun_time
507                                         rgn->OverrunTime = _get_token_uint32(str, &str);
508                                         break;
509                                 }
510                                 if( !str )      break ;
511                         }
512                         break;
513                         }
514                 case UDIPROPS__parent_bind_ops:
515                         {
516                         tUDI_BindOps    *bind = &driver_module->Parents[parent_index++];
517                         bind->meta_idx = _get_token_idx(str, &str);
518                         if( !str )      continue ;
519                         bind->region_idx = _get_token_idx(str, &str);
520                         if( !str )      continue ;
521                         bind->ops_idx = _get_token_idx(str, &str);
522                         if( !str )      continue ;
523                         bind->bind_cb_idx = _get_token_idx(str, &str);
524                         if( *str ) {
525                                 // Expected EOL, didn't get it :(
526                         }
527                         Log_Debug("UDI", "Parent bind - meta:%i,rgn:%i,ops:%i,bind:%i",
528                                 bind->meta_idx, bind->region_idx, bind->ops_idx, bind->bind_cb_idx);
529                         break;
530                         }
531                 case UDIPROPS__internal_bind_ops:
532                         {
533                         // Get region using index
534                         udi_index_t meta = _get_token_idx(str, &str);
535                         if( !str )      continue ;
536                         udi_index_t rgn_idx = _get_token_idx(str, &str);
537                         if( !str )      continue ;
538                         
539                         // Search for region index (just in case the relevant 'region' comes after)
540                         tUDI_PropRegion *rgn = &driver_module->RegionTypes[0];
541                         if( rgn_idx > 0 )
542                         {
543                                 rgn ++;
544                                  int    j;
545                                 for( j = 1; j < next_unpop_region; j ++, rgn ++ ) {
546                                         if( rgn->RegionIdx == rgn_idx )
547                                                 break;
548                                 }
549                                 if( j == next_unpop_region ) {
550                                         if( next_unpop_region == driver_module->nRegionTypes ) {
551                                                 // TODO: warning if reigon types overflow
552                                                 continue ;
553                                         }
554                                         next_unpop_region ++;
555                                         rgn->RegionIdx = rgn_idx;
556                                 }
557                         }
558         
559                         // Set properties
560                         rgn->BindMeta = meta;
561                         
562                         rgn->PriBindOps = _get_token_idx(str, &str);
563                         if( !str )      continue ;
564                         rgn->SecBindOps = _get_token_idx(str, &str);
565                         if( !str )      continue ;
566                         rgn->BindCb = _get_token_idx(str, &str);
567                         if( !str )      continue ;
568                         if( *str ) {
569                                 // TODO: Please sir, I want an EOL
570                         }
571                         break;
572                         }
573                 case UDIPROPS__child_bind_ops:
574                         {
575                         tUDI_BindOps    *bind = &driver_module->ChildBindOps[child_bind_index++];
576                         bind->meta_idx = _get_token_idx(str, &str);
577                         if( !str )      continue ;
578                         bind->region_idx = _get_token_idx(str, &str);
579                         if( !str )      continue ;
580                         bind->ops_idx = _get_token_idx(str, &str);
581                         if( *str ) {
582                                 // Expected EOL, didn't get it :(
583                         }
584                         Log_Debug("UDI", "Child bind - meta:%i,rgn:%i,ops:%i",
585                                 bind->meta_idx, bind->region_idx, bind->ops_idx);
586                         break;
587                         }
588                 case UDIPROPS__supplier:
589                 case UDIPROPS__contact:
590                 case UDIPROPS__name:
591                 case UDIPROPS__shortname:
592                 case UDIPROPS__release:
593                         break;
594                 //case UDIPROPS__requires:
595                 //      // TODO: Requires
596                 //      break;
597                 case UDIPROPS__device:
598                         {
599                          int    n_attr = 0;
600                         // Count properties (and validate)
601                         _get_token_idx(str, &str);      // message
602                         if( !str )      continue;
603                         _get_token_idx(str, &str);      // meta
604                         if( !str )      continue;
605                         while( *str )
606                         {
607                                 _get_token_str(str, &str, NULL);
608                                 if( !str )      break;
609                                 _get_token_sym(str, &str, true, "string", "ubit32", "boolean", "array", NULL);
610                                 if( !str )      break;
611                                 _get_token_str(str, &str, NULL);
612                                 if( !str )      break;
613                                 n_attr ++;
614                         }
615                         // Rewind and actually parse
616                         _get_token_str(udipropsptrs[i], &str, NULL);
617                         
618                         tUDI_PropDevSpec *dev = NEW_wA(tUDI_PropDevSpec, Attribs, n_attr);
619                         driver_module->Devices[device_index++] = dev;;
620                         dev->MessageNum = _get_token_idx(str, &str);
621                         dev->MetaIdx = _get_token_idx(str, &str);
622                         dev->nAttribs = n_attr;
623                         n_attr = 0;
624                         while( *str )
625                         {
626                                 udi_instance_attr_list_t *at = &dev->Attribs[n_attr];
627                                 _get_token_str(str, &str, at->attr_name);
628                                 if( !str )      break;
629                                 at->attr_type = _get_token_sym(str, &str, true,
630                                         " ", "string", "array", "ubit32", "boolean", NULL);
631                                 if( !str )      break;
632                                 udi_ubit32_t    val;
633                                 switch( dev->Attribs[n_attr].attr_type )
634                                 {
635                                 case 1: // String
636                                         at->attr_length = _get_token_str(str, &str, (char*)at->attr_value);
637                                         break;
638                                 case 2: // Array
639                                         // TODO: Array
640                                         Log_Warning("UDI", "TODO: Parse 'array' attribute in 'device'");
641                                         _get_token_str(str, &str, NULL);
642                                         break;
643                                 case 3: // ubit32
644                                         at->attr_length = sizeof(udi_ubit32_t);
645                                         val = _get_token_uint32(str, &str);
646                                         Log_Debug("UDI", "device %i: Value '%s'=%x", device_index,
647                                                 at->attr_name, val);
648                                         UDI_ATTR32_SET(at->attr_value, val);
649                                         break;
650                                 case 4: // boolean
651                                         at->attr_length = sizeof(udi_boolean_t);
652                                         UDI_ATTR32_SET(at->attr_value, _get_token_bool(str, &str));
653                                         break;
654                                 }
655                                 if( !str )      break;
656                                 n_attr ++;
657                         }
658                         
659                         break;
660                         }
661                 default:
662                         Log_Debug("UDI", "udipropsptrs[%i] = '%s'", i, udipropsptrs[i]);
663                         break;
664                 }
665         }
666         free(udipropsptrs);
667         
668         // Sort message list
669         // TODO: Sort message list
670
671          int    nSecondaryRgns = 0;
672         for( int i = 0; info->secondary_init_list && info->secondary_init_list[i].region_idx; i ++ )
673                 nSecondaryRgns ++;
674         driver_module->nRegions = 1+nSecondaryRgns;
675
676         
677         // -- Add to loaded module list
678         driver_module->Next = gpUDI_LoadedModules;
679         gpUDI_LoadedModules = driver_module;
680         
681         // Check for orphan drivers, and create an instance of them when loaded
682         if( driver_module->nParents == 0 )
683         {
684                 tUDI_DriverInstance *inst = UDI_MA_CreateInstance(driver_module);
685         
686                 // Enumerate so any pre-loaded drivers are detected     
687                 UDI_MA_BeginEnumeration(inst);
688         }
689         else
690         {
691                 // Search running instances for unbound children that can be bound to this driver
692                 UDI_MA_BindParents(driver_module);
693         }
694
695         return driver_module;
696 }
697
698 void UDI_int_DumpInitInfo(udi_init_t *info)
699 {
700         Log("primary_init_info = %p = {", info->primary_init_info);
701         {
702                 Log(" .mgmt_ops = %p = {", info->primary_init_info->mgmt_ops);
703                 Log("  .usage_ind_op: %p() - 0x%02x",
704                         info->primary_init_info->mgmt_ops->usage_ind_op,
705                         info->primary_init_info->mgmt_op_flags[0]
706                         );
707                 Log("  .enumerate_req_op: %p() - 0x%02x",
708                         info->primary_init_info->mgmt_ops->enumerate_req_op,
709                         info->primary_init_info->mgmt_op_flags[1]
710                         );
711                 Log("  .devmgmt_req_op: %p() - 0x%02x",
712                         info->primary_init_info->mgmt_ops->devmgmt_req_op,
713                         info->primary_init_info->mgmt_op_flags[2]
714                         );
715                 Log("  .final_cleanup_req_op: %p() - 0x%02x",
716                         info->primary_init_info->mgmt_ops->final_cleanup_req_op,
717                         info->primary_init_info->mgmt_op_flags[3]
718                         );
719                 Log(" }");
720                 Log(" .mgmt_scratch_requirement = 0x%x", info->primary_init_info->mgmt_scratch_requirement);
721                 Log(" .enumeration_attr_list_length = 0x%x", info->primary_init_info->enumeration_attr_list_length);
722                 Log(" .rdata_size = 0x%x", info->primary_init_info->rdata_size);
723                 Log(" .child_data_size = 0x%x", info->primary_init_info->child_data_size);
724                 Log(" .per_parent_paths = 0x%x", info->primary_init_info->per_parent_paths);
725         }
726         Log("}");
727         Log("secondary_init_list = %p {", info->secondary_init_list);
728         for( int i = 0; info->secondary_init_list && info->secondary_init_list[i].region_idx; i ++ )
729         {
730                 Log(" [%i] = { .region_idx=%i, .rdata_size=0x%x }",
731                         info->secondary_init_list[i].region_idx, info->secondary_init_list[i].rdata_size);
732         }
733         Log("}");
734         Log("ops_init_list = %p {", info->ops_init_list);
735         for( int i = 0; info->ops_init_list[i].ops_idx; i++ )
736         {
737                 Log(" [%i] = {", i);
738                 Log("  .ops_idx = 0x%x", info->ops_init_list[i].ops_idx);
739                 Log("  .meta_idx = 0x%x", info->ops_init_list[i].meta_idx);
740                 Log("  .meta_ops_num = 0x%x", info->ops_init_list[i].meta_ops_num);
741                 Log("  .chan_context_size = 0x%x", info->ops_init_list[i].chan_context_size);
742                 Log("  .ops_vector = %p", info->ops_init_list[i].ops_vector);
743 //              Log("  .op_flags = %p", info->ops_init_list[i].op_flags);
744                 Log(" }");
745         }
746         Log("}");
747         Log("cb_init_list = %p {", info->cb_init_list);
748         for( int i = 0; info->cb_init_list[i].cb_idx; i++ )
749         {
750                 udi_cb_init_t   *ent = &info->cb_init_list[i];
751                 Log(" [%i] = {", i);
752                 Log("  .cbidx = %i", ent->cb_idx);
753                 Log("  .meta_idx = %i", ent->meta_idx);
754                 Log("  .meta_cb_num = %i", ent->meta_cb_num);
755                 Log("  .scratch_requirement = 0x%x", ent->scratch_requirement);
756                 Log("  .inline_size = 0x%x", ent->inline_size);
757                 Log("  .inline_layout = %p", ent->inline_layout);
758                 Log(" }");
759         }
760 }
761
762 // TODO: Move this stuff out
763 udi_ops_init_t *UDI_int_GetOps(tUDI_DriverInstance *Inst, udi_index_t index)
764 {
765         udi_ops_init_t *ops = Inst->Module->InitInfo->ops_init_list;
766         while( ops->ops_idx && ops->ops_idx != index )
767                 ops ++;
768         if(ops->ops_idx == 0)
769                 return NULL;
770         return ops;
771 }
772
773 tUDI_MetaLang *UDI_int_GetMetaLang(tUDI_DriverInstance *Inst, udi_index_t index)
774 {
775         if( index == 0 )
776                 return &cMetaLang_Management;
777         ASSERT(Inst);
778         for( int i = 0; i < Inst->Module->nMetaLangs; i ++ )
779         {
780                 if( Inst->Module->MetaLangs[i].meta_idx == index )
781                         return Inst->Module->MetaLangs[i].metalang;
782         }
783         return NULL;
784 }
785
786 const tUDI_MetaLang *UDI_int_GetMetaLangByName(const char *Name)
787 {
788         //extern tUDI_MetaLang  cMetaLang_Management;
789         extern tUDI_MetaLang    cMetaLang_BusBridge;
790         const tUDI_MetaLang     *langs[] = {
791                 &cMetaLang_BusBridge,
792                 NULL
793         };
794         for( int i = 0; langs[i]; i ++ )
795         {
796                 if( strcmp(Name, langs[i]->Name) == 0 )
797                         return langs[i];
798         }
799         return NULL;
800 }
801

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