* devfs now uses the driver's name instead of its node_ref to see if it
already knows this driver. * This should also allow to have a driver in home/config/add-ons/... overlays a driver with the same name in system/add-ons/... * This should also fix bug #1750. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23892 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
217d31eac9
commit
dbc1da17ed
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
@ -125,6 +125,7 @@ enum {
|
||||
struct driver_entry {
|
||||
driver_entry *next;
|
||||
const char *path;
|
||||
const char *name;
|
||||
dev_t device;
|
||||
ino_t node;
|
||||
time_t last_modified;
|
||||
@ -163,12 +164,12 @@ static uint32
|
||||
driver_entry_hash(void *_driver, const void *_key, uint32 range)
|
||||
{
|
||||
driver_entry *driver = (driver_entry *)_driver;
|
||||
const ino_t *key = (const ino_t *)_key;
|
||||
const char *key = (const char *)_key;
|
||||
|
||||
if (driver != NULL)
|
||||
return driver->node % range;
|
||||
return hash_hash_string(driver->name) % range;
|
||||
|
||||
return (uint64)*key % range;
|
||||
return hash_hash_string(key) % range;
|
||||
}
|
||||
|
||||
|
||||
@ -176,12 +177,9 @@ static int
|
||||
driver_entry_compare(void *_driver, const void *_key)
|
||||
{
|
||||
driver_entry *driver = (driver_entry *)_driver;
|
||||
const ino_t *key = (const ino_t *)_key;
|
||||
const char *key = (const char *)_key;
|
||||
|
||||
if (driver->node == *key)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
return strcmp(driver->name, key);
|
||||
}
|
||||
|
||||
|
||||
@ -202,13 +200,6 @@ load_driver(driver_entry *driver)
|
||||
return image;
|
||||
}
|
||||
|
||||
// for prettier debug output
|
||||
const char *name = strrchr(driver->path, '/');
|
||||
if (name == NULL)
|
||||
name = driver->path;
|
||||
else
|
||||
name++;
|
||||
|
||||
// For a valid device driver the following exports are required
|
||||
|
||||
driver->api_version = &sDefaultApiVersion;
|
||||
@ -219,23 +210,24 @@ load_driver(driver_entry *driver)
|
||||
#error Add checks here for new vs old api version!
|
||||
#endif
|
||||
if (*driver->api_version > B_CUR_DRIVER_API_VERSION) {
|
||||
dprintf("%s: api_version %ld not handled\n", name, *driver->api_version);
|
||||
dprintf("%s: api_version %ld not handled\n", driver->name,
|
||||
*driver->api_version);
|
||||
status = B_BAD_VALUE;
|
||||
goto error1;
|
||||
}
|
||||
if (*driver->api_version < 1) {
|
||||
dprintf("%s: api_version invalid\n", name);
|
||||
dprintf("%s: api_version invalid\n", driver->name);
|
||||
status = B_BAD_VALUE;
|
||||
goto error1;
|
||||
}
|
||||
} else
|
||||
dprintf("%s: api_version missing\n", name);
|
||||
dprintf("%s: api_version missing\n", driver->name);
|
||||
|
||||
if (get_image_symbol(image, "publish_devices", B_SYMBOL_TYPE_TEXT,
|
||||
(void **)&driver->publish_devices) != B_OK
|
||||
|| get_image_symbol(image, "find_device", B_SYMBOL_TYPE_TEXT,
|
||||
(void **)&driver->find_device) != B_OK) {
|
||||
dprintf("%s: mandatory driver symbol(s) missing!\n", name);
|
||||
dprintf("%s: mandatory driver symbol(s) missing!\n", driver->name);
|
||||
status = B_BAD_VALUE;
|
||||
goto error1;
|
||||
}
|
||||
@ -245,7 +237,8 @@ load_driver(driver_entry *driver)
|
||||
if (get_image_symbol(image, "init_hardware", B_SYMBOL_TYPE_TEXT,
|
||||
(void **)&init_hardware) == B_OK
|
||||
&& (status = init_hardware()) != B_OK) {
|
||||
dprintf("%s: init_hardware() failed: %s\n", name, strerror(status));
|
||||
dprintf("%s: init_hardware() failed: %s\n", driver->name,
|
||||
strerror(status));
|
||||
status = ENXIO;
|
||||
goto error1;
|
||||
}
|
||||
@ -253,7 +246,8 @@ load_driver(driver_entry *driver)
|
||||
if (get_image_symbol(image, "init_driver", B_SYMBOL_TYPE_TEXT,
|
||||
(void **)&init_driver) == B_OK
|
||||
&& (status = init_driver()) != B_OK) {
|
||||
dprintf("%s: init_driver() failed: %s\n", name, strerror(status));
|
||||
dprintf("%s: init_driver() failed: %s\n", driver->name,
|
||||
strerror(status));
|
||||
status = ENXIO;
|
||||
goto error2;
|
||||
}
|
||||
@ -272,7 +266,7 @@ load_driver(driver_entry *driver)
|
||||
// we keep the driver loaded if it exports at least a single interface
|
||||
devicePaths = driver->publish_devices();
|
||||
if (devicePaths == NULL) {
|
||||
dprintf("%s: publish_devices() returned NULL.\n", name);
|
||||
dprintf("%s: publish_devices() returned NULL.\n", driver->name);
|
||||
status = ENXIO;
|
||||
goto error3;
|
||||
}
|
||||
@ -332,6 +326,17 @@ unload_driver(driver_entry *driver)
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
get_leaf(const char *path)
|
||||
{
|
||||
const char *name = strrchr(path, '/');
|
||||
if (name == NULL)
|
||||
return path;
|
||||
|
||||
return name + 1;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
add_driver(const char *path, image_id image)
|
||||
{
|
||||
@ -339,12 +344,11 @@ add_driver(const char *path, image_id image)
|
||||
|
||||
struct stat stat;
|
||||
if (image >= 0) {
|
||||
// TODO: Unfortunately only the node ID is the key for the hash table.
|
||||
// The image ID should be a small number and hopefully the boot FS
|
||||
// doesn't use small negative values -- if it is inode based, we should
|
||||
// be relatively safe.
|
||||
stat.st_dev = -1;
|
||||
stat.st_ino = -image;
|
||||
stat.st_ino = -1;
|
||||
} else {
|
||||
if (::stat(path, &stat) != 0)
|
||||
return errno;
|
||||
@ -353,10 +357,11 @@ add_driver(const char *path, image_id image)
|
||||
RecursiveLocker locker(&sDeviceFileSystem->lock);
|
||||
|
||||
driver_entry *driver = (driver_entry *)hash_lookup(
|
||||
sDeviceFileSystem->driver_hash, &stat.st_ino);
|
||||
sDeviceFileSystem->driver_hash, get_leaf(path));
|
||||
if (driver != NULL) {
|
||||
// we know this driver
|
||||
// ToDo: test for changes here? Although node monitoring should be enough.
|
||||
// TODO: test for changes here and/or via node monitoring and reload
|
||||
// the driver if necessary
|
||||
if (driver->image < B_OK)
|
||||
return driver->image;
|
||||
|
||||
@ -375,6 +380,7 @@ add_driver(const char *path, image_id image)
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
driver->name = get_leaf(driver->path);
|
||||
driver->device = stat.st_dev;
|
||||
driver->node = stat.st_ino;
|
||||
driver->image = image;
|
||||
|
Loading…
Reference in New Issue
Block a user