diff options
-rw-r--r-- | include/sound/core.h | 9 | ||||
-rw-r--r-- | include/sound/hwdep.h | 1 | ||||
-rw-r--r-- | include/sound/pcm.h | 2 | ||||
-rw-r--r-- | include/sound/rawmidi.h | 6 | ||||
-rw-r--r-- | sound/core/control.c | 7 | ||||
-rw-r--r-- | sound/core/hwdep.c | 91 | ||||
-rw-r--r-- | sound/core/oss/mixer_oss.c | 7 | ||||
-rw-r--r-- | sound/core/oss/pcm_oss.c | 14 | ||||
-rw-r--r-- | sound/core/pcm.c | 118 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 40 | ||||
-rw-r--r-- | sound/core/rawmidi.c | 87 | ||||
-rw-r--r-- | sound/core/seq/oss/seq_oss.c | 4 | ||||
-rw-r--r-- | sound/core/seq/seq_clientmgr.c | 2 | ||||
-rw-r--r-- | sound/core/seq/seq_midi.c | 10 | ||||
-rw-r--r-- | sound/core/sound.c | 46 | ||||
-rw-r--r-- | sound/core/sound_oss.c | 27 | ||||
-rw-r--r-- | sound/core/timer.c | 4 |
17 files changed, 278 insertions, 197 deletions
diff --git a/include/sound/core.h b/include/sound/core.h index 67b0a7e764e7..90ac6132ea3b 100644 --- a/include/sound/core.h +++ b/include/sound/core.h | |||
@@ -187,6 +187,7 @@ struct snd_minor { | |||
187 | int card; /* card number */ | 187 | int card; /* card number */ |
188 | int device; /* device number */ | 188 | int device; /* device number */ |
189 | struct file_operations *f_ops; /* file operations */ | 189 | struct file_operations *f_ops; /* file operations */ |
190 | void *private_data; /* private data for f_ops->open */ | ||
190 | char name[0]; /* device name (keep at the end of | 191 | char name[0]; /* device name (keep at the end of |
191 | structure) */ | 192 | structure) */ |
192 | }; | 193 | }; |
@@ -199,13 +200,17 @@ extern int snd_ecards_limit; | |||
199 | void snd_request_card(int card); | 200 | void snd_request_card(int card); |
200 | 201 | ||
201 | int snd_register_device(int type, struct snd_card *card, int dev, | 202 | int snd_register_device(int type, struct snd_card *card, int dev, |
202 | struct file_operations *f_ops, const char *name); | 203 | struct file_operations *f_ops, void *private_data, |
204 | const char *name); | ||
203 | int snd_unregister_device(int type, struct snd_card *card, int dev); | 205 | int snd_unregister_device(int type, struct snd_card *card, int dev); |
206 | void *snd_lookup_minor_data(unsigned int minor, int type); | ||
204 | 207 | ||
205 | #ifdef CONFIG_SND_OSSEMUL | 208 | #ifdef CONFIG_SND_OSSEMUL |
206 | int snd_register_oss_device(int type, struct snd_card *card, int dev, | 209 | int snd_register_oss_device(int type, struct snd_card *card, int dev, |
207 | struct file_operations *f_ops, const char *name); | 210 | struct file_operations *f_ops, void *private_data, |
211 | const char *name); | ||
208 | int snd_unregister_oss_device(int type, struct snd_card *card, int dev); | 212 | int snd_unregister_oss_device(int type, struct snd_card *card, int dev); |
213 | void *snd_lookup_oss_minor_data(unsigned int minor, int type); | ||
209 | #endif | 214 | #endif |
210 | 215 | ||
211 | int snd_minor_info_init(void); | 216 | int snd_minor_info_init(void); |
diff --git a/include/sound/hwdep.h b/include/sound/hwdep.h index 04b20bc4f144..c679e5b31111 100644 --- a/include/sound/hwdep.h +++ b/include/sound/hwdep.h | |||
@@ -43,6 +43,7 @@ struct snd_hwdep_ops { | |||
43 | 43 | ||
44 | struct snd_hwdep { | 44 | struct snd_hwdep { |
45 | struct snd_card *card; | 45 | struct snd_card *card; |
46 | struct list_head list; | ||
46 | int device; | 47 | int device; |
47 | char id[32]; | 48 | char id[32]; |
48 | char name[80]; | 49 | char name[80]; |
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 5e29b0e0f214..314268a11048 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
@@ -412,6 +412,7 @@ struct snd_pcm_str { | |||
412 | 412 | ||
413 | struct snd_pcm { | 413 | struct snd_pcm { |
414 | struct snd_card *card; | 414 | struct snd_card *card; |
415 | struct list_head list; | ||
415 | unsigned int device; /* device number */ | 416 | unsigned int device; /* device number */ |
416 | unsigned int info_flags; | 417 | unsigned int info_flags; |
417 | unsigned short dev_class; | 418 | unsigned short dev_class; |
@@ -439,7 +440,6 @@ struct snd_pcm_notify { | |||
439 | * Registering | 440 | * Registering |
440 | */ | 441 | */ |
441 | 442 | ||
442 | extern struct snd_pcm *snd_pcm_devices[]; | ||
443 | extern struct file_operations snd_pcm_f_ops[2]; | 443 | extern struct file_operations snd_pcm_f_ops[2]; |
444 | 444 | ||
445 | int snd_pcm_new(struct snd_card *card, char *id, int device, | 445 | int snd_pcm_new(struct snd_card *card, char *id, int device, |
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h index 9492a32c1026..d19bddfbf995 100644 --- a/include/sound/rawmidi.h +++ b/include/sound/rawmidi.h | |||
@@ -113,7 +113,7 @@ struct snd_rawmidi_str { | |||
113 | 113 | ||
114 | struct snd_rawmidi { | 114 | struct snd_rawmidi { |
115 | struct snd_card *card; | 115 | struct snd_card *card; |
116 | 116 | struct list_head list; | |
117 | unsigned int device; /* device number */ | 117 | unsigned int device; /* device number */ |
118 | unsigned int info_flags; /* SNDRV_RAWMIDI_INFO_XXXX */ | 118 | unsigned int info_flags; /* SNDRV_RAWMIDI_INFO_XXXX */ |
119 | char id[64]; | 119 | char id[64]; |
@@ -165,8 +165,8 @@ int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, | |||
165 | /* main midi functions */ | 165 | /* main midi functions */ |
166 | 166 | ||
167 | int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info); | 167 | int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info); |
168 | int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice, int mode, | 168 | int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, |
169 | struct snd_rawmidi_file *rfile); | 169 | int mode, struct snd_rawmidi_file *rfile); |
170 | int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile); | 170 | int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile); |
171 | int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, | 171 | int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream, |
172 | struct snd_rawmidi_params *params); | 172 | struct snd_rawmidi_params *params); |
diff --git a/sound/core/control.c b/sound/core/control.c index 23561e74712b..abd62f943726 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -47,13 +47,12 @@ static LIST_HEAD(snd_control_compat_ioctls); | |||
47 | 47 | ||
48 | static int snd_ctl_open(struct inode *inode, struct file *file) | 48 | static int snd_ctl_open(struct inode *inode, struct file *file) |
49 | { | 49 | { |
50 | int cardnum = SNDRV_MINOR_CARD(iminor(inode)); | ||
51 | unsigned long flags; | 50 | unsigned long flags; |
52 | struct snd_card *card; | 51 | struct snd_card *card; |
53 | struct snd_ctl_file *ctl; | 52 | struct snd_ctl_file *ctl; |
54 | int err; | 53 | int err; |
55 | 54 | ||
56 | card = snd_cards[cardnum]; | 55 | card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL); |
57 | if (!card) { | 56 | if (!card) { |
58 | err = -ENODEV; | 57 | err = -ENODEV; |
59 | goto __error1; | 58 | goto __error1; |
@@ -1277,8 +1276,8 @@ static int snd_ctl_dev_register(struct snd_device *device) | |||
1277 | cardnum = card->number; | 1276 | cardnum = card->number; |
1278 | snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO); | 1277 | snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO); |
1279 | sprintf(name, "controlC%i", cardnum); | 1278 | sprintf(name, "controlC%i", cardnum); |
1280 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, | 1279 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1, |
1281 | card, -1, &snd_ctl_f_ops, name)) < 0) | 1280 | &snd_ctl_f_ops, card, name)) < 0) |
1282 | return err; | 1281 | return err; |
1283 | return 0; | 1282 | return 0; |
1284 | } | 1283 | } |
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 27d5bf7266f0..b8c0c8c4d126 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c | |||
@@ -35,8 +35,7 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); | |||
35 | MODULE_DESCRIPTION("Hardware dependent layer"); | 35 | MODULE_DESCRIPTION("Hardware dependent layer"); |
36 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
37 | 37 | ||
38 | static struct snd_hwdep *snd_hwdep_devices[SNDRV_CARDS * SNDRV_MINOR_HWDEPS]; | 38 | static LIST_HEAD(snd_hwdep_devices); |
39 | |||
40 | static DECLARE_MUTEX(register_mutex); | 39 | static DECLARE_MUTEX(register_mutex); |
41 | 40 | ||
42 | static int snd_hwdep_free(struct snd_hwdep *hwdep); | 41 | static int snd_hwdep_free(struct snd_hwdep *hwdep); |
@@ -44,9 +43,19 @@ static int snd_hwdep_dev_free(struct snd_device *device); | |||
44 | static int snd_hwdep_dev_register(struct snd_device *device); | 43 | static int snd_hwdep_dev_register(struct snd_device *device); |
45 | static int snd_hwdep_dev_unregister(struct snd_device *device); | 44 | static int snd_hwdep_dev_unregister(struct snd_device *device); |
46 | 45 | ||
47 | /* | ||
48 | 46 | ||
49 | */ | 47 | static struct snd_hwdep *snd_hwdep_search(struct snd_card *card, int device) |
48 | { | ||
49 | struct list_head *p; | ||
50 | struct snd_hwdep *hwdep; | ||
51 | |||
52 | list_for_each(p, &snd_hwdep_devices) { | ||
53 | hwdep = list_entry(p, struct snd_hwdep, list); | ||
54 | if (hwdep->card == card && hwdep->device == device) | ||
55 | return hwdep; | ||
56 | } | ||
57 | return NULL; | ||
58 | } | ||
50 | 59 | ||
51 | static loff_t snd_hwdep_llseek(struct file * file, loff_t offset, int orig) | 60 | static loff_t snd_hwdep_llseek(struct file * file, loff_t offset, int orig) |
52 | { | 61 | { |
@@ -77,34 +86,25 @@ static ssize_t snd_hwdep_write(struct file * file, const char __user *buf, | |||
77 | static int snd_hwdep_open(struct inode *inode, struct file * file) | 86 | static int snd_hwdep_open(struct inode *inode, struct file * file) |
78 | { | 87 | { |
79 | int major = imajor(inode); | 88 | int major = imajor(inode); |
80 | int cardnum; | ||
81 | int device; | ||
82 | struct snd_hwdep *hw; | 89 | struct snd_hwdep *hw; |
83 | int err; | 90 | int err; |
84 | wait_queue_t wait; | 91 | wait_queue_t wait; |
85 | 92 | ||
86 | if (major == snd_major) { | 93 | if (major == snd_major) { |
87 | cardnum = SNDRV_MINOR_CARD(iminor(inode)); | 94 | hw = snd_lookup_minor_data(iminor(inode), |
88 | device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP; | 95 | SNDRV_DEVICE_TYPE_HWDEP); |
89 | #ifdef CONFIG_SND_OSSEMUL | 96 | #ifdef CONFIG_SND_OSSEMUL |
90 | } else if (major == SOUND_MAJOR) { | 97 | } else if (major == SOUND_MAJOR) { |
91 | cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); | 98 | hw = snd_lookup_oss_minor_data(iminor(inode), |
92 | device = 0; | 99 | SNDRV_OSS_DEVICE_TYPE_DMFM); |
93 | #endif | 100 | #endif |
94 | } else | 101 | } else |
95 | return -ENXIO; | 102 | return -ENXIO; |
96 | cardnum %= SNDRV_CARDS; | ||
97 | device %= SNDRV_MINOR_HWDEPS; | ||
98 | hw = snd_hwdep_devices[(cardnum * SNDRV_MINOR_HWDEPS) + device]; | ||
99 | if (hw == NULL) | 103 | if (hw == NULL) |
100 | return -ENODEV; | 104 | return -ENODEV; |
101 | 105 | ||
102 | if (!hw->ops.open) | 106 | if (!hw->ops.open) |
103 | return -ENXIO; | 107 | return -ENXIO; |
104 | #ifdef CONFIG_SND_OSSEMUL | ||
105 | if (major == SOUND_MAJOR && hw->oss_type < 0) | ||
106 | return -ENXIO; | ||
107 | #endif | ||
108 | 108 | ||
109 | if (!try_module_get(hw->card->module)) | 109 | if (!try_module_get(hw->card->module)) |
110 | return -EFAULT; | 110 | return -EFAULT; |
@@ -265,9 +265,6 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, | |||
265 | struct snd_ctl_file * control, | 265 | struct snd_ctl_file * control, |
266 | unsigned int cmd, unsigned long arg) | 266 | unsigned int cmd, unsigned long arg) |
267 | { | 267 | { |
268 | unsigned int tmp; | ||
269 | |||
270 | tmp = card->number * SNDRV_MINOR_HWDEPS; | ||
271 | switch (cmd) { | 268 | switch (cmd) { |
272 | case SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE: | 269 | case SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE: |
273 | { | 270 | { |
@@ -275,14 +272,16 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, | |||
275 | 272 | ||
276 | if (get_user(device, (int __user *)arg)) | 273 | if (get_user(device, (int __user *)arg)) |
277 | return -EFAULT; | 274 | return -EFAULT; |
275 | down(®ister_mutex); | ||
278 | device = device < 0 ? 0 : device + 1; | 276 | device = device < 0 ? 0 : device + 1; |
279 | while (device < SNDRV_MINOR_HWDEPS) { | 277 | while (device < SNDRV_MINOR_HWDEPS) { |
280 | if (snd_hwdep_devices[tmp + device]) | 278 | if (snd_hwdep_search(card, device)) |
281 | break; | 279 | break; |
282 | device++; | 280 | device++; |
283 | } | 281 | } |
284 | if (device >= SNDRV_MINOR_HWDEPS) | 282 | if (device >= SNDRV_MINOR_HWDEPS) |
285 | device = -1; | 283 | device = -1; |
284 | up(®ister_mutex); | ||
286 | if (put_user(device, (int __user *)arg)) | 285 | if (put_user(device, (int __user *)arg)) |
287 | return -EFAULT; | 286 | return -EFAULT; |
288 | return 0; | 287 | return 0; |
@@ -290,17 +289,19 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, | |||
290 | case SNDRV_CTL_IOCTL_HWDEP_INFO: | 289 | case SNDRV_CTL_IOCTL_HWDEP_INFO: |
291 | { | 290 | { |
292 | struct snd_hwdep_info __user *info = (struct snd_hwdep_info __user *)arg; | 291 | struct snd_hwdep_info __user *info = (struct snd_hwdep_info __user *)arg; |
293 | int device; | 292 | int device, err; |
294 | struct snd_hwdep *hwdep; | 293 | struct snd_hwdep *hwdep; |
295 | 294 | ||
296 | if (get_user(device, &info->device)) | 295 | if (get_user(device, &info->device)) |
297 | return -EFAULT; | 296 | return -EFAULT; |
298 | if (device < 0 || device >= SNDRV_MINOR_HWDEPS) | 297 | down(®ister_mutex); |
299 | return -ENXIO; | 298 | hwdep = snd_hwdep_search(card, device); |
300 | hwdep = snd_hwdep_devices[tmp + device]; | 299 | if (hwdep) |
301 | if (hwdep == NULL) | 300 | err = snd_hwdep_info(hwdep, info); |
302 | return -ENXIO; | 301 | else |
303 | return snd_hwdep_info(hwdep, info); | 302 | err = -ENXIO; |
303 | up(®ister_mutex); | ||
304 | return err; | ||
304 | } | 305 | } |
305 | } | 306 | } |
306 | return -ENOIOCTLCMD; | 307 | return -ENOIOCTLCMD; |
@@ -397,23 +398,22 @@ static int snd_hwdep_dev_free(struct snd_device *device) | |||
397 | static int snd_hwdep_dev_register(struct snd_device *device) | 398 | static int snd_hwdep_dev_register(struct snd_device *device) |
398 | { | 399 | { |
399 | struct snd_hwdep *hwdep = device->device_data; | 400 | struct snd_hwdep *hwdep = device->device_data; |
400 | int idx, err; | 401 | int err; |
401 | char name[32]; | 402 | char name[32]; |
402 | 403 | ||
403 | down(®ister_mutex); | 404 | down(®ister_mutex); |
404 | idx = (hwdep->card->number * SNDRV_MINOR_HWDEPS) + hwdep->device; | 405 | if (snd_hwdep_search(hwdep->card, hwdep->device)) { |
405 | if (snd_hwdep_devices[idx]) { | ||
406 | up(®ister_mutex); | 406 | up(®ister_mutex); |
407 | return -EBUSY; | 407 | return -EBUSY; |
408 | } | 408 | } |
409 | snd_hwdep_devices[idx] = hwdep; | 409 | list_add_tail(&hwdep->list, &snd_hwdep_devices); |
410 | sprintf(name, "hwC%iD%i", hwdep->card->number, hwdep->device); | 410 | sprintf(name, "hwC%iD%i", hwdep->card->number, hwdep->device); |
411 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_HWDEP, | 411 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_HWDEP, |
412 | hwdep->card, hwdep->device, | 412 | hwdep->card, hwdep->device, |
413 | &snd_hwdep_f_ops, name)) < 0) { | 413 | &snd_hwdep_f_ops, hwdep, name)) < 0) { |
414 | snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n", | 414 | snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n", |
415 | hwdep->card->number, hwdep->device); | 415 | hwdep->card->number, hwdep->device); |
416 | snd_hwdep_devices[idx] = NULL; | 416 | list_del(&hwdep->list); |
417 | up(®ister_mutex); | 417 | up(®ister_mutex); |
418 | return err; | 418 | return err; |
419 | } | 419 | } |
@@ -425,7 +425,7 @@ static int snd_hwdep_dev_register(struct snd_device *device) | |||
425 | } else { | 425 | } else { |
426 | if (snd_register_oss_device(hwdep->oss_type, | 426 | if (snd_register_oss_device(hwdep->oss_type, |
427 | hwdep->card, hwdep->device, | 427 | hwdep->card, hwdep->device, |
428 | &snd_hwdep_f_ops, | 428 | &snd_hwdep_f_ops, hwdep, |
429 | hwdep->oss_dev) < 0) { | 429 | hwdep->oss_dev) < 0) { |
430 | snd_printk(KERN_ERR "unable to register OSS compatibility device %i:%i\n", | 430 | snd_printk(KERN_ERR "unable to register OSS compatibility device %i:%i\n", |
431 | hwdep->card->number, hwdep->device); | 431 | hwdep->card->number, hwdep->device); |
@@ -441,12 +441,10 @@ static int snd_hwdep_dev_register(struct snd_device *device) | |||
441 | static int snd_hwdep_dev_unregister(struct snd_device *device) | 441 | static int snd_hwdep_dev_unregister(struct snd_device *device) |
442 | { | 442 | { |
443 | struct snd_hwdep *hwdep = device->device_data; | 443 | struct snd_hwdep *hwdep = device->device_data; |
444 | int idx; | ||
445 | 444 | ||
446 | snd_assert(hwdep != NULL, return -ENXIO); | 445 | snd_assert(hwdep != NULL, return -ENXIO); |
447 | down(®ister_mutex); | 446 | down(®ister_mutex); |
448 | idx = (hwdep->card->number * SNDRV_MINOR_HWDEPS) + hwdep->device; | 447 | if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) { |
449 | if (snd_hwdep_devices[idx] != hwdep) { | ||
450 | up(®ister_mutex); | 448 | up(®ister_mutex); |
451 | return -EINVAL; | 449 | return -EINVAL; |
452 | } | 450 | } |
@@ -455,7 +453,7 @@ static int snd_hwdep_dev_unregister(struct snd_device *device) | |||
455 | snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device); | 453 | snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device); |
456 | #endif | 454 | #endif |
457 | snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); | 455 | snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device); |
458 | snd_hwdep_devices[idx] = NULL; | 456 | list_del(&hwdep->list); |
459 | up(®ister_mutex); | 457 | up(®ister_mutex); |
460 | return snd_hwdep_free(hwdep); | 458 | return snd_hwdep_free(hwdep); |
461 | } | 459 | } |
@@ -467,18 +465,14 @@ static int snd_hwdep_dev_unregister(struct snd_device *device) | |||
467 | static void snd_hwdep_proc_read(struct snd_info_entry *entry, | 465 | static void snd_hwdep_proc_read(struct snd_info_entry *entry, |
468 | struct snd_info_buffer *buffer) | 466 | struct snd_info_buffer *buffer) |
469 | { | 467 | { |
470 | int idx; | 468 | struct list_head *p; |
471 | struct snd_hwdep *hwdep; | 469 | struct snd_hwdep *hwdep; |
472 | 470 | ||
473 | down(®ister_mutex); | 471 | down(®ister_mutex); |
474 | for (idx = 0; idx < SNDRV_CARDS * SNDRV_MINOR_HWDEPS; idx++) { | 472 | list_for_each(p, &snd_hwdep_devices) { |
475 | hwdep = snd_hwdep_devices[idx]; | 473 | hwdep = list_entry(p, struct snd_hwdep, list); |
476 | if (hwdep == NULL) | ||
477 | continue; | ||
478 | snd_iprintf(buffer, "%02i-%02i: %s\n", | 474 | snd_iprintf(buffer, "%02i-%02i: %s\n", |
479 | idx / SNDRV_MINOR_HWDEPS, | 475 | hwdep->card->number, hwdep->device, hwdep->name); |
480 | idx % SNDRV_MINOR_HWDEPS, | ||
481 | hwdep->name); | ||
482 | } | 476 | } |
483 | up(®ister_mutex); | 477 | up(®ister_mutex); |
484 | } | 478 | } |
@@ -493,9 +487,8 @@ static int __init alsa_hwdep_init(void) | |||
493 | { | 487 | { |
494 | struct snd_info_entry *entry; | 488 | struct snd_info_entry *entry; |
495 | 489 | ||
496 | memset(snd_hwdep_devices, 0, sizeof(snd_hwdep_devices)); | ||
497 | if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) { | 490 | if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) { |
498 | entry->c.text.read_size = 512; | 491 | entry->c.text.read_size = PAGE_SIZE; |
499 | entry->c.text.read = snd_hwdep_proc_read; | 492 | entry->c.text.read = snd_hwdep_proc_read; |
500 | if (snd_info_register(entry) < 0) { | 493 | if (snd_info_register(entry) < 0) { |
501 | snd_info_free_entry(entry); | 494 | snd_info_free_entry(entry); |
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 2dd6bf9b49ed..2d7a42014f51 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c | |||
@@ -41,12 +41,13 @@ MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_MIXER); | |||
41 | 41 | ||
42 | static int snd_mixer_oss_open(struct inode *inode, struct file *file) | 42 | static int snd_mixer_oss_open(struct inode *inode, struct file *file) |
43 | { | 43 | { |
44 | int cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); | ||
45 | struct snd_card *card; | 44 | struct snd_card *card; |
46 | struct snd_mixer_oss_file *fmixer; | 45 | struct snd_mixer_oss_file *fmixer; |
47 | int err; | 46 | int err; |
48 | 47 | ||
49 | if ((card = snd_cards[cardnum]) == NULL) | 48 | card = snd_lookup_oss_minor_data(iminor(inode), |
49 | SNDRV_OSS_DEVICE_TYPE_MIXER); | ||
50 | if (card == NULL) | ||
50 | return -ENODEV; | 51 | return -ENODEV; |
51 | if (card->mixer_oss == NULL) | 52 | if (card->mixer_oss == NULL) |
52 | return -ENODEV; | 53 | return -ENODEV; |
@@ -1286,7 +1287,7 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd) | |||
1286 | sprintf(name, "mixer%i%i", card->number, 0); | 1287 | sprintf(name, "mixer%i%i", card->number, 0); |
1287 | if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, | 1288 | if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER, |
1288 | card, 0, | 1289 | card, 0, |
1289 | &snd_mixer_oss_f_ops, | 1290 | &snd_mixer_oss_f_ops, card, |
1290 | name)) < 0) { | 1291 | name)) < 0) { |
1291 | snd_printk(KERN_ERR "unable to register OSS mixer device %i:%i\n", | 1292 | snd_printk(KERN_ERR "unable to register OSS mixer device %i:%i\n", |
1292 | card->number, 0); | 1293 | card->number, 0); |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 947bf08df42a..2ae283c7b28a 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -1834,9 +1834,6 @@ static int snd_task_name(struct task_struct *task, char *name, size_t size) | |||
1834 | 1834 | ||
1835 | static int snd_pcm_oss_open(struct inode *inode, struct file *file) | 1835 | static int snd_pcm_oss_open(struct inode *inode, struct file *file) |
1836 | { | 1836 | { |
1837 | int minor = iminor(inode); | ||
1838 | int cardnum = SNDRV_MINOR_OSS_CARD(minor); | ||
1839 | int device; | ||
1840 | int err; | 1837 | int err; |
1841 | char task_name[32]; | 1838 | char task_name[32]; |
1842 | struct snd_pcm *pcm; | 1839 | struct snd_pcm *pcm; |
@@ -1845,11 +1842,8 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) | |||
1845 | int nonblock; | 1842 | int nonblock; |
1846 | wait_queue_t wait; | 1843 | wait_queue_t wait; |
1847 | 1844 | ||
1848 | snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO); | 1845 | pcm = snd_lookup_oss_minor_data(iminor(inode), |
1849 | device = SNDRV_MINOR_OSS_DEVICE(minor) == SNDRV_MINOR_OSS_PCM1 ? | 1846 | SNDRV_OSS_DEVICE_TYPE_PCM); |
1850 | adsp_map[cardnum] : dsp_map[cardnum]; | ||
1851 | |||
1852 | pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + device]; | ||
1853 | if (pcm == NULL) { | 1847 | if (pcm == NULL) { |
1854 | err = -ENODEV; | 1848 | err = -ENODEV; |
1855 | goto __error1; | 1849 | goto __error1; |
@@ -1890,7 +1884,7 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) | |||
1890 | down(&pcm->open_mutex); | 1884 | down(&pcm->open_mutex); |
1891 | while (1) { | 1885 | while (1) { |
1892 | err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file, | 1886 | err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file, |
1893 | minor, psetup, csetup); | 1887 | iminor(inode), psetup, csetup); |
1894 | if (err >= 0) | 1888 | if (err >= 0) |
1895 | break; | 1889 | break; |
1896 | if (err == -EAGAIN) { | 1890 | if (err == -EAGAIN) { |
@@ -2450,7 +2444,7 @@ static void register_oss_dsp(struct snd_pcm *pcm, int index) | |||
2450 | sprintf(name, "dsp%i%i", pcm->card->number, pcm->device); | 2444 | sprintf(name, "dsp%i%i", pcm->card->number, pcm->device); |
2451 | if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM, | 2445 | if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM, |
2452 | pcm->card, index, &snd_pcm_oss_f_reg, | 2446 | pcm->card, index, &snd_pcm_oss_f_reg, |
2453 | name) < 0) { | 2447 | pcm, name) < 0) { |
2454 | snd_printk(KERN_ERR "unable to register OSS PCM device %i:%i\n", | 2448 | snd_printk(KERN_ERR "unable to register OSS PCM device %i:%i\n", |
2455 | pcm->card->number, pcm->device); | 2449 | pcm->card->number, pcm->device); |
2456 | } | 2450 | } |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 2bc5f69ec2a8..95036c83de43 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -33,7 +33,7 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Abramo Bagnara <abramo@alsa-proj | |||
33 | MODULE_DESCRIPTION("Midlevel PCM code for ALSA."); | 33 | MODULE_DESCRIPTION("Midlevel PCM code for ALSA."); |
34 | MODULE_LICENSE("GPL"); | 34 | MODULE_LICENSE("GPL"); |
35 | 35 | ||
36 | struct snd_pcm *snd_pcm_devices[SNDRV_CARDS * SNDRV_PCM_DEVICES]; | 36 | static LIST_HEAD(snd_pcm_devices); |
37 | static LIST_HEAD(snd_pcm_notify_list); | 37 | static LIST_HEAD(snd_pcm_notify_list); |
38 | static DECLARE_MUTEX(register_mutex); | 38 | static DECLARE_MUTEX(register_mutex); |
39 | 39 | ||
@@ -43,13 +43,23 @@ static int snd_pcm_dev_register(struct snd_device *device); | |||
43 | static int snd_pcm_dev_disconnect(struct snd_device *device); | 43 | static int snd_pcm_dev_disconnect(struct snd_device *device); |
44 | static int snd_pcm_dev_unregister(struct snd_device *device); | 44 | static int snd_pcm_dev_unregister(struct snd_device *device); |
45 | 45 | ||
46 | static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device) | ||
47 | { | ||
48 | struct list_head *p; | ||
49 | struct snd_pcm *pcm; | ||
50 | |||
51 | list_for_each(p, &snd_pcm_devices) { | ||
52 | pcm = list_entry(p, struct snd_pcm, list); | ||
53 | if (pcm->card == card && pcm->device == device) | ||
54 | return pcm; | ||
55 | } | ||
56 | return NULL; | ||
57 | } | ||
58 | |||
46 | static int snd_pcm_control_ioctl(struct snd_card *card, | 59 | static int snd_pcm_control_ioctl(struct snd_card *card, |
47 | struct snd_ctl_file *control, | 60 | struct snd_ctl_file *control, |
48 | unsigned int cmd, unsigned long arg) | 61 | unsigned int cmd, unsigned long arg) |
49 | { | 62 | { |
50 | unsigned int tmp; | ||
51 | |||
52 | tmp = card->number * SNDRV_PCM_DEVICES; | ||
53 | switch (cmd) { | 63 | switch (cmd) { |
54 | case SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE: | 64 | case SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE: |
55 | { | 65 | { |
@@ -57,14 +67,16 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
57 | 67 | ||
58 | if (get_user(device, (int __user *)arg)) | 68 | if (get_user(device, (int __user *)arg)) |
59 | return -EFAULT; | 69 | return -EFAULT; |
70 | down(®ister_mutex); | ||
60 | device = device < 0 ? 0 : device + 1; | 71 | device = device < 0 ? 0 : device + 1; |
61 | while (device < SNDRV_PCM_DEVICES) { | 72 | while (device < SNDRV_PCM_DEVICES) { |
62 | if (snd_pcm_devices[tmp + device]) | 73 | if (snd_pcm_search(card, device)) |
63 | break; | 74 | break; |
64 | device++; | 75 | device++; |
65 | } | 76 | } |
66 | if (device == SNDRV_PCM_DEVICES) | 77 | if (device == SNDRV_PCM_DEVICES) |
67 | device = -1; | 78 | device = -1; |
79 | up(®ister_mutex); | ||
68 | if (put_user(device, (int __user *)arg)) | 80 | if (put_user(device, (int __user *)arg)) |
69 | return -EFAULT; | 81 | return -EFAULT; |
70 | return 0; | 82 | return 0; |
@@ -77,31 +89,44 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
77 | struct snd_pcm *pcm; | 89 | struct snd_pcm *pcm; |
78 | struct snd_pcm_str *pstr; | 90 | struct snd_pcm_str *pstr; |
79 | struct snd_pcm_substream *substream; | 91 | struct snd_pcm_substream *substream; |
92 | int err; | ||
93 | |||
80 | info = (struct snd_pcm_info __user *)arg; | 94 | info = (struct snd_pcm_info __user *)arg; |
81 | if (get_user(device, &info->device)) | 95 | if (get_user(device, &info->device)) |
82 | return -EFAULT; | 96 | return -EFAULT; |
83 | if (device >= SNDRV_PCM_DEVICES) | ||
84 | return -ENXIO; | ||
85 | pcm = snd_pcm_devices[tmp + device]; | ||
86 | if (pcm == NULL) | ||
87 | return -ENXIO; | ||
88 | if (get_user(stream, &info->stream)) | 97 | if (get_user(stream, &info->stream)) |
89 | return -EFAULT; | 98 | return -EFAULT; |
90 | if (stream < 0 || stream > 1) | 99 | if (stream < 0 || stream > 1) |
91 | return -EINVAL; | 100 | return -EINVAL; |
92 | pstr = &pcm->streams[stream]; | ||
93 | if (pstr->substream_count == 0) | ||
94 | return -ENOENT; | ||
95 | if (get_user(subdevice, &info->subdevice)) | 101 | if (get_user(subdevice, &info->subdevice)) |
96 | return -EFAULT; | 102 | return -EFAULT; |
97 | if (subdevice >= pstr->substream_count) | 103 | down(®ister_mutex); |
98 | return -ENXIO; | 104 | pcm = snd_pcm_search(card, device); |
99 | for (substream = pstr->substream; substream; substream = substream->next) | 105 | if (pcm == NULL) { |
106 | err = -ENXIO; | ||
107 | goto _error; | ||
108 | } | ||
109 | pstr = &pcm->streams[stream]; | ||
110 | if (pstr->substream_count == 0) { | ||
111 | err = -ENOENT; | ||
112 | goto _error; | ||
113 | } | ||
114 | if (subdevice >= pstr->substream_count) { | ||
115 | err = -ENXIO; | ||
116 | goto _error; | ||
117 | } | ||
118 | for (substream = pstr->substream; substream; | ||
119 | substream = substream->next) | ||
100 | if (substream->number == (int)subdevice) | 120 | if (substream->number == (int)subdevice) |
101 | break; | 121 | break; |
102 | if (substream == NULL) | 122 | if (substream == NULL) { |
103 | return -ENXIO; | 123 | err = -ENXIO; |
104 | return snd_pcm_info_user(substream, info); | 124 | goto _error; |
125 | } | ||
126 | err = snd_pcm_info_user(substream, info); | ||
127 | _error: | ||
128 | up(®ister_mutex); | ||
129 | return err; | ||
105 | } | 130 | } |
106 | case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE: | 131 | case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE: |
107 | { | 132 | { |
@@ -865,8 +890,7 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream) | |||
865 | 890 | ||
866 | static int snd_pcm_dev_register(struct snd_device *device) | 891 | static int snd_pcm_dev_register(struct snd_device *device) |
867 | { | 892 | { |
868 | int idx, cidx, err; | 893 | int cidx, err; |
869 | unsigned short minor; | ||
870 | struct snd_pcm_substream *substream; | 894 | struct snd_pcm_substream *substream; |
871 | struct list_head *list; | 895 | struct list_head *list; |
872 | char str[16]; | 896 | char str[16]; |
@@ -874,12 +898,11 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
874 | 898 | ||
875 | snd_assert(pcm != NULL && device != NULL, return -ENXIO); | 899 | snd_assert(pcm != NULL && device != NULL, return -ENXIO); |
876 | down(®ister_mutex); | 900 | down(®ister_mutex); |
877 | idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device; | 901 | if (snd_pcm_search(pcm->card, pcm->device)) { |
878 | if (snd_pcm_devices[idx]) { | ||
879 | up(®ister_mutex); | 902 | up(®ister_mutex); |
880 | return -EBUSY; | 903 | return -EBUSY; |
881 | } | 904 | } |
882 | snd_pcm_devices[idx] = pcm; | 905 | list_add_tail(&pcm->list, &snd_pcm_devices); |
883 | for (cidx = 0; cidx < 2; cidx++) { | 906 | for (cidx = 0; cidx < 2; cidx++) { |
884 | int devtype = -1; | 907 | int devtype = -1; |
885 | if (pcm->streams[cidx].substream == NULL) | 908 | if (pcm->streams[cidx].substream == NULL) |
@@ -887,20 +910,19 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
887 | switch (cidx) { | 910 | switch (cidx) { |
888 | case SNDRV_PCM_STREAM_PLAYBACK: | 911 | case SNDRV_PCM_STREAM_PLAYBACK: |
889 | sprintf(str, "pcmC%iD%ip", pcm->card->number, pcm->device); | 912 | sprintf(str, "pcmC%iD%ip", pcm->card->number, pcm->device); |
890 | minor = SNDRV_MINOR_PCM_PLAYBACK + idx; | ||
891 | devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK; | 913 | devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK; |
892 | break; | 914 | break; |
893 | case SNDRV_PCM_STREAM_CAPTURE: | 915 | case SNDRV_PCM_STREAM_CAPTURE: |
894 | sprintf(str, "pcmC%iD%ic", pcm->card->number, pcm->device); | 916 | sprintf(str, "pcmC%iD%ic", pcm->card->number, pcm->device); |
895 | minor = SNDRV_MINOR_PCM_CAPTURE + idx; | ||
896 | devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE; | 917 | devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE; |
897 | break; | 918 | break; |
898 | } | 919 | } |
899 | if ((err = snd_register_device(devtype, pcm->card, | 920 | if ((err = snd_register_device(devtype, pcm->card, |
900 | pcm->device, | 921 | pcm->device, |
901 | &snd_pcm_f_ops[cidx], str)) < 0) | 922 | &snd_pcm_f_ops[cidx], |
923 | pcm, str)) < 0) | ||
902 | { | 924 | { |
903 | snd_pcm_devices[idx] = NULL; | 925 | list_del(&pcm->list); |
904 | up(®ister_mutex); | 926 | up(®ister_mutex); |
905 | return err; | 927 | return err; |
906 | } | 928 | } |
@@ -921,11 +943,10 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) | |||
921 | struct snd_pcm *pcm = device->device_data; | 943 | struct snd_pcm *pcm = device->device_data; |
922 | struct list_head *list; | 944 | struct list_head *list; |
923 | struct snd_pcm_substream *substream; | 945 | struct snd_pcm_substream *substream; |
924 | int idx, cidx; | 946 | int cidx; |
925 | 947 | ||
926 | down(®ister_mutex); | 948 | down(®ister_mutex); |
927 | idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device; | 949 | list_del_init(&pcm->list); |
928 | snd_pcm_devices[idx] = NULL; | ||
929 | for (cidx = 0; cidx < 2; cidx++) | 950 | for (cidx = 0; cidx < 2; cidx++) |
930 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) | 951 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) |
931 | if (substream->runtime) | 952 | if (substream->runtime) |
@@ -941,15 +962,14 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) | |||
941 | 962 | ||
942 | static int snd_pcm_dev_unregister(struct snd_device *device) | 963 | static int snd_pcm_dev_unregister(struct snd_device *device) |
943 | { | 964 | { |
944 | int idx, cidx, devtype; | 965 | int cidx, devtype; |
945 | struct snd_pcm_substream *substream; | 966 | struct snd_pcm_substream *substream; |
946 | struct list_head *list; | 967 | struct list_head *list; |
947 | struct snd_pcm *pcm = device->device_data; | 968 | struct snd_pcm *pcm = device->device_data; |
948 | 969 | ||
949 | snd_assert(pcm != NULL, return -ENXIO); | 970 | snd_assert(pcm != NULL, return -ENXIO); |
950 | down(®ister_mutex); | 971 | down(®ister_mutex); |
951 | idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device; | 972 | list_del(&pcm->list); |
952 | snd_pcm_devices[idx] = NULL; | ||
953 | for (cidx = 0; cidx < 2; cidx++) { | 973 | for (cidx = 0; cidx < 2; cidx++) { |
954 | devtype = -1; | 974 | devtype = -1; |
955 | switch (cidx) { | 975 | switch (cidx) { |
@@ -975,24 +995,19 @@ static int snd_pcm_dev_unregister(struct snd_device *device) | |||
975 | 995 | ||
976 | int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) | 996 | int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) |
977 | { | 997 | { |
978 | int idx; | 998 | struct list_head *p; |
979 | 999 | ||
980 | snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL); | 1000 | snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL); |
981 | down(®ister_mutex); | 1001 | down(®ister_mutex); |
982 | if (nfree) { | 1002 | if (nfree) { |
983 | list_del(¬ify->list); | 1003 | list_del(¬ify->list); |
984 | for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) { | 1004 | list_for_each(p, &snd_pcm_devices) |
985 | if (snd_pcm_devices[idx] == NULL) | 1005 | notify->n_unregister(list_entry(p, |
986 | continue; | 1006 | struct snd_pcm, list)); |
987 | notify->n_unregister(snd_pcm_devices[idx]); | ||
988 | } | ||
989 | } else { | 1007 | } else { |
990 | list_add_tail(¬ify->list, &snd_pcm_notify_list); | 1008 | list_add_tail(¬ify->list, &snd_pcm_notify_list); |
991 | for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) { | 1009 | list_for_each(p, &snd_pcm_devices) |
992 | if (snd_pcm_devices[idx] == NULL) | 1010 | notify->n_register(list_entry(p, struct snd_pcm, list)); |
993 | continue; | ||
994 | notify->n_register(snd_pcm_devices[idx]); | ||
995 | } | ||
996 | } | 1011 | } |
997 | up(®ister_mutex); | 1012 | up(®ister_mutex); |
998 | return 0; | 1013 | return 0; |
@@ -1005,16 +1020,14 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) | |||
1005 | static void snd_pcm_proc_read(struct snd_info_entry *entry, | 1020 | static void snd_pcm_proc_read(struct snd_info_entry *entry, |
1006 | struct snd_info_buffer *buffer) | 1021 | struct snd_info_buffer *buffer) |
1007 | { | 1022 | { |
1008 | int idx; | 1023 | struct list_head *p; |
1009 | struct snd_pcm *pcm; | 1024 | struct snd_pcm *pcm; |
1010 | 1025 | ||
1011 | down(®ister_mutex); | 1026 | down(®ister_mutex); |
1012 | for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) { | 1027 | list_for_each(p, &snd_pcm_devices) { |
1013 | pcm = snd_pcm_devices[idx]; | 1028 | pcm = list_entry(p, struct snd_pcm, list); |
1014 | if (pcm == NULL) | 1029 | snd_iprintf(buffer, "%02i-%02i: %s : %s", |
1015 | continue; | 1030 | pcm->card->number, pcm->device, pcm->id, pcm->name); |
1016 | snd_iprintf(buffer, "%02i-%02i: %s : %s", idx / SNDRV_PCM_DEVICES, | ||
1017 | idx % SNDRV_PCM_DEVICES, pcm->id, pcm->name); | ||
1018 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) | 1031 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) |
1019 | snd_iprintf(buffer, " : playback %i", | 1032 | snd_iprintf(buffer, " : playback %i", |
1020 | pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count); | 1033 | pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count); |
@@ -1063,7 +1076,6 @@ static void __exit alsa_pcm_exit(void) | |||
1063 | module_init(alsa_pcm_init) | 1076 | module_init(alsa_pcm_init) |
1064 | module_exit(alsa_pcm_exit) | 1077 | module_exit(alsa_pcm_exit) |
1065 | 1078 | ||
1066 | EXPORT_SYMBOL(snd_pcm_devices); | ||
1067 | EXPORT_SYMBOL(snd_pcm_new); | 1079 | EXPORT_SYMBOL(snd_pcm_new); |
1068 | EXPORT_SYMBOL(snd_pcm_new_stream); | 1080 | EXPORT_SYMBOL(snd_pcm_new_stream); |
1069 | EXPORT_SYMBOL(snd_pcm_notify); | 1081 | EXPORT_SYMBOL(snd_pcm_notify); |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index bb40c016135e..9010306bcead 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -62,6 +62,7 @@ static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream, | |||
62 | struct snd_pcm_hw_params_old __user * _oparams); | 62 | struct snd_pcm_hw_params_old __user * _oparams); |
63 | static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream, | 63 | static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream, |
64 | struct snd_pcm_hw_params_old __user * _oparams); | 64 | struct snd_pcm_hw_params_old __user * _oparams); |
65 | static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream); | ||
65 | 66 | ||
66 | /* | 67 | /* |
67 | * | 68 | * |
@@ -1554,7 +1555,8 @@ static struct file *snd_pcm_file_fd(int fd) | |||
1554 | { | 1555 | { |
1555 | struct file *file; | 1556 | struct file *file; |
1556 | struct inode *inode; | 1557 | struct inode *inode; |
1557 | unsigned short minor; | 1558 | unsigned int minor; |
1559 | |||
1558 | file = fget(fd); | 1560 | file = fget(fd); |
1559 | if (!file) | 1561 | if (!file) |
1560 | return NULL; | 1562 | return NULL; |
@@ -1565,8 +1567,8 @@ static struct file *snd_pcm_file_fd(int fd) | |||
1565 | return NULL; | 1567 | return NULL; |
1566 | } | 1568 | } |
1567 | minor = iminor(inode); | 1569 | minor = iminor(inode); |
1568 | if (minor >= 256 || | 1570 | if (!snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) && |
1569 | minor % SNDRV_MINOR_DEVICES < SNDRV_MINOR_PCM_PLAYBACK) { | 1571 | !snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE)) { |
1570 | fput(file); | 1572 | fput(file); |
1571 | return NULL; | 1573 | return NULL; |
1572 | } | 1574 | } |
@@ -2071,18 +2073,30 @@ static int snd_pcm_open_file(struct file *file, | |||
2071 | return 0; | 2073 | return 0; |
2072 | } | 2074 | } |
2073 | 2075 | ||
2074 | static int snd_pcm_open(struct inode *inode, struct file *file) | 2076 | static int snd_pcm_playback_open(struct inode *inode, struct file *file) |
2077 | { | ||
2078 | struct snd_pcm *pcm; | ||
2079 | |||
2080 | pcm = snd_lookup_minor_data(iminor(inode), | ||
2081 | SNDRV_DEVICE_TYPE_PCM_PLAYBACK); | ||
2082 | return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); | ||
2083 | } | ||
2084 | |||
2085 | static int snd_pcm_capture_open(struct inode *inode, struct file *file) | ||
2075 | { | 2086 | { |
2076 | int cardnum = SNDRV_MINOR_CARD(iminor(inode)); | ||
2077 | int device = SNDRV_MINOR_DEVICE(iminor(inode)); | ||
2078 | int err; | ||
2079 | struct snd_pcm *pcm; | 2087 | struct snd_pcm *pcm; |
2088 | |||
2089 | pcm = snd_lookup_minor_data(iminor(inode), | ||
2090 | SNDRV_DEVICE_TYPE_PCM_CAPTURE); | ||
2091 | return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); | ||
2092 | } | ||
2093 | |||
2094 | static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) | ||
2095 | { | ||
2096 | int err; | ||
2080 | struct snd_pcm_file *pcm_file; | 2097 | struct snd_pcm_file *pcm_file; |
2081 | wait_queue_t wait; | 2098 | wait_queue_t wait; |
2082 | 2099 | ||
2083 | if (device < SNDRV_MINOR_PCM_PLAYBACK || device >= SNDRV_MINOR_DEVICES) | ||
2084 | return -ENXIO; | ||
2085 | pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)]; | ||
2086 | if (pcm == NULL) { | 2100 | if (pcm == NULL) { |
2087 | err = -ENODEV; | 2101 | err = -ENODEV; |
2088 | goto __error1; | 2102 | goto __error1; |
@@ -2098,7 +2112,7 @@ static int snd_pcm_open(struct inode *inode, struct file *file) | |||
2098 | add_wait_queue(&pcm->open_wait, &wait); | 2112 | add_wait_queue(&pcm->open_wait, &wait); |
2099 | down(&pcm->open_mutex); | 2113 | down(&pcm->open_mutex); |
2100 | while (1) { | 2114 | while (1) { |
2101 | err = snd_pcm_open_file(file, pcm, device >= SNDRV_MINOR_PCM_CAPTURE ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK, &pcm_file); | 2115 | err = snd_pcm_open_file(file, pcm, stream, &pcm_file); |
2102 | if (err >= 0) | 2116 | if (err >= 0) |
2103 | break; | 2117 | break; |
2104 | if (err == -EAGAIN) { | 2118 | if (err == -EAGAIN) { |
@@ -3375,7 +3389,7 @@ struct file_operations snd_pcm_f_ops[2] = { | |||
3375 | .owner = THIS_MODULE, | 3389 | .owner = THIS_MODULE, |
3376 | .write = snd_pcm_write, | 3390 | .write = snd_pcm_write, |
3377 | .writev = snd_pcm_writev, | 3391 | .writev = snd_pcm_writev, |
3378 | .open = snd_pcm_open, | 3392 | .open = snd_pcm_playback_open, |
3379 | .release = snd_pcm_release, | 3393 | .release = snd_pcm_release, |
3380 | .poll = snd_pcm_playback_poll, | 3394 | .poll = snd_pcm_playback_poll, |
3381 | .unlocked_ioctl = snd_pcm_playback_ioctl, | 3395 | .unlocked_ioctl = snd_pcm_playback_ioctl, |
@@ -3387,7 +3401,7 @@ struct file_operations snd_pcm_f_ops[2] = { | |||
3387 | .owner = THIS_MODULE, | 3401 | .owner = THIS_MODULE, |
3388 | .read = snd_pcm_read, | 3402 | .read = snd_pcm_read, |
3389 | .readv = snd_pcm_readv, | 3403 | .readv = snd_pcm_readv, |
3390 | .open = snd_pcm_open, | 3404 | .open = snd_pcm_capture_open, |
3391 | .release = snd_pcm_release, | 3405 | .release = snd_pcm_release, |
3392 | .poll = snd_pcm_capture_poll, | 3406 | .poll = snd_pcm_capture_poll, |
3393 | .unlocked_ioctl = snd_pcm_capture_ioctl, | 3407 | .unlocked_ioctl = snd_pcm_capture_ioctl, |
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 7ac77e5ddcb1..e6ee0d813783 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -56,10 +56,22 @@ static int snd_rawmidi_dev_register(struct snd_device *device); | |||
56 | static int snd_rawmidi_dev_disconnect(struct snd_device *device); | 56 | static int snd_rawmidi_dev_disconnect(struct snd_device *device); |
57 | static int snd_rawmidi_dev_unregister(struct snd_device *device); | 57 | static int snd_rawmidi_dev_unregister(struct snd_device *device); |
58 | 58 | ||
59 | static struct snd_rawmidi *snd_rawmidi_devices[SNDRV_CARDS * SNDRV_RAWMIDI_DEVICES]; | 59 | static LIST_HEAD(snd_rawmidi_devices); |
60 | |||
61 | static DECLARE_MUTEX(register_mutex); | 60 | static DECLARE_MUTEX(register_mutex); |
62 | 61 | ||
62 | static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device) | ||
63 | { | ||
64 | struct list_head *p; | ||
65 | struct snd_rawmidi *rawmidi; | ||
66 | |||
67 | list_for_each(p, &snd_rawmidi_devices) { | ||
68 | rawmidi = list_entry(p, struct snd_rawmidi, list); | ||
69 | if (rawmidi->card == card && rawmidi->device == device) | ||
70 | return rawmidi; | ||
71 | } | ||
72 | return NULL; | ||
73 | } | ||
74 | |||
63 | static inline unsigned short snd_rawmidi_file_flags(struct file *file) | 75 | static inline unsigned short snd_rawmidi_file_flags(struct file *file) |
64 | { | 76 | { |
65 | switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) { | 77 | switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) { |
@@ -214,7 +226,7 @@ int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream) | |||
214 | return 0; | 226 | return 0; |
215 | } | 227 | } |
216 | 228 | ||
217 | int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice, | 229 | int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice, |
218 | int mode, struct snd_rawmidi_file * rfile) | 230 | int mode, struct snd_rawmidi_file * rfile) |
219 | { | 231 | { |
220 | struct snd_rawmidi *rmidi; | 232 | struct snd_rawmidi *rmidi; |
@@ -225,7 +237,9 @@ int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice, | |||
225 | 237 | ||
226 | if (rfile) | 238 | if (rfile) |
227 | rfile->input = rfile->output = NULL; | 239 | rfile->input = rfile->output = NULL; |
228 | rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device]; | 240 | down(®ister_mutex); |
241 | rmidi = snd_rawmidi_search(card, device); | ||
242 | up(®ister_mutex); | ||
229 | if (rmidi == NULL) { | 243 | if (rmidi == NULL) { |
230 | err = -ENODEV; | 244 | err = -ENODEV; |
231 | goto __error1; | 245 | goto __error1; |
@@ -368,9 +382,8 @@ int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice, | |||
368 | static int snd_rawmidi_open(struct inode *inode, struct file *file) | 382 | static int snd_rawmidi_open(struct inode *inode, struct file *file) |
369 | { | 383 | { |
370 | int maj = imajor(inode); | 384 | int maj = imajor(inode); |
371 | int cardnum; | ||
372 | struct snd_card *card; | 385 | struct snd_card *card; |
373 | int device, subdevice; | 386 | int subdevice; |
374 | unsigned short fflags; | 387 | unsigned short fflags; |
375 | int err; | 388 | int err; |
376 | struct snd_rawmidi *rmidi; | 389 | struct snd_rawmidi *rmidi; |
@@ -380,27 +393,18 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) | |||
380 | struct snd_ctl_file *kctl; | 393 | struct snd_ctl_file *kctl; |
381 | 394 | ||
382 | if (maj == snd_major) { | 395 | if (maj == snd_major) { |
383 | cardnum = SNDRV_MINOR_CARD(iminor(inode)); | 396 | rmidi = snd_lookup_minor_data(iminor(inode), |
384 | cardnum %= SNDRV_CARDS; | 397 | SNDRV_DEVICE_TYPE_RAWMIDI); |
385 | device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI; | ||
386 | device %= SNDRV_MINOR_RAWMIDIS; | ||
387 | #ifdef CONFIG_SND_OSSEMUL | 398 | #ifdef CONFIG_SND_OSSEMUL |
388 | } else if (maj == SOUND_MAJOR) { | 399 | } else if (maj == SOUND_MAJOR) { |
389 | cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); | 400 | rmidi = snd_lookup_oss_minor_data(iminor(inode), |
390 | cardnum %= SNDRV_CARDS; | 401 | SNDRV_OSS_DEVICE_TYPE_MIDI); |
391 | device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ? | ||
392 | midi_map[cardnum] : amidi_map[cardnum]; | ||
393 | #endif | 402 | #endif |
394 | } else | 403 | } else |
395 | return -ENXIO; | 404 | return -ENXIO; |
396 | 405 | ||
397 | rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device]; | ||
398 | if (rmidi == NULL) | 406 | if (rmidi == NULL) |
399 | return -ENODEV; | 407 | return -ENODEV; |
400 | #ifdef CONFIG_SND_OSSEMUL | ||
401 | if (maj == SOUND_MAJOR && !rmidi->ossreg) | ||
402 | return -ENXIO; | ||
403 | #endif | ||
404 | if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) | 408 | if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) |
405 | return -EINVAL; /* invalid combination */ | 409 | return -EINVAL; /* invalid combination */ |
406 | card = rmidi->card; | 410 | card = rmidi->card; |
@@ -430,7 +434,8 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) | |||
430 | } | 434 | } |
431 | } | 435 | } |
432 | up_read(&card->controls_rwsem); | 436 | up_read(&card->controls_rwsem); |
433 | err = snd_rawmidi_kernel_open(cardnum, device, subdevice, fflags, rawmidi_file); | 437 | err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device, |
438 | subdevice, fflags, rawmidi_file); | ||
434 | if (err >= 0) | 439 | if (err >= 0) |
435 | break; | 440 | break; |
436 | if (err == -EAGAIN) { | 441 | if (err == -EAGAIN) { |
@@ -570,9 +575,10 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info | |||
570 | struct snd_rawmidi_str *pstr; | 575 | struct snd_rawmidi_str *pstr; |
571 | struct snd_rawmidi_substream *substream; | 576 | struct snd_rawmidi_substream *substream; |
572 | struct list_head *list; | 577 | struct list_head *list; |
573 | if (info->device >= SNDRV_RAWMIDI_DEVICES) | 578 | |
574 | return -ENXIO; | 579 | down(®ister_mutex); |
575 | rmidi = snd_rawmidi_devices[card->number * SNDRV_RAWMIDI_DEVICES + info->device]; | 580 | rmidi = snd_rawmidi_search(card, info->device); |
581 | up(®ister_mutex); | ||
576 | if (!rmidi) | 582 | if (!rmidi) |
577 | return -ENXIO; | 583 | return -ENXIO; |
578 | if (info->stream < 0 || info->stream > 1) | 584 | if (info->stream < 0 || info->stream > 1) |
@@ -803,9 +809,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, | |||
803 | unsigned long arg) | 809 | unsigned long arg) |
804 | { | 810 | { |
805 | void __user *argp = (void __user *)arg; | 811 | void __user *argp = (void __user *)arg; |
806 | unsigned int tmp; | ||
807 | 812 | ||
808 | tmp = card->number * SNDRV_RAWMIDI_DEVICES; | ||
809 | switch (cmd) { | 813 | switch (cmd) { |
810 | case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE: | 814 | case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE: |
811 | { | 815 | { |
@@ -813,14 +817,16 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, | |||
813 | 817 | ||
814 | if (get_user(device, (int __user *)argp)) | 818 | if (get_user(device, (int __user *)argp)) |
815 | return -EFAULT; | 819 | return -EFAULT; |
820 | down(®ister_mutex); | ||
816 | device = device < 0 ? 0 : device + 1; | 821 | device = device < 0 ? 0 : device + 1; |
817 | while (device < SNDRV_RAWMIDI_DEVICES) { | 822 | while (device < SNDRV_RAWMIDI_DEVICES) { |
818 | if (snd_rawmidi_devices[tmp + device]) | 823 | if (snd_rawmidi_search(card, device)) |
819 | break; | 824 | break; |
820 | device++; | 825 | device++; |
821 | } | 826 | } |
822 | if (device == SNDRV_RAWMIDI_DEVICES) | 827 | if (device == SNDRV_RAWMIDI_DEVICES) |
823 | device = -1; | 828 | device = -1; |
829 | up(®ister_mutex); | ||
824 | if (put_user(device, (int __user *)argp)) | 830 | if (put_user(device, (int __user *)argp)) |
825 | return -EFAULT; | 831 | return -EFAULT; |
826 | return 0; | 832 | return 0; |
@@ -1493,7 +1499,7 @@ static void snd_rawmidi_dev_seq_free(struct snd_seq_device *device) | |||
1493 | 1499 | ||
1494 | static int snd_rawmidi_dev_register(struct snd_device *device) | 1500 | static int snd_rawmidi_dev_register(struct snd_device *device) |
1495 | { | 1501 | { |
1496 | int idx, err; | 1502 | int err; |
1497 | struct snd_info_entry *entry; | 1503 | struct snd_info_entry *entry; |
1498 | char name[16]; | 1504 | char name[16]; |
1499 | struct snd_rawmidi *rmidi = device->device_data; | 1505 | struct snd_rawmidi *rmidi = device->device_data; |
@@ -1501,25 +1507,24 @@ static int snd_rawmidi_dev_register(struct snd_device *device) | |||
1501 | if (rmidi->device >= SNDRV_RAWMIDI_DEVICES) | 1507 | if (rmidi->device >= SNDRV_RAWMIDI_DEVICES) |
1502 | return -ENOMEM; | 1508 | return -ENOMEM; |
1503 | down(®ister_mutex); | 1509 | down(®ister_mutex); |
1504 | idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device; | 1510 | if (snd_rawmidi_search(rmidi->card, rmidi->device)) { |
1505 | if (snd_rawmidi_devices[idx] != NULL) { | ||
1506 | up(®ister_mutex); | 1511 | up(®ister_mutex); |
1507 | return -EBUSY; | 1512 | return -EBUSY; |
1508 | } | 1513 | } |
1509 | snd_rawmidi_devices[idx] = rmidi; | 1514 | list_add_tail(&rmidi->list, &snd_rawmidi_devices); |
1510 | sprintf(name, "midiC%iD%i", rmidi->card->number, rmidi->device); | 1515 | sprintf(name, "midiC%iD%i", rmidi->card->number, rmidi->device); |
1511 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI, | 1516 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI, |
1512 | rmidi->card, rmidi->device, | 1517 | rmidi->card, rmidi->device, |
1513 | &snd_rawmidi_f_ops, name)) < 0) { | 1518 | &snd_rawmidi_f_ops, rmidi, name)) < 0) { |
1514 | snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device); | 1519 | snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device); |
1515 | snd_rawmidi_devices[idx] = NULL; | 1520 | list_del(&rmidi->list); |
1516 | up(®ister_mutex); | 1521 | up(®ister_mutex); |
1517 | return err; | 1522 | return err; |
1518 | } | 1523 | } |
1519 | if (rmidi->ops && rmidi->ops->dev_register && | 1524 | if (rmidi->ops && rmidi->ops->dev_register && |
1520 | (err = rmidi->ops->dev_register(rmidi)) < 0) { | 1525 | (err = rmidi->ops->dev_register(rmidi)) < 0) { |
1521 | snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); | 1526 | snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); |
1522 | snd_rawmidi_devices[idx] = NULL; | 1527 | list_del(&rmidi->list); |
1523 | up(®ister_mutex); | 1528 | up(®ister_mutex); |
1524 | return err; | 1529 | return err; |
1525 | } | 1530 | } |
@@ -1527,8 +1532,8 @@ static int snd_rawmidi_dev_register(struct snd_device *device) | |||
1527 | rmidi->ossreg = 0; | 1532 | rmidi->ossreg = 0; |
1528 | if ((int)rmidi->device == midi_map[rmidi->card->number]) { | 1533 | if ((int)rmidi->device == midi_map[rmidi->card->number]) { |
1529 | if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, | 1534 | if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, |
1530 | rmidi->card, 0, | 1535 | rmidi->card, 0, &snd_rawmidi_f_ops, |
1531 | &snd_rawmidi_f_ops, name) < 0) { | 1536 | rmidi, name) < 0) { |
1532 | snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0); | 1537 | snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0); |
1533 | } else { | 1538 | } else { |
1534 | rmidi->ossreg++; | 1539 | rmidi->ossreg++; |
@@ -1539,8 +1544,8 @@ static int snd_rawmidi_dev_register(struct snd_device *device) | |||
1539 | } | 1544 | } |
1540 | if ((int)rmidi->device == amidi_map[rmidi->card->number]) { | 1545 | if ((int)rmidi->device == amidi_map[rmidi->card->number]) { |
1541 | if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, | 1546 | if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, |
1542 | rmidi->card, 1, | 1547 | rmidi->card, 1, &snd_rawmidi_f_ops, |
1543 | &snd_rawmidi_f_ops, name) < 0) { | 1548 | rmidi, name) < 0) { |
1544 | snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1); | 1549 | snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1); |
1545 | } else { | 1550 | } else { |
1546 | rmidi->ossreg++; | 1551 | rmidi->ossreg++; |
@@ -1576,24 +1581,20 @@ static int snd_rawmidi_dev_register(struct snd_device *device) | |||
1576 | static int snd_rawmidi_dev_disconnect(struct snd_device *device) | 1581 | static int snd_rawmidi_dev_disconnect(struct snd_device *device) |
1577 | { | 1582 | { |
1578 | struct snd_rawmidi *rmidi = device->device_data; | 1583 | struct snd_rawmidi *rmidi = device->device_data; |
1579 | int idx; | ||
1580 | 1584 | ||
1581 | down(®ister_mutex); | 1585 | down(®ister_mutex); |
1582 | idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device; | 1586 | list_del_init(&rmidi->list); |
1583 | snd_rawmidi_devices[idx] = NULL; | ||
1584 | up(®ister_mutex); | 1587 | up(®ister_mutex); |
1585 | return 0; | 1588 | return 0; |
1586 | } | 1589 | } |
1587 | 1590 | ||
1588 | static int snd_rawmidi_dev_unregister(struct snd_device *device) | 1591 | static int snd_rawmidi_dev_unregister(struct snd_device *device) |
1589 | { | 1592 | { |
1590 | int idx; | ||
1591 | struct snd_rawmidi *rmidi = device->device_data; | 1593 | struct snd_rawmidi *rmidi = device->device_data; |
1592 | 1594 | ||
1593 | snd_assert(rmidi != NULL, return -ENXIO); | 1595 | snd_assert(rmidi != NULL, return -ENXIO); |
1594 | down(®ister_mutex); | 1596 | down(®ister_mutex); |
1595 | idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device; | 1597 | list_del(&rmidi->list); |
1596 | snd_rawmidi_devices[idx] = NULL; | ||
1597 | if (rmidi->proc_entry) { | 1598 | if (rmidi->proc_entry) { |
1598 | snd_info_unregister(rmidi->proc_entry); | 1599 | snd_info_unregister(rmidi->proc_entry); |
1599 | rmidi->proc_entry = NULL; | 1600 | rmidi->proc_entry = NULL; |
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c index 61c0a41376fd..4b51ab56507b 100644 --- a/sound/core/seq/oss/seq_oss.c +++ b/sound/core/seq/oss/seq_oss.c | |||
@@ -225,7 +225,7 @@ register_device(void) | |||
225 | down(®ister_mutex); | 225 | down(®ister_mutex); |
226 | if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, | 226 | if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, |
227 | NULL, 0, | 227 | NULL, 0, |
228 | &seq_oss_f_ops, | 228 | &seq_oss_f_ops, NULL, |
229 | SNDRV_SEQ_OSS_DEVNAME)) < 0) { | 229 | SNDRV_SEQ_OSS_DEVNAME)) < 0) { |
230 | snd_printk(KERN_ERR "can't register device seq\n"); | 230 | snd_printk(KERN_ERR "can't register device seq\n"); |
231 | up(®ister_mutex); | 231 | up(®ister_mutex); |
@@ -233,7 +233,7 @@ register_device(void) | |||
233 | } | 233 | } |
234 | if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, | 234 | if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC, |
235 | NULL, 0, | 235 | NULL, 0, |
236 | &seq_oss_f_ops, | 236 | &seq_oss_f_ops, NULL, |
237 | SNDRV_SEQ_OSS_DEVNAME)) < 0) { | 237 | SNDRV_SEQ_OSS_DEVNAME)) < 0) { |
238 | snd_printk(KERN_ERR "can't register device music\n"); | 238 | snd_printk(KERN_ERR "can't register device music\n"); |
239 | snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0); | 239 | snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0); |
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 087fdf32732b..c8bd37ee8375 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c | |||
@@ -2531,7 +2531,7 @@ int __init snd_sequencer_device_init(void) | |||
2531 | return -ERESTARTSYS; | 2531 | return -ERESTARTSYS; |
2532 | 2532 | ||
2533 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0, | 2533 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0, |
2534 | &snd_seq_f_ops, "seq")) < 0) { | 2534 | &snd_seq_f_ops, NULL, "seq")) < 0) { |
2535 | up(®ister_mutex); | 2535 | up(®ister_mutex); |
2536 | return err; | 2536 | return err; |
2537 | } | 2537 | } |
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index f88d2e3ee66e..0a65eb2f976b 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c | |||
@@ -183,7 +183,10 @@ static int midisynth_subscribe(void *private_data, struct snd_seq_port_subscribe | |||
183 | struct snd_rawmidi_params params; | 183 | struct snd_rawmidi_params params; |
184 | 184 | ||
185 | /* open midi port */ | 185 | /* open midi port */ |
186 | if ((err = snd_rawmidi_kernel_open(msynth->card->number, msynth->device, msynth->subdevice, SNDRV_RAWMIDI_LFLG_INPUT, &msynth->input_rfile)) < 0) { | 186 | if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device, |
187 | msynth->subdevice, | ||
188 | SNDRV_RAWMIDI_LFLG_INPUT, | ||
189 | &msynth->input_rfile)) < 0) { | ||
187 | snd_printd("midi input open failed!!!\n"); | 190 | snd_printd("midi input open failed!!!\n"); |
188 | return err; | 191 | return err; |
189 | } | 192 | } |
@@ -221,7 +224,10 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info | |||
221 | struct snd_rawmidi_params params; | 224 | struct snd_rawmidi_params params; |
222 | 225 | ||
223 | /* open midi port */ | 226 | /* open midi port */ |
224 | if ((err = snd_rawmidi_kernel_open(msynth->card->number, msynth->device, msynth->subdevice, SNDRV_RAWMIDI_LFLG_OUTPUT, &msynth->output_rfile)) < 0) { | 227 | if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device, |
228 | msynth->subdevice, | ||
229 | SNDRV_RAWMIDI_LFLG_OUTPUT, | ||
230 | &msynth->output_rfile)) < 0) { | ||
225 | snd_printd("midi output open failed!!!\n"); | 231 | snd_printd("midi output open failed!!!\n"); |
226 | return err; | 232 | return err; |
227 | } | 233 | } |
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); |
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index afbfd8df1298..b9e89cac4c5d 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c | |||
@@ -38,9 +38,25 @@ | |||
38 | #define SNDRV_OSS_MINORS 128 | 38 | #define SNDRV_OSS_MINORS 128 |
39 | 39 | ||
40 | static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; | 40 | static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS]; |
41 | |||
42 | static DECLARE_MUTEX(sound_oss_mutex); | 41 | static DECLARE_MUTEX(sound_oss_mutex); |
43 | 42 | ||
43 | void *snd_lookup_oss_minor_data(unsigned int minor, int type) | ||
44 | { | ||
45 | struct snd_minor *mreg; | ||
46 | void *private_data; | ||
47 | |||
48 | if (minor > ARRAY_SIZE(snd_oss_minors)) | ||
49 | return NULL; | ||
50 | down(&sound_oss_mutex); | ||
51 | mreg = snd_oss_minors[minor]; | ||
52 | if (mreg && mreg->type == type) | ||
53 | private_data = mreg->private_data; | ||
54 | else | ||
55 | private_data = NULL; | ||
56 | up(&sound_oss_mutex); | ||
57 | return private_data; | ||
58 | } | ||
59 | |||
44 | static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) | 60 | static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) |
45 | { | 61 | { |
46 | int minor; | 62 | int minor; |
@@ -78,7 +94,8 @@ static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev) | |||
78 | } | 94 | } |
79 | 95 | ||
80 | int snd_register_oss_device(int type, struct snd_card *card, int dev, | 96 | int snd_register_oss_device(int type, struct snd_card *card, int dev, |
81 | struct file_operations *f_ops, const char *name) | 97 | struct file_operations *f_ops, void *private_data, |
98 | const char *name) | ||
82 | { | 99 | { |
83 | int minor = snd_oss_kernel_minor(type, card, dev); | 100 | int minor = snd_oss_kernel_minor(type, card, dev); |
84 | int minor_unit; | 101 | int minor_unit; |
@@ -97,6 +114,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, | |||
97 | preg->card = card ? card->number : -1; | 114 | preg->card = card ? card->number : -1; |
98 | preg->device = dev; | 115 | preg->device = dev; |
99 | preg->f_ops = f_ops; | 116 | preg->f_ops = f_ops; |
117 | preg->private_data = private_data; | ||
100 | down(&sound_oss_mutex); | 118 | down(&sound_oss_mutex); |
101 | snd_oss_minors[minor] = preg; | 119 | snd_oss_minors[minor] = preg; |
102 | minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); | 120 | minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); |
@@ -121,6 +139,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, | |||
121 | carddev); | 139 | carddev); |
122 | if (register2 != track2) | 140 | if (register2 != track2) |
123 | goto __end; | 141 | goto __end; |
142 | snd_oss_minors[track2] = preg; | ||
124 | } | 143 | } |
125 | up(&sound_oss_mutex); | 144 | up(&sound_oss_mutex); |
126 | return 0; | 145 | return 0; |
@@ -163,8 +182,10 @@ int snd_unregister_oss_device(int type, struct snd_card *card, int dev) | |||
163 | track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1); | 182 | track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1); |
164 | break; | 183 | break; |
165 | } | 184 | } |
166 | if (track2 >= 0) | 185 | if (track2 >= 0) { |
167 | unregister_sound_special(track2); | 186 | unregister_sound_special(track2); |
187 | snd_oss_minors[track2] = NULL; | ||
188 | } | ||
168 | snd_oss_minors[minor] = NULL; | 189 | snd_oss_minors[minor] = NULL; |
169 | up(&sound_oss_mutex); | 190 | up(&sound_oss_mutex); |
170 | kfree(mptr); | 191 | kfree(mptr); |
diff --git a/sound/core/timer.c b/sound/core/timer.c index a7bcb04263cb..c62dbacdca13 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -1952,8 +1952,8 @@ static int __init alsa_timer_init(void) | |||
1952 | if ((err = snd_timer_register_system()) < 0) | 1952 | if ((err = snd_timer_register_system()) < 0) |
1953 | snd_printk(KERN_ERR "unable to register system timer (%i)\n", | 1953 | snd_printk(KERN_ERR "unable to register system timer (%i)\n", |
1954 | err); | 1954 | err); |
1955 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, | 1955 | if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0, |
1956 | NULL, 0, &snd_timer_f_ops, "timer")) < 0) | 1956 | &snd_timer_f_ops, NULL, "timer")) < 0) |
1957 | snd_printk(KERN_ERR "unable to register timer device (%i)\n", | 1957 | snd_printk(KERN_ERR "unable to register timer device (%i)\n", |
1958 | err); | 1958 | err); |
1959 | return 0; | 1959 | return 0; |