diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2005-11-20 08:06:59 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:29:17 -0500 |
commit | f87135f56cb266e031f5ec081dfbde7e43f55e80 (patch) | |
tree | c048abae6bb04df53f5d8d7dcffbf2c28bc638ff /sound/core/sound.c | |
parent | 6983b7240cd229787c3ee00e663ea94ea649d96a (diff) |
[ALSA] dynamic minors (3/6): store device-specific object pointers dynamically
Instead of storing the pointers to the device-specific structures in an
array, put them into the struct snd_minor, and look them up dynamically.
This makes the device type modules independent of the minor number
encoding.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Diffstat (limited to 'sound/core/sound.c')
-rw-r--r-- | sound/core/sound.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/sound/core/sound.c b/sound/core/sound.c index a509f49fa0b4..1e5eca546925 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
@@ -60,7 +60,6 @@ MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR); | |||
60 | int snd_ecards_limit; | 60 | int snd_ecards_limit; |
61 | 61 | ||
62 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; | 62 | static struct snd_minor *snd_minors[SNDRV_OS_MINORS]; |
63 | |||
64 | static DECLARE_MUTEX(sound_mutex); | 63 | static DECLARE_MUTEX(sound_mutex); |
65 | 64 | ||
66 | extern struct class *sound_class; | 65 | extern struct class *sound_class; |
@@ -107,6 +106,31 @@ static void snd_request_other(int minor) | |||
107 | 106 | ||
108 | #endif /* request_module support */ | 107 | #endif /* request_module support */ |
109 | 108 | ||
109 | /** | ||
110 | * snd_lookup_minor_data - get user data of a registered device | ||
111 | * @minor: the minor number | ||
112 | * @type: device type (SNDRV_DEVICE_TYPE_XXX) | ||
113 | * | ||
114 | * Checks that a minor device with the specified type is registered, and returns | ||
115 | * its user data pointer. | ||
116 | */ | ||
117 | void *snd_lookup_minor_data(unsigned int minor, int type) | ||
118 | { | ||
119 | struct snd_minor *mreg; | ||
120 | void *private_data; | ||
121 | |||
122 | if (minor > ARRAY_SIZE(snd_minors)) | ||
123 | return NULL; | ||
124 | down(&sound_mutex); | ||
125 | mreg = snd_minors[minor]; | ||
126 | if (mreg && mreg->type == type) | ||
127 | private_data = mreg->private_data; | ||
128 | else | ||
129 | private_data = NULL; | ||
130 | up(&sound_mutex); | ||
131 | return private_data; | ||
132 | } | ||
133 | |||
110 | static int snd_open(struct inode *inode, struct file *file) | 134 | static int snd_open(struct inode *inode, struct file *file) |
111 | { | 135 | { |
112 | int minor = iminor(inode); | 136 | int minor = iminor(inode); |
@@ -183,6 +207,7 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev) | |||
183 | * @card: the card instance | 207 | * @card: the card instance |
184 | * @dev: the device index | 208 | * @dev: the device index |
185 | * @f_ops: the file operations | 209 | * @f_ops: the file operations |
210 | * @private_data: user pointer for f_ops->open() | ||
186 | * @name: the device file name | 211 | * @name: the device file name |
187 | * | 212 | * |
188 | * Registers an ALSA device file for the given card. | 213 | * Registers an ALSA device file for the given card. |
@@ -191,7 +216,8 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev) | |||
191 | * Retrurns zero if successful, or a negative error code on failure. | 216 | * Retrurns zero if successful, or a negative error code on failure. |
192 | */ | 217 | */ |
193 | int snd_register_device(int type, struct snd_card *card, int dev, | 218 | int snd_register_device(int type, struct snd_card *card, int dev, |
194 | struct file_operations *f_ops, const char *name) | 219 | struct file_operations *f_ops, void *private_data, |
220 | const char *name) | ||
195 | { | 221 | { |
196 | int minor = snd_kernel_minor(type, card, dev); | 222 | int minor = snd_kernel_minor(type, card, dev); |
197 | struct snd_minor *preg; | 223 | struct snd_minor *preg; |
@@ -207,6 +233,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, | |||
207 | preg->card = card ? card->number : -1; | 233 | preg->card = card ? card->number : -1; |
208 | preg->device = dev; | 234 | preg->device = dev; |
209 | preg->f_ops = f_ops; | 235 | preg->f_ops = f_ops; |
236 | preg->private_data = private_data; | ||
210 | strcpy(preg->name, name); | 237 | strcpy(preg->name, name); |
211 | down(&sound_mutex); | 238 | down(&sound_mutex); |
212 | if (snd_minors[minor]) { | 239 | if (snd_minors[minor]) { |
@@ -238,13 +265,18 @@ int snd_register_device(int type, struct snd_card *card, int dev, | |||
238 | */ | 265 | */ |
239 | int snd_unregister_device(int type, struct snd_card *card, int dev) | 266 | int snd_unregister_device(int type, struct snd_card *card, int dev) |
240 | { | 267 | { |
241 | int minor = snd_kernel_minor(type, card, dev); | 268 | int cardnum, minor; |
242 | struct snd_minor *mptr; | 269 | struct snd_minor *mptr; |
243 | 270 | ||
244 | if (minor < 0) | 271 | cardnum = card ? card->number : -1; |
245 | return minor; | ||
246 | down(&sound_mutex); | 272 | down(&sound_mutex); |
247 | if ((mptr = snd_minors[minor]) == NULL) { | 273 | for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) |
274 | if ((mptr = snd_minors[minor]) != NULL && | ||
275 | mptr->type == type && | ||
276 | mptr->card == cardnum && | ||
277 | mptr->device == dev) | ||
278 | break; | ||
279 | if (minor == ARRAY_SIZE(snd_minors)) { | ||
248 | up(&sound_mutex); | 280 | up(&sound_mutex); |
249 | return -EINVAL; | 281 | return -EINVAL; |
250 | } | 282 | } |
@@ -392,9 +424,11 @@ EXPORT_SYMBOL(snd_request_card); | |||
392 | #endif | 424 | #endif |
393 | EXPORT_SYMBOL(snd_register_device); | 425 | EXPORT_SYMBOL(snd_register_device); |
394 | EXPORT_SYMBOL(snd_unregister_device); | 426 | EXPORT_SYMBOL(snd_unregister_device); |
427 | EXPORT_SYMBOL(snd_lookup_minor_data); | ||
395 | #if defined(CONFIG_SND_OSSEMUL) | 428 | #if defined(CONFIG_SND_OSSEMUL) |
396 | EXPORT_SYMBOL(snd_register_oss_device); | 429 | EXPORT_SYMBOL(snd_register_oss_device); |
397 | EXPORT_SYMBOL(snd_unregister_oss_device); | 430 | EXPORT_SYMBOL(snd_unregister_oss_device); |
431 | EXPORT_SYMBOL(snd_lookup_oss_minor_data); | ||
398 | #endif | 432 | #endif |
399 | /* memory.c */ | 433 | /* memory.c */ |
400 | EXPORT_SYMBOL(copy_to_user_fromio); | 434 | EXPORT_SYMBOL(copy_to_user_fromio); |