aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/minors.h2
-rw-r--r--include/sound/pcm.h9
-rw-r--r--sound/core/pcm.c50
-rw-r--r--sound/core/sound.c2
4 files changed, 46 insertions, 17 deletions
diff --git a/include/sound/minors.h b/include/sound/minors.h
index 46bcd2023ed8..a81798ab73ed 100644
--- a/include/sound/minors.h
+++ b/include/sound/minors.h
@@ -21,6 +21,8 @@
21 * 21 *
22 */ 22 */
23 23
24#define SNDRV_OS_MINORS 256
25
24#define SNDRV_MINOR_DEVICES 32 26#define SNDRV_MINOR_DEVICES 32
25#define SNDRV_MINOR_CARD(minor) ((minor) >> 5) 27#define SNDRV_MINOR_CARD(minor) ((minor) >> 5)
26#define SNDRV_MINOR_DEVICE(minor) ((minor) & 0x001f) 28#define SNDRV_MINOR_DEVICE(minor) ((minor) & 0x001f)
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 51d58ccda2d8..5dd8ea4a8c4b 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -25,6 +25,7 @@
25 25
26#include <sound/asound.h> 26#include <sound/asound.h>
27#include <sound/memalloc.h> 27#include <sound/memalloc.h>
28#include <sound/minors.h>
28#include <linux/poll.h> 29#include <linux/poll.h>
29#include <linux/mm.h> 30#include <linux/mm.h>
30#include <linux/bitops.h> 31#include <linux/bitops.h>
@@ -84,7 +85,11 @@ struct snd_pcm_ops {
84 * 85 *
85 */ 86 */
86 87
87#define SNDRV_PCM_DEVICES 8 88#if defined(CONFIG_SND_DYNAMIC_MINORS)
89#define SNDRV_PCM_DEVICES (SNDRV_OS_MINORS-2)
90#else
91#define SNDRV_PCM_DEVICES 8
92#endif
88 93
89#define SNDRV_PCM_IOCTL1_FALSE ((void *)0) 94#define SNDRV_PCM_IOCTL1_FALSE ((void *)0)
90#define SNDRV_PCM_IOCTL1_TRUE ((void *)1) 95#define SNDRV_PCM_IOCTL1_TRUE ((void *)1)
@@ -416,7 +421,7 @@ struct snd_pcm_str {
416struct snd_pcm { 421struct snd_pcm {
417 struct snd_card *card; 422 struct snd_card *card;
418 struct list_head list; 423 struct list_head list;
419 unsigned int device; /* device number */ 424 int device; /* device number */
420 unsigned int info_flags; 425 unsigned int info_flags;
421 unsigned short dev_class; 426 unsigned short dev_class;
422 unsigned short dev_subclass; 427 unsigned short dev_subclass;
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index ece25c718e95..517388b2eba9 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -42,7 +42,7 @@ static int snd_pcm_dev_free(struct snd_device *device);
42static int snd_pcm_dev_register(struct snd_device *device); 42static int snd_pcm_dev_register(struct snd_device *device);
43static int snd_pcm_dev_disconnect(struct snd_device *device); 43static int snd_pcm_dev_disconnect(struct snd_device *device);
44 44
45static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device) 45static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)
46{ 46{
47 struct snd_pcm *pcm; 47 struct snd_pcm *pcm;
48 48
@@ -53,6 +53,37 @@ static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device)
53 return NULL; 53 return NULL;
54} 54}
55 55
56static int snd_pcm_next(struct snd_card *card, int device)
57{
58 struct snd_pcm *pcm;
59
60 list_for_each_entry(pcm, &snd_pcm_devices, list) {
61 if (pcm->card == card && pcm->device > device)
62 return pcm->device;
63 else if (pcm->card->number > card->number)
64 return -1;
65 }
66 return -1;
67}
68
69static int snd_pcm_add(struct snd_pcm *newpcm)
70{
71 struct snd_pcm *pcm;
72
73 list_for_each_entry(pcm, &snd_pcm_devices, list) {
74 if (pcm->card == newpcm->card && pcm->device == newpcm->device)
75 return -EBUSY;
76 if (pcm->card->number > newpcm->card->number ||
77 (pcm->card == newpcm->card &&
78 pcm->device > newpcm->device)) {
79 list_add(&newpcm->list, pcm->list.prev);
80 return 0;
81 }
82 }
83 list_add_tail(&newpcm->list, &snd_pcm_devices);
84 return 0;
85}
86
56static int snd_pcm_control_ioctl(struct snd_card *card, 87static int snd_pcm_control_ioctl(struct snd_card *card,
57 struct snd_ctl_file *control, 88 struct snd_ctl_file *control,
58 unsigned int cmd, unsigned long arg) 89 unsigned int cmd, unsigned long arg)
@@ -65,14 +96,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
65 if (get_user(device, (int __user *)arg)) 96 if (get_user(device, (int __user *)arg))
66 return -EFAULT; 97 return -EFAULT;
67 mutex_lock(&register_mutex); 98 mutex_lock(&register_mutex);
68 device = device < 0 ? 0 : device + 1; 99 device = snd_pcm_next(card, device);
69 while (device < SNDRV_PCM_DEVICES) {
70 if (snd_pcm_search(card, device))
71 break;
72 device++;
73 }
74 if (device == SNDRV_PCM_DEVICES)
75 device = -1;
76 mutex_unlock(&register_mutex); 100 mutex_unlock(&register_mutex);
77 if (put_user(device, (int __user *)arg)) 101 if (put_user(device, (int __user *)arg))
78 return -EFAULT; 102 return -EFAULT;
@@ -98,7 +122,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
98 if (get_user(subdevice, &info->subdevice)) 122 if (get_user(subdevice, &info->subdevice))
99 return -EFAULT; 123 return -EFAULT;
100 mutex_lock(&register_mutex); 124 mutex_lock(&register_mutex);
101 pcm = snd_pcm_search(card, device); 125 pcm = snd_pcm_get(card, device);
102 if (pcm == NULL) { 126 if (pcm == NULL) {
103 err = -ENXIO; 127 err = -ENXIO;
104 goto _error; 128 goto _error;
@@ -931,11 +955,11 @@ static int snd_pcm_dev_register(struct snd_device *device)
931 955
932 snd_assert(pcm != NULL && device != NULL, return -ENXIO); 956 snd_assert(pcm != NULL && device != NULL, return -ENXIO);
933 mutex_lock(&register_mutex); 957 mutex_lock(&register_mutex);
934 if (snd_pcm_search(pcm->card, pcm->device)) { 958 err = snd_pcm_add(pcm);
959 if (err) {
935 mutex_unlock(&register_mutex); 960 mutex_unlock(&register_mutex);
936 return -EBUSY; 961 return err;
937 } 962 }
938 list_add_tail(&pcm->list, &snd_pcm_devices);
939 for (cidx = 0; cidx < 2; cidx++) { 963 for (cidx = 0; cidx < 2; cidx++) {
940 int devtype = -1; 964 int devtype = -1;
941 if (pcm->streams[cidx].substream == NULL) 965 if (pcm->streams[cidx].substream == NULL)
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 1003ae375d47..838dd9ee957c 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -34,8 +34,6 @@
34#include <linux/kmod.h> 34#include <linux/kmod.h>
35#include <linux/mutex.h> 35#include <linux/mutex.h>
36 36
37#define SNDRV_OS_MINORS 256
38
39static int major = CONFIG_SND_MAJOR; 37static int major = CONFIG_SND_MAJOR;
40int snd_major; 38int snd_major;
41EXPORT_SYMBOL(snd_major); 39EXPORT_SYMBOL(snd_major);