diff options
-rw-r--r-- | include/sound/minors.h | 2 | ||||
-rw-r--r-- | include/sound/pcm.h | 9 | ||||
-rw-r--r-- | sound/core/pcm.c | 50 | ||||
-rw-r--r-- | sound/core/sound.c | 2 |
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 { | |||
416 | struct snd_pcm { | 421 | struct 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); | |||
42 | static int snd_pcm_dev_register(struct snd_device *device); | 42 | 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 | 44 | ||
45 | static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device) | 45 | static 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 | ||
56 | static 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 | |||
69 | static 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 | |||
56 | static int snd_pcm_control_ioctl(struct snd_card *card, | 87 | static 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(®ister_mutex); | 98 | mutex_lock(®ister_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(®ister_mutex); | 100 | mutex_unlock(®ister_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(®ister_mutex); | 124 | mutex_lock(®ister_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(®ister_mutex); | 957 | mutex_lock(®ister_mutex); |
934 | if (snd_pcm_search(pcm->card, pcm->device)) { | 958 | err = snd_pcm_add(pcm); |
959 | if (err) { | ||
935 | mutex_unlock(®ister_mutex); | 960 | mutex_unlock(®ister_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 | |||
39 | static int major = CONFIG_SND_MAJOR; | 37 | static int major = CONFIG_SND_MAJOR; |
40 | int snd_major; | 38 | int snd_major; |
41 | EXPORT_SYMBOL(snd_major); | 39 | EXPORT_SYMBOL(snd_major); |