5 #define VERSION ((0<<8)|1)
9 #include "udi_internal.h"
12 int UDI_Install(char **Arguments);
13 int UDI_DetectDriver(void *Base);
14 int UDI_LoadDriver(void *Base);
16 tUDI_DriverInstance *UDI_CreateInstance(tUDI_DriverModule *DriverModule);
17 tUDI_DriverRegion *UDI_InitRegion(tUDI_DriverInstance *Inst, udi_ubit16_t Index, udi_ubit16_t Type, size_t RDataSize);
20 MODULE_DEFINE(0, VERSION, UDI, UDI_Install, NULL, NULL);
21 tModuleLoader gUDI_Loader = {
22 NULL, "UDI", UDI_DetectDriver, UDI_LoadDriver, NULL
27 * \fn int UDI_Install(char **Arguments)
28 * \brief Stub intialisation routine
30 int UDI_Install(char **Arguments)
32 Module_RegisterLoader( &gUDI_Loader );
37 * \brief Detects if a driver should be loaded by the UDI subsystem
39 int UDI_DetectDriver(void *Base)
43 if( Binary_FindSymbol(Base, "udi_init_info", &unused) == 0) {
46 if( Binary_FindSymbol(Base, "_udiprops", &unused) == 0 ) {
47 Log_Warning("UDI", "Driver has udi_init_info, but no _udiprops symbol");
50 if( Binary_FindSymbol(Base, "_udiprops_end", &unused) == 0) {
51 Log_Warning("UDI", "Driver has udi_init_info, but no _udiprops_end symbol");
59 * \fn int UDI_LoadDriver(void *Base)
61 int UDI_LoadDriver(void *Base)
64 char *udiprops = NULL;
65 char *udiprops_end = 0;
69 if( Binary_FindSymbol(Base, "udi_init_info", (Uint*)&info) == 0) {
75 Binary_FindSymbol(Base, "_udiprops", (Uint*)&udiprops);
76 Binary_FindSymbol(Base, "_udiprops_end", (Uint*)&udiprops_end);
79 Log("primary_init_info = %p = {", info->primary_init_info);
81 Log(" .mgmt_ops = %p = {", info->primary_init_info->mgmt_ops);
82 Log(" .usage_ind_op: %p() - 0x%02x",
83 info->primary_init_info->mgmt_ops->usage_ind_op,
84 info->primary_init_info->mgmt_op_flags[0]
86 Log(" .enumerate_req_op: %p() - 0x%02x",
87 info->primary_init_info->mgmt_ops->enumerate_req_op,
88 info->primary_init_info->mgmt_op_flags[1]
90 Log(" .devmgmt_req_op: %p() - 0x%02x",
91 info->primary_init_info->mgmt_ops->devmgmt_req_op,
92 info->primary_init_info->mgmt_op_flags[2]
94 Log(" .final_cleanup_req_op: %p() - 0x%02x",
95 info->primary_init_info->mgmt_ops->final_cleanup_req_op,
96 info->primary_init_info->mgmt_op_flags[3]
99 Log(" .mgmt_scratch_requirement = 0x%x", info->primary_init_info->mgmt_scratch_requirement);
100 Log(" .enumeration_attr_list_length = 0x%x", info->primary_init_info->enumeration_attr_list_length);
101 Log(" .rdata_size = 0x%x", info->primary_init_info->rdata_size);
102 Log(" .child_data_size = 0x%x", info->primary_init_info->child_data_size);
103 Log(" .per_parent_paths = 0x%x", info->primary_init_info->per_parent_paths);
106 Log("secondary_init_list = %p {", info->secondary_init_list);
107 for( int i = 0; info->secondary_init_list && info->secondary_init_list[i].region_idx; i ++ )
109 Log(" [%i] = { .region_idx=%i, .rdata_size=0x%x }",
110 info->secondary_init_list[i].region_idx, info->secondary_init_list[i].rdata_size);
113 Log("ops_init_list = %p", info->ops_init_list);
115 for( int i = 0; info->ops_init_list[i].ops_idx; i++ )
117 Log("info->ops_init_list[%i] = {", i);
118 Log(" .ops_idx = 0x%x", info->ops_init_list[i].ops_idx);
119 Log(" .meta_idx = 0x%x", info->ops_init_list[i].meta_idx);
120 Log(" .meta_ops_num = 0x%x", info->ops_init_list[i].meta_ops_num);
121 Log(" .chan_context_size = 0x%x", info->ops_init_list[i].chan_context_size);
122 Log(" .ops_vector = %p", info->ops_init_list[i].ops_vector);
123 // Log(" .op_flags = %p", info->ops_init_list[i].op_flags);
129 // TODO: Multiple modules?
130 tUDI_DriverModule *driver_module = NEW(tUDI_DriverModule,);
131 driver_module->InitInfo = info;
137 Log_Debug("UDI", "udiprops = %p, udiprops_end = %p", udiprops, udiprops_end);
138 size_t udiprops_size = udiprops_end - udiprops;
141 for( int i = 0; i < udiprops_size; i++ )
143 if( udiprops[i] == '\0' )
147 Log_Debug("UDI", "nLines = %i", nLines);
149 udipropsptrs = NEW(char*,*nLines);
151 udipropsptrs[line++] = udiprops;
152 for( int i = 0; i < udiprops_size; i++ )
154 if( udiprops[i] == '\0' ) {
155 udipropsptrs[line++] = &udiprops[i+1];
158 if(udipropsptrs[line-1] == &udiprops[udiprops_size])
161 for( int i = 0; i < nLines; i ++ )
166 // 'message' into driver_module->Messages
167 // 'region' into driver_module->RegionTypes
168 // 'module' into driver_module->ModuleName
172 int nRegionTypes = 0;
173 for( int i = 0; i < nLines; i ++ )
175 const char *str = udipropsptrs[i];
176 if( strncmp("module ", str, 7) == 0 ) {
177 driver_module->ModuleName = str + 7;
179 else if( strncmp("message ", str, 8) == 0 ) {
182 else if( strncmp("locale ", str, 7) == 0 ) {
185 else if( strncmp("region ", str, 7) == 0 ) {
190 // Allocate structures
191 driver_module->nMessages = nMessages;
192 driver_module->Messages = NEW(tUDI_PropMessage, *nMessages);
193 driver_module->nRegionTypes = nRegionTypes;
194 driver_module->RegionTypes = NEW(tUDI_PropRegion, *nRegionTypes);
199 for( int i = 0; i < nLines; i ++ )
201 const char *str = udipropsptrs[i];
202 if( strncmp("module ", str, 7) == 0 ) {
203 driver_module->ModuleName = str + 7;
205 else if( strncmp("message ", str, 8) == 0 ) {
206 tUDI_PropMessage *msg = &driver_module->Messages[msg_index++];
208 msg->locale = cur_locale;
209 msg->index = strtoul(str+8, &end, 10);
210 if( *end != ' ' && *end != '\t' ) {
214 while( isspace(*end) )
218 Log_Debug("UDI", "Message %i/%i: '%s'", msg->locale, msg->index, msg->string);
220 else if( strncmp("locale ", str, 7) == 0 ) {
224 else if( strncmp("region ", str, 7) == 0 ) {
228 Log_Debug("UDI", "udipropsptrs[%i] = '%s'", i, udipropsptrs[i]);
233 // TODO: Sort message list
236 int nSecondaryRgns = 0;
237 for( int i = 0; info->secondary_init_list && info->secondary_init_list[i].region_idx; i ++ )
239 driver_module->nSecondaryRegions = nSecondaryRgns;
241 // Create initial driver instance
242 tUDI_DriverInstance *inst = UDI_CreateInstance(driver_module);
244 for( int i = 0; i < 1+driver_module->nSecondaryRegions; i ++ )
245 Log("Rgn %i: %p", i, inst->Regions[i]);
247 // Send usage indication
249 memset(&ucb, 0, sizeof(ucb));
250 ucb.gcb.channel = inst->ManagementChannel;
251 udi_usage_ind(&ucb, UDI_RESOURCES_NORMAL);
256 tUDI_DriverInstance *UDI_CreateInstance(tUDI_DriverModule *DriverModule)
258 tUDI_DriverInstance *inst = NEW_wA(tUDI_DriverInstance, Regions, (1+DriverModule->nSecondaryRegions));
259 inst->Module = DriverModule;
260 inst->Regions[0] = UDI_InitRegion(inst, 0, 0, DriverModule->InitInfo->primary_init_info->rdata_size);
261 udi_secondary_init_t *sec_init = DriverModule->InitInfo->secondary_init_list;
264 for( int i = 0; sec_init[i].region_idx; i ++ )
266 inst->Regions[1+i] = UDI_InitRegion(inst, i, sec_init[i].region_idx, sec_init[i].rdata_size);
270 inst->ManagementChannel = UDI_CreateChannel(METALANG_MGMT, 0, NULL, 0, inst, 0);
275 tUDI_DriverRegion *UDI_InitRegion(tUDI_DriverInstance *Inst, udi_ubit16_t Index, udi_ubit16_t Type, size_t RDataSize)
277 // ASSERTCR( RDataSize, <=, UDI_MIN_ALLOC_LIMIT, NULL );
278 ASSERTCR( RDataSize, >, sizeof(udi_init_context_t), NULL );
279 tUDI_DriverRegion *rgn = NEW(tUDI_DriverRegion,+RDataSize);
280 rgn->InitContext = (void*)(rgn+1);
281 rgn->InitContext->region_idx = Type;
282 // rgn->InitContext->limits