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

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