* 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:
@@ -14,6 +14,9 @@ public:
|
|||||||
BaseDevice();
|
BaseDevice();
|
||||||
virtual ~BaseDevice();
|
virtual ~BaseDevice();
|
||||||
|
|
||||||
|
void SetID(ino_t id) { fID = id; }
|
||||||
|
ino_t ID() const { return fID; }
|
||||||
|
|
||||||
device_node* Node() const { return fNode; }
|
device_node* Node() const { return fNode; }
|
||||||
|
|
||||||
virtual status_t InitDevice();
|
virtual status_t InitDevice();
|
||||||
@@ -50,6 +53,7 @@ public:
|
|||||||
status_t Free(void* cookie);
|
status_t Free(void* cookie);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
ino_t fID;
|
||||||
device_node* fNode;
|
device_node* fNode;
|
||||||
int32 fInitialized;
|
int32 fInitialized;
|
||||||
device_module_info* fDeviceModule;
|
device_module_info* fDeviceModule;
|
||||||
|
|||||||
@@ -483,13 +483,6 @@ unpublish_node(struct devfs *fs, devfs_vnode *node, mode_t type)
|
|||||||
|
|
||||||
status = remove_vnode(fs->volume, node->id);
|
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:
|
out:
|
||||||
recursive_lock_unlock(&fs->lock);
|
recursive_lock_unlock(&fs->lock);
|
||||||
return status;
|
return status;
|
||||||
@@ -2082,6 +2075,9 @@ devfs_unpublish_device(const char* path, bool disconnect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - device_manager private API
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
devfs_publish_device(const char* path, BaseDevice* device)
|
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
|
// #pragma mark - support API for legacy drivers
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
class BaseDevice;
|
class BaseDevice;
|
||||||
|
|
||||||
status_t devfs_publish_device(const char* path, BaseDevice* device);
|
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);
|
status_t devfs_get_device(dev_t device, ino_t node, BaseDevice** _device);
|
||||||
|
|
||||||
#endif /* DEVFS_PRIVATE_H */
|
#endif /* DEVFS_PRIVATE_H */
|
||||||
|
|||||||
@@ -1156,35 +1156,23 @@ device_node::~device_node()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete children
|
// Delete children
|
||||||
NodeList::Iterator nodeIterator = fChildren.GetIterator();
|
while (device_node* child = fChildren.RemoveHead()) {
|
||||||
while (nodeIterator.HasNext()) {
|
|
||||||
device_node* child = nodeIterator.Next();
|
|
||||||
nodeIterator.Remove();
|
|
||||||
delete child;
|
delete child;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete devices
|
// Delete devices
|
||||||
DeviceList::Iterator deviceIterator = fDevices.GetIterator();
|
while (Device* device = fDevices.RemoveHead()) {
|
||||||
while (deviceIterator.HasNext()) {
|
devfs_unpublish_device(device, true);
|
||||||
Device* device = deviceIterator.Next();
|
|
||||||
deviceIterator.Remove();
|
|
||||||
// TODO: unpublish!
|
|
||||||
delete device;
|
delete device;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete attributes
|
// Delete attributes
|
||||||
AttributeList::Iterator attrIterator = fAttributes.GetIterator();
|
while (device_attr_private* attr = fAttributes.RemoveHead()) {
|
||||||
while (attrIterator.HasNext()) {
|
|
||||||
device_attr_private* attr = attrIterator.Next();
|
|
||||||
attrIterator.Remove();
|
|
||||||
delete attr;
|
delete attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete resources
|
// Delete resources
|
||||||
ResourceList::Iterator resourceIterator = fResources.GetIterator();
|
while (io_resource_private* resource = fResources.RemoveHead()) {
|
||||||
while (resourceIterator.HasNext()) {
|
|
||||||
io_resource_private* resource = resourceIterator.Next();
|
|
||||||
resourceIterator.Remove();
|
|
||||||
delete resource;
|
delete resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ struct legacy_driver {
|
|||||||
ino_t node;
|
ino_t node;
|
||||||
time_t last_modified;
|
time_t last_modified;
|
||||||
image_id image;
|
image_id image;
|
||||||
uint32 devices_published;
|
|
||||||
uint32 devices_used;
|
uint32 devices_used;
|
||||||
bool binary_updated;
|
bool binary_updated;
|
||||||
int32 priority;
|
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
|
static void
|
||||||
unpublish_driver(legacy_driver *driver)
|
unpublish_driver(legacy_driver *driver)
|
||||||
{
|
{
|
||||||
// Iterate through all nodes until all devices of this driver have
|
while (LegacyDevice* device = driver->devices.RemoveHead()) {
|
||||||
// been unpublished
|
devfs_unpublish_device(device, true);
|
||||||
|
delete device;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -618,7 +589,6 @@ add_driver(const char *path, image_id image)
|
|||||||
driver->node = stat.st_ino;
|
driver->node = stat.st_ino;
|
||||||
driver->image = image;
|
driver->image = image;
|
||||||
driver->last_modified = stat.st_mtime;
|
driver->last_modified = stat.st_mtime;
|
||||||
driver->devices_published = 0;
|
|
||||||
driver->devices_used = 0;
|
driver->devices_used = 0;
|
||||||
driver->binary_updated = false;
|
driver->binary_updated = false;
|
||||||
driver->priority = priority;
|
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
|
// #pragma mark - DriverWatcher
|
||||||
|
|
||||||
|
|
||||||
@@ -737,7 +752,7 @@ DriverWatcher::EventOccured(NotificationService& service,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
driver->binary_updated = true;
|
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) {
|
if (driver->devices_used == 0) {
|
||||||
// trigger a reload of the driver
|
// trigger a reload of the driver
|
||||||
atomic_add(&sDriverEvents, 1);
|
atomic_add(&sDriverEvents, 1);
|
||||||
@@ -764,7 +779,7 @@ dump_driver(int argc, char** argv)
|
|||||||
|
|
||||||
kprintf("%p %5ld %3ld %5ld %c %3ld %s\n", driver,
|
kprintf("%p %5ld %3ld %5ld %c %3ld %s\n", driver,
|
||||||
driver->image < 0 ? -1 : driver->image,
|
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->binary_updated ? 'U' : ' ', driver->priority,
|
||||||
driver->name);
|
driver->name);
|
||||||
}
|
}
|
||||||
@@ -792,7 +807,7 @@ dump_driver(int argc, char** argv)
|
|||||||
kprintf(" node: %Ld\n", driver->node);
|
kprintf(" node: %Ld\n", driver->node);
|
||||||
kprintf(" last modified: %ld\n", driver->last_modified);
|
kprintf(" last modified: %ld\n", driver->last_modified);
|
||||||
kprintf(" devs used: %ld\n", driver->devices_used);
|
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(" binary updated: %d\n", driver->binary_updated);
|
||||||
kprintf(" priority: %ld\n", driver->priority);
|
kprintf(" priority: %ld\n", driver->priority);
|
||||||
kprintf(" api version: %ld\n", driver->api_version);
|
kprintf(" api version: %ld\n", driver->api_version);
|
||||||
@@ -988,16 +1003,14 @@ DirectoryWatcher::EventOccured(NotificationService& service,
|
|||||||
dprintf("driver \"%s\" %s\n", path.Leaf(),
|
dprintf("driver \"%s\" %s\n", path.Leaf(),
|
||||||
opcode == B_ENTRY_CREATED ? "added" : "removed");
|
opcode == B_ENTRY_CREATED ? "added" : "removed");
|
||||||
|
|
||||||
#if 0
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case B_ENTRY_CREATED:
|
case B_ENTRY_CREATED:
|
||||||
devfs_driver_added(path.Path());
|
driver_added(path.Path());
|
||||||
break;
|
break;
|
||||||
case B_ENTRY_REMOVED:
|
case B_ENTRY_REMOVED:
|
||||||
devfs_driver_removed(path.Path());
|
driver_removed(path.Path());
|
||||||
break;
|
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
|
extern "C" status_t
|
||||||
legacy_driver_publish(const char *path, device_hooks *hooks)
|
legacy_driver_publish(const char *path, device_hooks *hooks)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user