diff options
Diffstat (limited to 'sound/core/pcm.c')
-rw-r--r-- | sound/core/pcm.c | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 28ca61eb0b0d..3da6a38c2d0f 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/time.h> | 25 | #include <linux/time.h> |
26 | #include <linux/mutex.h> | ||
26 | #include <sound/core.h> | 27 | #include <sound/core.h> |
27 | #include <sound/minors.h> | 28 | #include <sound/minors.h> |
28 | #include <sound/pcm.h> | 29 | #include <sound/pcm.h> |
@@ -35,7 +36,7 @@ MODULE_LICENSE("GPL"); | |||
35 | 36 | ||
36 | static LIST_HEAD(snd_pcm_devices); | 37 | static LIST_HEAD(snd_pcm_devices); |
37 | static LIST_HEAD(snd_pcm_notify_list); | 38 | static LIST_HEAD(snd_pcm_notify_list); |
38 | static DECLARE_MUTEX(register_mutex); | 39 | static DEFINE_MUTEX(register_mutex); |
39 | 40 | ||
40 | static int snd_pcm_free(struct snd_pcm *pcm); | 41 | static int snd_pcm_free(struct snd_pcm *pcm); |
41 | static int snd_pcm_dev_free(struct snd_device *device); | 42 | static int snd_pcm_dev_free(struct snd_device *device); |
@@ -67,7 +68,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
67 | 68 | ||
68 | if (get_user(device, (int __user *)arg)) | 69 | if (get_user(device, (int __user *)arg)) |
69 | return -EFAULT; | 70 | return -EFAULT; |
70 | down(®ister_mutex); | 71 | mutex_lock(®ister_mutex); |
71 | device = device < 0 ? 0 : device + 1; | 72 | device = device < 0 ? 0 : device + 1; |
72 | while (device < SNDRV_PCM_DEVICES) { | 73 | while (device < SNDRV_PCM_DEVICES) { |
73 | if (snd_pcm_search(card, device)) | 74 | if (snd_pcm_search(card, device)) |
@@ -76,7 +77,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
76 | } | 77 | } |
77 | if (device == SNDRV_PCM_DEVICES) | 78 | if (device == SNDRV_PCM_DEVICES) |
78 | device = -1; | 79 | device = -1; |
79 | up(®ister_mutex); | 80 | mutex_unlock(®ister_mutex); |
80 | if (put_user(device, (int __user *)arg)) | 81 | if (put_user(device, (int __user *)arg)) |
81 | return -EFAULT; | 82 | return -EFAULT; |
82 | return 0; | 83 | return 0; |
@@ -100,7 +101,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
100 | return -EINVAL; | 101 | return -EINVAL; |
101 | if (get_user(subdevice, &info->subdevice)) | 102 | if (get_user(subdevice, &info->subdevice)) |
102 | return -EFAULT; | 103 | return -EFAULT; |
103 | down(®ister_mutex); | 104 | mutex_lock(®ister_mutex); |
104 | pcm = snd_pcm_search(card, device); | 105 | pcm = snd_pcm_search(card, device); |
105 | if (pcm == NULL) { | 106 | if (pcm == NULL) { |
106 | err = -ENXIO; | 107 | err = -ENXIO; |
@@ -125,7 +126,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
125 | } | 126 | } |
126 | err = snd_pcm_info_user(substream, info); | 127 | err = snd_pcm_info_user(substream, info); |
127 | _error: | 128 | _error: |
128 | up(®ister_mutex); | 129 | mutex_unlock(®ister_mutex); |
129 | return err; | 130 | return err; |
130 | } | 131 | } |
131 | case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE: | 132 | case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE: |
@@ -140,6 +141,9 @@ static int snd_pcm_control_ioctl(struct snd_card *card, | |||
140 | } | 141 | } |
141 | return -ENOIOCTLCMD; | 142 | return -ENOIOCTLCMD; |
142 | } | 143 | } |
144 | |||
145 | #if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS) | ||
146 | |||
143 | #define STATE(v) [SNDRV_PCM_STATE_##v] = #v | 147 | #define STATE(v) [SNDRV_PCM_STATE_##v] = #v |
144 | #define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v | 148 | #define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v |
145 | #define READY(v) [SNDRV_PCM_READY_##v] = #v | 149 | #define READY(v) [SNDRV_PCM_READY_##v] = #v |
@@ -197,7 +201,6 @@ const char *snd_pcm_format_name(snd_pcm_format_t format) | |||
197 | return snd_pcm_format_names[format]; | 201 | return snd_pcm_format_names[format]; |
198 | } | 202 | } |
199 | 203 | ||
200 | #ifdef CONFIG_PROC_FS | ||
201 | static char *snd_pcm_stream_names[] = { | 204 | static char *snd_pcm_stream_names[] = { |
202 | STREAM(PLAYBACK), | 205 | STREAM(PLAYBACK), |
203 | STREAM(CAPTURE), | 206 | STREAM(CAPTURE), |
@@ -260,6 +263,7 @@ static const char *snd_pcm_state_name(snd_pcm_state_t state) | |||
260 | 263 | ||
261 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) | 264 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) |
262 | #include <linux/soundcard.h> | 265 | #include <linux/soundcard.h> |
266 | |||
263 | static const char *snd_pcm_oss_format_name(int format) | 267 | static const char *snd_pcm_oss_format_name(int format) |
264 | { | 268 | { |
265 | switch (format) { | 269 | switch (format) { |
@@ -622,7 +626,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) | |||
622 | struct snd_pcm_substream *substream, *prev; | 626 | struct snd_pcm_substream *substream, *prev; |
623 | 627 | ||
624 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) | 628 | #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) |
625 | init_MUTEX(&pstr->oss.setup_mutex); | 629 | mutex_init(&pstr->oss.setup_mutex); |
626 | #endif | 630 | #endif |
627 | pstr->stream = stream; | 631 | pstr->stream = stream; |
628 | pstr->pcm = pcm; | 632 | pstr->pcm = pcm; |
@@ -716,7 +720,7 @@ int snd_pcm_new(struct snd_card *card, char *id, int device, | |||
716 | snd_pcm_free(pcm); | 720 | snd_pcm_free(pcm); |
717 | return err; | 721 | return err; |
718 | } | 722 | } |
719 | init_MUTEX(&pcm->open_mutex); | 723 | mutex_init(&pcm->open_mutex); |
720 | init_waitqueue_head(&pcm->open_wait); | 724 | init_waitqueue_head(&pcm->open_wait); |
721 | if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) { | 725 | if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) { |
722 | snd_pcm_free(pcm); | 726 | snd_pcm_free(pcm); |
@@ -902,9 +906,9 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
902 | struct snd_pcm *pcm = device->device_data; | 906 | struct snd_pcm *pcm = device->device_data; |
903 | 907 | ||
904 | snd_assert(pcm != NULL && device != NULL, return -ENXIO); | 908 | snd_assert(pcm != NULL && device != NULL, return -ENXIO); |
905 | down(®ister_mutex); | 909 | mutex_lock(®ister_mutex); |
906 | if (snd_pcm_search(pcm->card, pcm->device)) { | 910 | if (snd_pcm_search(pcm->card, pcm->device)) { |
907 | up(®ister_mutex); | 911 | mutex_unlock(®ister_mutex); |
908 | return -EBUSY; | 912 | return -EBUSY; |
909 | } | 913 | } |
910 | list_add_tail(&pcm->list, &snd_pcm_devices); | 914 | list_add_tail(&pcm->list, &snd_pcm_devices); |
@@ -928,7 +932,7 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
928 | pcm, str)) < 0) | 932 | pcm, str)) < 0) |
929 | { | 933 | { |
930 | list_del(&pcm->list); | 934 | list_del(&pcm->list); |
931 | up(®ister_mutex); | 935 | mutex_unlock(®ister_mutex); |
932 | return err; | 936 | return err; |
933 | } | 937 | } |
934 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) | 938 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) |
@@ -939,7 +943,7 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
939 | notify = list_entry(list, struct snd_pcm_notify, list); | 943 | notify = list_entry(list, struct snd_pcm_notify, list); |
940 | notify->n_register(pcm); | 944 | notify->n_register(pcm); |
941 | } | 945 | } |
942 | up(®ister_mutex); | 946 | mutex_unlock(®ister_mutex); |
943 | return 0; | 947 | return 0; |
944 | } | 948 | } |
945 | 949 | ||
@@ -950,7 +954,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) | |||
950 | struct snd_pcm_substream *substream; | 954 | struct snd_pcm_substream *substream; |
951 | int cidx; | 955 | int cidx; |
952 | 956 | ||
953 | down(®ister_mutex); | 957 | mutex_lock(®ister_mutex); |
954 | list_del_init(&pcm->list); | 958 | list_del_init(&pcm->list); |
955 | for (cidx = 0; cidx < 2; cidx++) | 959 | for (cidx = 0; cidx < 2; cidx++) |
956 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) | 960 | for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) |
@@ -961,7 +965,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) | |||
961 | notify = list_entry(list, struct snd_pcm_notify, list); | 965 | notify = list_entry(list, struct snd_pcm_notify, list); |
962 | notify->n_disconnect(pcm); | 966 | notify->n_disconnect(pcm); |
963 | } | 967 | } |
964 | up(®ister_mutex); | 968 | mutex_unlock(®ister_mutex); |
965 | return 0; | 969 | return 0; |
966 | } | 970 | } |
967 | 971 | ||
@@ -973,7 +977,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device) | |||
973 | struct snd_pcm *pcm = device->device_data; | 977 | struct snd_pcm *pcm = device->device_data; |
974 | 978 | ||
975 | snd_assert(pcm != NULL, return -ENXIO); | 979 | snd_assert(pcm != NULL, return -ENXIO); |
976 | down(®ister_mutex); | 980 | mutex_lock(®ister_mutex); |
977 | list_del(&pcm->list); | 981 | list_del(&pcm->list); |
978 | for (cidx = 0; cidx < 2; cidx++) { | 982 | for (cidx = 0; cidx < 2; cidx++) { |
979 | devtype = -1; | 983 | devtype = -1; |
@@ -994,7 +998,7 @@ static int snd_pcm_dev_unregister(struct snd_device *device) | |||
994 | notify = list_entry(list, struct snd_pcm_notify, list); | 998 | notify = list_entry(list, struct snd_pcm_notify, list); |
995 | notify->n_unregister(pcm); | 999 | notify->n_unregister(pcm); |
996 | } | 1000 | } |
997 | up(®ister_mutex); | 1001 | mutex_unlock(®ister_mutex); |
998 | return snd_pcm_free(pcm); | 1002 | return snd_pcm_free(pcm); |
999 | } | 1003 | } |
1000 | 1004 | ||
@@ -1003,7 +1007,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) | |||
1003 | struct list_head *p; | 1007 | struct list_head *p; |
1004 | 1008 | ||
1005 | snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL); | 1009 | snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL); |
1006 | down(®ister_mutex); | 1010 | mutex_lock(®ister_mutex); |
1007 | if (nfree) { | 1011 | if (nfree) { |
1008 | list_del(¬ify->list); | 1012 | list_del(¬ify->list); |
1009 | list_for_each(p, &snd_pcm_devices) | 1013 | list_for_each(p, &snd_pcm_devices) |
@@ -1014,7 +1018,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) | |||
1014 | list_for_each(p, &snd_pcm_devices) | 1018 | list_for_each(p, &snd_pcm_devices) |
1015 | notify->n_register(list_entry(p, struct snd_pcm, list)); | 1019 | notify->n_register(list_entry(p, struct snd_pcm, list)); |
1016 | } | 1020 | } |
1017 | up(®ister_mutex); | 1021 | mutex_unlock(®ister_mutex); |
1018 | return 0; | 1022 | return 0; |
1019 | } | 1023 | } |
1020 | 1024 | ||
@@ -1029,7 +1033,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry, | |||
1029 | struct list_head *p; | 1033 | struct list_head *p; |
1030 | struct snd_pcm *pcm; | 1034 | struct snd_pcm *pcm; |
1031 | 1035 | ||
1032 | down(®ister_mutex); | 1036 | mutex_lock(®ister_mutex); |
1033 | list_for_each(p, &snd_pcm_devices) { | 1037 | list_for_each(p, &snd_pcm_devices) { |
1034 | pcm = list_entry(p, struct snd_pcm, list); | 1038 | pcm = list_entry(p, struct snd_pcm, list); |
1035 | snd_iprintf(buffer, "%02i-%02i: %s : %s", | 1039 | snd_iprintf(buffer, "%02i-%02i: %s : %s", |
@@ -1042,7 +1046,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry, | |||
1042 | pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count); | 1046 | pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count); |
1043 | snd_iprintf(buffer, "\n"); | 1047 | snd_iprintf(buffer, "\n"); |
1044 | } | 1048 | } |
1045 | up(®ister_mutex); | 1049 | mutex_unlock(®ister_mutex); |
1046 | } | 1050 | } |
1047 | 1051 | ||
1048 | static struct snd_info_entry *snd_pcm_proc_entry = NULL; | 1052 | static struct snd_info_entry *snd_pcm_proc_entry = NULL; |
@@ -1101,7 +1105,6 @@ EXPORT_SYMBOL(snd_pcm_new_stream); | |||
1101 | EXPORT_SYMBOL(snd_pcm_notify); | 1105 | EXPORT_SYMBOL(snd_pcm_notify); |
1102 | EXPORT_SYMBOL(snd_pcm_open_substream); | 1106 | EXPORT_SYMBOL(snd_pcm_open_substream); |
1103 | EXPORT_SYMBOL(snd_pcm_release_substream); | 1107 | EXPORT_SYMBOL(snd_pcm_release_substream); |
1104 | EXPORT_SYMBOL(snd_pcm_format_name); | ||
1105 | /* pcm_native.c */ | 1108 | /* pcm_native.c */ |
1106 | EXPORT_SYMBOL(snd_pcm_link_rwlock); | 1109 | EXPORT_SYMBOL(snd_pcm_link_rwlock); |
1107 | #ifdef CONFIG_PM | 1110 | #ifdef CONFIG_PM |