From c35ab0c38d10cbbaa712e06044a7cf49b942a64e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 18 Aug 2008 11:07:47 +0000 Subject: [PATCH] * Added new devfs_unpublish_device() that gets a BaseDevice instead of a path. * Added inode ID member to BaseDevice to make this possible. * Removed unused and unmaintained legacy_driver::devices_published field. * Implemented legacy driver's unpublish_driver(). * Reenabled legacy driver reloading on changes. * Renamed devfs_driver_{added|removed}() to driver_{added|removed}(), and made them private. * Simplified deletion of device_node lists (no need to use an iterator here), added device unpublishing. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27033 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/device_manager/BaseDevice.h | 4 + src/system/kernel/device_manager/devfs.cpp | 29 +++- .../kernel/device_manager/devfs_private.h | 1 + .../kernel/device_manager/device_manager.cpp | 22 +-- .../kernel/device_manager/legacy_drivers.cpp | 140 +++++++----------- 5 files changed, 86 insertions(+), 110 deletions(-) diff --git a/src/system/kernel/device_manager/BaseDevice.h b/src/system/kernel/device_manager/BaseDevice.h index 96c0389ea2..8b0bfa8346 100644 --- a/src/system/kernel/device_manager/BaseDevice.h +++ b/src/system/kernel/device_manager/BaseDevice.h @@ -14,6 +14,9 @@ public: BaseDevice(); virtual ~BaseDevice(); + void SetID(ino_t id) { fID = id; } + ino_t ID() const { return fID; } + device_node* Node() const { return fNode; } virtual status_t InitDevice(); @@ -50,6 +53,7 @@ public: status_t Free(void* cookie); protected: + ino_t fID; device_node* fNode; int32 fInitialized; device_module_info* fDeviceModule; diff --git a/src/system/kernel/device_manager/devfs.cpp b/src/system/kernel/device_manager/devfs.cpp index c970ceae66..26c62c6552 100644 --- a/src/system/kernel/device_manager/devfs.cpp +++ b/src/system/kernel/device_manager/devfs.cpp @@ -483,13 +483,6 @@ unpublish_node(struct devfs *fs, devfs_vnode *node, mode_t type) status = remove_vnode(fs->volume, node->id); -#if 0 - if (status == B_OK && S_ISCHR(node->stream.type) - && node->stream.u.dev.driver != NULL) { - node->stream.u.dev.driver->devices_published--; - } -#endif - out: recursive_lock_unlock(&fs->lock); return status; @@ -2082,6 +2075,9 @@ devfs_unpublish_device(const char* path, bool disconnect) } +// #pragma mark - device_manager private API + + status_t devfs_publish_device(const char* path, BaseDevice* device) { @@ -2089,6 +2085,25 @@ devfs_publish_device(const char* path, BaseDevice* device) } +status_t +devfs_unpublish_device(BaseDevice* device, bool disconnect) +{ + devfs_vnode* node; + status_t status = get_vnode(sDeviceFileSystem->volume, device->ID(), + (void**)&node); + if (status != B_OK) + return status; + + status = unpublish_node(sDeviceFileSystem, node, S_IFCHR); + + if (status == B_OK && disconnect) + vfs_disconnect_vnode(sDeviceFileSystem->id, node->id); + + put_vnode(sDeviceFileSystem->volume, node->id); + return status; +} + + // #pragma mark - support API for legacy drivers diff --git a/src/system/kernel/device_manager/devfs_private.h b/src/system/kernel/device_manager/devfs_private.h index 120c5c57ea..beeca381e9 100644 --- a/src/system/kernel/device_manager/devfs_private.h +++ b/src/system/kernel/device_manager/devfs_private.h @@ -12,6 +12,7 @@ class BaseDevice; status_t devfs_publish_device(const char* path, BaseDevice* device); +status_t devfs_unpublish_device(BaseDevice* device, bool disconnect); status_t devfs_get_device(dev_t device, ino_t node, BaseDevice** _device); #endif /* DEVFS_PRIVATE_H */ diff --git a/src/system/kernel/device_manager/device_manager.cpp b/src/system/kernel/device_manager/device_manager.cpp index ea52fe4173..5f24def09d 100644 --- a/src/system/kernel/device_manager/device_manager.cpp +++ b/src/system/kernel/device_manager/device_manager.cpp @@ -1156,35 +1156,23 @@ device_node::~device_node() } // Delete children - NodeList::Iterator nodeIterator = fChildren.GetIterator(); - while (nodeIterator.HasNext()) { - device_node* child = nodeIterator.Next(); - nodeIterator.Remove(); + while (device_node* child = fChildren.RemoveHead()) { delete child; } // Delete devices - DeviceList::Iterator deviceIterator = fDevices.GetIterator(); - while (deviceIterator.HasNext()) { - Device* device = deviceIterator.Next(); - deviceIterator.Remove(); - // TODO: unpublish! + while (Device* device = fDevices.RemoveHead()) { + devfs_unpublish_device(device, true); delete device; } // Delete attributes - AttributeList::Iterator attrIterator = fAttributes.GetIterator(); - while (attrIterator.HasNext()) { - device_attr_private* attr = attrIterator.Next(); - attrIterator.Remove(); + while (device_attr_private* attr = fAttributes.RemoveHead()) { delete attr; } // Delete resources - ResourceList::Iterator resourceIterator = fResources.GetIterator(); - while (resourceIterator.HasNext()) { - io_resource_private* resource = resourceIterator.Next(); - resourceIterator.Remove(); + while (io_resource_private* resource = fResources.RemoveHead()) { delete resource; } diff --git a/src/system/kernel/device_manager/legacy_drivers.cpp b/src/system/kernel/device_manager/legacy_drivers.cpp index c548a6b8ad..5823594c6c 100644 --- a/src/system/kernel/device_manager/legacy_drivers.cpp +++ b/src/system/kernel/device_manager/legacy_drivers.cpp @@ -80,7 +80,6 @@ struct legacy_driver { ino_t node; time_t last_modified; image_id image; - uint32 devices_published; uint32 devices_used; bool binary_updated; int32 priority; @@ -454,42 +453,14 @@ unload_driver(legacy_driver *driver) } -/*! Collects all devices belonging to the \a driver and unpublishs them. -*/ +/*! Unpublishes all devices belonging to the \a driver. */ static void unpublish_driver(legacy_driver *driver) { - // Iterate through all nodes until all devices of this driver have - // been unpublished - -dprintf("IMPLEMENT unpublish_driver()!\n"); -#if 0 - while (driver->devices_published > 0) { - struct hash_iterator i; - hash_open(sDeviceFileSystem->vnode_hash, &i); - - while (true) { - devfs_vnode *vnode = (devfs_vnode *)hash_next( - sDeviceFileSystem->vnode_hash, &i); - if (vnode == NULL) - break; - - if (S_ISCHR(vnode->stream.type) - && vnode->stream.u.dev.driver == driver) { - void *dummy; - get_vnode(sDeviceFileSystem->volume, vnode->id, &dummy); - // We need to get/put the node, so that it is - // actually removed - - unpublish_node(sDeviceFileSystem, vnode, S_IFCHR); - put_vnode(sDeviceFileSystem->volume, vnode->id); - break; - } - } - - hash_close(sDeviceFileSystem->vnode_hash, &i, false); + while (LegacyDevice* device = driver->devices.RemoveHead()) { + devfs_unpublish_device(device, true); + delete device; } -#endif } @@ -618,7 +589,6 @@ add_driver(const char *path, image_id image) driver->node = stat.st_ino; driver->image = image; driver->last_modified = stat.st_mtime; - driver->devices_published = 0; driver->devices_used = 0; driver->binary_updated = false; driver->priority = priority; @@ -708,6 +678,51 @@ handle_driver_events(void */*_fs*/, int /*iteration*/) } +static void +driver_added(const char *path) +{ + int32 priority = get_priority(path); + RecursiveLocker locker(sLock); + + legacy_driver *driver = (legacy_driver *)hash_lookup(sDriverHash, + get_leaf(path)); + + if (driver == NULL) { + // Add the driver to our list + path_entry *entry = new(std::nothrow) path_entry; + if (entry == NULL) + return; + + strlcpy(entry->path, path, sizeof(entry->path)); + sDriversToAdd.Add(entry); + } else { + // Update the driver if it is affected by the new entry + if (priority < driver->priority) + return; + + driver->binary_updated = true; + } + + atomic_add(&sDriverEvents, 1); +} + + +static void +driver_removed(const char* path) +{ + int32 priority = get_priority(path); + RecursiveLocker locker(sLock); + + legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash, + get_leaf(path)); + if (driver == NULL || priority < driver->priority) + return; + + driver->binary_updated = true; + atomic_add(&sDriverEvents, 1); +} + + // #pragma mark - DriverWatcher @@ -737,7 +752,7 @@ DriverWatcher::EventOccured(NotificationService& service, return; driver->binary_updated = true; -//dprintf("%s: devices published %ld, used %ld\n", driver->name, driver->devices_published, driver->devices_used); + if (driver->devices_used == 0) { // trigger a reload of the driver atomic_add(&sDriverEvents, 1); @@ -764,7 +779,7 @@ dump_driver(int argc, char** argv) kprintf("%p %5ld %3ld %5ld %c %3ld %s\n", driver, driver->image < 0 ? -1 : driver->image, - driver->devices_used, driver->devices_published, + driver->devices_used, driver->devices.Size(), driver->binary_updated ? 'U' : ' ', driver->priority, driver->name); } @@ -792,7 +807,7 @@ dump_driver(int argc, char** argv) kprintf(" node: %Ld\n", driver->node); kprintf(" last modified: %ld\n", driver->last_modified); kprintf(" devs used: %ld\n", driver->devices_used); - kprintf(" devs published: %ld\n", driver->devices_published); + kprintf(" devs published: %ld\n", driver->devices.Size()); kprintf(" binary updated: %d\n", driver->binary_updated); kprintf(" priority: %ld\n", driver->priority); kprintf(" api version: %ld\n", driver->api_version); @@ -988,16 +1003,14 @@ DirectoryWatcher::EventOccured(NotificationService& service, dprintf("driver \"%s\" %s\n", path.Leaf(), opcode == B_ENTRY_CREATED ? "added" : "removed"); -#if 0 switch (opcode) { case B_ENTRY_CREATED: - devfs_driver_added(path.Path()); + driver_added(path.Path()); break; case B_ENTRY_REMOVED: - devfs_driver_removed(path.Path()); + driver_removed(path.Path()); break; } -#endif } @@ -1306,51 +1319,6 @@ legacy_driver_add(const char* path) } -extern "C" void -devfs_driver_added(const char *path) -{ - int32 priority = get_priority(path); - RecursiveLocker locker(sLock); - - legacy_driver *driver = (legacy_driver *)hash_lookup(sDriverHash, - get_leaf(path)); - - if (driver == NULL) { - // Add the driver to our list - path_entry *entry = new(std::nothrow) path_entry; - if (entry == NULL) - return; - - strlcpy(entry->path, path, sizeof(entry->path)); - sDriversToAdd.Add(entry); - } else { - // Update the driver if it is affected by the new entry - if (priority < driver->priority) - return; - - driver->binary_updated = true; - } - - atomic_add(&sDriverEvents, 1); -} - - -extern "C" void -devfs_driver_removed(const char* path) -{ - int32 priority = get_priority(path); - RecursiveLocker locker(sLock); - - legacy_driver* driver = (legacy_driver*)hash_lookup(sDriverHash, - get_leaf(path)); - if (driver == NULL || priority < driver->priority) - return; - - driver->binary_updated = true; - atomic_add(&sDriverEvents, 1); -} - - extern "C" status_t legacy_driver_publish(const char *path, device_hooks *hooks) {