提交 6983b724 编写于 作者: C Clemens Ladisch 提交者: Jaroslav Kysela

[ALSA] dynamic minors (2/6): simplify storage of snd_minor structures

Modules: ALSA Core

Store the snd_minor structure pointers in one array instead of using a
separate list for each card.  This simplifies the mapping from device
files to minor struct by removing the need to know about the encoding
of the card number in the minor number.
Signed-off-by: NClemens Ladisch <clemens@ladisch.de>
上级 2af677fc
...@@ -183,9 +183,8 @@ static inline int snd_power_wait(struct snd_card *card, unsigned int state, stru ...@@ -183,9 +183,8 @@ static inline int snd_power_wait(struct snd_card *card, unsigned int state, stru
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
struct snd_minor { struct snd_minor {
struct list_head list; /* list of all minors per card */
int number; /* minor number */
int type; /* SNDRV_DEVICE_TYPE_XXX */ int type; /* SNDRV_DEVICE_TYPE_XXX */
int card; /* card number */
int device; /* device number */ int device; /* device number */
struct file_operations *f_ops; /* file operations */ struct file_operations *f_ops; /* file operations */
char name[0]; /* device name (keep at the end of char name[0]; /* device name (keep at the end of
...@@ -217,11 +216,9 @@ int snd_minor_info_done(void); ...@@ -217,11 +216,9 @@ int snd_minor_info_done(void);
#ifdef CONFIG_SND_OSSEMUL #ifdef CONFIG_SND_OSSEMUL
int snd_minor_info_oss_init(void); int snd_minor_info_oss_init(void);
int snd_minor_info_oss_done(void); int snd_minor_info_oss_done(void);
int snd_oss_init_module(void);
#else #else
#define snd_minor_info_oss_init() /*NOP*/ #define snd_minor_info_oss_init() /*NOP*/
#define snd_minor_info_oss_done() /*NOP*/ #define snd_minor_info_oss_done() /*NOP*/
#define snd_oss_init_module() 0
#endif #endif
/* memory.c */ /* memory.c */
......
...@@ -59,7 +59,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR); ...@@ -59,7 +59,7 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
*/ */
int snd_ecards_limit; int snd_ecards_limit;
static struct list_head snd_minors_hash[SNDRV_CARDS]; static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
static DECLARE_MUTEX(sound_mutex); static DECLARE_MUTEX(sound_mutex);
...@@ -107,19 +107,6 @@ static void snd_request_other(int minor) ...@@ -107,19 +107,6 @@ static void snd_request_other(int minor)
#endif /* request_module support */ #endif /* request_module support */
static struct snd_minor *snd_minor_search(int minor)
{
struct list_head *list;
struct snd_minor *mptr;
list_for_each(list, &snd_minors_hash[SNDRV_MINOR_CARD(minor)]) {
mptr = list_entry(list, struct snd_minor, list);
if (mptr->number == minor)
return mptr;
}
return NULL;
}
static int snd_open(struct inode *inode, struct file *file) static int snd_open(struct inode *inode, struct file *file)
{ {
int minor = iminor(inode); int minor = iminor(inode);
...@@ -139,11 +126,11 @@ static int snd_open(struct inode *inode, struct file *file) ...@@ -139,11 +126,11 @@ static int snd_open(struct inode *inode, struct file *file)
} }
} else { } else {
#ifdef CONFIG_KMOD #ifdef CONFIG_KMOD
if ((mptr = snd_minor_search(minor)) == NULL) if ((mptr = snd_minors[minor]) == NULL)
snd_request_other(minor); snd_request_other(minor);
#endif #endif
} }
if (mptr == NULL && (mptr = snd_minor_search(minor)) == NULL) if (mptr == NULL && (mptr = snd_minors[minor]) == NULL)
return -ENODEV; return -ENODEV;
old_fops = file->f_op; old_fops = file->f_op;
file->f_op = fops_get(mptr->f_ops); file->f_op = fops_get(mptr->f_ops);
...@@ -213,22 +200,22 @@ int snd_register_device(int type, struct snd_card *card, int dev, ...@@ -213,22 +200,22 @@ int snd_register_device(int type, struct snd_card *card, int dev,
if (minor < 0) if (minor < 0)
return minor; return minor;
snd_assert(name, return -EINVAL); snd_assert(name, return -EINVAL);
preg = kzalloc(sizeof(struct snd_minor) + strlen(name) + 1, GFP_KERNEL); preg = kmalloc(sizeof(struct snd_minor) + strlen(name) + 1, GFP_KERNEL);
if (preg == NULL) if (preg == NULL)
return -ENOMEM; return -ENOMEM;
preg->number = minor;
preg->type = type; preg->type = type;
preg->card = card ? card->number : -1;
preg->device = dev; preg->device = dev;
preg->f_ops = f_ops; preg->f_ops = f_ops;
strcpy(preg->name, name); strcpy(preg->name, name);
down(&sound_mutex); down(&sound_mutex);
if (snd_minor_search(minor)) { if (snd_minors[minor]) {
up(&sound_mutex); up(&sound_mutex);
kfree(preg); kfree(preg);
return -EBUSY; return -EBUSY;
} }
list_add_tail(&preg->list, &snd_minors_hash[SNDRV_MINOR_CARD(minor)]); snd_minors[minor] = preg;
if (strncmp(name, "controlC", 8) || card->number >= cards_limit) if (type != SNDRV_DEVICE_TYPE_CONTROL || preg->card >= cards_limit)
devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name); devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name);
if (card) if (card)
device = card->dev; device = card->dev;
...@@ -257,16 +244,17 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) ...@@ -257,16 +244,17 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
if (minor < 0) if (minor < 0)
return minor; return minor;
down(&sound_mutex); down(&sound_mutex);
if ((mptr = snd_minor_search(minor)) == NULL) { if ((mptr = snd_minors[minor]) == NULL) {
up(&sound_mutex); up(&sound_mutex);
return -EINVAL; return -EINVAL;
} }
if (strncmp(mptr->name, "controlC", 8) || card->number >= cards_limit) /* created in sound.c */ if (mptr->type != SNDRV_DEVICE_TYPE_CONTROL ||
mptr->card >= cards_limit) /* created in sound.c */
devfs_remove("snd/%s", mptr->name); devfs_remove("snd/%s", mptr->name);
class_device_destroy(sound_class, MKDEV(major, minor)); class_device_destroy(sound_class, MKDEV(major, minor));
list_del(&mptr->list); snd_minors[minor] = NULL;
up(&sound_mutex); up(&sound_mutex);
kfree(mptr); kfree(mptr);
return 0; return 0;
...@@ -302,23 +290,25 @@ static const char *snd_device_type_name(int type) ...@@ -302,23 +290,25 @@ static const char *snd_device_type_name(int type)
static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
{ {
int card, device; int minor;
struct list_head *list;
struct snd_minor *mptr; struct snd_minor *mptr;
down(&sound_mutex); down(&sound_mutex);
for (card = 0; card < SNDRV_CARDS; card++) { for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) {
list_for_each(list, &snd_minors_hash[card]) { if (!(mptr = snd_minors[minor]))
mptr = list_entry(list, struct snd_minor, list); continue;
if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_GLOBAL) { if (mptr->card >= 0) {
if ((device = mptr->device) >= 0) if (mptr->device >= 0)
snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, device, snd_device_type_name(mptr->type)); snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n",
minor, mptr->card, mptr->device,
snd_device_type_name(mptr->type));
else else
snd_iprintf(buffer, "%3i: [%i] : %s\n", mptr->number, card, snd_device_type_name(mptr->type)); snd_iprintf(buffer, "%3i: [%i] : %s\n",
} else { minor, mptr->card,
snd_iprintf(buffer, "%3i: : %s\n", mptr->number, snd_device_type_name(mptr->type)); snd_device_type_name(mptr->type));
} } else
} snd_iprintf(buffer, "%3i: : %s\n", minor,
snd_device_type_name(mptr->type));
} }
up(&sound_mutex); up(&sound_mutex);
} }
...@@ -354,15 +344,9 @@ int __exit snd_minor_info_done(void) ...@@ -354,15 +344,9 @@ int __exit snd_minor_info_done(void)
static int __init alsa_sound_init(void) static int __init alsa_sound_init(void)
{ {
short controlnum; short controlnum;
int err;
int card;
snd_major = major; snd_major = major;
snd_ecards_limit = cards_limit; snd_ecards_limit = cards_limit;
for (card = 0; card < SNDRV_CARDS; card++)
INIT_LIST_HEAD(&snd_minors_hash[card]);
if ((err = snd_oss_init_module()) < 0)
return err;
devfs_mk_dir("snd"); devfs_mk_dir("snd");
if (register_chrdev(major, "alsa", &snd_fops)) { if (register_chrdev(major, "alsa", &snd_fops)) {
snd_printk(KERN_ERR "unable to register native major device number %d\n", major); snd_printk(KERN_ERR "unable to register native major device number %d\n", major);
......
...@@ -35,25 +35,12 @@ ...@@ -35,25 +35,12 @@
#include <sound/info.h> #include <sound/info.h>
#include <linux/sound.h> #include <linux/sound.h>
#define SNDRV_OS_MINORS 256 #define SNDRV_OSS_MINORS 128
static struct list_head snd_oss_minors_hash[SNDRV_CARDS]; static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
static DECLARE_MUTEX(sound_oss_mutex); static DECLARE_MUTEX(sound_oss_mutex);
static struct snd_minor *snd_oss_minor_search(int minor)
{
struct list_head *list;
struct snd_minor *mptr;
list_for_each(list, &snd_oss_minors_hash[SNDRV_MINOR_OSS_CARD(minor)]) {
mptr = list_entry(list, struct snd_minor, list);
if (mptr->number == minor)
return mptr;
}
return NULL;
}
static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
{ {
int minor; int minor;
...@@ -86,7 +73,7 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) ...@@ -86,7 +73,7 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
default: default:
return -EINVAL; return -EINVAL;
} }
snd_assert(minor >= 0 && minor < SNDRV_OS_MINORS, return -EINVAL); snd_assert(minor >= 0 && minor < SNDRV_OSS_MINORS, return -EINVAL);
return minor; return minor;
} }
...@@ -103,15 +90,15 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, ...@@ -103,15 +90,15 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
if (minor < 0) if (minor < 0)
return minor; return minor;
preg = kzalloc(sizeof(struct snd_minor), GFP_KERNEL); preg = kmalloc(sizeof(struct snd_minor), GFP_KERNEL);
if (preg == NULL) if (preg == NULL)
return -ENOMEM; return -ENOMEM;
preg->number = minor;
preg->type = type; preg->type = type;
preg->card = card ? card->number : -1;
preg->device = dev; preg->device = dev;
preg->f_ops = f_ops; preg->f_ops = f_ops;
down(&sound_oss_mutex); down(&sound_oss_mutex);
list_add_tail(&preg->list, &snd_oss_minors_hash[cidx]); snd_oss_minors[minor] = preg;
minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
switch (minor_unit) { switch (minor_unit) {
case SNDRV_MINOR_OSS_PCM: case SNDRV_MINOR_OSS_PCM:
...@@ -143,7 +130,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, ...@@ -143,7 +130,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev,
unregister_sound_special(register2); unregister_sound_special(register2);
if (register1 >= 0) if (register1 >= 0)
unregister_sound_special(register1); unregister_sound_special(register1);
list_del(&preg->list); snd_oss_minors[minor] = NULL;
up(&sound_oss_mutex); up(&sound_oss_mutex);
kfree(preg); kfree(preg);
return -EBUSY; return -EBUSY;
...@@ -159,7 +146,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) ...@@ -159,7 +146,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
if (minor < 0) if (minor < 0)
return minor; return minor;
down(&sound_oss_mutex); down(&sound_oss_mutex);
mptr = snd_oss_minor_search(minor); mptr = snd_oss_minors[minor];
if (mptr == NULL) { if (mptr == NULL) {
up(&sound_oss_mutex); up(&sound_oss_mutex);
return -ENOENT; return -ENOENT;
...@@ -178,7 +165,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) ...@@ -178,7 +165,7 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
} }
if (track2 >= 0) if (track2 >= 0)
unregister_sound_special(track2); unregister_sound_special(track2);
list_del(&mptr->list); snd_oss_minors[minor] = NULL;
up(&sound_oss_mutex); up(&sound_oss_mutex);
kfree(mptr); kfree(mptr);
return 0; return 0;
...@@ -214,22 +201,20 @@ static const char *snd_oss_device_type_name(int type) ...@@ -214,22 +201,20 @@ static const char *snd_oss_device_type_name(int type)
static void snd_minor_info_oss_read(struct snd_info_entry *entry, static void snd_minor_info_oss_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer) struct snd_info_buffer *buffer)
{ {
int card, dev; int minor;
struct list_head *list;
struct snd_minor *mptr; struct snd_minor *mptr;
down(&sound_oss_mutex); down(&sound_oss_mutex);
for (card = 0; card < SNDRV_CARDS; card++) { for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) {
list_for_each(list, &snd_oss_minors_hash[card]) { if (!(mptr = snd_oss_minors[minor]))
mptr = list_entry(list, struct snd_minor, list); continue;
dev = SNDRV_MINOR_OSS_DEVICE(mptr->number); if (mptr->card >= 0)
if (dev != SNDRV_MINOR_OSS_SNDSTAT && snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", minor,
dev != SNDRV_MINOR_OSS_SEQUENCER && mptr->card, mptr->device,
dev != SNDRV_MINOR_OSS_MUSIC) snd_oss_device_type_name(mptr->type));
snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, dev, snd_oss_device_type_name(mptr->type));
else else
snd_iprintf(buffer, "%3i: : %s\n", mptr->number, snd_oss_device_type_name(mptr->type)); snd_iprintf(buffer, "%3i: : %s\n", minor,
} snd_oss_device_type_name(mptr->type));
} }
up(&sound_oss_mutex); up(&sound_oss_mutex);
} }
...@@ -264,13 +249,4 @@ int __exit snd_minor_info_oss_done(void) ...@@ -264,13 +249,4 @@ int __exit snd_minor_info_oss_done(void)
return 0; return 0;
} }
int __init snd_oss_init_module(void)
{
int card;
for (card = 0; card < SNDRV_CARDS; card++)
INIT_LIST_HEAD(&snd_oss_minors_hash[card]);
return 0;
}
#endif /* CONFIG_SND_OSSEMUL */ #endif /* CONFIG_SND_OSSEMUL */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册