* Greatly simplified republish_driver(); it doesn't need to use the path_entry
stuff at all, anymore. * Removed now unused get_device_for_path(). * unpublish_driver() now only deletes the device if unpublishing actually worked out okay. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27038 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -64,10 +64,14 @@ public:
|
|||||||
void** _cookie);
|
void** _cookie);
|
||||||
virtual status_t Select(void* cookie, uint8 event, selectsync* sync);
|
virtual status_t Select(void* cookie, uint8 event, selectsync* sync);
|
||||||
|
|
||||||
|
bool Republished() const { return fRepublished; }
|
||||||
|
void SetRepublished(bool republished)
|
||||||
|
{ fRepublished = republished; }
|
||||||
private:
|
private:
|
||||||
legacy_driver* fDriver;
|
legacy_driver* fDriver;
|
||||||
const char* fPath;
|
const char* fPath;
|
||||||
device_hooks* fHooks;
|
device_hooks* fHooks;
|
||||||
|
bool fRepublished;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef DoublyLinkedList<LegacyDevice> DeviceList;
|
typedef DoublyLinkedList<LegacyDevice> DeviceList;
|
||||||
@@ -213,21 +217,6 @@ driver_entry_compare(void *_driver, const void *_key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static LegacyDevice*
|
|
||||||
get_device_for_path(legacy_driver* driver, const char* path)
|
|
||||||
{
|
|
||||||
DeviceList::Iterator iterator = driver->devices.GetIterator();
|
|
||||||
while (iterator.HasNext()) {
|
|
||||||
LegacyDevice* device = iterator.Next();
|
|
||||||
|
|
||||||
if (!strcmp(device->Path(), path))
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! Collects all published devices of a driver, compares them to what the
|
/*! Collects all published devices of a driver, compares them to what the
|
||||||
driver would publish now, and then publishes/unpublishes the devices
|
driver would publish now, and then publishes/unpublishes the devices
|
||||||
as needed.
|
as needed.
|
||||||
@@ -241,59 +230,42 @@ republish_driver(legacy_driver* driver)
|
|||||||
return load_driver(driver);
|
return load_driver(driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
// build the list of currently present devices of this driver
|
// mark all devices
|
||||||
DeviceList::Iterator iterator = driver->devices.GetIterator();
|
DeviceList::Iterator iterator = driver->devices.GetIterator();
|
||||||
DoublyLinkedList<path_entry> currentNodes;
|
while (LegacyDevice* device = iterator.Next()) {
|
||||||
while (iterator.HasNext()) {
|
device->SetRepublished(false);
|
||||||
LegacyDevice* device = iterator.Next();
|
|
||||||
|
|
||||||
path_entry* entry = new(std::nothrow) path_entry;
|
|
||||||
if (entry == NULL) {
|
|
||||||
while ((entry = currentNodes.RemoveHead()))
|
|
||||||
delete entry;
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
strlcpy(entry->path, device->Path(), sizeof(entry->path));
|
|
||||||
currentNodes.Add(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// now ask the driver for it's currently published devices
|
// now ask the driver for it's currently published devices
|
||||||
const char **devicePaths = driver->publish_devices();
|
const char** devicePaths = driver->publish_devices();
|
||||||
|
|
||||||
int32 exported = 0;
|
int32 exported = 0;
|
||||||
for (; devicePaths != NULL && devicePaths[0]; devicePaths++) {
|
for (; devicePaths != NULL && devicePaths[0]; devicePaths++) {
|
||||||
bool present = false;
|
LegacyDevice* device;
|
||||||
path_entry *entry = currentNodes.Head();
|
|
||||||
while (entry) {
|
iterator = driver->devices.GetIterator();
|
||||||
if (strncmp(entry->path, devicePaths[0], B_PATH_NAME_LENGTH) == 0) {
|
while ((device = iterator.Next()) != NULL) {
|
||||||
// this device was present before and still is -> no republish
|
if (!strncmp(device->Path(), devicePaths[0], B_PATH_NAME_LENGTH)) {
|
||||||
currentNodes.Remove(entry);
|
// mark device as republished
|
||||||
delete entry;
|
device->SetRepublished(true);
|
||||||
exported++;
|
exported++;
|
||||||
present = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = currentNodes.GetNext(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
device_hooks *hooks = driver->find_device(devicePaths[0]);
|
device_hooks* hooks = driver->find_device(devicePaths[0]);
|
||||||
if (hooks == NULL)
|
if (hooks == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (present) {
|
if (device != NULL) {
|
||||||
// update hooks
|
// update hooks
|
||||||
LegacyDevice* device = get_device_for_path(driver, devicePaths[0]);
|
device->SetHooks(hooks);
|
||||||
if (device != NULL)
|
|
||||||
device->SetHooks(hooks);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the device was not present before -> publish it now
|
// the device was not present before -> publish it now
|
||||||
TRACE(("devfs: publishing new device \"%s\"\n", devicePaths[0]));
|
TRACE(("devfs: publishing new device \"%s\"\n", devicePaths[0]));
|
||||||
LegacyDevice* device = new(std::nothrow) LegacyDevice(driver,
|
device = new(std::nothrow) LegacyDevice(driver, devicePaths[0], hooks);
|
||||||
devicePaths[0], hooks);
|
|
||||||
if (device != NULL && device->InitCheck() == B_OK
|
if (device != NULL && device->InitCheck() == B_OK
|
||||||
&& devfs_publish_device(devicePaths[0], device) == B_OK) {
|
&& devfs_publish_device(devicePaths[0], device) == B_OK) {
|
||||||
driver->devices.Add(device);
|
driver->devices.Add(device);
|
||||||
@@ -302,24 +274,22 @@ republish_driver(legacy_driver* driver)
|
|||||||
delete device;
|
delete device;
|
||||||
}
|
}
|
||||||
|
|
||||||
// what's left in currentNodes was present but is not anymore -> unpublish
|
// remove all devices that weren't republished
|
||||||
while (true) {
|
iterator = driver->devices.GetIterator();
|
||||||
path_entry *entry = currentNodes.RemoveHead();
|
while (LegacyDevice* device = iterator.Next()) {
|
||||||
if (entry == NULL)
|
if (device->Republished())
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
TRACE(("devfs: unpublishing no more present \"%s\"\n", entry->path));
|
TRACE(("devfs: unpublishing no more present \"%s\"\n", device->Path()));
|
||||||
LegacyDevice* device = get_device_for_path(driver, entry->path);
|
iterator.Remove();
|
||||||
if (device != NULL)
|
|
||||||
driver->devices.Remove(device);
|
|
||||||
|
|
||||||
devfs_unpublish_device(entry->path, true);
|
devfs_unpublish_device(device, true);
|
||||||
delete device;
|
delete device;
|
||||||
delete entry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exported == 0) {
|
if (exported == 0) {
|
||||||
TRACE(("devfs: driver \"%s\" does not publish any more nodes and is unloaded\n", driver->path));
|
TRACE(("devfs: driver \"%s\" does not publish any more nodes and is "
|
||||||
|
"unloaded\n", driver->path));
|
||||||
unload_driver(driver);
|
unload_driver(driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,8 +428,8 @@ static void
|
|||||||
unpublish_driver(legacy_driver *driver)
|
unpublish_driver(legacy_driver *driver)
|
||||||
{
|
{
|
||||||
while (LegacyDevice* device = driver->devices.RemoveHead()) {
|
while (LegacyDevice* device = driver->devices.RemoveHead()) {
|
||||||
devfs_unpublish_device(device, true);
|
if (devfs_unpublish_device(device, true) == B_OK)
|
||||||
delete device;
|
delete device;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +520,7 @@ add_driver(const char *path, image_id image)
|
|||||||
// isn't the same anymore so rescanning of drivers will work in
|
// isn't the same anymore so rescanning of drivers will work in
|
||||||
// case this driver was loaded so early that it has a boot module
|
// case this driver was loaded so early that it has a boot module
|
||||||
// path and not a proper driver path
|
// path and not a proper driver path
|
||||||
free((char *)driver->path);
|
free((char*)driver->path);
|
||||||
driver->path = strdup(path);
|
driver->path = strdup(path);
|
||||||
driver->name = get_leaf(driver->path);
|
driver->name = get_leaf(driver->path);
|
||||||
driver->binary_updated = true;
|
driver->binary_updated = true;
|
||||||
@@ -652,7 +622,7 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
|
|||||||
RecursiveLocker locker(sLock);
|
RecursiveLocker locker(sLock);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
path_entry *path = sDriversToAdd.RemoveHead();
|
path_entry* path = sDriversToAdd.RemoveHead();
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -679,17 +649,17 @@ handle_driver_events(void */*_fs*/, int /*iteration*/)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
driver_added(const char *path)
|
driver_added(const char* path)
|
||||||
{
|
{
|
||||||
int32 priority = get_priority(path);
|
int32 priority = get_priority(path);
|
||||||
RecursiveLocker locker(sLock);
|
RecursiveLocker locker(sLock);
|
||||||
|
|
||||||
legacy_driver *driver = (legacy_driver *)hash_lookup(sDriverHash,
|
legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash,
|
||||||
get_leaf(path));
|
get_leaf(path));
|
||||||
|
|
||||||
if (driver == NULL) {
|
if (driver == NULL) {
|
||||||
// Add the driver to our list
|
// Add the driver to our list
|
||||||
path_entry *entry = new(std::nothrow) path_entry;
|
path_entry* entry = new(std::nothrow) path_entry;
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -1155,7 +1125,8 @@ probe_for_drivers(const char *type)
|
|||||||
LegacyDevice::LegacyDevice(legacy_driver* driver, const char* path,
|
LegacyDevice::LegacyDevice(legacy_driver* driver, const char* path,
|
||||||
device_hooks* hooks)
|
device_hooks* hooks)
|
||||||
:
|
:
|
||||||
fDriver(driver)
|
fDriver(driver),
|
||||||
|
fRepublished(true)
|
||||||
{
|
{
|
||||||
fDeviceModule = (device_module_info*)malloc(sizeof(device_module_info));
|
fDeviceModule = (device_module_info*)malloc(sizeof(device_module_info));
|
||||||
if (fDeviceModule != NULL)
|
if (fDeviceModule != NULL)
|
||||||
|
|||||||
Reference in New Issue
Block a user