Commit b6f43d8d 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 ad80d2d1 8861b6ce
...@@ -264,8 +264,6 @@ int class_device_add(struct class_device *class_dev) ...@@ -264,8 +264,6 @@ int class_device_add(struct class_device *class_dev)
return -EINVAL; return -EINVAL;
parent = class_get(class_dev->class); parent = class_get(class_dev->class);
if (class_dev->dev)
get_device(class_dev->dev);
pr_debug("CLASS: registering class device: ID = '%s'\n", pr_debug("CLASS: registering class device: ID = '%s'\n",
class_dev->class_id); class_dev->class_id);
......
...@@ -117,9 +117,16 @@ int sysdev_driver_register(struct sysdev_class * cls, ...@@ -117,9 +117,16 @@ int sysdev_driver_register(struct sysdev_class * cls,
struct sysdev_driver * drv) struct sysdev_driver * drv)
{ {
down_write(&system_subsys.rwsem); down_write(&system_subsys.rwsem);
if (cls && kset_get(&cls->kset)) if (cls && kset_get(&cls->kset)) {
list_add_tail(&drv->entry,&cls->drivers); list_add_tail(&drv->entry,&cls->drivers);
else
/* If devices of this class already exist, tell the driver */
if (drv->add) {
struct sys_device *dev;
list_for_each_entry(dev, &cls->kset.list, kobj.entry)
drv->add(dev);
}
} else
list_add_tail(&drv->entry,&global_drivers); list_add_tail(&drv->entry,&global_drivers);
up_write(&system_subsys.rwsem); up_write(&system_subsys.rwsem);
return 0; return 0;
...@@ -136,8 +143,14 @@ void sysdev_driver_unregister(struct sysdev_class * cls, ...@@ -136,8 +143,14 @@ void sysdev_driver_unregister(struct sysdev_class * cls,
{ {
down_write(&system_subsys.rwsem); down_write(&system_subsys.rwsem);
list_del_init(&drv->entry); list_del_init(&drv->entry);
if (cls) if (cls) {
if (drv->remove) {
struct sys_device *dev;
list_for_each_entry(dev, &cls->kset.list, kobj.entry)
drv->remove(dev);
}
kset_put(&cls->kset); kset_put(&cls->kset);
}
up_write(&system_subsys.rwsem); up_write(&system_subsys.rwsem);
} }
...@@ -170,7 +183,7 @@ int sys_device_register(struct sys_device * sysdev) ...@@ -170,7 +183,7 @@ int sys_device_register(struct sys_device * sysdev)
if (!error) { if (!error) {
struct sysdev_driver * drv; struct sysdev_driver * drv;
down_read(&system_subsys.rwsem); down_write(&system_subsys.rwsem);
/* Generic notification is implicit, because it's that /* Generic notification is implicit, because it's that
* code that should have called us. * code that should have called us.
*/ */
...@@ -186,7 +199,7 @@ int sys_device_register(struct sys_device * sysdev) ...@@ -186,7 +199,7 @@ int sys_device_register(struct sys_device * sysdev)
if (drv->add) if (drv->add)
drv->add(sysdev); drv->add(sysdev);
} }
up_read(&system_subsys.rwsem); up_write(&system_subsys.rwsem);
} }
return error; return error;
} }
...@@ -195,7 +208,7 @@ void sys_device_unregister(struct sys_device * sysdev) ...@@ -195,7 +208,7 @@ void sys_device_unregister(struct sys_device * sysdev)
{ {
struct sysdev_driver * drv; struct sysdev_driver * drv;
down_read(&system_subsys.rwsem); down_write(&system_subsys.rwsem);
list_for_each_entry(drv,&global_drivers,entry) { list_for_each_entry(drv,&global_drivers,entry) {
if (drv->remove) if (drv->remove)
drv->remove(sysdev); drv->remove(sysdev);
...@@ -205,7 +218,10 @@ void sys_device_unregister(struct sys_device * sysdev) ...@@ -205,7 +218,10 @@ void sys_device_unregister(struct sys_device * sysdev)
if (drv->remove) if (drv->remove)
drv->remove(sysdev); drv->remove(sysdev);
} }
up_read(&system_subsys.rwsem);
list_del_init(&sysdev->entry);
up_write(&system_subsys.rwsem);
kobject_unregister(&sysdev->kobj); kobject_unregister(&sysdev->kobj);
} }
......
...@@ -22,7 +22,7 @@ fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) ...@@ -22,7 +22,7 @@ fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count)
} }
static ssize_t static ssize_t
read(struct file * file, char * userbuf, size_t count, loff_t * off) read(struct file * file, char __user * userbuf, size_t count, loff_t * off)
{ {
char *buffer = file->private_data; char *buffer = file->private_data;
struct dentry *dentry = file->f_dentry; struct dentry *dentry = file->f_dentry;
...@@ -65,7 +65,7 @@ flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) ...@@ -65,7 +65,7 @@ flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count)
return attr->write(kobj, buffer, offset, count); return attr->write(kobj, buffer, offset, count);
} }
static ssize_t write(struct file * file, const char * userbuf, static ssize_t write(struct file * file, const char __user * userbuf,
size_t count, loff_t * off) size_t count, loff_t * off)
{ {
char *buffer = file->private_data; char *buffer = file->private_data;
......
...@@ -109,7 +109,7 @@ static int fill_read_buffer(struct file * file, struct sysfs_buffer * buffer) ...@@ -109,7 +109,7 @@ static int fill_read_buffer(struct file * file, struct sysfs_buffer * buffer)
* the amount they specify each time. * the amount they specify each time.
* This may be called continuously until the buffer is empty. * This may be called continuously until the buffer is empty.
*/ */
static int flush_read_buffer(struct sysfs_buffer * buffer, char * buf, static int flush_read_buffer(struct sysfs_buffer * buffer, char __user * buf,
size_t count, loff_t * ppos) size_t count, loff_t * ppos)
{ {
int error; int error;
...@@ -143,7 +143,7 @@ static int flush_read_buffer(struct sysfs_buffer * buffer, char * buf, ...@@ -143,7 +143,7 @@ static int flush_read_buffer(struct sysfs_buffer * buffer, char * buf,
*/ */
static ssize_t static ssize_t
sysfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos) sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{ {
struct sysfs_buffer * buffer = file->private_data; struct sysfs_buffer * buffer = file->private_data;
ssize_t retval = 0; ssize_t retval = 0;
...@@ -169,7 +169,7 @@ sysfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos) ...@@ -169,7 +169,7 @@ sysfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos)
*/ */
static int static int
fill_write_buffer(struct sysfs_buffer * buffer, const char * buf, size_t count) fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t count)
{ {
int error; int error;
...@@ -224,7 +224,7 @@ flush_write_buffer(struct file * file, struct sysfs_buffer * buffer, size_t coun ...@@ -224,7 +224,7 @@ flush_write_buffer(struct file * file, struct sysfs_buffer * buffer, size_t coun
*/ */
static ssize_t static ssize_t
sysfs_write_file(struct file *file, const char *buf, size_t count, loff_t *ppos) sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{ {
struct sysfs_buffer * buffer = file->private_data; struct sysfs_buffer * buffer = file->private_data;
......
...@@ -72,6 +72,7 @@ struct sys_device { ...@@ -72,6 +72,7 @@ struct sys_device {
u32 id; u32 id;
struct sysdev_class * cls; struct sysdev_class * cls;
struct kobject kobj; struct kobject kobj;
struct list_head entry;
}; };
extern int sys_device_register(struct sys_device *); extern int sys_device_register(struct sys_device *);
......
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