Driver Core update for 2.6.3-rc1
Subsystems (7)
PATCH 1/1 Driver Core update for 2.6.3-rc1
Hi,
Here are a few driver core changes for 2.6.3-rc1. The big one here is the cdev changes which make that interface a lot simpler to use. These changes have all been in the past few -mm trees with no problems.
Please pull from:
bk://kernel.bkbits.net/gregkh/linux/driver-2.6
thanks,
greg k-h
p.s. I'll send these as patches in response to this email to lkml for those who want to see them.
drivers/base/class.c | 25 +++++++------------------ drivers/base/class_simple.c | 22 +++++++++++++++++++--- drivers/base/core.c | 23 ----------------------- drivers/char/tty_io.c | 1 - drivers/ieee1394/amdtp.c | 1 - drivers/ieee1394/dv1394.c | 1 - drivers/ieee1394/raw1394.c | 1 - drivers/ieee1394/video1394.c | 1 - drivers/scsi/sg.c | 1 - drivers/scsi/st.c | 4 ---- fs/char_dev.c | 7 ++++--- include/linux/cdev.h | 4 ++-- include/linux/device.h | 4 ++-- lib/kobject.c | 3 +++ 14 files changed, 37 insertions(+), 61 deletions(-)
-----
<eugene.teo:eugeneteo.net>:
o Kobject: export some missing symbols
<jonsmirl:yahoo.com>:
o Driver core: add hotplug support for class_simple
Greg Kroah-Hartman:
o Driver Core: fix up list_for_each() calls to list_for_each_entry()
o Driver core: remove device_unregister_wait() as it's a very bad idea
Jonathan Corbet:
o Char drivers: cdev_unmap()
PATCH 1/1 Driver Core update for 2.6.3-rc1
ChangeSet 1.1500.2.170, 2004/02/06 14:07:24-08:00, [email protected]
[PATCH] Char drivers: cdev_unmap()
To recap my argument: the current cdev implementation keeps an uncounted reference to every cdev in cdev_map. Creators of cdevs must know to call cdev_unmap() with the same arguments they passed to cdev_add() before releasing the device, or that reference will remain and will oops the kernel should user space attempt to open the (missing) device. It's an easy mistake to make, and, IMO, entirely unnecessary; the cdev code should be able to do its own bookkeeping.
drivers/char/tty_io.c | 1 - drivers/ieee1394/amdtp.c | 1 - drivers/ieee1394/dv1394.c | 1 - drivers/ieee1394/raw1394.c | 1 - drivers/ieee1394/video1394.c | 1 - drivers/scsi/sg.c | 1 - drivers/scsi/st.c | 4 ---- fs/char_dev.c | 7 ++++--- include/linux/cdev.h | 4 ++-- 9 files changed, 6 insertions(+), 15 deletions(-)
drivers/char/tty_io.c +0 -1
@@ -2264,7 +2264,6 @@if (driver->refcount)return -EBUSY ; -cdev_unmap (MKDEV (driver->major, driver->minor_start), driver->num);unregister_chrdev_region (MKDEV (driver->major, driver->minor_start), driver->num);
drivers/ieee1394/amdtp.c +0 -1
@@ -1308,7 +1308,6 @@hpsb_unregister_highlevel (&amdtp_highlevel);devfs_remove ("amdtp" ); -cdev_unmap (IEEE1394_AMDTP_DEV ,16 );cdev_del (&amdtp_cdev);HPSB_INFO ("Unloaded AMDTP driver" );
drivers/ieee1394/dv1394.c +0 -1
@@ -2609,7 +2609,6 @@hpsb_unregister_protocol (&dv1394_driver);hpsb_unregister_highlevel (&dv1394_highlevel); -cdev_unmap (IEEE1394_DV1394_DEV ,16 );cdev_del (&dv1394_cdev);devfs_remove ("ieee1394/dv" ); }
drivers/ieee1394/raw1394.c +0 -1
@@ -2682,7 +2682,6 @@ static void __exit cleanup_raw1394(void) {hpsb_unregister_protocol (&raw1394_driver); -cdev_unmap (IEEE1394_RAW1394_DEV ,1 );cdev_del (&raw1394_cdev);devfs_remove (RAW1394_DEVICE_NAME );hpsb_unregister_highlevel (&raw1394_highlevel);
drivers/ieee1394/video1394.c +0 -1
@@ -1447,7 +1447,6 @@hpsb_unregister_highlevel (&video1394_highlevel);devfs_remove (VIDEO1394_DRIVER_NAME ); -cdev_unmap (IEEE1394_VIDEO1394_DEV ,16 );cdev_del (&video1394_cdev);PRINT_G (KERN_INFO ,"Removed " VIDEO1394_DRIVER_NAME " module" );
drivers/scsi/sg.c +0 -1
@@ -1521,7 +1521,6 @@if (sdp) {sysfs_remove_link (&scsidp->sdev_gendev.kobj,"generic" );class_simple_device_remove (MKDEV (SCSI_GENERIC_MAJOR , k)); -cdev_unmap (MKDEV (SCSI_GENERIC_MAJOR , k),1 );cdev_del (sdp->cdev); sdp->cdev =NULL ;devfs_remove ("%s/generic" , scsidp->devfs_name);
drivers/scsi/st.c +0 -4
@@ -3946,8 +3946,6 @@if (cdev == STm->cdevs[j]) cdev =NULL ;sysfs_remove_link (&STm->cdevs[j]->kobj,"device" ); -cdev_unmap (MKDEV (SCSI_TAPE_MAJOR , -TAPE_MINOR (dev_num, mode, j)),1 );cdev_del (STm->cdevs[j]); } }
@@ -3990,8 +3988,6 @@for (j=0 ; j <2 ; j++) {sysfs_remove_link (&tpnt->modes[mode].cdevs[j]->kobj,"device" ); -cdev_unmap (MKDEV (SCSI_TAPE_MAJOR , -TAPE_MINOR (i, mode, j)),1 );cdev_del (tpnt->modes[mode].cdevs[j]); tpnt->modes[mode].cdevs[j] =NULL ; }
fs/char_dev.c +4 -3
@@ -240,7 +240,6 @@int unregister_chrdev (unsigned int major,const char *name) {struct char_device_struct *cd; -cdev_unmap (MKDEV (major,0 ),256 ); cd =__unregister_chrdev_region (major,0 ,256 );if (cd && cd->cdev)cdev_del (cd->cdev);
@@ -347,16 +346,19 @@ err =kobj_map (cdev_map, dev, count,NULL , exact_match, exact_lock, p);if (err)kobject_del (&p->kobj); + p->dev = dev; + p->count = count;return err; } -void cdev_unmap (dev_t dev,unsigned count) +static void cdev_unmap (dev_t dev,unsigned count) {kobj_unmap (cdev_map, dev, count); }void cdev_del (struct cdev *p) { +cdev_unmap (p->dev, p->count);kobject_del (&p->kobj);kobject_put (&p->kobj); }
@@ -458,6 +460,5 @@EXPORT_SYMBOL (cdev_put);EXPORT_SYMBOL (cdev_del);EXPORT_SYMBOL (cdev_add); -EXPORT_SYMBOL (cdev_unmap);EXPORT_SYMBOL (register_chrdev);EXPORT_SYMBOL (unregister_chrdev);
include/linux/cdev.h +2 -2
@@ -7,6 +7,8 @@struct module *owner;struct file_operations *ops;struct list_head list; +dev_t dev; +unsigned int count; };void cdev_init (struct cdev *,struct file_operations *);
@@ -20,8 +22,6 @@int cdev_add (struct cdev *,dev_t ,unsigned );void cdev_del (struct cdev *); - -void cdev_unmap (dev_t ,unsigned );void cd_forget (struct inode *);
ChangeSet 1.1500.19.1, 2004/02/02 15:39:32-08:00, [email protected]
[PATCH] Driver core: add hotplug support for class_simple
This is needed by the DRI code.
drivers/base/class_simple.c | 18 ++++++++++++++++++ include/linux/device.h | 2 ++ 2 files changed, 20 insertions(+)
drivers/base/class_simple.c +18 -0
@@ -170,6 +170,24 @@EXPORT_SYMBOL (class_simple_device_add);/** +* class_simple_set_hotplug - set the hotplug callback in the embedded struct class +* @cs: pointer to the struct class_simple to hold the pointer +* @hotplug: function pointer to the hotplug function +* +* Implement and set a hotplug function to add environment variables specific to this +* class on the hotplug event. +*/ +int class_simple_set_hotplug (struct class_simple *cs, +int (*hotplug)(struct class_device *dev,char **envp,int num_envp,char *buffer,int buffer_size)) +{ +if ((cs ==NULL ) || (IS_ERR (cs))) +return -ENODEV ; + cs->class.hotplug = hotplug; +return 0 ; +} +EXPORT_SYMBOL (class_simple_set_hotplug); + +/** * class_simple_device_remove - removes a class device that was created with class_simple_device_add() * @dev: the dev_t of the device that was previously registered. *
include/linux/device.h +2 -0
@@ -253,6 +253,8 @@extern void class_simple_destroy (struct class_simple *cs);extern struct class_device *class_simple_device_add (struct class_simple *cs,dev_t dev,struct device *device,const char *fmt, ...) __attribute__((format (printf,4 ,5 ))); +extern int class_simple_set_hotplug (struct class_simple *, +int (*hotplug)(struct class_device *dev,char **envp,int num_envp,char *buffer,int buffer_size));extern void class_simple_device_remove (dev_t dev);
ChangeSet 1.1500.19.2, 2004/02/02 15:40:06-08:00, [email protected]
[PATCH] Kobject: export some missing symbols
lib/kobject.c | 3 +++ 1 files changed, 3 insertions(+)
lib/kobject.c +3 -0
@@ -630,6 +630,9 @@EXPORT_SYMBOL (kobject_unregister);EXPORT_SYMBOL (kobject_get);EXPORT_SYMBOL (kobject_put); +EXPORT_SYMBOL (kobject_add); +EXPORT_SYMBOL (kobject_del); +EXPORT_SYMBOL (kobject_rename);EXPORT_SYMBOL (kobject_hotplug);EXPORT_SYMBOL (kset_register);
ChangeSet 1.1500.19.3, 2004/02/04 13:48:53-08:00, [email protected]
[PATCH] Driver core: remove device_unregister_wait() as it's a very bad idea.
drivers/base/core.c | 23 ----------------------- include/linux/device.h | 2 -- 2 files changed, 25 deletions(-)
drivers/base/core.c +0 -23
@@ -76,7 +76,6 @@static void device_release (struct kobject * kobj) {struct device * dev =to_dev (kobj); -struct completion * c = dev->complete;if (dev->release) dev->release (dev);
@@ -86,8 +85,6 @@ dev->bus_id);WARN_ON (1 ); } -if (c) -complete (c); }static struct kobj_type ktype_device = {
@@ -355,25 +352,6 @@/** -* device_unregister_wait - Unregister device and wait for it to be freed. -* @dev: Device to unregister. -* -* For the cases where the caller needs to wait for all references to -* be dropped from the device before continuing (e.g. modules with -* statically allocated devices), this function uses a completion struct -* to wait, along with a matching complete() in device_release() above. -*/ - -void device_unregister_wait (struct device * dev) -{ -struct completion c; -init_completion (&c); - dev->complete = &c; -device_unregister (dev); -wait_for_completion (&c); -} - -/** * device_for_each_child - device child iterator. * @dev: parent struct device. * @data: data for the callback.
@@ -421,7 +399,6 @@EXPORT_SYMBOL (device_del);EXPORT_SYMBOL (device_unregister); -EXPORT_SYMBOL (device_unregister_wait);EXPORT_SYMBOL (get_device);EXPORT_SYMBOL (put_device);EXPORT_SYMBOL (device_find);
include/linux/device.h +0 -2
@@ -265,7 +265,6 @@struct list_head children;struct device * parent; -struct completion * complete;/* Notification for freeing device. */ struct kobject kobj;char bus_id[BUS_ID_SIZE ];/* position on parent bus */
@@ -313,7 +312,6 @@*/ extern int device_register (struct device * dev);extern void device_unregister (struct device * dev); -extern void device_unregister_wait (struct device * dev);extern void device_initialize (struct device * dev);extern int device_add (struct device * dev);extern void device_del (struct device * dev);
ChangeSet 1.1607, 2004/02/09 14:01:07-08:00, [email protected]
Driver Core: fix up list_for_each() calls to list_for_each_entry()
Now this should get that Rusty^Wmonkey off my back...
drivers/base/class.c | 25 +++++++------------------ drivers/base/class_simple.c | 4 +--- 2 files changed, 8 insertions(+), 21 deletions(-)
drivers/base/class.c +7 -18
@@ -3,8 +3,8 @@* * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs -* Copyright (c) 2003 Greg Kroah-Hartman -* Copyright (c) 2003 IBM Corp. +* Copyright (c) 2003-2004 Greg Kroah-Hartman +* Copyright (c) 2003-2004 IBM Corp. * * This file is released under the GPLv2 *
@@ -278,7 +278,6 @@ {struct class * parent;struct class_interface * class_intf; -struct list_head * entry;int error; class_dev =class_device_get (class_dev);
@@ -302,11 +301,9 @@if (parent) {down_write (&parent->subsys.rwsem);list_add_tail (&class_dev->node, &parent->children); -list_for_each (entry, &parent->interfaces) { - class_intf = container_of(entry, struct class_interface, node); +list_for_each_entry (class_intf, &parent->interfaces, node)if (class_intf->add) class_intf->add (class_dev); - }up_write (&parent->subsys.rwsem); }
@@ -330,16 +327,13 @@ {struct class * parent = class_dev->class;struct class_interface * class_intf; -struct list_head * entry;if (parent) {down_write (&parent->subsys.rwsem);list_del_init (&class_dev->node); -list_for_each (entry, &parent->interfaces) { - class_intf = container_of(entry, struct class_interface, node); +list_for_each_entry (class_intf, &parent->interfaces, node)if (class_intf->remove) class_intf->remove (class_dev); - }up_write (&parent->subsys.rwsem); }
@@ -395,7 +389,6 @@ {struct class * parent;struct class_device * class_dev; -struct list_head * entry;if (!class_intf || !class_intf->class)return -ENODEV ;
@@ -408,10 +401,8 @@list_add_tail (&class_intf->node, &parent->interfaces);if (class_intf->add) { -list_for_each (entry, &parent->children) { - class_dev = container_of(entry, struct class_device, node); +list_for_each_entry (class_dev, &parent->children, node) class_intf->add (class_dev); - } }up_write (&parent->subsys.rwsem);
@@ -421,7 +412,7 @@void class_interface_unregister (struct class_interface *class_intf) {struct class * parent = class_intf->class; -struct list_head * entry; +struct class_device *class_dev;if (!parent)return ;
@@ -430,10 +421,8 @@list_del_init (&class_intf->node);if (class_intf->remove) { -list_for_each (entry, &parent->children) { - struct class_device *class_dev = container_of(entry, struct class_device, node); +list_for_each_entry (class_dev, &parent->children, node) class_intf->remove (class_dev); - } }up_write (&parent->subsys.rwsem);
drivers/base/class_simple.c +1 -3
@@ -197,12 +197,10 @@void class_simple_device_remove (dev_t dev) {struct simple_dev *s_dev =NULL ; -struct list_head *tmp;int found =0 ;spin_lock (&simple_dev_list_lock); -list_for_each (tmp, &simple_dev_list) { - s_dev = list_entry(tmp, struct simple_dev, node); +list_for_each_entry (s_dev, &simple_dev_list, node) {if (s_dev->dev == dev) { found =1 ;break ;