* 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
This commit is contained in:
Axel Dörfler 2008-08-18 11:07:47 +00:00
parent aac7507616
commit c35ab0c38d
5 changed files with 86 additions and 110 deletions

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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;
}

View File

@ -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)
{