diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 12:41:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-20 12:41:44 -0400 |
commit | 7f06a8b26aba1dc03b42272dc0089a800372c575 (patch) | |
tree | 7c67198f83d069eb13fd417e022d111b7e4c82a1 /sound/core | |
parent | c3ad33c9bcb6616999953af76f16318120fe3691 (diff) | |
parent | d71f4cece4bd97d05592836202fc04ff2e7817e3 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (250 commits)
ALSA: hda: Storage class should be before const qualifier
ASoC: tpa6130a2: Remove CPVSS and HPVdd supplies
ASoC: tpa6130a2: Define output pins with SND_SOC_DAPM_OUTPUT
ASoC: sdp4430 - add sdp4430 pcm ops to DAI.
ASoC: TWL6040: Enable earphone path in codec
ASoC: SDP4430: Add support for Earphone speaker
ASoC: SDP4430: Add sdp4430 machine driver
ASoC: tlv320dac33: Avoid powering off while in BIAS_OFF
ASoC: tlv320dac33: Use dev_dbg in dac33_hard_power function
ALSA: sound/pci/asihpi: Use kzalloc
ALSA: hdmi - dont fail on extra nodes
ALSA: intelhdmi - add id for the CougarPoint chipset
ALSA: intelhdmi - user friendly codec name
ALSA: intelhdmi - add dependency on SND_DYNAMIC_MINORS
ALSA: asihpi: incorrect range check
ALSA: asihpi: testing the wrong variable
ALSA: es1688: add pedantic range checks
ARM: McBSP: Add support for omap4 in McBSP driver
ARM: McBSP: Fix request for irq in OMAP4
OMAP: McBSP: Add 32-bit mode support
...
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/control.c | 5 | ||||
-rw-r--r-- | sound/core/info.c | 74 | ||||
-rw-r--r-- | sound/core/jack.c | 71 | ||||
-rw-r--r-- | sound/core/oss/mixer_oss.c | 5 | ||||
-rw-r--r-- | sound/core/oss/pcm_oss.c | 5 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 49 | ||||
-rw-r--r-- | sound/core/rawmidi.c | 5 | ||||
-rw-r--r-- | sound/core/seq/seq_clientmgr.c | 6 | ||||
-rw-r--r-- | sound/core/sound.c | 73 | ||||
-rw-r--r-- | sound/core/timer.c | 6 |
10 files changed, 210 insertions, 89 deletions
diff --git a/sound/core/control.c b/sound/core/control.c index 439ce64f9d82..070aab490191 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -50,6 +50,10 @@ static int snd_ctl_open(struct inode *inode, struct file *file) | |||
50 | struct snd_ctl_file *ctl; | 50 | struct snd_ctl_file *ctl; |
51 | int err; | 51 | int err; |
52 | 52 | ||
53 | err = nonseekable_open(inode, file); | ||
54 | if (err < 0) | ||
55 | return err; | ||
56 | |||
53 | card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL); | 57 | card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL); |
54 | if (!card) { | 58 | if (!card) { |
55 | err = -ENODEV; | 59 | err = -ENODEV; |
@@ -1388,6 +1392,7 @@ static const struct file_operations snd_ctl_f_ops = | |||
1388 | .read = snd_ctl_read, | 1392 | .read = snd_ctl_read, |
1389 | .open = snd_ctl_open, | 1393 | .open = snd_ctl_open, |
1390 | .release = snd_ctl_release, | 1394 | .release = snd_ctl_release, |
1395 | .llseek = no_llseek, | ||
1391 | .poll = snd_ctl_poll, | 1396 | .poll = snd_ctl_poll, |
1392 | .unlocked_ioctl = snd_ctl_ioctl, | 1397 | .unlocked_ioctl = snd_ctl_ioctl, |
1393 | .compat_ioctl = snd_ctl_ioctl_compat, | 1398 | .compat_ioctl = snd_ctl_ioctl_compat, |
diff --git a/sound/core/info.c b/sound/core/info.c index cc4a53d4b7f8..b70564ed8b37 100644 --- a/sound/core/info.c +++ b/sound/core/info.c | |||
@@ -164,40 +164,44 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) | |||
164 | { | 164 | { |
165 | struct snd_info_private_data *data; | 165 | struct snd_info_private_data *data; |
166 | struct snd_info_entry *entry; | 166 | struct snd_info_entry *entry; |
167 | loff_t ret; | 167 | loff_t ret = -EINVAL, size; |
168 | 168 | ||
169 | data = file->private_data; | 169 | data = file->private_data; |
170 | entry = data->entry; | 170 | entry = data->entry; |
171 | lock_kernel(); | 171 | mutex_lock(&entry->access); |
172 | switch (entry->content) { | 172 | if (entry->content == SNDRV_INFO_CONTENT_DATA && |
173 | case SNDRV_INFO_CONTENT_TEXT: | 173 | entry->c.ops->llseek) { |
174 | switch (orig) { | 174 | offset = entry->c.ops->llseek(entry, |
175 | case SEEK_SET: | 175 | data->file_private_data, |
176 | file->f_pos = offset; | 176 | file, offset, orig); |
177 | ret = file->f_pos; | 177 | goto out; |
178 | goto out; | 178 | } |
179 | case SEEK_CUR: | 179 | if (entry->content == SNDRV_INFO_CONTENT_DATA) |
180 | file->f_pos += offset; | 180 | size = entry->size; |
181 | ret = file->f_pos; | 181 | else |
182 | goto out; | 182 | size = 0; |
183 | case SEEK_END: | 183 | switch (orig) { |
184 | default: | 184 | case SEEK_SET: |
185 | ret = -EINVAL; | ||
186 | goto out; | ||
187 | } | ||
188 | break; | 185 | break; |
189 | case SNDRV_INFO_CONTENT_DATA: | 186 | case SEEK_CUR: |
190 | if (entry->c.ops->llseek) { | 187 | offset += file->f_pos; |
191 | ret = entry->c.ops->llseek(entry, | 188 | break; |
192 | data->file_private_data, | 189 | case SEEK_END: |
193 | file, offset, orig); | 190 | if (!size) |
194 | goto out; | 191 | goto out; |
195 | } | 192 | offset += size; |
196 | break; | 193 | break; |
197 | } | 194 | default: |
198 | ret = -ENXIO; | 195 | goto out; |
199 | out: | 196 | } |
200 | unlock_kernel(); | 197 | if (offset < 0) |
198 | goto out; | ||
199 | if (size && offset > size) | ||
200 | offset = size; | ||
201 | file->f_pos = offset; | ||
202 | ret = offset; | ||
203 | out: | ||
204 | mutex_unlock(&entry->access); | ||
201 | return ret; | 205 | return ret; |
202 | } | 206 | } |
203 | 207 | ||
@@ -232,10 +236,15 @@ static ssize_t snd_info_entry_read(struct file *file, char __user *buffer, | |||
232 | return -EFAULT; | 236 | return -EFAULT; |
233 | break; | 237 | break; |
234 | case SNDRV_INFO_CONTENT_DATA: | 238 | case SNDRV_INFO_CONTENT_DATA: |
235 | if (entry->c.ops->read) | 239 | if (pos >= entry->size) |
240 | return 0; | ||
241 | if (entry->c.ops->read) { | ||
242 | size = entry->size - pos; | ||
243 | size = min(count, size); | ||
236 | size = entry->c.ops->read(entry, | 244 | size = entry->c.ops->read(entry, |
237 | data->file_private_data, | 245 | data->file_private_data, |
238 | file, buffer, count, pos); | 246 | file, buffer, size, pos); |
247 | } | ||
239 | break; | 248 | break; |
240 | } | 249 | } |
241 | if ((ssize_t) size > 0) | 250 | if ((ssize_t) size > 0) |
@@ -282,10 +291,13 @@ static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer | |||
282 | size = count; | 291 | size = count; |
283 | break; | 292 | break; |
284 | case SNDRV_INFO_CONTENT_DATA: | 293 | case SNDRV_INFO_CONTENT_DATA: |
285 | if (entry->c.ops->write) | 294 | if (entry->c.ops->write && count > 0) { |
295 | size_t maxsize = entry->size - pos; | ||
296 | count = min(count, maxsize); | ||
286 | size = entry->c.ops->write(entry, | 297 | size = entry->c.ops->write(entry, |
287 | data->file_private_data, | 298 | data->file_private_data, |
288 | file, buffer, count, pos); | 299 | file, buffer, count, pos); |
300 | } | ||
289 | break; | 301 | break; |
290 | } | 302 | } |
291 | if ((ssize_t) size > 0) | 303 | if ((ssize_t) size > 0) |
diff --git a/sound/core/jack.c b/sound/core/jack.c index 14b8a4ee690d..4902ae568730 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <sound/jack.h> | 24 | #include <sound/jack.h> |
25 | #include <sound/core.h> | 25 | #include <sound/core.h> |
26 | 26 | ||
27 | static int jack_types[] = { | 27 | static int jack_switch_types[] = { |
28 | SW_HEADPHONE_INSERT, | 28 | SW_HEADPHONE_INSERT, |
29 | SW_MICROPHONE_INSERT, | 29 | SW_MICROPHONE_INSERT, |
30 | SW_LINEOUT_INSERT, | 30 | SW_LINEOUT_INSERT, |
@@ -56,7 +56,7 @@ static int snd_jack_dev_register(struct snd_device *device) | |||
56 | { | 56 | { |
57 | struct snd_jack *jack = device->device_data; | 57 | struct snd_jack *jack = device->device_data; |
58 | struct snd_card *card = device->card; | 58 | struct snd_card *card = device->card; |
59 | int err; | 59 | int err, i; |
60 | 60 | ||
61 | snprintf(jack->name, sizeof(jack->name), "%s %s", | 61 | snprintf(jack->name, sizeof(jack->name), "%s %s", |
62 | card->shortname, jack->id); | 62 | card->shortname, jack->id); |
@@ -66,6 +66,19 @@ static int snd_jack_dev_register(struct snd_device *device) | |||
66 | if (!jack->input_dev->dev.parent) | 66 | if (!jack->input_dev->dev.parent) |
67 | jack->input_dev->dev.parent = snd_card_get_device_link(card); | 67 | jack->input_dev->dev.parent = snd_card_get_device_link(card); |
68 | 68 | ||
69 | /* Add capabilities for any keys that are enabled */ | ||
70 | for (i = 0; i < ARRAY_SIZE(jack->key); i++) { | ||
71 | int testbit = SND_JACK_BTN_0 >> i; | ||
72 | |||
73 | if (!(jack->type & testbit)) | ||
74 | continue; | ||
75 | |||
76 | if (!jack->key[i]) | ||
77 | jack->key[i] = BTN_0 + i; | ||
78 | |||
79 | input_set_capability(jack->input_dev, EV_KEY, jack->key[i]); | ||
80 | } | ||
81 | |||
69 | err = input_register_device(jack->input_dev); | 82 | err = input_register_device(jack->input_dev); |
70 | if (err == 0) | 83 | if (err == 0) |
71 | jack->registered = 1; | 84 | jack->registered = 1; |
@@ -113,10 +126,10 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, | |||
113 | 126 | ||
114 | jack->type = type; | 127 | jack->type = type; |
115 | 128 | ||
116 | for (i = 0; i < ARRAY_SIZE(jack_types); i++) | 129 | for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) |
117 | if (type & (1 << i)) | 130 | if (type & (1 << i)) |
118 | input_set_capability(jack->input_dev, EV_SW, | 131 | input_set_capability(jack->input_dev, EV_SW, |
119 | jack_types[i]); | 132 | jack_switch_types[i]); |
120 | 133 | ||
121 | err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); | 134 | err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); |
122 | if (err < 0) | 135 | if (err < 0) |
@@ -152,6 +165,43 @@ void snd_jack_set_parent(struct snd_jack *jack, struct device *parent) | |||
152 | EXPORT_SYMBOL(snd_jack_set_parent); | 165 | EXPORT_SYMBOL(snd_jack_set_parent); |
153 | 166 | ||
154 | /** | 167 | /** |
168 | * snd_jack_set_key - Set a key mapping on a jack | ||
169 | * | ||
170 | * @jack: The jack to configure | ||
171 | * @type: Jack report type for this key | ||
172 | * @keytype: Input layer key type to be reported | ||
173 | * | ||
174 | * Map a SND_JACK_BTN_ button type to an input layer key, allowing | ||
175 | * reporting of keys on accessories via the jack abstraction. If no | ||
176 | * mapping is provided but keys are enabled in the jack type then | ||
177 | * BTN_n numeric buttons will be reported. | ||
178 | * | ||
179 | * Note that this is intended to be use by simple devices with small | ||
180 | * numbers of keys that can be reported. It is also possible to | ||
181 | * access the input device directly - devices with complex input | ||
182 | * capabilities on accessories should consider doing this rather than | ||
183 | * using this abstraction. | ||
184 | * | ||
185 | * This function may only be called prior to registration of the jack. | ||
186 | */ | ||
187 | int snd_jack_set_key(struct snd_jack *jack, enum snd_jack_types type, | ||
188 | int keytype) | ||
189 | { | ||
190 | int key = fls(SND_JACK_BTN_0) - fls(type); | ||
191 | |||
192 | WARN_ON(jack->registered); | ||
193 | |||
194 | if (!keytype || key >= ARRAY_SIZE(jack->key)) | ||
195 | return -EINVAL; | ||
196 | |||
197 | jack->type |= type; | ||
198 | jack->key[key] = keytype; | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | EXPORT_SYMBOL(snd_jack_set_key); | ||
203 | |||
204 | /** | ||
155 | * snd_jack_report - Report the current status of a jack | 205 | * snd_jack_report - Report the current status of a jack |
156 | * | 206 | * |
157 | * @jack: The jack to report status for | 207 | * @jack: The jack to report status for |
@@ -164,10 +214,19 @@ void snd_jack_report(struct snd_jack *jack, int status) | |||
164 | if (!jack) | 214 | if (!jack) |
165 | return; | 215 | return; |
166 | 216 | ||
167 | for (i = 0; i < ARRAY_SIZE(jack_types); i++) { | 217 | for (i = 0; i < ARRAY_SIZE(jack->key); i++) { |
218 | int testbit = SND_JACK_BTN_0 >> i; | ||
219 | |||
220 | if (jack->type & testbit) | ||
221 | input_report_key(jack->input_dev, jack->key[i], | ||
222 | status & testbit); | ||
223 | } | ||
224 | |||
225 | for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) { | ||
168 | int testbit = 1 << i; | 226 | int testbit = 1 << i; |
169 | if (jack->type & testbit) | 227 | if (jack->type & testbit) |
170 | input_report_switch(jack->input_dev, jack_types[i], | 228 | input_report_switch(jack->input_dev, |
229 | jack_switch_types[i], | ||
171 | status & testbit); | 230 | status & testbit); |
172 | } | 231 | } |
173 | 232 | ||
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 54e2eb56e4c2..f50ebf20df96 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c | |||
@@ -43,6 +43,10 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) | |||
43 | struct snd_mixer_oss_file *fmixer; | 43 | struct snd_mixer_oss_file *fmixer; |
44 | int err; | 44 | int err; |
45 | 45 | ||
46 | err = nonseekable_open(inode, file); | ||
47 | if (err < 0) | ||
48 | return err; | ||
49 | |||
46 | card = snd_lookup_oss_minor_data(iminor(inode), | 50 | card = snd_lookup_oss_minor_data(iminor(inode), |
47 | SNDRV_OSS_DEVICE_TYPE_MIXER); | 51 | SNDRV_OSS_DEVICE_TYPE_MIXER); |
48 | if (card == NULL) | 52 | if (card == NULL) |
@@ -397,6 +401,7 @@ static const struct file_operations snd_mixer_oss_f_ops = | |||
397 | .owner = THIS_MODULE, | 401 | .owner = THIS_MODULE, |
398 | .open = snd_mixer_oss_open, | 402 | .open = snd_mixer_oss_open, |
399 | .release = snd_mixer_oss_release, | 403 | .release = snd_mixer_oss_release, |
404 | .llseek = no_llseek, | ||
400 | .unlocked_ioctl = snd_mixer_oss_ioctl, | 405 | .unlocked_ioctl = snd_mixer_oss_ioctl, |
401 | .compat_ioctl = snd_mixer_oss_ioctl_compat, | 406 | .compat_ioctl = snd_mixer_oss_ioctl_compat, |
402 | }; | 407 | }; |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 82d4e3329b3d..5c8c7dff8ede 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -2379,6 +2379,10 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) | |||
2379 | int nonblock; | 2379 | int nonblock; |
2380 | wait_queue_t wait; | 2380 | wait_queue_t wait; |
2381 | 2381 | ||
2382 | err = nonseekable_open(inode, file); | ||
2383 | if (err < 0) | ||
2384 | return err; | ||
2385 | |||
2382 | pcm = snd_lookup_oss_minor_data(iminor(inode), | 2386 | pcm = snd_lookup_oss_minor_data(iminor(inode), |
2383 | SNDRV_OSS_DEVICE_TYPE_PCM); | 2387 | SNDRV_OSS_DEVICE_TYPE_PCM); |
2384 | if (pcm == NULL) { | 2388 | if (pcm == NULL) { |
@@ -2977,6 +2981,7 @@ static const struct file_operations snd_pcm_oss_f_reg = | |||
2977 | .write = snd_pcm_oss_write, | 2981 | .write = snd_pcm_oss_write, |
2978 | .open = snd_pcm_oss_open, | 2982 | .open = snd_pcm_oss_open, |
2979 | .release = snd_pcm_oss_release, | 2983 | .release = snd_pcm_oss_release, |
2984 | .llseek = no_llseek, | ||
2980 | .poll = snd_pcm_oss_poll, | 2985 | .poll = snd_pcm_oss_poll, |
2981 | .unlocked_ioctl = snd_pcm_oss_ioctl, | 2986 | .unlocked_ioctl = snd_pcm_oss_ioctl, |
2982 | .compat_ioctl = snd_pcm_oss_ioctl_compat, | 2987 | .compat_ioctl = snd_pcm_oss_ioctl_compat, |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 192dd407512f..644c2bb17b86 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -2112,7 +2112,9 @@ static int snd_pcm_open_file(struct file *file, | |||
2112 | static int snd_pcm_playback_open(struct inode *inode, struct file *file) | 2112 | static int snd_pcm_playback_open(struct inode *inode, struct file *file) |
2113 | { | 2113 | { |
2114 | struct snd_pcm *pcm; | 2114 | struct snd_pcm *pcm; |
2115 | 2115 | int err = nonseekable_open(inode, file); | |
2116 | if (err < 0) | ||
2117 | return err; | ||
2116 | pcm = snd_lookup_minor_data(iminor(inode), | 2118 | pcm = snd_lookup_minor_data(iminor(inode), |
2117 | SNDRV_DEVICE_TYPE_PCM_PLAYBACK); | 2119 | SNDRV_DEVICE_TYPE_PCM_PLAYBACK); |
2118 | return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); | 2120 | return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); |
@@ -2121,7 +2123,9 @@ static int snd_pcm_playback_open(struct inode *inode, struct file *file) | |||
2121 | static int snd_pcm_capture_open(struct inode *inode, struct file *file) | 2123 | static int snd_pcm_capture_open(struct inode *inode, struct file *file) |
2122 | { | 2124 | { |
2123 | struct snd_pcm *pcm; | 2125 | struct snd_pcm *pcm; |
2124 | 2126 | int err = nonseekable_open(inode, file); | |
2127 | if (err < 0) | ||
2128 | return err; | ||
2125 | pcm = snd_lookup_minor_data(iminor(inode), | 2129 | pcm = snd_lookup_minor_data(iminor(inode), |
2126 | SNDRV_DEVICE_TYPE_PCM_CAPTURE); | 2130 | SNDRV_DEVICE_TYPE_PCM_CAPTURE); |
2127 | return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); | 2131 | return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); |
@@ -3312,18 +3316,13 @@ static int snd_pcm_fasync(int fd, struct file * file, int on) | |||
3312 | struct snd_pcm_file * pcm_file; | 3316 | struct snd_pcm_file * pcm_file; |
3313 | struct snd_pcm_substream *substream; | 3317 | struct snd_pcm_substream *substream; |
3314 | struct snd_pcm_runtime *runtime; | 3318 | struct snd_pcm_runtime *runtime; |
3315 | int err = -ENXIO; | ||
3316 | 3319 | ||
3317 | lock_kernel(); | ||
3318 | pcm_file = file->private_data; | 3320 | pcm_file = file->private_data; |
3319 | substream = pcm_file->substream; | 3321 | substream = pcm_file->substream; |
3320 | if (PCM_RUNTIME_CHECK(substream)) | 3322 | if (PCM_RUNTIME_CHECK(substream)) |
3321 | goto out; | 3323 | return -ENXIO; |
3322 | runtime = substream->runtime; | 3324 | runtime = substream->runtime; |
3323 | err = fasync_helper(fd, file, on, &runtime->fasync); | 3325 | return fasync_helper(fd, file, on, &runtime->fasync); |
3324 | out: | ||
3325 | unlock_kernel(); | ||
3326 | return err; | ||
3327 | } | 3326 | } |
3328 | 3327 | ||
3329 | /* | 3328 | /* |
@@ -3443,14 +3442,28 @@ out: | |||
3443 | #endif /* CONFIG_SND_SUPPORT_OLD_API */ | 3442 | #endif /* CONFIG_SND_SUPPORT_OLD_API */ |
3444 | 3443 | ||
3445 | #ifndef CONFIG_MMU | 3444 | #ifndef CONFIG_MMU |
3446 | unsigned long dummy_get_unmapped_area(struct file *file, unsigned long addr, | 3445 | static unsigned long snd_pcm_get_unmapped_area(struct file *file, |
3447 | unsigned long len, unsigned long pgoff, | 3446 | unsigned long addr, |
3448 | unsigned long flags) | 3447 | unsigned long len, |
3449 | { | 3448 | unsigned long pgoff, |
3450 | return 0; | 3449 | unsigned long flags) |
3450 | { | ||
3451 | struct snd_pcm_file *pcm_file = file->private_data; | ||
3452 | struct snd_pcm_substream *substream = pcm_file->substream; | ||
3453 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
3454 | unsigned long offset = pgoff << PAGE_SHIFT; | ||
3455 | |||
3456 | switch (offset) { | ||
3457 | case SNDRV_PCM_MMAP_OFFSET_STATUS: | ||
3458 | return (unsigned long)runtime->status; | ||
3459 | case SNDRV_PCM_MMAP_OFFSET_CONTROL: | ||
3460 | return (unsigned long)runtime->control; | ||
3461 | default: | ||
3462 | return (unsigned long)runtime->dma_area + offset; | ||
3463 | } | ||
3451 | } | 3464 | } |
3452 | #else | 3465 | #else |
3453 | # define dummy_get_unmapped_area NULL | 3466 | # define snd_pcm_get_unmapped_area NULL |
3454 | #endif | 3467 | #endif |
3455 | 3468 | ||
3456 | /* | 3469 | /* |
@@ -3464,12 +3477,13 @@ const struct file_operations snd_pcm_f_ops[2] = { | |||
3464 | .aio_write = snd_pcm_aio_write, | 3477 | .aio_write = snd_pcm_aio_write, |
3465 | .open = snd_pcm_playback_open, | 3478 | .open = snd_pcm_playback_open, |
3466 | .release = snd_pcm_release, | 3479 | .release = snd_pcm_release, |
3480 | .llseek = no_llseek, | ||
3467 | .poll = snd_pcm_playback_poll, | 3481 | .poll = snd_pcm_playback_poll, |
3468 | .unlocked_ioctl = snd_pcm_playback_ioctl, | 3482 | .unlocked_ioctl = snd_pcm_playback_ioctl, |
3469 | .compat_ioctl = snd_pcm_ioctl_compat, | 3483 | .compat_ioctl = snd_pcm_ioctl_compat, |
3470 | .mmap = snd_pcm_mmap, | 3484 | .mmap = snd_pcm_mmap, |
3471 | .fasync = snd_pcm_fasync, | 3485 | .fasync = snd_pcm_fasync, |
3472 | .get_unmapped_area = dummy_get_unmapped_area, | 3486 | .get_unmapped_area = snd_pcm_get_unmapped_area, |
3473 | }, | 3487 | }, |
3474 | { | 3488 | { |
3475 | .owner = THIS_MODULE, | 3489 | .owner = THIS_MODULE, |
@@ -3477,11 +3491,12 @@ const struct file_operations snd_pcm_f_ops[2] = { | |||
3477 | .aio_read = snd_pcm_aio_read, | 3491 | .aio_read = snd_pcm_aio_read, |
3478 | .open = snd_pcm_capture_open, | 3492 | .open = snd_pcm_capture_open, |
3479 | .release = snd_pcm_release, | 3493 | .release = snd_pcm_release, |
3494 | .llseek = no_llseek, | ||
3480 | .poll = snd_pcm_capture_poll, | 3495 | .poll = snd_pcm_capture_poll, |
3481 | .unlocked_ioctl = snd_pcm_capture_ioctl, | 3496 | .unlocked_ioctl = snd_pcm_capture_ioctl, |
3482 | .compat_ioctl = snd_pcm_ioctl_compat, | 3497 | .compat_ioctl = snd_pcm_ioctl_compat, |
3483 | .mmap = snd_pcm_mmap, | 3498 | .mmap = snd_pcm_mmap, |
3484 | .fasync = snd_pcm_fasync, | 3499 | .fasync = snd_pcm_fasync, |
3485 | .get_unmapped_area = dummy_get_unmapped_area, | 3500 | .get_unmapped_area = snd_pcm_get_unmapped_area, |
3486 | } | 3501 | } |
3487 | }; | 3502 | }; |
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 0f5a194695d9..eb68326c37d4 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c | |||
@@ -376,6 +376,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) | |||
376 | if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) | 376 | if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) |
377 | return -EINVAL; /* invalid combination */ | 377 | return -EINVAL; /* invalid combination */ |
378 | 378 | ||
379 | err = nonseekable_open(inode, file); | ||
380 | if (err < 0) | ||
381 | return err; | ||
382 | |||
379 | if (maj == snd_major) { | 383 | if (maj == snd_major) { |
380 | rmidi = snd_lookup_minor_data(iminor(inode), | 384 | rmidi = snd_lookup_minor_data(iminor(inode), |
381 | SNDRV_DEVICE_TYPE_RAWMIDI); | 385 | SNDRV_DEVICE_TYPE_RAWMIDI); |
@@ -1391,6 +1395,7 @@ static const struct file_operations snd_rawmidi_f_ops = | |||
1391 | .write = snd_rawmidi_write, | 1395 | .write = snd_rawmidi_write, |
1392 | .open = snd_rawmidi_open, | 1396 | .open = snd_rawmidi_open, |
1393 | .release = snd_rawmidi_release, | 1397 | .release = snd_rawmidi_release, |
1398 | .llseek = no_llseek, | ||
1394 | .poll = snd_rawmidi_poll, | 1399 | .poll = snd_rawmidi_poll, |
1395 | .unlocked_ioctl = snd_rawmidi_ioctl, | 1400 | .unlocked_ioctl = snd_rawmidi_ioctl, |
1396 | .compat_ioctl = snd_rawmidi_ioctl_compat, | 1401 | .compat_ioctl = snd_rawmidi_ioctl_compat, |
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index 48eca9ff9ee7..99a485f13648 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c | |||
@@ -318,6 +318,11 @@ static int snd_seq_open(struct inode *inode, struct file *file) | |||
318 | int c, mode; /* client id */ | 318 | int c, mode; /* client id */ |
319 | struct snd_seq_client *client; | 319 | struct snd_seq_client *client; |
320 | struct snd_seq_user_client *user; | 320 | struct snd_seq_user_client *user; |
321 | int err; | ||
322 | |||
323 | err = nonseekable_open(inode, file); | ||
324 | if (err < 0) | ||
325 | return err; | ||
321 | 326 | ||
322 | if (mutex_lock_interruptible(®ister_mutex)) | 327 | if (mutex_lock_interruptible(®ister_mutex)) |
323 | return -ERESTARTSYS; | 328 | return -ERESTARTSYS; |
@@ -2550,6 +2555,7 @@ static const struct file_operations snd_seq_f_ops = | |||
2550 | .write = snd_seq_write, | 2555 | .write = snd_seq_write, |
2551 | .open = snd_seq_open, | 2556 | .open = snd_seq_open, |
2552 | .release = snd_seq_release, | 2557 | .release = snd_seq_release, |
2558 | .llseek = no_llseek, | ||
2553 | .poll = snd_seq_poll, | 2559 | .poll = snd_seq_poll, |
2554 | .unlocked_ioctl = snd_seq_ioctl, | 2560 | .unlocked_ioctl = snd_seq_ioctl, |
2555 | .compat_ioctl = snd_seq_ioctl_compat, | 2561 | .compat_ioctl = snd_seq_ioctl_compat, |
diff --git a/sound/core/sound.c b/sound/core/sound.c index 563d1967a0ad..ac42af42b787 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
@@ -120,7 +120,29 @@ void *snd_lookup_minor_data(unsigned int minor, int type) | |||
120 | 120 | ||
121 | EXPORT_SYMBOL(snd_lookup_minor_data); | 121 | EXPORT_SYMBOL(snd_lookup_minor_data); |
122 | 122 | ||
123 | static int __snd_open(struct inode *inode, struct file *file) | 123 | #ifdef CONFIG_MODULES |
124 | static struct snd_minor *autoload_device(unsigned int minor) | ||
125 | { | ||
126 | int dev; | ||
127 | mutex_unlock(&sound_mutex); /* release lock temporarily */ | ||
128 | dev = SNDRV_MINOR_DEVICE(minor); | ||
129 | if (dev == SNDRV_MINOR_CONTROL) { | ||
130 | /* /dev/aloadC? */ | ||
131 | int card = SNDRV_MINOR_CARD(minor); | ||
132 | if (snd_cards[card] == NULL) | ||
133 | snd_request_card(card); | ||
134 | } else if (dev == SNDRV_MINOR_GLOBAL) { | ||
135 | /* /dev/aloadSEQ */ | ||
136 | snd_request_other(minor); | ||
137 | } | ||
138 | mutex_lock(&sound_mutex); /* reacuire lock */ | ||
139 | return snd_minors[minor]; | ||
140 | } | ||
141 | #else /* !CONFIG_MODULES */ | ||
142 | #define autoload_device(minor) NULL | ||
143 | #endif /* CONFIG_MODULES */ | ||
144 | |||
145 | static int snd_open(struct inode *inode, struct file *file) | ||
124 | { | 146 | { |
125 | unsigned int minor = iminor(inode); | 147 | unsigned int minor = iminor(inode); |
126 | struct snd_minor *mptr = NULL; | 148 | struct snd_minor *mptr = NULL; |
@@ -129,55 +151,36 @@ static int __snd_open(struct inode *inode, struct file *file) | |||
129 | 151 | ||
130 | if (minor >= ARRAY_SIZE(snd_minors)) | 152 | if (minor >= ARRAY_SIZE(snd_minors)) |
131 | return -ENODEV; | 153 | return -ENODEV; |
154 | mutex_lock(&sound_mutex); | ||
132 | mptr = snd_minors[minor]; | 155 | mptr = snd_minors[minor]; |
133 | if (mptr == NULL) { | 156 | if (mptr == NULL) { |
134 | #ifdef CONFIG_MODULES | 157 | mptr = autoload_device(minor); |
135 | int dev = SNDRV_MINOR_DEVICE(minor); | 158 | if (!mptr) { |
136 | if (dev == SNDRV_MINOR_CONTROL) { | 159 | mutex_unlock(&sound_mutex); |
137 | /* /dev/aloadC? */ | ||
138 | int card = SNDRV_MINOR_CARD(minor); | ||
139 | if (snd_cards[card] == NULL) | ||
140 | snd_request_card(card); | ||
141 | } else if (dev == SNDRV_MINOR_GLOBAL) { | ||
142 | /* /dev/aloadSEQ */ | ||
143 | snd_request_other(minor); | ||
144 | } | ||
145 | #ifndef CONFIG_SND_DYNAMIC_MINORS | ||
146 | /* /dev/snd/{controlC?,seq} */ | ||
147 | mptr = snd_minors[minor]; | ||
148 | if (mptr == NULL) | ||
149 | #endif | ||
150 | #endif | ||
151 | return -ENODEV; | 160 | return -ENODEV; |
161 | } | ||
152 | } | 162 | } |
153 | old_fops = file->f_op; | 163 | old_fops = file->f_op; |
154 | file->f_op = fops_get(mptr->f_ops); | 164 | file->f_op = fops_get(mptr->f_ops); |
155 | if (file->f_op == NULL) { | 165 | if (file->f_op == NULL) { |
156 | file->f_op = old_fops; | 166 | file->f_op = old_fops; |
157 | return -ENODEV; | 167 | err = -ENODEV; |
158 | } | 168 | } |
159 | if (file->f_op->open) | 169 | mutex_unlock(&sound_mutex); |
170 | if (err < 0) | ||
171 | return err; | ||
172 | |||
173 | if (file->f_op->open) { | ||
160 | err = file->f_op->open(inode, file); | 174 | err = file->f_op->open(inode, file); |
161 | if (err) { | 175 | if (err) { |
162 | fops_put(file->f_op); | 176 | fops_put(file->f_op); |
163 | file->f_op = fops_get(old_fops); | 177 | file->f_op = fops_get(old_fops); |
178 | } | ||
164 | } | 179 | } |
165 | fops_put(old_fops); | 180 | fops_put(old_fops); |
166 | return err; | 181 | return err; |
167 | } | 182 | } |
168 | 183 | ||
169 | |||
170 | /* BKL pushdown: nasty #ifdef avoidance wrapper */ | ||
171 | static int snd_open(struct inode *inode, struct file *file) | ||
172 | { | ||
173 | int ret; | ||
174 | |||
175 | lock_kernel(); | ||
176 | ret = __snd_open(inode, file); | ||
177 | unlock_kernel(); | ||
178 | return ret; | ||
179 | } | ||
180 | |||
181 | static const struct file_operations snd_fops = | 184 | static const struct file_operations snd_fops = |
182 | { | 185 | { |
183 | .owner = THIS_MODULE, | 186 | .owner = THIS_MODULE, |
diff --git a/sound/core/timer.c b/sound/core/timer.c index 5040c7b862fe..13afb60999b9 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -1238,6 +1238,11 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri, | |||
1238 | static int snd_timer_user_open(struct inode *inode, struct file *file) | 1238 | static int snd_timer_user_open(struct inode *inode, struct file *file) |
1239 | { | 1239 | { |
1240 | struct snd_timer_user *tu; | 1240 | struct snd_timer_user *tu; |
1241 | int err; | ||
1242 | |||
1243 | err = nonseekable_open(inode, file); | ||
1244 | if (err < 0) | ||
1245 | return err; | ||
1241 | 1246 | ||
1242 | tu = kzalloc(sizeof(*tu), GFP_KERNEL); | 1247 | tu = kzalloc(sizeof(*tu), GFP_KERNEL); |
1243 | if (tu == NULL) | 1248 | if (tu == NULL) |
@@ -1922,6 +1927,7 @@ static const struct file_operations snd_timer_f_ops = | |||
1922 | .read = snd_timer_user_read, | 1927 | .read = snd_timer_user_read, |
1923 | .open = snd_timer_user_open, | 1928 | .open = snd_timer_user_open, |
1924 | .release = snd_timer_user_release, | 1929 | .release = snd_timer_user_release, |
1930 | .llseek = no_llseek, | ||
1925 | .poll = snd_timer_user_poll, | 1931 | .poll = snd_timer_user_poll, |
1926 | .unlocked_ioctl = snd_timer_user_ioctl, | 1932 | .unlocked_ioctl = snd_timer_user_ioctl, |
1927 | .compat_ioctl = snd_timer_user_ioctl_compat, | 1933 | .compat_ioctl = snd_timer_user_ioctl_compat, |