Commit d745be1e authored by Patrick Mochel's avatar Patrick Mochel

Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin

into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-core
parents 8e12e1f9 3c0405be
...@@ -175,7 +175,7 @@ int device_register(struct device *dev) ...@@ -175,7 +175,7 @@ int device_register(struct device *dev)
INIT_LIST_HEAD(&dev->intf_list); INIT_LIST_HEAD(&dev->intf_list);
spin_lock_init(&dev->lock); spin_lock_init(&dev->lock);
atomic_set(&dev->refcount,2); atomic_set(&dev->refcount,2);
dev->present = 1;
spin_lock(&device_lock); spin_lock(&device_lock);
if (dev->parent) { if (dev->parent) {
get_device_locked(dev->parent); get_device_locked(dev->parent);
...@@ -219,7 +219,7 @@ int device_register(struct device *dev) ...@@ -219,7 +219,7 @@ int device_register(struct device *dev)
struct device * get_device_locked(struct device * dev) struct device * get_device_locked(struct device * dev)
{ {
struct device * ret = dev; struct device * ret = dev;
if (dev && atomic_read(&dev->refcount) > 0) if (dev && dev->present && atomic_read(&dev->refcount) > 0)
atomic_inc(&dev->refcount); atomic_inc(&dev->refcount);
else else
ret = NULL; ret = NULL;
...@@ -241,8 +241,35 @@ struct device * get_device(struct device * dev) ...@@ -241,8 +241,35 @@ struct device * get_device(struct device * dev)
*/ */
void put_device(struct device * dev) void put_device(struct device * dev)
{ {
struct device * parent;
if (!atomic_dec_and_lock(&dev->refcount,&device_lock)) if (!atomic_dec_and_lock(&dev->refcount,&device_lock))
return; return;
parent = dev->parent;
dev->parent = NULL;
spin_unlock(&device_lock);
BUG_ON(dev->present);
if (dev->release)
dev->release(dev);
if (parent)
put_device(parent);
}
/**
* device_unregister - unlink device
* @dev: device going away
*
* The device has been removed from the system, so we disavow knowledge
* of it. It might not be the final reference to the device, so we mark
* it as !present, so no more references to it can be acquired.
* In the end, we decrement the final reference count for it.
*/
void device_unregister(struct device * dev)
{
spin_lock(&device_lock);
dev->present = 0;
list_del_init(&dev->node); list_del_init(&dev->node);
list_del_init(&dev->g_list); list_del_init(&dev->g_list);
list_del_init(&dev->bus_list); list_del_init(&dev->bus_list);
...@@ -267,11 +294,7 @@ void put_device(struct device * dev) ...@@ -267,11 +294,7 @@ void put_device(struct device * dev)
/* remove the driverfs directory */ /* remove the driverfs directory */
device_remove_dir(dev); device_remove_dir(dev);
if (dev->release) put_device(dev);
dev->release(dev);
if (dev->parent)
put_device(dev->parent);
} }
static int __init device_init(void) static int __init device_init(void)
...@@ -287,5 +310,6 @@ static int __init device_init(void) ...@@ -287,5 +310,6 @@ static int __init device_init(void)
core_initcall(device_init); core_initcall(device_init);
EXPORT_SYMBOL(device_register); EXPORT_SYMBOL(device_register);
EXPORT_SYMBOL(device_unregister);
EXPORT_SYMBOL(get_device); EXPORT_SYMBOL(get_device);
EXPORT_SYMBOL(put_device); EXPORT_SYMBOL(put_device);
...@@ -90,8 +90,7 @@ int device_create_file(struct device * dev, struct device_attribute * entry) ...@@ -90,8 +90,7 @@ int device_create_file(struct device * dev, struct device_attribute * entry)
{ {
int error = -EINVAL; int error = -EINVAL;
if (dev) { if (get_device(dev)) {
get_device(dev);
error = driverfs_create_file(&entry->attr,&dev->dir); error = driverfs_create_file(&entry->attr,&dev->dir);
put_device(dev); put_device(dev);
} }
......
...@@ -1802,7 +1802,7 @@ static int idedisk_cleanup (ide_drive_t *drive) ...@@ -1802,7 +1802,7 @@ static int idedisk_cleanup (ide_drive_t *drive)
{ {
struct gendisk *g = drive->disk; struct gendisk *g = drive->disk;
put_device(&drive->disk->disk_dev); device_unregister(&drive->disk->disk_dev);
if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache) if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
if (do_idedisk_flushcache(drive)) if (do_idedisk_flushcache(drive))
printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n", printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
......
...@@ -789,7 +789,7 @@ void usb_disconnect(struct usb_device **pdev) ...@@ -789,7 +789,7 @@ void usb_disconnect(struct usb_device **pdev)
struct usb_interface *interface = &dev->actconfig->interface[i]; struct usb_interface *interface = &dev->actconfig->interface[i];
/* remove this interface */ /* remove this interface */
put_device(&interface->dev); device_unregister(&interface->dev);
} }
} }
...@@ -797,7 +797,7 @@ void usb_disconnect(struct usb_device **pdev) ...@@ -797,7 +797,7 @@ void usb_disconnect(struct usb_device **pdev)
if (dev->devnum > 0) { if (dev->devnum > 0) {
clear_bit(dev->devnum, dev->bus->devmap.devicemap); clear_bit(dev->devnum, dev->bus->devmap.devicemap);
usbfs_remove_device(dev); usbfs_remove_device(dev);
put_device(&dev->dev); device_unregister(&dev->dev);
} }
/* Decrement the reference count, it'll auto free everything when */ /* Decrement the reference count, it'll auto free everything when */
......
...@@ -289,6 +289,7 @@ struct device { ...@@ -289,6 +289,7 @@ struct device {
void *platform_data; /* Platform specific data (e.g. ACPI, void *platform_data; /* Platform specific data (e.g. ACPI,
BIOS data relevant to device) */ BIOS data relevant to device) */
u32 present;
u32 current_state; /* Current operating state. In u32 current_state; /* Current operating state. In
ACPI-speak, this is D0-D3, D0 ACPI-speak, this is D0-D3, D0
being fully functional, and D3 being fully functional, and D3
...@@ -327,7 +328,7 @@ dev_set_drvdata (struct device *dev, void *data) ...@@ -327,7 +328,7 @@ dev_set_drvdata (struct device *dev, void *data)
* High level routines for use by the bus drivers * High level routines for use by the bus drivers
*/ */
extern int device_register(struct device * dev); extern int device_register(struct device * dev);
extern void device_unregister(struct device * dev);
/* driverfs interface for exporting device attributes */ /* driverfs interface for exporting device attributes */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment