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

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