chrdev: implement __[un]register_chrdev()
Subsystems (3)
PATCH 1/3 chrdev: implement __[un]register_chrdev()
[un]register_chrdev() assume minor range 0-255. This patch adds __ prefixed versions which take @minorbase and @count explicitly.
---
This is updated repost of the make-OSS-device-number-claiming-optional patchset.
http://thread.gmane.org/gmane.linux.kernel/873475
Changes from the last take are...
* soundcore now emits standard chrdev module aliases too.
* The sound-slot/service-* module aliases are now scheduled to be removed in a year along with the config and kernel parameter to disable it.
* sound_insert_unit() updated to deal with minors claimed by others at chrdev layer.
Thanks.
fs/char_dev.c | 39 ++++++++++++++++++++++++++------------- include/linux/fs.h | 19 ++++++++++++++++--- 2 files changed, 42 insertions(+), 16 deletions(-)
fs/char_dev.c +26 -13
@@ -237,8 +237,10 @@ int alloc_chrdev_region(dev_t *dev, unsi }/** -* register_chrdev() - Register a major number for character devices. +* __register_chrdev() - create and register a cdev occupying a range of minors * @major: major device number or 0 for dynamic allocation +* @baseminor: first of the requested range of minor numbers +* @count: the number of minor numbers required * @name: name of this range of devices * @fops: file operations associated with this devices *
@@ -254,19 +256,17 @@ int alloc_chrdev_region(dev_t *dev, unsi* /dev. It only helps to keep track of the different owners of devices. If * your module name has only one type of devices it's ok to use e.g. the name * of the module here. -* -* This function registers a range of 256 minor numbers. The first minor number -* is 0. */ -int register_chrdev (unsigned int major,const char *name, -const struct file_operations *fops) +int __register_chrdev (unsigned int major,unsigned int baseminor, +unsigned int count,const char *name, +const struct file_operations *fops) {struct char_device_struct *cd;struct cdev *cdev;char *s;int err = -ENOMEM ; - cd =__register_chrdev_region (major,0 ,256 , name); + cd =__register_chrdev_region (major, baseminor, count, name);if (IS_ERR (cd))return PTR_ERR (cd);
@@ -280,7 +280,7 @@ int register_chrdev(unsigned int major,for (s =strchr (kobject_name (&cdev->kobj),'/' ); s; s =strchr (s,'/' )) *s ='!' ; - err =cdev_add (cdev,MKDEV (cd->major,0 ),256 ); + err =cdev_add (cdev,MKDEV (cd->major, baseminor), count);if (err) goto out;
@@ -290,7 +290,7 @@ int register_chrdev(unsigned int major, out:kobject_put (&cdev->kobj); out2: -kfree (__unregister_chrdev_region (cd->major,0 ,256 )); +kfree (__unregister_chrdev_region (cd->major, baseminor, count));return err; }
@@ -316,10 +316,23 @@ void unregister_chrdev_region(dev_t from } } -void unregister_chrdev (unsigned int major,const char *name) +/** +* __unregister_chrdev - unregister and destroy a cdev +* @major: major device number +* @baseminor: first of the range of minor numbers +* @count: the number of minor numbers this cdev is occupying +* @name: name of this range of devices +* +* Unregister and destroy the cdev occupying the region described by +* @major, @baseminor and @count. This function undoes what +* __register_chrdev() did. +*/ +void __unregister_chrdev (unsigned int major,unsigned int baseminor, +unsigned int count,const char *name) {struct char_device_struct *cd; - cd =__unregister_chrdev_region (major,0 ,256 ); + + cd =__unregister_chrdev_region (major, baseminor, count);if (cd && cd->cdev)cdev_del (cd->cdev);kfree (cd);
@@ -568,6 +581,6 @@ EXPORT_SYMBOL(cdev_alloc);EXPORT_SYMBOL (cdev_del);EXPORT_SYMBOL (cdev_add);EXPORT_SYMBOL (cdev_index); -EXPORT_SYMBOL (register_chrdev); -EXPORT_SYMBOL (unregister_chrdev); +EXPORT_SYMBOL (__register_chrdev); +EXPORT_SYMBOL (__unregister_chrdev);EXPORT_SYMBOL (directly_mappable_cdev_bdi);
include/linux/fs.h +16 -3
@@ -1998,12 +1998,25 @@ extern void bd_release_from_disk(struct#define CHRDEV_MAJOR_HASH_SIZE 255extern int alloc_chrdev_region (dev_t *,unsigned ,unsigned ,const char *);extern int register_chrdev_region (dev_t ,unsigned ,const char *); -extern int register_chrdev (unsigned int ,const char *, -const struct file_operations *); -extern void unregister_chrdev (unsigned int ,const char *); +extern int __register_chrdev (unsigned int major,unsigned int baseminor, +unsigned int count,const char *name, +const struct file_operations *fops); +extern void __unregister_chrdev (unsigned int major,unsigned int baseminor, +unsigned int count,const char *name);extern void unregister_chrdev_region (dev_t ,unsigned );extern void chrdev_show (struct seq_file *,off_t ); +static inline int register_chrdev (unsigned int major,const char *name, +const struct file_operations *fops) +{ +return __register_chrdev (major,0 ,256 , name, fops); +} + +static inline void unregister_chrdev (unsigned int major,const char *name) +{ +__unregister_chrdev (major,0 ,256 , name); +} +/* fs/block_dev.c */ #define BDEVNAME_SIZE 32/* Largest string for a blockdev identifier */ #define BDEVT_SIZE 10/* Largest string for MAJ:MIN for blkdev */
PATCH 2/3 sound: request char-major-* module aliases for missing OSS devices
Till now missing OSS devices emitted sound-slot/service-* module alises instead of the standard char-major-* if a missing device number is opened if soundcore is loaded. The custom module aliases don't have any inherent benefit than backward compatibility.
sound-slot/service-* module aliases is scheduled to be removed and to help the transition this patch makes soundcore emit the standard module alises along with the custom ones.
--- sound/sound_core.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
sound/sound_core.c +12 -0
@@ -541,6 +541,7 @@ static int soundcore_open(struct inode * new_fops =fops_get (s->unit_fops);if (!new_fops) {spin_unlock (&sound_loader_lock); +/* * Please, don't change this order or code. * For ALSA slot means soundcard and OSS emulation code
@@ -550,6 +551,17 @@ static int soundcore_open(struct inode **/ request_module ("sound-slot-%i" , unit>>4 );request_module ("sound-service-%i-%i" , unit>>4 , chain); + +/* +* sound-slot/service-* module aliases are scheduled +* for removal in favor of the standard char-major-* +* module aliases. For the time being, generate both +* the legacy and standard module aliases to ease +* transition. +*/ +if (request_module ("char-major-%d-%d" ,SOUND_MAJOR , unit) >0 ) +request_module ("char-major-%d" ,SOUND_MAJOR ); +spin_lock (&sound_loader_lock); s =__look_for_unit (chain, unit);if (s)
PATCH 3/3 sound: make OSS device number claiming optional and schedule its removal
If any OSS support is enabled, regardless of built-in or module, sound_core claims full OSS major number (that is, the old 0-255 region) to trap open attempts and request sound modules using custom module aliases. This feature is redundant as chrdev already has such mechanism. This preemptive claiming prevents alternative OSS implementation.
The custom module aliases are scheduled to be removed and the previous patch made soundcore emit the standard chrdev aliases too to help transition.
This patch schedule the feature for removal in a year and makes it optional so that developers and distros can try new things in the meantime without rebuilding the kernel. The pre-claiming can be turned off by using SOUND_OSS_CORE_PRECLAIM and/or kernel parameter soundcore.preclaim_oss.
As this allows sound minors to be individually grabbed by other users, this patch updates sound_insert_unit() such that if registering individual device region fails, it tries the next available slot.
For details on removal plan, please read the entry added by this patch in feature-removal-schedule.txt .
--- Documentation/feature-removal-schedule.txt | 24 +++++++ sound/Kconfig | 28 +++++++++ sound/sound_core.c | 88 +++++++++++++++++++++++------ 3 files changed, 122 insertions(+), 18 deletions(-)
sound/Kconfig +28 -0
@@ -32,6 +32,34 @@ config SOUND_OSS_CORE bool default n +config SOUND_OSS_CORE_PRECLAIM + bool "Preclaim OSS device numbers" + depends on SOUND_OSS_CORE + default y + help + With this option enabled, the kernel will claim all OSS device + numbers if any OSS support (native or emulation) is enabled + whether the respective module is loaded or not and try to load the + appropriate module using sound-slot/service-* and char-major-* + module aliases when one of the device numbers is opened. With + this option disabled, kernel will only claim actually in-use + device numbers and opening a missing device will generate only the + standard char-major-* aliases. + + The only visible difference is use of additional module aliases + and whether OSS sound devices appear multiple times in + /proc/devices. sound-slot/service-* module aliases are scheduled + to be removed (ie. PRECLAIM won't be available) and this option is + to make the transition easier. This option can be overridden + during boot using the kernel parameter soundcore.preclaim_oss. + + Disabling this allows alternative OSS implementations. + + Please read Documentation/feature-removal-schedule.txt for + details. + + If unusre, say Y. + source "sound/oss/dmasound/Kconfig" if !M68K
sound/sound_core.c +70 -18
134 lines not on this page · raw message
Documentation/feature-removal-schedule.txt +24 -0
@@ -468,3 +468,27 @@ Why: cpu_policy_rwsem has a new cleaner cpufreq core and contained inside cpufreq.c. Other dependent drivers should not use it in order to safely avoid lockdep issues. Who: Venkatesh Pallipadi <[email protected]> + +---------------------------- + +What: sound-slot/service-* module aliases and related clutters in + sound/sound_core.c +When: August 2010 +Why: OSS sound_core grabs all legacy minors (0-255) of SOUND_MAJOR + (14) and requests modules using custom sound-slot/service-* + module aliases. The only benefit of doing this is allowing + use of custom module aliases which might as well be considered + a bug at this point. This preemptive claiming prevents + alternative OSS implementations. + + Till the feature is removed, the kernel will be requesting + both sound-slot/service-* and the standard char-major-* module + aliases and allow turning off the pre-claiming selectively via + CONFIG_SOUND_OSS_CORE_PRECLAIM and soundcore.preclaim_oss + kernel parameter. + + After the transition phase is complete, both the custom module + aliases and switches to disable it will go away. This removal + will also allow making ALSA OSS emulation independent of + sound_core. The dependency will be broken then too. +Who: Tejun Heo <[email protected]>
At Thu, 06 Aug 2009 18:13:23 +0900,
Quoted 15 lines · Tejun Heo
[un]register_chrdev() assume minor range 0-255. This patch adds __ prefixed versions which take @minorbase and @count explicitly.
Signed-off-by Tejun Heo <[email protected]>Cc Al Viro <[email protected]>Cc Greg Kroah-Hartman <[email protected]>---
This is updated repost of the make-OSS-device-number-claiming-optional patchset.http://thread.gmane.org/gmane.linux.kernel/873475
Changes from the last take are...
Quoted 8 lines
* soundcore now emits standard chrdev module aliases too.
* The sound-slot/service-* module aliases are now scheduled to be removed in a year along with the config and kernel parameter to disable it.
*
sound_insert_unit()updated to deal with minors claimed by others at chrdev layer.
I merged this to sound-unstable tree now to check the builds. I'm going to move it to the sound tree for linux-next in tomorrow or later.
If anybody still sees the problem with this patch set, please let me know.
Thanks!
Takashi
Quoted 134 lines
Thanks.
fs/char_dev.c | 39 ++++++++++++++++++++++++++------------- include/linux/fs.h | 19 ++++++++++++++++--- 2 files changed, 42 insertions(+), 16 deletions(-)Index:
work/fs/char_dev.c
===================================================================fs/char_dev.c +26
-13@@ -237,8 +237,10 @@ int alloc_chrdev_region(dev_t *dev, unsi }/** -* register_chrdev() - Register a major number for character devices. +* __register_chrdev() - create and register a cdev occupying a range of minors * @major: major device number or 0 for dynamic allocation +* @baseminor: first of the requested range of minor numbers +* @count: the number of minor numbers required * @name: name of this range of devices * @fops: file operations associated with this devices * @@ -254,19 +256,17 @@ int alloc_chrdev_region(dev_t *dev, unsi* /dev. It only helps to keep track of the different owners of devices. If * your module name has only one type of devices it's ok to use e.g. the name * of the module here. -* -* This function registers a range of 256 minor numbers. The first minor number -* is 0. */ -int register_chrdev (unsigned int major,const char *name, -const struct file_operations *fops) +int __register_chrdev (unsigned int major,unsigned int baseminor, +unsigned int count,const char *name, +const struct file_operations *fops) {struct char_device_struct *cd;struct cdev *cdev;char *s;int err = -ENOMEM ; - cd =__register_chrdev_region (major,0 ,256 , name); + cd =__register_chrdev_region (major, baseminor, count, name);if (IS_ERR (cd))return PTR_ERR (cd);@@ -280,7 +280,7 @@ int register_chrdev(unsigned int major,for (s =strchr (kobject_name (&cdev->kobj),'/' ); s; s =strchr (s,'/' )) *s ='!' ; - err =cdev_add (cdev,MKDEV (cd->major,0 ),256 ); + err =cdev_add (cdev,MKDEV (cd->major, baseminor), count);if (err) goto out;@@ -290,7 +290,7 @@ int register_chrdev(unsigned int major, out:kobject_put (&cdev->kobj); out2: -kfree (__unregister_chrdev_region (cd->major,0 ,256 )); +kfree (__unregister_chrdev_region (cd->major, baseminor, count));return err; }@@ -316,10 +316,23 @@ void unregister_chrdev_region(dev_t from } } -void unregister_chrdev (unsigned int major,const char *name) +/** +* __unregister_chrdev - unregister and destroy a cdev +* @major: major device number +* @baseminor: first of the range of minor numbers +* @count: the number of minor numbers this cdev is occupying +* @name: name of this range of devices +* +* Unregister and destroy the cdev occupying the region described by +* @major, @baseminor and @count. This function undoes what +* __register_chrdev() did. +*/ +void __unregister_chrdev (unsigned int major,unsigned int baseminor, +unsigned int count,const char *name) {struct char_device_struct *cd; - cd =__unregister_chrdev_region (major,0 ,256 ); + + cd =__unregister_chrdev_region (major, baseminor, count);if (cd && cd->cdev)cdev_del (cd->cdev);kfree (cd);@@ -568,6 +581,6 @@ EXPORT_SYMBOL(cdev_alloc);EXPORT_SYMBOL (cdev_del);EXPORT_SYMBOL (cdev_add);EXPORT_SYMBOL (cdev_index); -EXPORT_SYMBOL (register_chrdev); -EXPORT_SYMBOL (unregister_chrdev); +EXPORT_SYMBOL (__register_chrdev); +EXPORT_SYMBOL (__unregister_chrdev);EXPORT_SYMBOL (directly_mappable_cdev_bdi);Index:
work/include/linux/fs.h
===================================================================include/linux/fs.h +16
-3@@ -1998,12 +1998,25 @@ extern void bd_release_from_disk(struct#define CHRDEV_MAJOR_HASH_SIZE 255extern int alloc_chrdev_region (dev_t *,unsigned ,unsigned ,const char *);extern int register_chrdev_region (dev_t ,unsigned ,const char *); -extern int register_chrdev (unsigned int ,const char *, -const struct file_operations *); -extern void unregister_chrdev (unsigned int ,const char *); +extern int __register_chrdev (unsigned int major,unsigned int baseminor, +unsigned int count,const char *name, +const struct file_operations *fops); +extern void __unregister_chrdev (unsigned int major,unsigned int baseminor, +unsigned int count,const char *name);extern void unregister_chrdev_region (dev_t ,unsigned );extern void chrdev_show (struct seq_file *,off_t ); +static inline int register_chrdev (unsigned int major,const char *name, +const struct file_operations *fops) +{ +return __register_chrdev (major,0 ,256 , name, fops); +} + +static inline void unregister_chrdev (unsigned int major,const char *name) +{ +__unregister_chrdev (major,0 ,256 , name); +} +/* fs/block_dev.c */ #define BDEVNAME_SIZE 32/* Largest string for a blockdev identifier */ #define BDEVT_SIZE 10/* Largest string for MAJ:MIN for blkdev */
At Mon, 10 Aug 2009 14:02:17 +0200,
Quoted 27 lines · I wrote:
At Thu, 06 Aug 2009 18:13:23 +0900,
Quoted 15 lines · Tejun Heo
[un]register_chrdev() assume minor range 0-255. This patch adds __ prefixed versions which take @minorbase and @count explicitly.
Signed-off-by Tejun Heo <[email protected]>Cc Al Viro <[email protected]>Cc Greg Kroah-Hartman <[email protected]>---
This is updated repost of the make-OSS-device-number-claiming-optional patchset.http://thread.gmane.org/gmane.linux.kernel/873475
Changes from the last take are...
Quoted 8 lines
* soundcore now emits standard chrdev module aliases too.
* The sound-slot/service-* module aliases are now scheduled to be removed in a year along with the config and kernel parameter to disable it.
*
sound_insert_unit()updated to deal with minors claimed by others at chrdev layer.
Quoted 6 lines
I merged this to sound-unstable tree now to check the builds. I'm going to move it to the sound tree for linux-next in tomorrow or later.
If anybody still sees the problem with this patch set, please let me know.
As no objection came, I merged this patch series now for linux-next.
thanks,
Takashi