Bye, bye elf_lookup_symbol(), hello get_image_symbol().

Also renamed elf_load_kspace() to load_kernel_add_on(), and friends.
The new unload_kernel_add_on() now has an image_id as parameter, no longer
a path (like the former elf_unload_kspace()).
Now requires a driver to export the api_version symbol.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7528 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-05-11 19:53:37 +00:00
parent b918b5035f
commit d00edc2f92
+30 -39
View File
@@ -73,9 +73,9 @@ int dev_init(kernel_args *ka)
image_id image_id
dev_load_dev_module(const char *name, const char *dirpath) dev_load_dev_module(const char *name, const char *dirpath)
{ {
image_id id; image_id image;
char path[SYS_MAX_PATH_LEN]; char path[SYS_MAX_PATH_LEN];
uint32 *api_version; uint32 *api_version = NULL;
status_t (*init_hardware)(void); status_t (*init_hardware)(void);
status_t (*init_driver)(void); status_t (*init_driver)(void);
status_t (*uninit_driver)(void); status_t (*uninit_driver)(void);
@@ -83,66 +83,57 @@ dev_load_dev_module(const char *name, const char *dirpath)
const char **(*publish_devices)(void); const char **(*publish_devices)(void);
const char **devfs_paths; const char **devfs_paths;
bool keep_loaded; bool keep_loaded;
status_t status;
sprintf(path, "%s/%s", dirpath, name); sprintf(path, "%s/%s", dirpath, name);
/* Load the module, return error if unable */ /* Load the module, return error if unable */
id = elf_load_kspace(path, ""); image = load_kernel_add_on(path);
if (id < 0) if (image < 0)
return id; return image;
/* Don't get all the symbols we will require initially. Just get the /* Don't get all the symbols we will require initially. Just get the
* ones we need to check we have a valid module. * ones we need to check we have a valid module.
* elf_find_symbol is an extra call and so we don't make it more often
* than we have to.
*/ */
/* For a valid device driver we MUST have the publish_devices and
* find_device functions available
*/
/* XXX - very few drivers have the api_version symbol defined yet.
* Add api_version to the rest of the drivers!
*/
api_version = (uint32 *) elf_lookup_symbol(id, "api_version");
publish_devices = (void *) elf_lookup_symbol(id, "publish_devices");
find_device = (void *) elf_lookup_symbol(id, "find_device");
if (publish_devices == NULL || find_device == NULL) { // For a valid device driver the following exports are required
if (get_image_symbol(image, "publish_devices", B_SYMBOL_TYPE_TEXT, (void **)&publish_devices) != B_OK
|| get_image_symbol(image, "api_version", B_SYMBOL_TYPE_DATA, (void **)&api_version) != B_OK
|| get_image_symbol(image, "find_device", B_SYMBOL_TYPE_TEXT, (void **)&find_device) != B_OK) {
dprintf("DEV: %s: mandatory driver symbol(s) missing! :(\n", name); dprintf("DEV: %s: mandatory driver symbol(s) missing! :(\n", name);
id = EINVAL; status = EINVAL;
goto error; goto error;
} }
/* ToDo: we should fail if the driver doesn't export the api_version,
* but right now, there are some drivers in our tree that doesn't...
*/
if (api_version == NULL)
dprintf("driver \"%s\" has no api_version set!\n", name);
/* Next, do we have an init_hardware function? If we do run it and /* Next, do we have an init_hardware function? If we do run it and
* if it fails simply fall through to the exit... * if it fails simply fall through to the exit...
*/ */
init_hardware = (void *) elf_lookup_symbol(id, "init_hardware"); if (get_image_symbol(image, "init_hardware", B_SYMBOL_TYPE_TEXT,
if (init_hardware && init_hardware() != 0) { (void **)&init_hardware) == B_OK
&& init_hardware() != B_OK) {
dprintf("DEV: %s: init_hardware failed :(\n", name); dprintf("DEV: %s: init_hardware failed :(\n", name);
id = ENXIO; status = ENXIO;
goto error; goto error;
} }
/* OK, so we now have what appears to be a valid module that has /* OK, so we now have what appears to be a valid module that has
* completed init_hardware and thus thinks it should be used. * completed init_hardware and thus thinks it should be used.
* XXX - this is bogus! * ToDo:
* XXX - the driver init routines should be called by devfs and * - this is bogus!
* - the driver init routines should be called by devfs and
* only when the driver is first needed. However, that level * only when the driver is first needed. However, that level
* level of support is not yet in devfs, so we have a hack * level of support is not yet in devfs, so we have a hack
* here that calls the init_driver function at this point. * here that calls the init_driver function at this point.
* As a result we will check to see if we actually manage to * As a result we will check to see if we actually manage to
* publish the device, and if we do we will keep the module * publish the device, and if we do we will keep the module
* loaded. * loaded.
* XXX - remove this when devfs is fixed! * - remove this when devfs is fixed!
*/ */
init_driver = (void *) elf_lookup_symbol(id, "init_driver"); if (get_image_symbol(image, "init_driver", B_SYMBOL_TYPE_TEXT,
if (init_driver && init_driver() != 0) { (void **)&init_driver) == B_OK
&& init_driver() != B_OK) {
dprintf("DEV: %s: init_driver failed :(\n", name); dprintf("DEV: %s: init_driver failed :(\n", name);
id = ENXIO; status = ENXIO;
goto error; goto error;
} }
@@ -167,7 +158,7 @@ dev_load_dev_module(const char *name, const char *dirpath)
* XXX - This is bogus, see above * XXX - This is bogus, see above
*/ */
if (keep_loaded) if (keep_loaded)
return id; return image;
/* If the function gets here then the following has happenned... /* If the function gets here then the following has happenned...
* - the driver has been loaded * - the driver has been loaded
@@ -178,19 +169,19 @@ dev_load_dev_module(const char *name, const char *dirpath)
* devfs_publish_device has for some reason failed on each path. * devfs_publish_device has for some reason failed on each path.
*/ */
uninit_driver = (void *) elf_lookup_symbol(id, "uninit_driver"); if (get_image_symbol(image, "uninit_driver", B_SYMBOL_TYPE_TEXT,
if (uninit_driver) (void **)&uninit_driver) == B_OK)
uninit_driver(); uninit_driver();
// ToDo: That might not be the best error code // ToDo: That might not be the best error code
id = ENXIO; status = ENXIO;
error: error:
/* If we've gotten here then the driver will be unloaded and an /* If we've gotten here then the driver will be unloaded and an
* error code returned. * error code returned.
*/ */
elf_unload_kspace(path); unload_kernel_add_on(image);
return id; return status;
} }