ALSA: pcm: Remove arch-dependent mmap kludges
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / sound / core / pcm_native.c
CommitLineData
1da177e4
LT
1/*
2 * Digital Audio (PCM) abstract layer
c1017a4c 3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
1da177e4
LT
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
1da177e4 22#include <linux/mm.h>
da155d5b 23#include <linux/module.h>
1da177e4
LT
24#include <linux/file.h>
25#include <linux/slab.h>
26#include <linux/time.h>
e8db0be1 27#include <linux/pm_qos.h>
a27bb332 28#include <linux/aio.h>
657b1989 29#include <linux/dma-mapping.h>
1da177e4
LT
30#include <sound/core.h>
31#include <sound/control.h>
32#include <sound/info.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/timer.h>
36#include <sound/minors.h>
37#include <asm/io.h>
38
39/*
40 * Compatibility
41 */
42
877211f5 43struct snd_pcm_hw_params_old {
1da177e4
LT
44 unsigned int flags;
45 unsigned int masks[SNDRV_PCM_HW_PARAM_SUBFORMAT -
46 SNDRV_PCM_HW_PARAM_ACCESS + 1];
877211f5 47 struct snd_interval intervals[SNDRV_PCM_HW_PARAM_TICK_TIME -
1da177e4
LT
48 SNDRV_PCM_HW_PARAM_SAMPLE_BITS + 1];
49 unsigned int rmask;
50 unsigned int cmask;
51 unsigned int info;
52 unsigned int msbits;
53 unsigned int rate_num;
54 unsigned int rate_den;
877211f5 55 snd_pcm_uframes_t fifo_size;
1da177e4
LT
56 unsigned char reserved[64];
57};
58
59d48582 59#ifdef CONFIG_SND_SUPPORT_OLD_API
877211f5
TI
60#define SNDRV_PCM_IOCTL_HW_REFINE_OLD _IOWR('A', 0x10, struct snd_pcm_hw_params_old)
61#define SNDRV_PCM_IOCTL_HW_PARAMS_OLD _IOWR('A', 0x11, struct snd_pcm_hw_params_old)
1da177e4 62
877211f5
TI
63static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream,
64 struct snd_pcm_hw_params_old __user * _oparams);
65static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream,
66 struct snd_pcm_hw_params_old __user * _oparams);
59d48582 67#endif
f87135f5 68static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream);
1da177e4
LT
69
70/*
71 *
72 */
73
7af142f7
TI
74static DEFINE_RWLOCK(snd_pcm_link_rwlock);
75static DECLARE_RWSEM(snd_pcm_link_rwsem);
1da177e4 76
7af142f7
TI
77void snd_pcm_stream_lock(struct snd_pcm_substream *substream)
78{
79 if (substream->pcm->nonatomic) {
80 down_read(&snd_pcm_link_rwsem);
81 mutex_lock(&substream->self_group.mutex);
82 } else {
83 read_lock(&snd_pcm_link_rwlock);
84 spin_lock(&substream->self_group.lock);
85 }
86}
87EXPORT_SYMBOL_GPL(snd_pcm_stream_lock);
88
89void snd_pcm_stream_unlock(struct snd_pcm_substream *substream)
90{
91 if (substream->pcm->nonatomic) {
92 mutex_unlock(&substream->self_group.mutex);
93 up_read(&snd_pcm_link_rwsem);
94 } else {
95 spin_unlock(&substream->self_group.lock);
96 read_unlock(&snd_pcm_link_rwlock);
97 }
98}
99EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock);
100
101void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream)
102{
103 if (!substream->pcm->nonatomic)
104 local_irq_disable();
105 snd_pcm_stream_lock(substream);
106}
107EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq);
108
109void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream)
110{
111 snd_pcm_stream_unlock(substream);
112 if (!substream->pcm->nonatomic)
113 local_irq_enable();
114}
115EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irq);
116
117unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream)
118{
119 unsigned long flags = 0;
120 if (!substream->pcm->nonatomic)
121 local_irq_save(flags);
122 snd_pcm_stream_lock(substream);
123 return flags;
124}
125EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave);
126
127void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
128 unsigned long flags)
129{
130 snd_pcm_stream_unlock(substream);
131 if (!substream->pcm->nonatomic)
132 local_irq_restore(flags);
133}
134EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore);
1da177e4
LT
135
136static inline mm_segment_t snd_enter_user(void)
137{
138 mm_segment_t fs = get_fs();
139 set_fs(get_ds());
140 return fs;
141}
142
143static inline void snd_leave_user(mm_segment_t fs)
144{
145 set_fs(fs);
146}
147
148
149
877211f5 150int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
1da177e4 151{
877211f5
TI
152 struct snd_pcm_runtime *runtime;
153 struct snd_pcm *pcm = substream->pcm;
154 struct snd_pcm_str *pstr = substream->pstr;
1da177e4 155
1da177e4
LT
156 memset(info, 0, sizeof(*info));
157 info->card = pcm->card->number;
158 info->device = pcm->device;
159 info->stream = substream->stream;
160 info->subdevice = substream->number;
161 strlcpy(info->id, pcm->id, sizeof(info->id));
162 strlcpy(info->name, pcm->name, sizeof(info->name));
163 info->dev_class = pcm->dev_class;
164 info->dev_subclass = pcm->dev_subclass;
165 info->subdevices_count = pstr->substream_count;
166 info->subdevices_avail = pstr->substream_count - pstr->substream_opened;
167 strlcpy(info->subname, substream->name, sizeof(info->subname));
168 runtime = substream->runtime;
169 /* AB: FIXME!!! This is definitely nonsense */
170 if (runtime) {
171 info->sync = runtime->sync;
172 substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_INFO, info);
173 }
174 return 0;
175}
176
877211f5
TI
177int snd_pcm_info_user(struct snd_pcm_substream *substream,
178 struct snd_pcm_info __user * _info)
1da177e4 179{
877211f5 180 struct snd_pcm_info *info;
1da177e4
LT
181 int err;
182
183 info = kmalloc(sizeof(*info), GFP_KERNEL);
184 if (! info)
185 return -ENOMEM;
186 err = snd_pcm_info(substream, info);
187 if (err >= 0) {
188 if (copy_to_user(_info, info, sizeof(*info)))
189 err = -EFAULT;
190 }
191 kfree(info);
192 return err;
193}
194
195#undef RULES_DEBUG
196
197#ifdef RULES_DEBUG
198#define HW_PARAM(v) [SNDRV_PCM_HW_PARAM_##v] = #v
47023ec7 199static const char * const snd_pcm_hw_param_names[] = {
1da177e4
LT
200 HW_PARAM(ACCESS),
201 HW_PARAM(FORMAT),
202 HW_PARAM(SUBFORMAT),
203 HW_PARAM(SAMPLE_BITS),
204 HW_PARAM(FRAME_BITS),
205 HW_PARAM(CHANNELS),
206 HW_PARAM(RATE),
207 HW_PARAM(PERIOD_TIME),
208 HW_PARAM(PERIOD_SIZE),
209 HW_PARAM(PERIOD_BYTES),
210 HW_PARAM(PERIODS),
211 HW_PARAM(BUFFER_TIME),
212 HW_PARAM(BUFFER_SIZE),
213 HW_PARAM(BUFFER_BYTES),
214 HW_PARAM(TICK_TIME),
215};
216#endif
217
877211f5
TI
218int snd_pcm_hw_refine(struct snd_pcm_substream *substream,
219 struct snd_pcm_hw_params *params)
1da177e4
LT
220{
221 unsigned int k;
877211f5
TI
222 struct snd_pcm_hardware *hw;
223 struct snd_interval *i = NULL;
224 struct snd_mask *m = NULL;
225 struct snd_pcm_hw_constraints *constrs = &substream->runtime->hw_constraints;
1da177e4
LT
226 unsigned int rstamps[constrs->rules_num];
227 unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1];
228 unsigned int stamp = 2;
229 int changed, again;
230
231 params->info = 0;
232 params->fifo_size = 0;
233 if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_SAMPLE_BITS))
234 params->msbits = 0;
235 if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_RATE)) {
236 params->rate_num = 0;
237 params->rate_den = 0;
238 }
239
240 for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) {
241 m = hw_param_mask(params, k);
242 if (snd_mask_empty(m))
243 return -EINVAL;
244 if (!(params->rmask & (1 << k)))
245 continue;
246#ifdef RULES_DEBUG
09e56df8
TI
247 pr_debug("%s = ", snd_pcm_hw_param_names[k]);
248 pr_cont("%04x%04x%04x%04x -> ", m->bits[3], m->bits[2], m->bits[1], m->bits[0]);
1da177e4
LT
249#endif
250 changed = snd_mask_refine(m, constrs_mask(constrs, k));
251#ifdef RULES_DEBUG
09e56df8 252 pr_cont("%04x%04x%04x%04x\n", m->bits[3], m->bits[2], m->bits[1], m->bits[0]);
1da177e4
LT
253#endif
254 if (changed)
255 params->cmask |= 1 << k;
256 if (changed < 0)
257 return changed;
258 }
259
260 for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) {
261 i = hw_param_interval(params, k);
262 if (snd_interval_empty(i))
263 return -EINVAL;
264 if (!(params->rmask & (1 << k)))
265 continue;
266#ifdef RULES_DEBUG
09e56df8 267 pr_debug("%s = ", snd_pcm_hw_param_names[k]);
1da177e4 268 if (i->empty)
09e56df8 269 pr_cont("empty");
1da177e4 270 else
09e56df8 271 pr_cont("%c%u %u%c",
1da177e4
LT
272 i->openmin ? '(' : '[', i->min,
273 i->max, i->openmax ? ')' : ']');
09e56df8 274 pr_cont(" -> ");
1da177e4
LT
275#endif
276 changed = snd_interval_refine(i, constrs_interval(constrs, k));
277#ifdef RULES_DEBUG
278 if (i->empty)
09e56df8 279 pr_cont("empty\n");
1da177e4 280 else
09e56df8 281 pr_cont("%c%u %u%c\n",
1da177e4
LT
282 i->openmin ? '(' : '[', i->min,
283 i->max, i->openmax ? ')' : ']');
284#endif
285 if (changed)
286 params->cmask |= 1 << k;
287 if (changed < 0)
288 return changed;
289 }
290
291 for (k = 0; k < constrs->rules_num; k++)
292 rstamps[k] = 0;
293 for (k = 0; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++)
294 vstamps[k] = (params->rmask & (1 << k)) ? 1 : 0;
295 do {
296 again = 0;
297 for (k = 0; k < constrs->rules_num; k++) {
877211f5 298 struct snd_pcm_hw_rule *r = &constrs->rules[k];
1da177e4
LT
299 unsigned int d;
300 int doit = 0;
301 if (r->cond && !(r->cond & params->flags))
302 continue;
303 for (d = 0; r->deps[d] >= 0; d++) {
304 if (vstamps[r->deps[d]] > rstamps[k]) {
305 doit = 1;
306 break;
307 }
308 }
309 if (!doit)
310 continue;
311#ifdef RULES_DEBUG
09e56df8 312 pr_debug("Rule %d [%p]: ", k, r->func);
1da177e4 313 if (r->var >= 0) {
09e56df8 314 pr_cont("%s = ", snd_pcm_hw_param_names[r->var]);
1da177e4
LT
315 if (hw_is_mask(r->var)) {
316 m = hw_param_mask(params, r->var);
09e56df8 317 pr_cont("%x", *m->bits);
1da177e4
LT
318 } else {
319 i = hw_param_interval(params, r->var);
320 if (i->empty)
09e56df8 321 pr_cont("empty");
1da177e4 322 else
09e56df8 323 pr_cont("%c%u %u%c",
1da177e4
LT
324 i->openmin ? '(' : '[', i->min,
325 i->max, i->openmax ? ')' : ']');
326 }
327 }
328#endif
329 changed = r->func(params, r);
330#ifdef RULES_DEBUG
331 if (r->var >= 0) {
09e56df8 332 pr_cont(" -> ");
1da177e4 333 if (hw_is_mask(r->var))
09e56df8 334 pr_cont("%x", *m->bits);
1da177e4
LT
335 else {
336 if (i->empty)
09e56df8 337 pr_cont("empty");
1da177e4 338 else
09e56df8 339 pr_cont("%c%u %u%c",
1da177e4
LT
340 i->openmin ? '(' : '[', i->min,
341 i->max, i->openmax ? ')' : ']');
342 }
343 }
09e56df8 344 pr_cont("\n");
1da177e4
LT
345#endif
346 rstamps[k] = stamp;
347 if (changed && r->var >= 0) {
348 params->cmask |= (1 << r->var);
349 vstamps[r->var] = stamp;
350 again = 1;
351 }
352 if (changed < 0)
353 return changed;
354 stamp++;
355 }
356 } while (again);
357 if (!params->msbits) {
358 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
359 if (snd_interval_single(i))
360 params->msbits = snd_interval_value(i);
361 }
362
363 if (!params->rate_den) {
364 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
365 if (snd_interval_single(i)) {
366 params->rate_num = snd_interval_value(i);
367 params->rate_den = 1;
368 }
369 }
370
371 hw = &substream->runtime->hw;
372 if (!params->info)
8bea869c
JK
373 params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES;
374 if (!params->fifo_size) {
3be522a9
JK
375 m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
376 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
377 if (snd_mask_min(m) == snd_mask_max(m) &&
378 snd_interval_min(i) == snd_interval_max(i)) {
8bea869c
JK
379 changed = substream->ops->ioctl(substream,
380 SNDRV_PCM_IOCTL1_FIFO_SIZE, params);
8bd9bca3 381 if (changed < 0)
8bea869c
JK
382 return changed;
383 }
384 }
1da177e4
LT
385 params->rmask = 0;
386 return 0;
387}
388
e88e8ae6
TI
389EXPORT_SYMBOL(snd_pcm_hw_refine);
390
877211f5
TI
391static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream,
392 struct snd_pcm_hw_params __user * _params)
1da177e4 393{
877211f5 394 struct snd_pcm_hw_params *params;
1da177e4
LT
395 int err;
396
ef44a1ec
LZ
397 params = memdup_user(_params, sizeof(*params));
398 if (IS_ERR(params))
399 return PTR_ERR(params);
400
1da177e4
LT
401 err = snd_pcm_hw_refine(substream, params);
402 if (copy_to_user(_params, params, sizeof(*params))) {
403 if (!err)
404 err = -EFAULT;
405 }
ef44a1ec 406
1da177e4
LT
407 kfree(params);
408 return err;
409}
410
9442e691
TI
411static int period_to_usecs(struct snd_pcm_runtime *runtime)
412{
413 int usecs;
414
415 if (! runtime->rate)
416 return -1; /* invalid */
417
418 /* take 75% of period time as the deadline */
419 usecs = (750000 / runtime->rate) * runtime->period_size;
420 usecs += ((750000 % runtime->rate) * runtime->period_size) /
421 runtime->rate;
422
423 return usecs;
424}
425
9b0573c0
TI
426static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state)
427{
428 snd_pcm_stream_lock_irq(substream);
429 if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED)
430 substream->runtime->status->state = state;
431 snd_pcm_stream_unlock_irq(substream);
432}
433
877211f5
TI
434static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
435 struct snd_pcm_hw_params *params)
1da177e4 436{
877211f5 437 struct snd_pcm_runtime *runtime;
9442e691 438 int err, usecs;
1da177e4
LT
439 unsigned int bits;
440 snd_pcm_uframes_t frames;
441
7eaa943c
TI
442 if (PCM_RUNTIME_CHECK(substream))
443 return -ENXIO;
1da177e4 444 runtime = substream->runtime;
1da177e4
LT
445 snd_pcm_stream_lock_irq(substream);
446 switch (runtime->status->state) {
447 case SNDRV_PCM_STATE_OPEN:
448 case SNDRV_PCM_STATE_SETUP:
449 case SNDRV_PCM_STATE_PREPARED:
450 break;
451 default:
452 snd_pcm_stream_unlock_irq(substream);
453 return -EBADFD;
454 }
455 snd_pcm_stream_unlock_irq(substream);
8eeaa2f9 456#if IS_ENABLED(CONFIG_SND_PCM_OSS)
1da177e4
LT
457 if (!substream->oss.oss)
458#endif
9c323fcb 459 if (atomic_read(&substream->mmap_count))
1da177e4
LT
460 return -EBADFD;
461
462 params->rmask = ~0U;
463 err = snd_pcm_hw_refine(substream, params);
464 if (err < 0)
465 goto _error;
466
467 err = snd_pcm_hw_params_choose(substream, params);
468 if (err < 0)
469 goto _error;
470
471 if (substream->ops->hw_params != NULL) {
472 err = substream->ops->hw_params(substream, params);
473 if (err < 0)
474 goto _error;
475 }
476
477 runtime->access = params_access(params);
478 runtime->format = params_format(params);
479 runtime->subformat = params_subformat(params);
480 runtime->channels = params_channels(params);
481 runtime->rate = params_rate(params);
482 runtime->period_size = params_period_size(params);
483 runtime->periods = params_periods(params);
484 runtime->buffer_size = params_buffer_size(params);
1da177e4
LT
485 runtime->info = params->info;
486 runtime->rate_num = params->rate_num;
487 runtime->rate_den = params->rate_den;
ab69a490
CL
488 runtime->no_period_wakeup =
489 (params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) &&
490 (params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP);
1da177e4
LT
491
492 bits = snd_pcm_format_physical_width(runtime->format);
493 runtime->sample_bits = bits;
494 bits *= runtime->channels;
495 runtime->frame_bits = bits;
496 frames = 1;
497 while (bits % 8 != 0) {
498 bits *= 2;
499 frames *= 2;
500 }
501 runtime->byte_align = bits / 8;
502 runtime->min_align = frames;
503
504 /* Default sw params */
505 runtime->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
506 runtime->period_step = 1;
1da177e4 507 runtime->control->avail_min = runtime->period_size;
1da177e4
LT
508 runtime->start_threshold = 1;
509 runtime->stop_threshold = runtime->buffer_size;
510 runtime->silence_threshold = 0;
511 runtime->silence_size = 0;
ead4046b
CL
512 runtime->boundary = runtime->buffer_size;
513 while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
514 runtime->boundary *= 2;
1da177e4
LT
515
516 snd_pcm_timer_resolution_change(substream);
9b0573c0 517 snd_pcm_set_state(substream, SNDRV_PCM_STATE_SETUP);
9442e691 518
82f68251
JB
519 if (pm_qos_request_active(&substream->latency_pm_qos_req))
520 pm_qos_remove_request(&substream->latency_pm_qos_req);
9442e691 521 if ((usecs = period_to_usecs(runtime)) >= 0)
82f68251
JB
522 pm_qos_add_request(&substream->latency_pm_qos_req,
523 PM_QOS_CPU_DMA_LATENCY, usecs);
1da177e4
LT
524 return 0;
525 _error:
25985edc 526 /* hardware might be unusable from this time,
1da177e4
LT
527 so we force application to retry to set
528 the correct hardware parameter settings */
9b0573c0 529 snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
1da177e4
LT
530 if (substream->ops->hw_free != NULL)
531 substream->ops->hw_free(substream);
532 return err;
533}
534
877211f5
TI
535static int snd_pcm_hw_params_user(struct snd_pcm_substream *substream,
536 struct snd_pcm_hw_params __user * _params)
1da177e4 537{
877211f5 538 struct snd_pcm_hw_params *params;
1da177e4
LT
539 int err;
540
ef44a1ec
LZ
541 params = memdup_user(_params, sizeof(*params));
542 if (IS_ERR(params))
543 return PTR_ERR(params);
544
1da177e4
LT
545 err = snd_pcm_hw_params(substream, params);
546 if (copy_to_user(_params, params, sizeof(*params))) {
547 if (!err)
548 err = -EFAULT;
549 }
ef44a1ec 550
1da177e4
LT
551 kfree(params);
552 return err;
553}
554
877211f5 555static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
1da177e4 556{
877211f5 557 struct snd_pcm_runtime *runtime;
1da177e4
LT
558 int result = 0;
559
7eaa943c
TI
560 if (PCM_RUNTIME_CHECK(substream))
561 return -ENXIO;
1da177e4 562 runtime = substream->runtime;
1da177e4
LT
563 snd_pcm_stream_lock_irq(substream);
564 switch (runtime->status->state) {
565 case SNDRV_PCM_STATE_SETUP:
566 case SNDRV_PCM_STATE_PREPARED:
567 break;
568 default:
569 snd_pcm_stream_unlock_irq(substream);
570 return -EBADFD;
571 }
572 snd_pcm_stream_unlock_irq(substream);
9c323fcb 573 if (atomic_read(&substream->mmap_count))
1da177e4
LT
574 return -EBADFD;
575 if (substream->ops->hw_free)
576 result = substream->ops->hw_free(substream);
9b0573c0 577 snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
82f68251 578 pm_qos_remove_request(&substream->latency_pm_qos_req);
1da177e4
LT
579 return result;
580}
581
877211f5
TI
582static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
583 struct snd_pcm_sw_params *params)
1da177e4 584{
877211f5 585 struct snd_pcm_runtime *runtime;
1250932e 586 int err;
1da177e4 587
7eaa943c
TI
588 if (PCM_RUNTIME_CHECK(substream))
589 return -ENXIO;
1da177e4 590 runtime = substream->runtime;
1da177e4
LT
591 snd_pcm_stream_lock_irq(substream);
592 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
593 snd_pcm_stream_unlock_irq(substream);
594 return -EBADFD;
595 }
596 snd_pcm_stream_unlock_irq(substream);
597
598 if (params->tstamp_mode > SNDRV_PCM_TSTAMP_LAST)
599 return -EINVAL;
58900810
TI
600 if (params->proto >= SNDRV_PROTOCOL_VERSION(2, 0, 12) &&
601 params->tstamp_type > SNDRV_PCM_TSTAMP_TYPE_LAST)
5646eda5 602 return -EINVAL;
1da177e4
LT
603 if (params->avail_min == 0)
604 return -EINVAL;
1da177e4
LT
605 if (params->silence_size >= runtime->boundary) {
606 if (params->silence_threshold != 0)
607 return -EINVAL;
608 } else {
609 if (params->silence_size > params->silence_threshold)
610 return -EINVAL;
611 if (params->silence_threshold > runtime->buffer_size)
612 return -EINVAL;
613 }
1250932e 614 err = 0;
1da177e4
LT
615 snd_pcm_stream_lock_irq(substream);
616 runtime->tstamp_mode = params->tstamp_mode;
58900810
TI
617 if (params->proto >= SNDRV_PROTOCOL_VERSION(2, 0, 12))
618 runtime->tstamp_type = params->tstamp_type;
1da177e4
LT
619 runtime->period_step = params->period_step;
620 runtime->control->avail_min = params->avail_min;
621 runtime->start_threshold = params->start_threshold;
622 runtime->stop_threshold = params->stop_threshold;
623 runtime->silence_threshold = params->silence_threshold;
624 runtime->silence_size = params->silence_size;
1da177e4
LT
625 params->boundary = runtime->boundary;
626 if (snd_pcm_running(substream)) {
1da177e4
LT
627 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
628 runtime->silence_size > 0)
629 snd_pcm_playback_silence(substream, ULONG_MAX);
1250932e 630 err = snd_pcm_update_state(substream, runtime);
1da177e4
LT
631 }
632 snd_pcm_stream_unlock_irq(substream);
1250932e 633 return err;
1da177e4
LT
634}
635
877211f5
TI
636static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream,
637 struct snd_pcm_sw_params __user * _params)
1da177e4 638{
877211f5 639 struct snd_pcm_sw_params params;
1da177e4
LT
640 int err;
641 if (copy_from_user(&params, _params, sizeof(params)))
642 return -EFAULT;
643 err = snd_pcm_sw_params(substream, &params);
644 if (copy_to_user(_params, &params, sizeof(params)))
645 return -EFAULT;
646 return err;
647}
648
877211f5
TI
649int snd_pcm_status(struct snd_pcm_substream *substream,
650 struct snd_pcm_status *status)
1da177e4 651{
877211f5 652 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
653
654 snd_pcm_stream_lock_irq(substream);
655 status->state = runtime->status->state;
656 status->suspended_state = runtime->status->suspended_state;
657 if (status->state == SNDRV_PCM_STATE_OPEN)
658 goto _end;
659 status->trigger_tstamp = runtime->trigger_tstamp;
8c121586 660 if (snd_pcm_running(substream)) {
1da177e4 661 snd_pcm_update_hw_ptr(substream);
8c121586
JK
662 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) {
663 status->tstamp = runtime->status->tstamp;
4eeaaeae
PLB
664 status->audio_tstamp =
665 runtime->status->audio_tstamp;
8c121586
JK
666 goto _tstamp_end;
667 }
668 }
a713b583 669 snd_pcm_gettime(runtime, &status->tstamp);
8c121586 670 _tstamp_end:
1da177e4
LT
671 status->appl_ptr = runtime->control->appl_ptr;
672 status->hw_ptr = runtime->status->hw_ptr;
673 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
674 status->avail = snd_pcm_playback_avail(runtime);
675 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
4bbe1ddf 676 runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
1da177e4 677 status->delay = runtime->buffer_size - status->avail;
4bbe1ddf
TI
678 status->delay += runtime->delay;
679 } else
1da177e4
LT
680 status->delay = 0;
681 } else {
682 status->avail = snd_pcm_capture_avail(runtime);
683 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
4bbe1ddf 684 status->delay = status->avail + runtime->delay;
1da177e4
LT
685 else
686 status->delay = 0;
687 }
688 status->avail_max = runtime->avail_max;
689 status->overrange = runtime->overrange;
690 runtime->avail_max = 0;
691 runtime->overrange = 0;
692 _end:
693 snd_pcm_stream_unlock_irq(substream);
694 return 0;
695}
696
877211f5
TI
697static int snd_pcm_status_user(struct snd_pcm_substream *substream,
698 struct snd_pcm_status __user * _status)
1da177e4 699{
877211f5 700 struct snd_pcm_status status;
1da177e4
LT
701 int res;
702
1da177e4
LT
703 memset(&status, 0, sizeof(status));
704 res = snd_pcm_status(substream, &status);
705 if (res < 0)
706 return res;
707 if (copy_to_user(_status, &status, sizeof(status)))
708 return -EFAULT;
709 return 0;
710}
711
877211f5
TI
712static int snd_pcm_channel_info(struct snd_pcm_substream *substream,
713 struct snd_pcm_channel_info * info)
1da177e4 714{
877211f5 715 struct snd_pcm_runtime *runtime;
1da177e4
LT
716 unsigned int channel;
717
1da177e4
LT
718 channel = info->channel;
719 runtime = substream->runtime;
720 snd_pcm_stream_lock_irq(substream);
721 if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
722 snd_pcm_stream_unlock_irq(substream);
723 return -EBADFD;
724 }
725 snd_pcm_stream_unlock_irq(substream);
726 if (channel >= runtime->channels)
727 return -EINVAL;
728 memset(info, 0, sizeof(*info));
729 info->channel = channel;
730 return substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_CHANNEL_INFO, info);
731}
732
877211f5
TI
733static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
734 struct snd_pcm_channel_info __user * _info)
1da177e4 735{
877211f5 736 struct snd_pcm_channel_info info;
1da177e4
LT
737 int res;
738
739 if (copy_from_user(&info, _info, sizeof(info)))
740 return -EFAULT;
741 res = snd_pcm_channel_info(substream, &info);
742 if (res < 0)
743 return res;
744 if (copy_to_user(_info, &info, sizeof(info)))
745 return -EFAULT;
746 return 0;
747}
748
877211f5 749static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream)
1da177e4 750{
877211f5 751 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
752 if (runtime->trigger_master == NULL)
753 return;
754 if (runtime->trigger_master == substream) {
b751eef1 755 snd_pcm_gettime(runtime, &runtime->trigger_tstamp);
1da177e4
LT
756 } else {
757 snd_pcm_trigger_tstamp(runtime->trigger_master);
758 runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
759 }
760 runtime->trigger_master = NULL;
761}
762
763struct action_ops {
877211f5
TI
764 int (*pre_action)(struct snd_pcm_substream *substream, int state);
765 int (*do_action)(struct snd_pcm_substream *substream, int state);
766 void (*undo_action)(struct snd_pcm_substream *substream, int state);
767 void (*post_action)(struct snd_pcm_substream *substream, int state);
1da177e4
LT
768};
769
770/*
771 * this functions is core for handling of linked stream
772 * Note: the stream state might be changed also on failure
773 * Note2: call with calling stream lock + link lock
774 */
775static int snd_pcm_action_group(struct action_ops *ops,
877211f5 776 struct snd_pcm_substream *substream,
1da177e4
LT
777 int state, int do_lock)
778{
877211f5
TI
779 struct snd_pcm_substream *s = NULL;
780 struct snd_pcm_substream *s1;
1da177e4
LT
781 int res = 0;
782
ef991b95 783 snd_pcm_group_for_each_entry(s, substream) {
257f8cce
TI
784 if (do_lock && s != substream) {
785 if (s->pcm->nonatomic)
786 mutex_lock_nested(&s->self_group.mutex,
787 SINGLE_DEPTH_NESTING);
788 else
789 spin_lock_nested(&s->self_group.lock,
790 SINGLE_DEPTH_NESTING);
791 }
1da177e4
LT
792 res = ops->pre_action(s, state);
793 if (res < 0)
794 goto _unlock;
795 }
ef991b95 796 snd_pcm_group_for_each_entry(s, substream) {
1da177e4
LT
797 res = ops->do_action(s, state);
798 if (res < 0) {
799 if (ops->undo_action) {
ef991b95 800 snd_pcm_group_for_each_entry(s1, substream) {
1da177e4
LT
801 if (s1 == s) /* failed stream */
802 break;
803 ops->undo_action(s1, state);
804 }
805 }
806 s = NULL; /* unlock all */
807 goto _unlock;
808 }
809 }
ef991b95 810 snd_pcm_group_for_each_entry(s, substream) {
1da177e4
LT
811 ops->post_action(s, state);
812 }
813 _unlock:
814 if (do_lock) {
815 /* unlock streams */
ef991b95 816 snd_pcm_group_for_each_entry(s1, substream) {
257f8cce 817 if (s1 != substream) {
811deede 818 if (s1->pcm->nonatomic)
257f8cce
TI
819 mutex_unlock(&s1->self_group.mutex);
820 else
821 spin_unlock(&s1->self_group.lock);
822 }
1da177e4
LT
823 if (s1 == s) /* end */
824 break;
825 }
826 }
827 return res;
828}
829
830/*
831 * Note: call with stream lock
832 */
833static int snd_pcm_action_single(struct action_ops *ops,
877211f5 834 struct snd_pcm_substream *substream,
1da177e4
LT
835 int state)
836{
837 int res;
838
839 res = ops->pre_action(substream, state);
840 if (res < 0)
841 return res;
842 res = ops->do_action(substream, state);
843 if (res == 0)
844 ops->post_action(substream, state);
845 else if (ops->undo_action)
846 ops->undo_action(substream, state);
847 return res;
848}
849
257f8cce
TI
850/* call in mutex-protected context */
851static int snd_pcm_action_mutex(struct action_ops *ops,
852 struct snd_pcm_substream *substream,
853 int state)
854{
855 int res;
856
857 if (snd_pcm_stream_linked(substream)) {
858 if (!mutex_trylock(&substream->group->mutex)) {
859 mutex_unlock(&substream->self_group.mutex);
860 mutex_lock(&substream->group->mutex);
861 mutex_lock(&substream->self_group.mutex);
862 }
863 res = snd_pcm_action_group(ops, substream, state, 1);
864 mutex_unlock(&substream->group->mutex);
865 } else {
866 res = snd_pcm_action_single(ops, substream, state);
867 }
868 return res;
869}
870
1da177e4
LT
871/*
872 * Note: call with stream lock
873 */
874static int snd_pcm_action(struct action_ops *ops,
877211f5 875 struct snd_pcm_substream *substream,
1da177e4
LT
876 int state)
877{
878 int res;
879
257f8cce
TI
880 if (substream->pcm->nonatomic)
881 return snd_pcm_action_mutex(ops, substream, state);
882
1da177e4
LT
883 if (snd_pcm_stream_linked(substream)) {
884 if (!spin_trylock(&substream->group->lock)) {
885 spin_unlock(&substream->self_group.lock);
886 spin_lock(&substream->group->lock);
887 spin_lock(&substream->self_group.lock);
888 }
889 res = snd_pcm_action_group(ops, substream, state, 1);
890 spin_unlock(&substream->group->lock);
891 } else {
892 res = snd_pcm_action_single(ops, substream, state);
893 }
894 return res;
895}
896
257f8cce
TI
897static int snd_pcm_action_lock_mutex(struct action_ops *ops,
898 struct snd_pcm_substream *substream,
899 int state)
900{
901 int res;
902
903 down_read(&snd_pcm_link_rwsem);
904 if (snd_pcm_stream_linked(substream)) {
905 mutex_lock(&substream->group->mutex);
906 mutex_lock_nested(&substream->self_group.mutex,
907 SINGLE_DEPTH_NESTING);
908 res = snd_pcm_action_group(ops, substream, state, 1);
909 mutex_unlock(&substream->self_group.mutex);
910 mutex_unlock(&substream->group->mutex);
911 } else {
912 mutex_lock(&substream->self_group.mutex);
913 res = snd_pcm_action_single(ops, substream, state);
914 mutex_unlock(&substream->self_group.mutex);
915 }
916 up_read(&snd_pcm_link_rwsem);
917 return res;
918}
919
1da177e4
LT
920/*
921 * Note: don't use any locks before
922 */
923static int snd_pcm_action_lock_irq(struct action_ops *ops,
877211f5 924 struct snd_pcm_substream *substream,
1da177e4
LT
925 int state)
926{
927 int res;
928
257f8cce
TI
929 if (substream->pcm->nonatomic)
930 return snd_pcm_action_lock_mutex(ops, substream, state);
931
1da177e4
LT
932 read_lock_irq(&snd_pcm_link_rwlock);
933 if (snd_pcm_stream_linked(substream)) {
934 spin_lock(&substream->group->lock);
935 spin_lock(&substream->self_group.lock);
936 res = snd_pcm_action_group(ops, substream, state, 1);
937 spin_unlock(&substream->self_group.lock);
938 spin_unlock(&substream->group->lock);
939 } else {
940 spin_lock(&substream->self_group.lock);
941 res = snd_pcm_action_single(ops, substream, state);
942 spin_unlock(&substream->self_group.lock);
943 }
944 read_unlock_irq(&snd_pcm_link_rwlock);
945 return res;
946}
947
948/*
949 */
950static int snd_pcm_action_nonatomic(struct action_ops *ops,
877211f5 951 struct snd_pcm_substream *substream,
1da177e4
LT
952 int state)
953{
954 int res;
955
956 down_read(&snd_pcm_link_rwsem);
957 if (snd_pcm_stream_linked(substream))
958 res = snd_pcm_action_group(ops, substream, state, 0);
959 else
960 res = snd_pcm_action_single(ops, substream, state);
961 up_read(&snd_pcm_link_rwsem);
962 return res;
963}
964
965/*
966 * start callbacks
967 */
877211f5 968static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state)
1da177e4 969{
877211f5 970 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
971 if (runtime->status->state != SNDRV_PCM_STATE_PREPARED)
972 return -EBADFD;
973 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
974 !snd_pcm_playback_data(substream))
975 return -EPIPE;
976 runtime->trigger_master = substream;
977 return 0;
978}
979
877211f5 980static int snd_pcm_do_start(struct snd_pcm_substream *substream, int state)
1da177e4
LT
981{
982 if (substream->runtime->trigger_master != substream)
983 return 0;
984 return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
985}
986
877211f5 987static void snd_pcm_undo_start(struct snd_pcm_substream *substream, int state)
1da177e4
LT
988{
989 if (substream->runtime->trigger_master == substream)
990 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
991}
992
877211f5 993static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
1da177e4 994{
877211f5 995 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4 996 snd_pcm_trigger_tstamp(substream);
6af3fb72 997 runtime->hw_ptr_jiffies = jiffies;
bd76af0f
JK
998 runtime->hw_ptr_buffer_jiffies = (runtime->buffer_size * HZ) /
999 runtime->rate;
1da177e4
LT
1000 runtime->status->state = state;
1001 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
1002 runtime->silence_size > 0)
1003 snd_pcm_playback_silence(substream, ULONG_MAX);
1da177e4 1004 if (substream->timer)
877211f5
TI
1005 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART,
1006 &runtime->trigger_tstamp);
1da177e4
LT
1007}
1008
1009static struct action_ops snd_pcm_action_start = {
1010 .pre_action = snd_pcm_pre_start,
1011 .do_action = snd_pcm_do_start,
1012 .undo_action = snd_pcm_undo_start,
1013 .post_action = snd_pcm_post_start
1014};
1015
1016/**
1c85cc64 1017 * snd_pcm_start - start all linked streams
df8db936 1018 * @substream: the PCM substream instance
eb7c06e8
YB
1019 *
1020 * Return: Zero if successful, or a negative error code.
1da177e4 1021 */
877211f5 1022int snd_pcm_start(struct snd_pcm_substream *substream)
1da177e4 1023{
877211f5
TI
1024 return snd_pcm_action(&snd_pcm_action_start, substream,
1025 SNDRV_PCM_STATE_RUNNING);
1da177e4
LT
1026}
1027
1028/*
1029 * stop callbacks
1030 */
877211f5 1031static int snd_pcm_pre_stop(struct snd_pcm_substream *substream, int state)
1da177e4 1032{
877211f5 1033 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1034 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1035 return -EBADFD;
1036 runtime->trigger_master = substream;
1037 return 0;
1038}
1039
877211f5 1040static int snd_pcm_do_stop(struct snd_pcm_substream *substream, int state)
1da177e4
LT
1041{
1042 if (substream->runtime->trigger_master == substream &&
1043 snd_pcm_running(substream))
1044 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
1045 return 0; /* unconditonally stop all substreams */
1046}
1047
877211f5 1048static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
1da177e4 1049{
877211f5 1050 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1051 if (runtime->status->state != state) {
1052 snd_pcm_trigger_tstamp(substream);
1053 if (substream->timer)
877211f5
TI
1054 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP,
1055 &runtime->trigger_tstamp);
1da177e4 1056 runtime->status->state = state;
1da177e4
LT
1057 }
1058 wake_up(&runtime->sleep);
c91a988d 1059 wake_up(&runtime->tsleep);
1da177e4
LT
1060}
1061
1062static struct action_ops snd_pcm_action_stop = {
1063 .pre_action = snd_pcm_pre_stop,
1064 .do_action = snd_pcm_do_stop,
1065 .post_action = snd_pcm_post_stop
1066};
1067
1068/**
1c85cc64 1069 * snd_pcm_stop - try to stop all running streams in the substream group
df8db936
TI
1070 * @substream: the PCM substream instance
1071 * @state: PCM state after stopping the stream
1da177e4 1072 *
1c85cc64 1073 * The state of each stream is then changed to the given state unconditionally.
eb7c06e8 1074 *
0a11458c 1075 * Return: Zero if successful, or a negative error code.
1da177e4 1076 */
fea952e5 1077int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t state)
1da177e4
LT
1078{
1079 return snd_pcm_action(&snd_pcm_action_stop, substream, state);
1080}
1081
e88e8ae6
TI
1082EXPORT_SYMBOL(snd_pcm_stop);
1083
1da177e4 1084/**
1c85cc64 1085 * snd_pcm_drain_done - stop the DMA only when the given stream is playback
df8db936 1086 * @substream: the PCM substream
1da177e4 1087 *
1c85cc64 1088 * After stopping, the state is changed to SETUP.
1da177e4 1089 * Unlike snd_pcm_stop(), this affects only the given stream.
eb7c06e8
YB
1090 *
1091 * Return: Zero if succesful, or a negative error code.
1da177e4 1092 */
877211f5 1093int snd_pcm_drain_done(struct snd_pcm_substream *substream)
1da177e4 1094{
877211f5
TI
1095 return snd_pcm_action_single(&snd_pcm_action_stop, substream,
1096 SNDRV_PCM_STATE_SETUP);
1da177e4
LT
1097}
1098
1099/*
1100 * pause callbacks
1101 */
877211f5 1102static int snd_pcm_pre_pause(struct snd_pcm_substream *substream, int push)
1da177e4 1103{
877211f5 1104 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1105 if (!(runtime->info & SNDRV_PCM_INFO_PAUSE))
1106 return -ENOSYS;
1107 if (push) {
1108 if (runtime->status->state != SNDRV_PCM_STATE_RUNNING)
1109 return -EBADFD;
1110 } else if (runtime->status->state != SNDRV_PCM_STATE_PAUSED)
1111 return -EBADFD;
1112 runtime->trigger_master = substream;
1113 return 0;
1114}
1115
877211f5 1116static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
1da177e4
LT
1117{
1118 if (substream->runtime->trigger_master != substream)
1119 return 0;
56385a12
JK
1120 /* some drivers might use hw_ptr to recover from the pause -
1121 update the hw_ptr now */
1122 if (push)
1123 snd_pcm_update_hw_ptr(substream);
6af3fb72 1124 /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
b595076a 1125 * a delta between the current jiffies, this gives a large enough
6af3fb72
TI
1126 * delta, effectively to skip the check once.
1127 */
1128 substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000;
1da177e4
LT
1129 return substream->ops->trigger(substream,
1130 push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH :
1131 SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
1132}
1133
877211f5 1134static void snd_pcm_undo_pause(struct snd_pcm_substream *substream, int push)
1da177e4
LT
1135{
1136 if (substream->runtime->trigger_master == substream)
1137 substream->ops->trigger(substream,
1138 push ? SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
1139 SNDRV_PCM_TRIGGER_PAUSE_PUSH);
1140}
1141
877211f5 1142static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
1da177e4 1143{
877211f5 1144 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1145 snd_pcm_trigger_tstamp(substream);
1146 if (push) {
1147 runtime->status->state = SNDRV_PCM_STATE_PAUSED;
1148 if (substream->timer)
877211f5
TI
1149 snd_timer_notify(substream->timer,
1150 SNDRV_TIMER_EVENT_MPAUSE,
1151 &runtime->trigger_tstamp);
1da177e4 1152 wake_up(&runtime->sleep);
c91a988d 1153 wake_up(&runtime->tsleep);
1da177e4
LT
1154 } else {
1155 runtime->status->state = SNDRV_PCM_STATE_RUNNING;
1da177e4 1156 if (substream->timer)
877211f5
TI
1157 snd_timer_notify(substream->timer,
1158 SNDRV_TIMER_EVENT_MCONTINUE,
1159 &runtime->trigger_tstamp);
1da177e4
LT
1160 }
1161}
1162
1163static struct action_ops snd_pcm_action_pause = {
1164 .pre_action = snd_pcm_pre_pause,
1165 .do_action = snd_pcm_do_pause,
1166 .undo_action = snd_pcm_undo_pause,
1167 .post_action = snd_pcm_post_pause
1168};
1169
1170/*
1171 * Push/release the pause for all linked streams.
1172 */
877211f5 1173static int snd_pcm_pause(struct snd_pcm_substream *substream, int push)
1da177e4
LT
1174{
1175 return snd_pcm_action(&snd_pcm_action_pause, substream, push);
1176}
1177
1178#ifdef CONFIG_PM
1179/* suspend */
1180
877211f5 1181static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state)
1da177e4 1182{
877211f5 1183 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1184 if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
1185 return -EBUSY;
1186 runtime->trigger_master = substream;
1187 return 0;
1188}
1189
877211f5 1190static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, int state)
1da177e4 1191{
877211f5 1192 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1193 if (runtime->trigger_master != substream)
1194 return 0;
1195 if (! snd_pcm_running(substream))
1196 return 0;
1197 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
1198 return 0; /* suspend unconditionally */
1199}
1200
877211f5 1201static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
1da177e4 1202{
877211f5 1203 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1204 snd_pcm_trigger_tstamp(substream);
1205 if (substream->timer)
877211f5
TI
1206 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSUSPEND,
1207 &runtime->trigger_tstamp);
1da177e4
LT
1208 runtime->status->suspended_state = runtime->status->state;
1209 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
1da177e4 1210 wake_up(&runtime->sleep);
c91a988d 1211 wake_up(&runtime->tsleep);
1da177e4
LT
1212}
1213
1214static struct action_ops snd_pcm_action_suspend = {
1215 .pre_action = snd_pcm_pre_suspend,
1216 .do_action = snd_pcm_do_suspend,
1217 .post_action = snd_pcm_post_suspend
1218};
1219
1220/**
1c85cc64 1221 * snd_pcm_suspend - trigger SUSPEND to all linked streams
df8db936 1222 * @substream: the PCM substream
1da177e4 1223 *
1da177e4 1224 * After this call, all streams are changed to SUSPENDED state.
eb7c06e8
YB
1225 *
1226 * Return: Zero if successful (or @substream is %NULL), or a negative error
1227 * code.
1da177e4 1228 */
877211f5 1229int snd_pcm_suspend(struct snd_pcm_substream *substream)
1da177e4
LT
1230{
1231 int err;
1232 unsigned long flags;
1233
603bf524
TI
1234 if (! substream)
1235 return 0;
1236
1da177e4
LT
1237 snd_pcm_stream_lock_irqsave(substream, flags);
1238 err = snd_pcm_action(&snd_pcm_action_suspend, substream, 0);
1239 snd_pcm_stream_unlock_irqrestore(substream, flags);
1240 return err;
1241}
1242
e88e8ae6
TI
1243EXPORT_SYMBOL(snd_pcm_suspend);
1244
1da177e4 1245/**
1c85cc64 1246 * snd_pcm_suspend_all - trigger SUSPEND to all substreams in the given pcm
df8db936 1247 * @pcm: the PCM instance
1da177e4 1248 *
1da177e4 1249 * After this call, all streams are changed to SUSPENDED state.
eb7c06e8
YB
1250 *
1251 * Return: Zero if successful (or @pcm is %NULL), or a negative error code.
1da177e4 1252 */
877211f5 1253int snd_pcm_suspend_all(struct snd_pcm *pcm)
1da177e4 1254{
877211f5 1255 struct snd_pcm_substream *substream;
1da177e4
LT
1256 int stream, err = 0;
1257
603bf524
TI
1258 if (! pcm)
1259 return 0;
1260
1da177e4 1261 for (stream = 0; stream < 2; stream++) {
877211f5
TI
1262 for (substream = pcm->streams[stream].substream;
1263 substream; substream = substream->next) {
1da177e4
LT
1264 /* FIXME: the open/close code should lock this as well */
1265 if (substream->runtime == NULL)
1266 continue;
1267 err = snd_pcm_suspend(substream);
1268 if (err < 0 && err != -EBUSY)
1269 return err;
1270 }
1271 }
1272 return 0;
1273}
1274
e88e8ae6
TI
1275EXPORT_SYMBOL(snd_pcm_suspend_all);
1276
1da177e4
LT
1277/* resume */
1278
877211f5 1279static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
1da177e4 1280{
877211f5 1281 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1282 if (!(runtime->info & SNDRV_PCM_INFO_RESUME))
1283 return -ENOSYS;
1284 runtime->trigger_master = substream;
1285 return 0;
1286}
1287
877211f5 1288static int snd_pcm_do_resume(struct snd_pcm_substream *substream, int state)
1da177e4 1289{
877211f5 1290 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1291 if (runtime->trigger_master != substream)
1292 return 0;
1293 /* DMA not running previously? */
1294 if (runtime->status->suspended_state != SNDRV_PCM_STATE_RUNNING &&
1295 (runtime->status->suspended_state != SNDRV_PCM_STATE_DRAINING ||
1296 substream->stream != SNDRV_PCM_STREAM_PLAYBACK))
1297 return 0;
1298 return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME);
1299}
1300
877211f5 1301static void snd_pcm_undo_resume(struct snd_pcm_substream *substream, int state)
1da177e4
LT
1302{
1303 if (substream->runtime->trigger_master == substream &&
1304 snd_pcm_running(substream))
1305 substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
1306}
1307
877211f5 1308static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
1da177e4 1309{
877211f5 1310 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1311 snd_pcm_trigger_tstamp(substream);
1312 if (substream->timer)
877211f5
TI
1313 snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME,
1314 &runtime->trigger_tstamp);
1da177e4 1315 runtime->status->state = runtime->status->suspended_state;
1da177e4
LT
1316}
1317
1318static struct action_ops snd_pcm_action_resume = {
1319 .pre_action = snd_pcm_pre_resume,
1320 .do_action = snd_pcm_do_resume,
1321 .undo_action = snd_pcm_undo_resume,
1322 .post_action = snd_pcm_post_resume
1323};
1324
877211f5 1325static int snd_pcm_resume(struct snd_pcm_substream *substream)
1da177e4 1326{
877211f5 1327 struct snd_card *card = substream->pcm->card;
1da177e4
LT
1328 int res;
1329
1330 snd_power_lock(card);
cbac4b0c 1331 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
1da177e4
LT
1332 res = snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0);
1333 snd_power_unlock(card);
1334 return res;
1335}
1336
1337#else
1338
877211f5 1339static int snd_pcm_resume(struct snd_pcm_substream *substream)
1da177e4
LT
1340{
1341 return -ENOSYS;
1342}
1343
1344#endif /* CONFIG_PM */
1345
1346/*
1347 * xrun ioctl
1348 *
1349 * Change the RUNNING stream(s) to XRUN state.
1350 */
877211f5 1351static int snd_pcm_xrun(struct snd_pcm_substream *substream)
1da177e4 1352{
877211f5
TI
1353 struct snd_card *card = substream->pcm->card;
1354 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1355 int result;
1356
1357 snd_power_lock(card);
1358 if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
cbac4b0c 1359 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
1da177e4
LT
1360 if (result < 0)
1361 goto _unlock;
1362 }
1363
1364 snd_pcm_stream_lock_irq(substream);
1365 switch (runtime->status->state) {
1366 case SNDRV_PCM_STATE_XRUN:
1367 result = 0; /* already there */
1368 break;
1369 case SNDRV_PCM_STATE_RUNNING:
1370 result = snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
1371 break;
1372 default:
1373 result = -EBADFD;
1374 }
1375 snd_pcm_stream_unlock_irq(substream);
1376 _unlock:
1377 snd_power_unlock(card);
1378 return result;
1379}
1380
1381/*
1382 * reset ioctl
1383 */
877211f5 1384static int snd_pcm_pre_reset(struct snd_pcm_substream *substream, int state)
1da177e4 1385{
877211f5 1386 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1387 switch (runtime->status->state) {
1388 case SNDRV_PCM_STATE_RUNNING:
1389 case SNDRV_PCM_STATE_PREPARED:
1390 case SNDRV_PCM_STATE_PAUSED:
1391 case SNDRV_PCM_STATE_SUSPENDED:
1392 return 0;
1393 default:
1394 return -EBADFD;
1395 }
1396}
1397
877211f5 1398static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
1da177e4 1399{
877211f5 1400 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1401 int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
1402 if (err < 0)
1403 return err;
1da177e4 1404 runtime->hw_ptr_base = 0;
e7636925
JK
1405 runtime->hw_ptr_interrupt = runtime->status->hw_ptr -
1406 runtime->status->hw_ptr % runtime->period_size;
1da177e4
LT
1407 runtime->silence_start = runtime->status->hw_ptr;
1408 runtime->silence_filled = 0;
1409 return 0;
1410}
1411
877211f5 1412static void snd_pcm_post_reset(struct snd_pcm_substream *substream, int state)
1da177e4 1413{
877211f5 1414 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1415 runtime->control->appl_ptr = runtime->status->hw_ptr;
1416 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
1417 runtime->silence_size > 0)
1418 snd_pcm_playback_silence(substream, ULONG_MAX);
1419}
1420
1421static struct action_ops snd_pcm_action_reset = {
1422 .pre_action = snd_pcm_pre_reset,
1423 .do_action = snd_pcm_do_reset,
1424 .post_action = snd_pcm_post_reset
1425};
1426
877211f5 1427static int snd_pcm_reset(struct snd_pcm_substream *substream)
1da177e4
LT
1428{
1429 return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream, 0);
1430}
1431
1432/*
1433 * prepare ioctl
1434 */
0df63e44
TI
1435/* we use the second argument for updating f_flags */
1436static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
1437 int f_flags)
1da177e4 1438{
877211f5 1439 struct snd_pcm_runtime *runtime = substream->runtime;
de1b8b93
TI
1440 if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
1441 runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
1da177e4
LT
1442 return -EBADFD;
1443 if (snd_pcm_running(substream))
1444 return -EBUSY;
0df63e44 1445 substream->f_flags = f_flags;
1da177e4
LT
1446 return 0;
1447}
1448
877211f5 1449static int snd_pcm_do_prepare(struct snd_pcm_substream *substream, int state)
1da177e4
LT
1450{
1451 int err;
1452 err = substream->ops->prepare(substream);
1453 if (err < 0)
1454 return err;
1455 return snd_pcm_do_reset(substream, 0);
1456}
1457
877211f5 1458static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state)
1da177e4 1459{
877211f5 1460 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4 1461 runtime->control->appl_ptr = runtime->status->hw_ptr;
9b0573c0 1462 snd_pcm_set_state(substream, SNDRV_PCM_STATE_PREPARED);
1da177e4
LT
1463}
1464
1465static struct action_ops snd_pcm_action_prepare = {
1466 .pre_action = snd_pcm_pre_prepare,
1467 .do_action = snd_pcm_do_prepare,
1468 .post_action = snd_pcm_post_prepare
1469};
1470
1471/**
1c85cc64 1472 * snd_pcm_prepare - prepare the PCM substream to be triggerable
df8db936 1473 * @substream: the PCM substream instance
0df63e44 1474 * @file: file to refer f_flags
eb7c06e8
YB
1475 *
1476 * Return: Zero if successful, or a negative error code.
1da177e4 1477 */
0df63e44
TI
1478static int snd_pcm_prepare(struct snd_pcm_substream *substream,
1479 struct file *file)
1da177e4
LT
1480{
1481 int res;
877211f5 1482 struct snd_card *card = substream->pcm->card;
0df63e44
TI
1483 int f_flags;
1484
1485 if (file)
1486 f_flags = file->f_flags;
1487 else
1488 f_flags = substream->f_flags;
1da177e4
LT
1489
1490 snd_power_lock(card);
cbac4b0c 1491 if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0)) >= 0)
0df63e44
TI
1492 res = snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
1493 substream, f_flags);
1da177e4
LT
1494 snd_power_unlock(card);
1495 return res;
1496}
1497
1498/*
1499 * drain ioctl
1500 */
1501
877211f5 1502static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
1da177e4 1503{
4f7c39dc
TI
1504 struct snd_pcm_runtime *runtime = substream->runtime;
1505 switch (runtime->status->state) {
1506 case SNDRV_PCM_STATE_OPEN:
1507 case SNDRV_PCM_STATE_DISCONNECTED:
1508 case SNDRV_PCM_STATE_SUSPENDED:
1509 return -EBADFD;
1510 }
1511 runtime->trigger_master = substream;
1da177e4
LT
1512 return 0;
1513}
1514
877211f5 1515static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
1da177e4 1516{
877211f5 1517 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
1518 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1519 switch (runtime->status->state) {
1520 case SNDRV_PCM_STATE_PREPARED:
1521 /* start playback stream if possible */
1522 if (! snd_pcm_playback_empty(substream)) {
1523 snd_pcm_do_start(substream, SNDRV_PCM_STATE_DRAINING);
1524 snd_pcm_post_start(substream, SNDRV_PCM_STATE_DRAINING);
1525 }
1526 break;
1527 case SNDRV_PCM_STATE_RUNNING:
1528 runtime->status->state = SNDRV_PCM_STATE_DRAINING;
1529 break;
4f7c39dc
TI
1530 case SNDRV_PCM_STATE_XRUN:
1531 runtime->status->state = SNDRV_PCM_STATE_SETUP;
1532 break;
1da177e4
LT
1533 default:
1534 break;
1535 }
1536 } else {
1537 /* stop running stream */
1538 if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
b05e5787 1539 int new_state = snd_pcm_capture_avail(runtime) > 0 ?
1da177e4 1540 SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP;
b05e5787
1541 snd_pcm_do_stop(substream, new_state);
1542 snd_pcm_post_stop(substream, new_state);
1da177e4
LT
1543 }
1544 }
1545 return 0;
1546}
1547
877211f5 1548static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream, int state)
1da177e4
LT
1549{
1550}
1551
1552static struct action_ops snd_pcm_action_drain_init = {
1553 .pre_action = snd_pcm_pre_drain_init,
1554 .do_action = snd_pcm_do_drain_init,
1555 .post_action = snd_pcm_post_drain_init
1556};
1557
877211f5 1558static int snd_pcm_drop(struct snd_pcm_substream *substream);
1da177e4
LT
1559
1560/*
1561 * Drain the stream(s).
1562 * When the substream is linked, sync until the draining of all playback streams
1563 * is finished.
1564 * After this call, all streams are supposed to be either SETUP or DRAINING
1565 * (capture only) state.
1566 */
4cdc115f
TI
1567static int snd_pcm_drain(struct snd_pcm_substream *substream,
1568 struct file *file)
1da177e4 1569{
877211f5
TI
1570 struct snd_card *card;
1571 struct snd_pcm_runtime *runtime;
ef991b95 1572 struct snd_pcm_substream *s;
d3a7dcfe 1573 wait_queue_t wait;
1da177e4 1574 int result = 0;
4cdc115f 1575 int nonblock = 0;
1da177e4 1576
1da177e4
LT
1577 card = substream->pcm->card;
1578 runtime = substream->runtime;
1579
1580 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1581 return -EBADFD;
1582
1da177e4
LT
1583 snd_power_lock(card);
1584 if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
cbac4b0c 1585 result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
21cb2a2e
TI
1586 if (result < 0) {
1587 snd_power_unlock(card);
1588 return result;
1589 }
1da177e4
LT
1590 }
1591
4cdc115f
TI
1592 if (file) {
1593 if (file->f_flags & O_NONBLOCK)
1594 nonblock = 1;
1595 } else if (substream->f_flags & O_NONBLOCK)
1596 nonblock = 1;
1597
21cb2a2e 1598 down_read(&snd_pcm_link_rwsem);
21cb2a2e
TI
1599 snd_pcm_stream_lock_irq(substream);
1600 /* resume pause */
d3a7dcfe 1601 if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
21cb2a2e
TI
1602 snd_pcm_pause(substream, 0);
1603
1604 /* pre-start/stop - all running streams are changed to DRAINING state */
1605 result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
4cdc115f
TI
1606 if (result < 0)
1607 goto unlock;
1608 /* in non-blocking, we don't wait in ioctl but let caller poll */
1609 if (nonblock) {
1610 result = -EAGAIN;
1611 goto unlock;
21cb2a2e 1612 }
1da177e4
LT
1613
1614 for (;;) {
1615 long tout;
d3a7dcfe 1616 struct snd_pcm_runtime *to_check;
1da177e4
LT
1617 if (signal_pending(current)) {
1618 result = -ERESTARTSYS;
1619 break;
1620 }
d3a7dcfe
TI
1621 /* find a substream to drain */
1622 to_check = NULL;
1623 snd_pcm_group_for_each_entry(s, substream) {
1624 if (s->stream != SNDRV_PCM_STREAM_PLAYBACK)
1625 continue;
1626 runtime = s->runtime;
1627 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
1628 to_check = runtime;
21cb2a2e 1629 break;
d3a7dcfe 1630 }
21cb2a2e 1631 }
d3a7dcfe
TI
1632 if (!to_check)
1633 break; /* all drained */
1634 init_waitqueue_entry(&wait, current);
1635 add_wait_queue(&to_check->sleep, &wait);
1da177e4 1636 snd_pcm_stream_unlock_irq(substream);
d3a7dcfe 1637 up_read(&snd_pcm_link_rwsem);
1da177e4 1638 snd_power_unlock(card);
f2b3614c
TI
1639 if (runtime->no_period_wakeup)
1640 tout = MAX_SCHEDULE_TIMEOUT;
1641 else {
1642 tout = 10;
1643 if (runtime->rate) {
1644 long t = runtime->period_size * 2 / runtime->rate;
1645 tout = max(t, tout);
1646 }
1647 tout = msecs_to_jiffies(tout * 1000);
1648 }
1649 tout = schedule_timeout_interruptible(tout);
1da177e4 1650 snd_power_lock(card);
d3a7dcfe 1651 down_read(&snd_pcm_link_rwsem);
1da177e4 1652 snd_pcm_stream_lock_irq(substream);
d3a7dcfe 1653 remove_wait_queue(&to_check->sleep, &wait);
0914f796
TI
1654 if (card->shutdown) {
1655 result = -ENODEV;
1656 break;
1657 }
1da177e4
LT
1658 if (tout == 0) {
1659 if (substream->runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
1660 result = -ESTRPIPE;
1661 else {
09e56df8
TI
1662 dev_dbg(substream->pcm->card->dev,
1663 "playback drain error (DMA or IRQ trouble?)\n");
1da177e4
LT
1664 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
1665 result = -EIO;
1666 }
1667 break;
1668 }
1da177e4 1669 }
21cb2a2e 1670
4cdc115f 1671 unlock:
21cb2a2e 1672 snd_pcm_stream_unlock_irq(substream);
d3a7dcfe 1673 up_read(&snd_pcm_link_rwsem);
1da177e4 1674 snd_power_unlock(card);
1da177e4
LT
1675
1676 return result;
1677}
1678
1679/*
1680 * drop ioctl
1681 *
1682 * Immediately put all linked substreams into SETUP state.
1683 */
877211f5 1684static int snd_pcm_drop(struct snd_pcm_substream *substream)
1da177e4 1685{
877211f5 1686 struct snd_pcm_runtime *runtime;
1da177e4
LT
1687 int result = 0;
1688
7eaa943c
TI
1689 if (PCM_RUNTIME_CHECK(substream))
1690 return -ENXIO;
1da177e4 1691 runtime = substream->runtime;
1da177e4 1692
de1b8b93 1693 if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
24e8fc49
TI
1694 runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED ||
1695 runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
1da177e4
LT
1696 return -EBADFD;
1697
1da177e4
LT
1698 snd_pcm_stream_lock_irq(substream);
1699 /* resume pause */
1700 if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
1701 snd_pcm_pause(substream, 0);
1702
1703 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
1704 /* runtime->control->appl_ptr = runtime->status->hw_ptr; */
1705 snd_pcm_stream_unlock_irq(substream);
24e8fc49 1706
1da177e4
LT
1707 return result;
1708}
1709
1710
0888c321 1711static bool is_pcm_file(struct file *file)
1da177e4 1712{
0888c321 1713 struct inode *inode = file_inode(file);
f87135f5
CL
1714 unsigned int minor;
1715
0888c321
AV
1716 if (!S_ISCHR(inode->i_mode) || imajor(inode) != snd_major)
1717 return false;
1da177e4 1718 minor = iminor(inode);
0888c321
AV
1719 return snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) ||
1720 snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE);
1da177e4
LT
1721}
1722
1723/*
1724 * PCM link handling
1725 */
877211f5 1726static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
1da177e4
LT
1727{
1728 int res = 0;
877211f5
TI
1729 struct snd_pcm_file *pcm_file;
1730 struct snd_pcm_substream *substream1;
1662591b 1731 struct snd_pcm_group *group;
0888c321 1732 struct fd f = fdget(fd);
1da177e4 1733
0888c321 1734 if (!f.file)
1da177e4 1735 return -EBADFD;
0888c321
AV
1736 if (!is_pcm_file(f.file)) {
1737 res = -EBADFD;
1738 goto _badf;
1739 }
1740 pcm_file = f.file->private_data;
1da177e4 1741 substream1 = pcm_file->substream;
1662591b
TI
1742 group = kmalloc(sizeof(*group), GFP_KERNEL);
1743 if (!group) {
1744 res = -ENOMEM;
1745 goto _nolock;
1746 }
1da177e4
LT
1747 down_write(&snd_pcm_link_rwsem);
1748 write_lock_irq(&snd_pcm_link_rwlock);
1749 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
257f8cce
TI
1750 substream->runtime->status->state != substream1->runtime->status->state ||
1751 substream->pcm->nonatomic != substream1->pcm->nonatomic) {
1da177e4
LT
1752 res = -EBADFD;
1753 goto _end;
1754 }
1755 if (snd_pcm_stream_linked(substream1)) {
1756 res = -EALREADY;
1757 goto _end;
1758 }
1759 if (!snd_pcm_stream_linked(substream)) {
1662591b 1760 substream->group = group;
dd6c5cd8 1761 group = NULL;
1da177e4 1762 spin_lock_init(&substream->group->lock);
257f8cce 1763 mutex_init(&substream->group->mutex);
1da177e4
LT
1764 INIT_LIST_HEAD(&substream->group->substreams);
1765 list_add_tail(&substream->link_list, &substream->group->substreams);
1766 substream->group->count = 1;
1767 }
1768 list_add_tail(&substream1->link_list, &substream->group->substreams);
1769 substream->group->count++;
1770 substream1->group = substream->group;
1771 _end:
1772 write_unlock_irq(&snd_pcm_link_rwlock);
1773 up_write(&snd_pcm_link_rwsem);
1662591b 1774 _nolock:
a0830dbd 1775 snd_card_unref(substream1->pcm->card);
dd6c5cd8 1776 kfree(group);
0888c321
AV
1777 _badf:
1778 fdput(f);
1da177e4
LT
1779 return res;
1780}
1781
877211f5 1782static void relink_to_local(struct snd_pcm_substream *substream)
1da177e4
LT
1783{
1784 substream->group = &substream->self_group;
1785 INIT_LIST_HEAD(&substream->self_group.substreams);
1786 list_add_tail(&substream->link_list, &substream->self_group.substreams);
1787}
1788
877211f5 1789static int snd_pcm_unlink(struct snd_pcm_substream *substream)
1da177e4 1790{
ef991b95 1791 struct snd_pcm_substream *s;
1da177e4
LT
1792 int res = 0;
1793
1794 down_write(&snd_pcm_link_rwsem);
1795 write_lock_irq(&snd_pcm_link_rwlock);
1796 if (!snd_pcm_stream_linked(substream)) {
1797 res = -EALREADY;
1798 goto _end;
1799 }
1800 list_del(&substream->link_list);
1801 substream->group->count--;
1802 if (substream->group->count == 1) { /* detach the last stream, too */
ef991b95
TI
1803 snd_pcm_group_for_each_entry(s, substream) {
1804 relink_to_local(s);
1da177e4
LT
1805 break;
1806 }
1807 kfree(substream->group);
1808 }
1809 relink_to_local(substream);
1810 _end:
1811 write_unlock_irq(&snd_pcm_link_rwlock);
1812 up_write(&snd_pcm_link_rwsem);
1813 return res;
1814}
1815
1816/*
1817 * hw configurator
1818 */
877211f5
TI
1819static int snd_pcm_hw_rule_mul(struct snd_pcm_hw_params *params,
1820 struct snd_pcm_hw_rule *rule)
1da177e4 1821{
877211f5 1822 struct snd_interval t;
1da177e4
LT
1823 snd_interval_mul(hw_param_interval_c(params, rule->deps[0]),
1824 hw_param_interval_c(params, rule->deps[1]), &t);
1825 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
1826}
1827
877211f5
TI
1828static int snd_pcm_hw_rule_div(struct snd_pcm_hw_params *params,
1829 struct snd_pcm_hw_rule *rule)
1da177e4 1830{
877211f5 1831 struct snd_interval t;
1da177e4
LT
1832 snd_interval_div(hw_param_interval_c(params, rule->deps[0]),
1833 hw_param_interval_c(params, rule->deps[1]), &t);
1834 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
1835}
1836
877211f5
TI
1837static int snd_pcm_hw_rule_muldivk(struct snd_pcm_hw_params *params,
1838 struct snd_pcm_hw_rule *rule)
1da177e4 1839{
877211f5 1840 struct snd_interval t;
1da177e4
LT
1841 snd_interval_muldivk(hw_param_interval_c(params, rule->deps[0]),
1842 hw_param_interval_c(params, rule->deps[1]),
1843 (unsigned long) rule->private, &t);
1844 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
1845}
1846
877211f5
TI
1847static int snd_pcm_hw_rule_mulkdiv(struct snd_pcm_hw_params *params,
1848 struct snd_pcm_hw_rule *rule)
1da177e4 1849{
877211f5 1850 struct snd_interval t;
1da177e4
LT
1851 snd_interval_mulkdiv(hw_param_interval_c(params, rule->deps[0]),
1852 (unsigned long) rule->private,
1853 hw_param_interval_c(params, rule->deps[1]), &t);
1854 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
1855}
1856
877211f5
TI
1857static int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params,
1858 struct snd_pcm_hw_rule *rule)
1da177e4
LT
1859{
1860 unsigned int k;
877211f5
TI
1861 struct snd_interval *i = hw_param_interval(params, rule->deps[0]);
1862 struct snd_mask m;
1863 struct snd_mask *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1da177e4
LT
1864 snd_mask_any(&m);
1865 for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) {
1866 int bits;
1867 if (! snd_mask_test(mask, k))
1868 continue;
1869 bits = snd_pcm_format_physical_width(k);
1870 if (bits <= 0)
1871 continue; /* ignore invalid formats */
1872 if ((unsigned)bits < i->min || (unsigned)bits > i->max)
1873 snd_mask_reset(&m, k);
1874 }
1875 return snd_mask_refine(mask, &m);
1876}
1877
877211f5
TI
1878static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params,
1879 struct snd_pcm_hw_rule *rule)
1da177e4 1880{
877211f5 1881 struct snd_interval t;
1da177e4
LT
1882 unsigned int k;
1883 t.min = UINT_MAX;
1884 t.max = 0;
1885 t.openmin = 0;
1886 t.openmax = 0;
1887 for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) {
1888 int bits;
1889 if (! snd_mask_test(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), k))
1890 continue;
1891 bits = snd_pcm_format_physical_width(k);
1892 if (bits <= 0)
1893 continue; /* ignore invalid formats */
1894 if (t.min > (unsigned)bits)
1895 t.min = bits;
1896 if (t.max < (unsigned)bits)
1897 t.max = bits;
1898 }
1899 t.integer = 1;
1900 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
1901}
1902
1903#if SNDRV_PCM_RATE_5512 != 1 << 0 || SNDRV_PCM_RATE_192000 != 1 << 12
1904#error "Change this table"
1905#endif
1906
1907static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
1908 48000, 64000, 88200, 96000, 176400, 192000 };
1909
7653d557
CL
1910const struct snd_pcm_hw_constraint_list snd_pcm_known_rates = {
1911 .count = ARRAY_SIZE(rates),
1912 .list = rates,
1913};
1914
877211f5
TI
1915static int snd_pcm_hw_rule_rate(struct snd_pcm_hw_params *params,
1916 struct snd_pcm_hw_rule *rule)
1da177e4 1917{
877211f5 1918 struct snd_pcm_hardware *hw = rule->private;
1da177e4 1919 return snd_interval_list(hw_param_interval(params, rule->var),
7653d557
CL
1920 snd_pcm_known_rates.count,
1921 snd_pcm_known_rates.list, hw->rates);
1da177e4
LT
1922}
1923
877211f5
TI
1924static int snd_pcm_hw_rule_buffer_bytes_max(struct snd_pcm_hw_params *params,
1925 struct snd_pcm_hw_rule *rule)
1da177e4 1926{
877211f5
TI
1927 struct snd_interval t;
1928 struct snd_pcm_substream *substream = rule->private;
1da177e4
LT
1929 t.min = 0;
1930 t.max = substream->buffer_bytes_max;
1931 t.openmin = 0;
1932 t.openmax = 0;
1933 t.integer = 1;
1934 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
1935}
1936
877211f5 1937int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
1da177e4 1938{
877211f5
TI
1939 struct snd_pcm_runtime *runtime = substream->runtime;
1940 struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
1da177e4
LT
1941 int k, err;
1942
1943 for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) {
1944 snd_mask_any(constrs_mask(constrs, k));
1945 }
1946
1947 for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++) {
1948 snd_interval_any(constrs_interval(constrs, k));
1949 }
1950
1951 snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_CHANNELS));
1952 snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_BUFFER_SIZE));
1953 snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_BUFFER_BYTES));
1954 snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_SAMPLE_BITS));
1955 snd_interval_setinteger(constrs_interval(constrs, SNDRV_PCM_HW_PARAM_FRAME_BITS));
1956
1957 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
1958 snd_pcm_hw_rule_format, NULL,
1959 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
1960 if (err < 0)
1961 return err;
1962 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1963 snd_pcm_hw_rule_sample_bits, NULL,
1964 SNDRV_PCM_HW_PARAM_FORMAT,
1965 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
1966 if (err < 0)
1967 return err;
1968 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1969 snd_pcm_hw_rule_div, NULL,
1970 SNDRV_PCM_HW_PARAM_FRAME_BITS, SNDRV_PCM_HW_PARAM_CHANNELS, -1);
1971 if (err < 0)
1972 return err;
1973 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FRAME_BITS,
1974 snd_pcm_hw_rule_mul, NULL,
1975 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, SNDRV_PCM_HW_PARAM_CHANNELS, -1);
1976 if (err < 0)
1977 return err;
1978 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FRAME_BITS,
1979 snd_pcm_hw_rule_mulkdiv, (void*) 8,
1980 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1);
1981 if (err < 0)
1982 return err;
1983 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FRAME_BITS,
1984 snd_pcm_hw_rule_mulkdiv, (void*) 8,
1985 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1);
1986 if (err < 0)
1987 return err;
1988 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1989 snd_pcm_hw_rule_div, NULL,
1990 SNDRV_PCM_HW_PARAM_FRAME_BITS, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
1991 if (err < 0)
1992 return err;
1993 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1994 snd_pcm_hw_rule_mulkdiv, (void*) 1000000,
1995 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_PERIOD_TIME, -1);
1996 if (err < 0)
1997 return err;
1998 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1999 snd_pcm_hw_rule_mulkdiv, (void*) 1000000,
2000 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_BUFFER_TIME, -1);
2001 if (err < 0)
2002 return err;
2003 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS,
2004 snd_pcm_hw_rule_div, NULL,
2005 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1);
2006 if (err < 0)
2007 return err;
2008 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
2009 snd_pcm_hw_rule_div, NULL,
2010 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_PERIODS, -1);
2011 if (err < 0)
2012 return err;
2013 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
2014 snd_pcm_hw_rule_mulkdiv, (void*) 8,
2015 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1);
2016 if (err < 0)
2017 return err;
2018 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
2019 snd_pcm_hw_rule_muldivk, (void*) 1000000,
2020 SNDRV_PCM_HW_PARAM_PERIOD_TIME, SNDRV_PCM_HW_PARAM_RATE, -1);
2021 if (err < 0)
2022 return err;
2023 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
2024 snd_pcm_hw_rule_mul, NULL,
2025 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_PERIODS, -1);
2026 if (err < 0)
2027 return err;
2028 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
2029 snd_pcm_hw_rule_mulkdiv, (void*) 8,
2030 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1);
2031 if (err < 0)
2032 return err;
2033 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
2034 snd_pcm_hw_rule_muldivk, (void*) 1000000,
2035 SNDRV_PCM_HW_PARAM_BUFFER_TIME, SNDRV_PCM_HW_PARAM_RATE, -1);
2036 if (err < 0)
2037 return err;
2038 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
2039 snd_pcm_hw_rule_muldivk, (void*) 8,
2040 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1);
2041 if (err < 0)
2042 return err;
2043 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
2044 snd_pcm_hw_rule_muldivk, (void*) 8,
2045 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_FRAME_BITS, -1);
2046 if (err < 0)
2047 return err;
2048 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_TIME,
2049 snd_pcm_hw_rule_mulkdiv, (void*) 1000000,
2050 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, SNDRV_PCM_HW_PARAM_RATE, -1);
2051 if (err < 0)
2052 return err;
2053 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_TIME,
2054 snd_pcm_hw_rule_mulkdiv, (void*) 1000000,
2055 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, SNDRV_PCM_HW_PARAM_RATE, -1);
2056 if (err < 0)
2057 return err;
2058 return 0;
2059}
2060
877211f5 2061int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
1da177e4 2062{
877211f5
TI
2063 struct snd_pcm_runtime *runtime = substream->runtime;
2064 struct snd_pcm_hardware *hw = &runtime->hw;
1da177e4
LT
2065 int err;
2066 unsigned int mask = 0;
2067
2068 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)
2069 mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED;
2070 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)
2071 mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED;
2072 if (hw->info & SNDRV_PCM_INFO_MMAP) {
2073 if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)
2074 mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED;
2075 if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)
2076 mask |= 1 << SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED;
2077 if (hw->info & SNDRV_PCM_INFO_COMPLEX)
2078 mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX;
2079 }
2080 err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask);
7eaa943c
TI
2081 if (err < 0)
2082 return err;
1da177e4
LT
2083
2084 err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats);
7eaa943c
TI
2085 if (err < 0)
2086 return err;
1da177e4
LT
2087
2088 err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD);
7eaa943c
TI
2089 if (err < 0)
2090 return err;
1da177e4
LT
2091
2092 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
2093 hw->channels_min, hw->channels_max);
7eaa943c
TI
2094 if (err < 0)
2095 return err;
1da177e4
LT
2096
2097 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE,
2098 hw->rate_min, hw->rate_max);
8b90ca08
GL
2099 if (err < 0)
2100 return err;
1da177e4
LT
2101
2102 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
2103 hw->period_bytes_min, hw->period_bytes_max);
8b90ca08
GL
2104 if (err < 0)
2105 return err;
1da177e4
LT
2106
2107 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIODS,
2108 hw->periods_min, hw->periods_max);
7eaa943c
TI
2109 if (err < 0)
2110 return err;
1da177e4
LT
2111
2112 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
2113 hw->period_bytes_min, hw->buffer_bytes_max);
7eaa943c
TI
2114 if (err < 0)
2115 return err;
1da177e4
LT
2116
2117 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
2118 snd_pcm_hw_rule_buffer_bytes_max, substream,
2119 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, -1);
2120 if (err < 0)
2121 return err;
2122
2123 /* FIXME: remove */
2124 if (runtime->dma_bytes) {
2125 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 0, runtime->dma_bytes);
7eaa943c 2126 if (err < 0)
6cf95152 2127 return err;
1da177e4
LT
2128 }
2129
2130 if (!(hw->rates & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))) {
2131 err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
2132 snd_pcm_hw_rule_rate, hw,
2133 SNDRV_PCM_HW_PARAM_RATE, -1);
2134 if (err < 0)
2135 return err;
2136 }
2137
2138 /* FIXME: this belong to lowlevel */
1da177e4
LT
2139 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
2140
2141 return 0;
2142}
2143
3bf75f9b 2144static void pcm_release_private(struct snd_pcm_substream *substream)
1da177e4 2145{
1da177e4 2146 snd_pcm_unlink(substream);
3bf75f9b
TI
2147}
2148
2149void snd_pcm_release_substream(struct snd_pcm_substream *substream)
2150{
0df63e44
TI
2151 substream->ref_count--;
2152 if (substream->ref_count > 0)
2153 return;
2154
3bf75f9b 2155 snd_pcm_drop(substream);
3bf75f9b 2156 if (substream->hw_opened) {
1da177e4
LT
2157 if (substream->ops->hw_free != NULL)
2158 substream->ops->hw_free(substream);
2159 substream->ops->close(substream);
3bf75f9b 2160 substream->hw_opened = 0;
1da177e4 2161 }
8699a0b6
TI
2162 if (pm_qos_request_active(&substream->latency_pm_qos_req))
2163 pm_qos_remove_request(&substream->latency_pm_qos_req);
1576274d
TI
2164 if (substream->pcm_release) {
2165 substream->pcm_release(substream);
2166 substream->pcm_release = NULL;
2167 }
3bf75f9b
TI
2168 snd_pcm_detach_substream(substream);
2169}
2170
e88e8ae6
TI
2171EXPORT_SYMBOL(snd_pcm_release_substream);
2172
3bf75f9b
TI
2173int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
2174 struct file *file,
2175 struct snd_pcm_substream **rsubstream)
2176{
2177 struct snd_pcm_substream *substream;
2178 int err;
2179
2180 err = snd_pcm_attach_substream(pcm, stream, file, &substream);
2181 if (err < 0)
2182 return err;
0df63e44
TI
2183 if (substream->ref_count > 1) {
2184 *rsubstream = substream;
2185 return 0;
2186 }
2187
3bf75f9b
TI
2188 err = snd_pcm_hw_constraints_init(substream);
2189 if (err < 0) {
09e56df8 2190 pcm_dbg(pcm, "snd_pcm_hw_constraints_init failed\n");
3bf75f9b
TI
2191 goto error;
2192 }
2193
2194 if ((err = substream->ops->open(substream)) < 0)
2195 goto error;
2196
2197 substream->hw_opened = 1;
2198
2199 err = snd_pcm_hw_constraints_complete(substream);
2200 if (err < 0) {
09e56df8 2201 pcm_dbg(pcm, "snd_pcm_hw_constraints_complete failed\n");
3bf75f9b
TI
2202 goto error;
2203 }
2204
2205 *rsubstream = substream;
1da177e4 2206 return 0;
3bf75f9b
TI
2207
2208 error:
2209 snd_pcm_release_substream(substream);
2210 return err;
1da177e4
LT
2211}
2212
e88e8ae6
TI
2213EXPORT_SYMBOL(snd_pcm_open_substream);
2214
1da177e4 2215static int snd_pcm_open_file(struct file *file,
877211f5 2216 struct snd_pcm *pcm,
ffd3d5c6 2217 int stream)
1da177e4 2218{
877211f5
TI
2219 struct snd_pcm_file *pcm_file;
2220 struct snd_pcm_substream *substream;
3bf75f9b 2221 int err;
1da177e4 2222
3bf75f9b
TI
2223 err = snd_pcm_open_substream(pcm, stream, file, &substream);
2224 if (err < 0)
2225 return err;
2226
548a648b
TI
2227 pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL);
2228 if (pcm_file == NULL) {
2229 snd_pcm_release_substream(substream);
2230 return -ENOMEM;
2231 }
2232 pcm_file->substream = substream;
2233 if (substream->ref_count == 1) {
0df63e44
TI
2234 substream->file = pcm_file;
2235 substream->pcm_release = pcm_release_private;
1da177e4 2236 }
1da177e4 2237 file->private_data = pcm_file;
ffd3d5c6 2238
1da177e4
LT
2239 return 0;
2240}
2241
f87135f5
CL
2242static int snd_pcm_playback_open(struct inode *inode, struct file *file)
2243{
2244 struct snd_pcm *pcm;
02f4865f
TI
2245 int err = nonseekable_open(inode, file);
2246 if (err < 0)
2247 return err;
f87135f5
CL
2248 pcm = snd_lookup_minor_data(iminor(inode),
2249 SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
a0830dbd 2250 err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
8bb4d9ce
TI
2251 if (pcm)
2252 snd_card_unref(pcm->card);
a0830dbd 2253 return err;
f87135f5
CL
2254}
2255
2256static int snd_pcm_capture_open(struct inode *inode, struct file *file)
1da177e4 2257{
877211f5 2258 struct snd_pcm *pcm;
02f4865f
TI
2259 int err = nonseekable_open(inode, file);
2260 if (err < 0)
2261 return err;
f87135f5
CL
2262 pcm = snd_lookup_minor_data(iminor(inode),
2263 SNDRV_DEVICE_TYPE_PCM_CAPTURE);
a0830dbd 2264 err = snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
8bb4d9ce
TI
2265 if (pcm)
2266 snd_card_unref(pcm->card);
a0830dbd 2267 return err;
f87135f5
CL
2268}
2269
2270static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
2271{
2272 int err;
1da177e4
LT
2273 wait_queue_t wait;
2274
1da177e4
LT
2275 if (pcm == NULL) {
2276 err = -ENODEV;
2277 goto __error1;
2278 }
2279 err = snd_card_file_add(pcm->card, file);
2280 if (err < 0)
2281 goto __error1;
2282 if (!try_module_get(pcm->card->module)) {
2283 err = -EFAULT;
2284 goto __error2;
2285 }
2286 init_waitqueue_entry(&wait, current);
2287 add_wait_queue(&pcm->open_wait, &wait);
1a60d4c5 2288 mutex_lock(&pcm->open_mutex);
1da177e4 2289 while (1) {
ffd3d5c6 2290 err = snd_pcm_open_file(file, pcm, stream);
1da177e4
LT
2291 if (err >= 0)
2292 break;
2293 if (err == -EAGAIN) {
2294 if (file->f_flags & O_NONBLOCK) {
2295 err = -EBUSY;
2296 break;
2297 }
2298 } else
2299 break;
2300 set_current_state(TASK_INTERRUPTIBLE);
1a60d4c5 2301 mutex_unlock(&pcm->open_mutex);
1da177e4 2302 schedule();
1a60d4c5 2303 mutex_lock(&pcm->open_mutex);
0914f796
TI
2304 if (pcm->card->shutdown) {
2305 err = -ENODEV;
2306 break;
2307 }
1da177e4
LT
2308 if (signal_pending(current)) {
2309 err = -ERESTARTSYS;
2310 break;
2311 }
2312 }
2313 remove_wait_queue(&pcm->open_wait, &wait);
1a60d4c5 2314 mutex_unlock(&pcm->open_mutex);
1da177e4
LT
2315 if (err < 0)
2316 goto __error;
2317 return err;
2318
2319 __error:
2320 module_put(pcm->card->module);
2321 __error2:
2322 snd_card_file_remove(pcm->card, file);
2323 __error1:
2324 return err;
2325}
2326
2327static int snd_pcm_release(struct inode *inode, struct file *file)
2328{
877211f5
TI
2329 struct snd_pcm *pcm;
2330 struct snd_pcm_substream *substream;
2331 struct snd_pcm_file *pcm_file;
1da177e4
LT
2332
2333 pcm_file = file->private_data;
2334 substream = pcm_file->substream;
7eaa943c
TI
2335 if (snd_BUG_ON(!substream))
2336 return -ENXIO;
1da177e4 2337 pcm = substream->pcm;
1a60d4c5 2338 mutex_lock(&pcm->open_mutex);
3bf75f9b 2339 snd_pcm_release_substream(substream);
548a648b 2340 kfree(pcm_file);
1a60d4c5 2341 mutex_unlock(&pcm->open_mutex);
1da177e4
LT
2342 wake_up(&pcm->open_wait);
2343 module_put(pcm->card->module);
2344 snd_card_file_remove(pcm->card, file);
2345 return 0;
2346}
2347
877211f5
TI
2348static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream,
2349 snd_pcm_uframes_t frames)
1da177e4 2350{
877211f5 2351 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
2352 snd_pcm_sframes_t appl_ptr;
2353 snd_pcm_sframes_t ret;
2354 snd_pcm_sframes_t hw_avail;
2355
2356 if (frames == 0)
2357 return 0;
2358
2359 snd_pcm_stream_lock_irq(substream);
2360 switch (runtime->status->state) {
2361 case SNDRV_PCM_STATE_PREPARED:
2362 break;
2363 case SNDRV_PCM_STATE_DRAINING:
2364 case SNDRV_PCM_STATE_RUNNING:
2365 if (snd_pcm_update_hw_ptr(substream) >= 0)
2366 break;
2367 /* Fall through */
2368 case SNDRV_PCM_STATE_XRUN:
2369 ret = -EPIPE;
2370 goto __end;
51840409
LR
2371 case SNDRV_PCM_STATE_SUSPENDED:
2372 ret = -ESTRPIPE;
2373 goto __end;
1da177e4
LT
2374 default:
2375 ret = -EBADFD;
2376 goto __end;
2377 }
2378
2379 hw_avail = snd_pcm_playback_hw_avail(runtime);
2380 if (hw_avail <= 0) {
2381 ret = 0;
2382 goto __end;
2383 }
2384 if (frames > (snd_pcm_uframes_t)hw_avail)
2385 frames = hw_avail;
1da177e4
LT
2386 appl_ptr = runtime->control->appl_ptr - frames;
2387 if (appl_ptr < 0)
2388 appl_ptr += runtime->boundary;
2389 runtime->control->appl_ptr = appl_ptr;
1da177e4
LT
2390 ret = frames;
2391 __end:
2392 snd_pcm_stream_unlock_irq(substream);
2393 return ret;
2394}
2395
877211f5
TI
2396static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substream,
2397 snd_pcm_uframes_t frames)
1da177e4 2398{
877211f5 2399 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
2400 snd_pcm_sframes_t appl_ptr;
2401 snd_pcm_sframes_t ret;
2402 snd_pcm_sframes_t hw_avail;
2403
2404 if (frames == 0)
2405 return 0;
2406
2407 snd_pcm_stream_lock_irq(substream);
2408 switch (runtime->status->state) {
2409 case SNDRV_PCM_STATE_PREPARED:
2410 case SNDRV_PCM_STATE_DRAINING:
2411 break;
2412 case SNDRV_PCM_STATE_RUNNING:
2413 if (snd_pcm_update_hw_ptr(substream) >= 0)
2414 break;
2415 /* Fall through */
2416 case SNDRV_PCM_STATE_XRUN:
2417 ret = -EPIPE;
2418 goto __end;
51840409
LR
2419 case SNDRV_PCM_STATE_SUSPENDED:
2420 ret = -ESTRPIPE;
2421 goto __end;
1da177e4
LT
2422 default:
2423 ret = -EBADFD;
2424 goto __end;
2425 }
2426
2427 hw_avail = snd_pcm_capture_hw_avail(runtime);
2428 if (hw_avail <= 0) {
2429 ret = 0;
2430 goto __end;
2431 }
2432 if (frames > (snd_pcm_uframes_t)hw_avail)
2433 frames = hw_avail;
1da177e4
LT
2434 appl_ptr = runtime->control->appl_ptr - frames;
2435 if (appl_ptr < 0)
2436 appl_ptr += runtime->boundary;
2437 runtime->control->appl_ptr = appl_ptr;
1da177e4
LT
2438 ret = frames;
2439 __end:
2440 snd_pcm_stream_unlock_irq(substream);
2441 return ret;
2442}
2443
877211f5
TI
2444static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *substream,
2445 snd_pcm_uframes_t frames)
1da177e4 2446{
877211f5 2447 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
2448 snd_pcm_sframes_t appl_ptr;
2449 snd_pcm_sframes_t ret;
2450 snd_pcm_sframes_t avail;
2451
2452 if (frames == 0)
2453 return 0;
2454
2455 snd_pcm_stream_lock_irq(substream);
2456 switch (runtime->status->state) {
2457 case SNDRV_PCM_STATE_PREPARED:
2458 case SNDRV_PCM_STATE_PAUSED:
2459 break;
2460 case SNDRV_PCM_STATE_DRAINING:
2461 case SNDRV_PCM_STATE_RUNNING:
2462 if (snd_pcm_update_hw_ptr(substream) >= 0)
2463 break;
2464 /* Fall through */
2465 case SNDRV_PCM_STATE_XRUN:
2466 ret = -EPIPE;
2467 goto __end;
51840409
LR
2468 case SNDRV_PCM_STATE_SUSPENDED:
2469 ret = -ESTRPIPE;
2470 goto __end;
1da177e4
LT
2471 default:
2472 ret = -EBADFD;
2473 goto __end;
2474 }
2475
2476 avail = snd_pcm_playback_avail(runtime);
2477 if (avail <= 0) {
2478 ret = 0;
2479 goto __end;
2480 }
2481 if (frames > (snd_pcm_uframes_t)avail)
2482 frames = avail;
1da177e4
LT
2483 appl_ptr = runtime->control->appl_ptr + frames;
2484 if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
2485 appl_ptr -= runtime->boundary;
2486 runtime->control->appl_ptr = appl_ptr;
1da177e4
LT
2487 ret = frames;
2488 __end:
2489 snd_pcm_stream_unlock_irq(substream);
2490 return ret;
2491}
2492
877211f5
TI
2493static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *substream,
2494 snd_pcm_uframes_t frames)
1da177e4 2495{
877211f5 2496 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
2497 snd_pcm_sframes_t appl_ptr;
2498 snd_pcm_sframes_t ret;
2499 snd_pcm_sframes_t avail;
2500
2501 if (frames == 0)
2502 return 0;
2503
2504 snd_pcm_stream_lock_irq(substream);
2505 switch (runtime->status->state) {
2506 case SNDRV_PCM_STATE_PREPARED:
2507 case SNDRV_PCM_STATE_DRAINING:
2508 case SNDRV_PCM_STATE_PAUSED:
2509 break;
2510 case SNDRV_PCM_STATE_RUNNING:
2511 if (snd_pcm_update_hw_ptr(substream) >= 0)
2512 break;
2513 /* Fall through */
2514 case SNDRV_PCM_STATE_XRUN:
2515 ret = -EPIPE;
2516 goto __end;
51840409
LR
2517 case SNDRV_PCM_STATE_SUSPENDED:
2518 ret = -ESTRPIPE;
2519 goto __end;
1da177e4
LT
2520 default:
2521 ret = -EBADFD;
2522 goto __end;
2523 }
2524
2525 avail = snd_pcm_capture_avail(runtime);
2526 if (avail <= 0) {
2527 ret = 0;
2528 goto __end;
2529 }
2530 if (frames > (snd_pcm_uframes_t)avail)
2531 frames = avail;
1da177e4
LT
2532 appl_ptr = runtime->control->appl_ptr + frames;
2533 if (appl_ptr >= (snd_pcm_sframes_t)runtime->boundary)
2534 appl_ptr -= runtime->boundary;
2535 runtime->control->appl_ptr = appl_ptr;
1da177e4
LT
2536 ret = frames;
2537 __end:
2538 snd_pcm_stream_unlock_irq(substream);
2539 return ret;
2540}
2541
877211f5 2542static int snd_pcm_hwsync(struct snd_pcm_substream *substream)
1da177e4 2543{
877211f5 2544 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
2545 int err;
2546
2547 snd_pcm_stream_lock_irq(substream);
2548 switch (runtime->status->state) {
2549 case SNDRV_PCM_STATE_DRAINING:
2550 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
2551 goto __badfd;
1f96153b 2552 /* Fall through */
1da177e4
LT
2553 case SNDRV_PCM_STATE_RUNNING:
2554 if ((err = snd_pcm_update_hw_ptr(substream)) < 0)
2555 break;
2556 /* Fall through */
2557 case SNDRV_PCM_STATE_PREPARED:
2558 case SNDRV_PCM_STATE_SUSPENDED:
2559 err = 0;
2560 break;
2561 case SNDRV_PCM_STATE_XRUN:
2562 err = -EPIPE;
2563 break;
2564 default:
2565 __badfd:
2566 err = -EBADFD;
2567 break;
2568 }
2569 snd_pcm_stream_unlock_irq(substream);
2570 return err;
2571}
2572
877211f5
TI
2573static int snd_pcm_delay(struct snd_pcm_substream *substream,
2574 snd_pcm_sframes_t __user *res)
1da177e4 2575{
877211f5 2576 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
2577 int err;
2578 snd_pcm_sframes_t n = 0;
2579
2580 snd_pcm_stream_lock_irq(substream);
2581 switch (runtime->status->state) {
2582 case SNDRV_PCM_STATE_DRAINING:
2583 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
2584 goto __badfd;
1f96153b 2585 /* Fall through */
1da177e4
LT
2586 case SNDRV_PCM_STATE_RUNNING:
2587 if ((err = snd_pcm_update_hw_ptr(substream)) < 0)
2588 break;
2589 /* Fall through */
2590 case SNDRV_PCM_STATE_PREPARED:
2591 case SNDRV_PCM_STATE_SUSPENDED:
2592 err = 0;
2593 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2594 n = snd_pcm_playback_hw_avail(runtime);
2595 else
2596 n = snd_pcm_capture_avail(runtime);
4bbe1ddf 2597 n += runtime->delay;
1da177e4
LT
2598 break;
2599 case SNDRV_PCM_STATE_XRUN:
2600 err = -EPIPE;
2601 break;
2602 default:
2603 __badfd:
2604 err = -EBADFD;
2605 break;
2606 }
2607 snd_pcm_stream_unlock_irq(substream);
2608 if (!err)
2609 if (put_user(n, res))
2610 err = -EFAULT;
2611 return err;
2612}
2613
877211f5
TI
2614static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
2615 struct snd_pcm_sync_ptr __user *_sync_ptr)
1da177e4 2616{
877211f5
TI
2617 struct snd_pcm_runtime *runtime = substream->runtime;
2618 struct snd_pcm_sync_ptr sync_ptr;
2619 volatile struct snd_pcm_mmap_status *status;
2620 volatile struct snd_pcm_mmap_control *control;
1da177e4
LT
2621 int err;
2622
2623 memset(&sync_ptr, 0, sizeof(sync_ptr));
2624 if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
2625 return -EFAULT;
877211f5 2626 if (copy_from_user(&sync_ptr.c.control, &(_sync_ptr->c.control), sizeof(struct snd_pcm_mmap_control)))
1da177e4
LT
2627 return -EFAULT;
2628 status = runtime->status;
2629 control = runtime->control;
2630 if (sync_ptr.flags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
2631 err = snd_pcm_hwsync(substream);
2632 if (err < 0)
2633 return err;
2634 }
2635 snd_pcm_stream_lock_irq(substream);
2636 if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL))
2637 control->appl_ptr = sync_ptr.c.control.appl_ptr;
2638 else
2639 sync_ptr.c.control.appl_ptr = control->appl_ptr;
2640 if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
2641 control->avail_min = sync_ptr.c.control.avail_min;
2642 else
2643 sync_ptr.c.control.avail_min = control->avail_min;
2644 sync_ptr.s.status.state = status->state;
2645 sync_ptr.s.status.hw_ptr = status->hw_ptr;
2646 sync_ptr.s.status.tstamp = status->tstamp;
2647 sync_ptr.s.status.suspended_state = status->suspended_state;
2648 snd_pcm_stream_unlock_irq(substream);
2649 if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
2650 return -EFAULT;
2651 return 0;
2652}
b751eef1
JK
2653
2654static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
2655{
2656 struct snd_pcm_runtime *runtime = substream->runtime;
2657 int arg;
2658
2659 if (get_user(arg, _arg))
2660 return -EFAULT;
2661 if (arg < 0 || arg > SNDRV_PCM_TSTAMP_TYPE_LAST)
2662 return -EINVAL;
2408c219 2663 runtime->tstamp_type = arg;
b751eef1
JK
2664 return 0;
2665}
1da177e4 2666
0df63e44
TI
2667static int snd_pcm_common_ioctl1(struct file *file,
2668 struct snd_pcm_substream *substream,
1da177e4
LT
2669 unsigned int cmd, void __user *arg)
2670{
1da177e4
LT
2671 switch (cmd) {
2672 case SNDRV_PCM_IOCTL_PVERSION:
2673 return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
2674 case SNDRV_PCM_IOCTL_INFO:
2675 return snd_pcm_info_user(substream, arg);
28e9e473
JK
2676 case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */
2677 return 0;
b751eef1
JK
2678 case SNDRV_PCM_IOCTL_TTSTAMP:
2679 return snd_pcm_tstamp(substream, arg);
1da177e4
LT
2680 case SNDRV_PCM_IOCTL_HW_REFINE:
2681 return snd_pcm_hw_refine_user(substream, arg);
2682 case SNDRV_PCM_IOCTL_HW_PARAMS:
2683 return snd_pcm_hw_params_user(substream, arg);
2684 case SNDRV_PCM_IOCTL_HW_FREE:
2685 return snd_pcm_hw_free(substream);
2686 case SNDRV_PCM_IOCTL_SW_PARAMS:
2687 return snd_pcm_sw_params_user(substream, arg);
2688 case SNDRV_PCM_IOCTL_STATUS:
2689 return snd_pcm_status_user(substream, arg);
2690 case SNDRV_PCM_IOCTL_CHANNEL_INFO:
2691 return snd_pcm_channel_info_user(substream, arg);
2692 case SNDRV_PCM_IOCTL_PREPARE:
0df63e44 2693 return snd_pcm_prepare(substream, file);
1da177e4
LT
2694 case SNDRV_PCM_IOCTL_RESET:
2695 return snd_pcm_reset(substream);
2696 case SNDRV_PCM_IOCTL_START:
2697 return snd_pcm_action_lock_irq(&snd_pcm_action_start, substream, SNDRV_PCM_STATE_RUNNING);
2698 case SNDRV_PCM_IOCTL_LINK:
2699 return snd_pcm_link(substream, (int)(unsigned long) arg);
2700 case SNDRV_PCM_IOCTL_UNLINK:
2701 return snd_pcm_unlink(substream);
2702 case SNDRV_PCM_IOCTL_RESUME:
2703 return snd_pcm_resume(substream);
2704 case SNDRV_PCM_IOCTL_XRUN:
2705 return snd_pcm_xrun(substream);
2706 case SNDRV_PCM_IOCTL_HWSYNC:
2707 return snd_pcm_hwsync(substream);
2708 case SNDRV_PCM_IOCTL_DELAY:
2709 return snd_pcm_delay(substream, arg);
2710 case SNDRV_PCM_IOCTL_SYNC_PTR:
2711 return snd_pcm_sync_ptr(substream, arg);
59d48582 2712#ifdef CONFIG_SND_SUPPORT_OLD_API
1da177e4
LT
2713 case SNDRV_PCM_IOCTL_HW_REFINE_OLD:
2714 return snd_pcm_hw_refine_old_user(substream, arg);
2715 case SNDRV_PCM_IOCTL_HW_PARAMS_OLD:
2716 return snd_pcm_hw_params_old_user(substream, arg);
59d48582 2717#endif
1da177e4 2718 case SNDRV_PCM_IOCTL_DRAIN:
4cdc115f 2719 return snd_pcm_drain(substream, file);
1da177e4
LT
2720 case SNDRV_PCM_IOCTL_DROP:
2721 return snd_pcm_drop(substream);
e661d0dd
TI
2722 case SNDRV_PCM_IOCTL_PAUSE:
2723 {
2724 int res;
2725 snd_pcm_stream_lock_irq(substream);
2726 res = snd_pcm_pause(substream, (int)(unsigned long)arg);
2727 snd_pcm_stream_unlock_irq(substream);
2728 return res;
2729 }
1da177e4 2730 }
09e56df8 2731 pcm_dbg(substream->pcm, "unknown ioctl = 0x%x\n", cmd);
1da177e4
LT
2732 return -ENOTTY;
2733}
2734
0df63e44
TI
2735static int snd_pcm_playback_ioctl1(struct file *file,
2736 struct snd_pcm_substream *substream,
1da177e4
LT
2737 unsigned int cmd, void __user *arg)
2738{
7eaa943c
TI
2739 if (snd_BUG_ON(!substream))
2740 return -ENXIO;
2741 if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK))
2742 return -EINVAL;
1da177e4
LT
2743 switch (cmd) {
2744 case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
2745 {
877211f5
TI
2746 struct snd_xferi xferi;
2747 struct snd_xferi __user *_xferi = arg;
2748 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
2749 snd_pcm_sframes_t result;
2750 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2751 return -EBADFD;
2752 if (put_user(0, &_xferi->result))
2753 return -EFAULT;
2754 if (copy_from_user(&xferi, _xferi, sizeof(xferi)))
2755 return -EFAULT;
2756 result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames);
2757 __put_user(result, &_xferi->result);
2758 return result < 0 ? result : 0;
2759 }
2760 case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
2761 {
877211f5
TI
2762 struct snd_xfern xfern;
2763 struct snd_xfern __user *_xfern = arg;
2764 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
2765 void __user **bufs;
2766 snd_pcm_sframes_t result;
2767 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2768 return -EBADFD;
2769 if (runtime->channels > 128)
2770 return -EINVAL;
2771 if (put_user(0, &_xfern->result))
2772 return -EFAULT;
2773 if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
2774 return -EFAULT;
ef44a1ec
LZ
2775
2776 bufs = memdup_user(xfern.bufs,
2777 sizeof(void *) * runtime->channels);
2778 if (IS_ERR(bufs))
2779 return PTR_ERR(bufs);
1da177e4
LT
2780 result = snd_pcm_lib_writev(substream, bufs, xfern.frames);
2781 kfree(bufs);
2782 __put_user(result, &_xfern->result);
2783 return result < 0 ? result : 0;
2784 }
2785 case SNDRV_PCM_IOCTL_REWIND:
2786 {
2787 snd_pcm_uframes_t frames;
2788 snd_pcm_uframes_t __user *_frames = arg;
2789 snd_pcm_sframes_t result;
2790 if (get_user(frames, _frames))
2791 return -EFAULT;
2792 if (put_user(0, _frames))
2793 return -EFAULT;
2794 result = snd_pcm_playback_rewind(substream, frames);
2795 __put_user(result, _frames);
2796 return result < 0 ? result : 0;
2797 }
2798 case SNDRV_PCM_IOCTL_FORWARD:
2799 {
2800 snd_pcm_uframes_t frames;
2801 snd_pcm_uframes_t __user *_frames = arg;
2802 snd_pcm_sframes_t result;
2803 if (get_user(frames, _frames))
2804 return -EFAULT;
2805 if (put_user(0, _frames))
2806 return -EFAULT;
2807 result = snd_pcm_playback_forward(substream, frames);
2808 __put_user(result, _frames);
2809 return result < 0 ? result : 0;
2810 }
1da177e4 2811 }
0df63e44 2812 return snd_pcm_common_ioctl1(file, substream, cmd, arg);
1da177e4
LT
2813}
2814
0df63e44
TI
2815static int snd_pcm_capture_ioctl1(struct file *file,
2816 struct snd_pcm_substream *substream,
1da177e4
LT
2817 unsigned int cmd, void __user *arg)
2818{
7eaa943c
TI
2819 if (snd_BUG_ON(!substream))
2820 return -ENXIO;
2821 if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE))
2822 return -EINVAL;
1da177e4
LT
2823 switch (cmd) {
2824 case SNDRV_PCM_IOCTL_READI_FRAMES:
2825 {
877211f5
TI
2826 struct snd_xferi xferi;
2827 struct snd_xferi __user *_xferi = arg;
2828 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
2829 snd_pcm_sframes_t result;
2830 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2831 return -EBADFD;
2832 if (put_user(0, &_xferi->result))
2833 return -EFAULT;
2834 if (copy_from_user(&xferi, _xferi, sizeof(xferi)))
2835 return -EFAULT;
2836 result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames);
2837 __put_user(result, &_xferi->result);
2838 return result < 0 ? result : 0;
2839 }
2840 case SNDRV_PCM_IOCTL_READN_FRAMES:
2841 {
877211f5
TI
2842 struct snd_xfern xfern;
2843 struct snd_xfern __user *_xfern = arg;
2844 struct snd_pcm_runtime *runtime = substream->runtime;
1da177e4
LT
2845 void *bufs;
2846 snd_pcm_sframes_t result;
2847 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2848 return -EBADFD;
2849 if (runtime->channels > 128)
2850 return -EINVAL;
2851 if (put_user(0, &_xfern->result))
2852 return -EFAULT;
2853 if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
2854 return -EFAULT;
ef44a1ec
LZ
2855
2856 bufs = memdup_user(xfern.bufs,
2857 sizeof(void *) * runtime->channels);
2858 if (IS_ERR(bufs))
2859 return PTR_ERR(bufs);
1da177e4
LT
2860 result = snd_pcm_lib_readv(substream, bufs, xfern.frames);
2861 kfree(bufs);
2862 __put_user(result, &_xfern->result);
2863 return result < 0 ? result : 0;
2864 }
2865 case SNDRV_PCM_IOCTL_REWIND:
2866 {
2867 snd_pcm_uframes_t frames;
2868 snd_pcm_uframes_t __user *_frames = arg;
2869 snd_pcm_sframes_t result;
2870 if (get_user(frames, _frames))
2871 return -EFAULT;
2872 if (put_user(0, _frames))
2873 return -EFAULT;
2874 result = snd_pcm_capture_rewind(substream, frames);
2875 __put_user(result, _frames);
2876 return result < 0 ? result : 0;
2877 }
2878 case SNDRV_PCM_IOCTL_FORWARD:
2879 {
2880 snd_pcm_uframes_t frames;
2881 snd_pcm_uframes_t __user *_frames = arg;
2882 snd_pcm_sframes_t result;
2883 if (get_user(frames, _frames))
2884 return -EFAULT;
2885 if (put_user(0, _frames))
2886 return -EFAULT;
2887 result = snd_pcm_capture_forward(substream, frames);
2888 __put_user(result, _frames);
2889 return result < 0 ? result : 0;
2890 }
2891 }
0df63e44 2892 return snd_pcm_common_ioctl1(file, substream, cmd, arg);
1da177e4
LT
2893}
2894
877211f5
TI
2895static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
2896 unsigned long arg)
1da177e4 2897{
877211f5 2898 struct snd_pcm_file *pcm_file;
1da177e4
LT
2899
2900 pcm_file = file->private_data;
2901
2902 if (((cmd >> 8) & 0xff) != 'A')
2903 return -ENOTTY;
2904
0df63e44
TI
2905 return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd,
2906 (void __user *)arg);
1da177e4
LT
2907}
2908
877211f5
TI
2909static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
2910 unsigned long arg)
1da177e4 2911{
877211f5 2912 struct snd_pcm_file *pcm_file;
1da177e4
LT
2913
2914 pcm_file = file->private_data;
2915
2916 if (((cmd >> 8) & 0xff) != 'A')
2917 return -ENOTTY;
2918
0df63e44
TI
2919 return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd,
2920 (void __user *)arg);
1da177e4
LT
2921}
2922
bf1bbb5a
TI
2923int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
2924 unsigned int cmd, void *arg)
1da177e4
LT
2925{
2926 mm_segment_t fs;
2927 int result;
2928
2929 fs = snd_enter_user();
1da177e4
LT
2930 switch (substream->stream) {
2931 case SNDRV_PCM_STREAM_PLAYBACK:
0df63e44
TI
2932 result = snd_pcm_playback_ioctl1(NULL, substream, cmd,
2933 (void __user *)arg);
bf1bbb5a 2934 break;
1da177e4 2935 case SNDRV_PCM_STREAM_CAPTURE:
0df63e44
TI
2936 result = snd_pcm_capture_ioctl1(NULL, substream, cmd,
2937 (void __user *)arg);
bf1bbb5a 2938 break;
1da177e4 2939 default:
bf1bbb5a
TI
2940 result = -EINVAL;
2941 break;
1da177e4 2942 }
bf1bbb5a
TI
2943 snd_leave_user(fs);
2944 return result;
1da177e4
LT
2945}
2946
e88e8ae6
TI
2947EXPORT_SYMBOL(snd_pcm_kernel_ioctl);
2948
877211f5
TI
2949static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
2950 loff_t * offset)
1da177e4 2951{
877211f5
TI
2952 struct snd_pcm_file *pcm_file;
2953 struct snd_pcm_substream *substream;
2954 struct snd_pcm_runtime *runtime;
1da177e4
LT
2955 snd_pcm_sframes_t result;
2956
2957 pcm_file = file->private_data;
2958 substream = pcm_file->substream;
7eaa943c
TI
2959 if (PCM_RUNTIME_CHECK(substream))
2960 return -ENXIO;
1da177e4
LT
2961 runtime = substream->runtime;
2962 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2963 return -EBADFD;
2964 if (!frame_aligned(runtime, count))
2965 return -EINVAL;
2966 count = bytes_to_frames(runtime, count);
2967 result = snd_pcm_lib_read(substream, buf, count);
2968 if (result > 0)
2969 result = frames_to_bytes(runtime, result);
2970 return result;
2971}
2972
877211f5
TI
2973static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
2974 size_t count, loff_t * offset)
1da177e4 2975{
877211f5
TI
2976 struct snd_pcm_file *pcm_file;
2977 struct snd_pcm_substream *substream;
2978 struct snd_pcm_runtime *runtime;
1da177e4
LT
2979 snd_pcm_sframes_t result;
2980
2981 pcm_file = file->private_data;
2982 substream = pcm_file->substream;
7eaa943c
TI
2983 if (PCM_RUNTIME_CHECK(substream))
2984 return -ENXIO;
1da177e4 2985 runtime = substream->runtime;
7eaa943c
TI
2986 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
2987 return -EBADFD;
2988 if (!frame_aligned(runtime, count))
2989 return -EINVAL;
1da177e4
LT
2990 count = bytes_to_frames(runtime, count);
2991 result = snd_pcm_lib_write(substream, buf, count);
2992 if (result > 0)
2993 result = frames_to_bytes(runtime, result);
1da177e4
LT
2994 return result;
2995}
2996
ee0b3e67
BP
2997static ssize_t snd_pcm_aio_read(struct kiocb *iocb, const struct iovec *iov,
2998 unsigned long nr_segs, loff_t pos)
1da177e4
LT
2999
3000{
877211f5
TI
3001 struct snd_pcm_file *pcm_file;
3002 struct snd_pcm_substream *substream;
3003 struct snd_pcm_runtime *runtime;
1da177e4
LT
3004 snd_pcm_sframes_t result;
3005 unsigned long i;
3006 void __user **bufs;
3007 snd_pcm_uframes_t frames;
3008
ee0b3e67 3009 pcm_file = iocb->ki_filp->private_data;
1da177e4 3010 substream = pcm_file->substream;
7eaa943c
TI
3011 if (PCM_RUNTIME_CHECK(substream))
3012 return -ENXIO;
1da177e4
LT
3013 runtime = substream->runtime;
3014 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
3015 return -EBADFD;
ee0b3e67 3016 if (nr_segs > 1024 || nr_segs != runtime->channels)
1da177e4 3017 return -EINVAL;
ee0b3e67 3018 if (!frame_aligned(runtime, iov->iov_len))
1da177e4 3019 return -EINVAL;
ee0b3e67
BP
3020 frames = bytes_to_samples(runtime, iov->iov_len);
3021 bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
1da177e4
LT
3022 if (bufs == NULL)
3023 return -ENOMEM;
ee0b3e67
BP
3024 for (i = 0; i < nr_segs; ++i)
3025 bufs[i] = iov[i].iov_base;
1da177e4
LT
3026 result = snd_pcm_lib_readv(substream, bufs, frames);
3027 if (result > 0)
3028 result = frames_to_bytes(runtime, result);
3029 kfree(bufs);
3030 return result;
3031}
3032
ee0b3e67
BP
3033static ssize_t snd_pcm_aio_write(struct kiocb *iocb, const struct iovec *iov,
3034 unsigned long nr_segs, loff_t pos)
1da177e4 3035{
877211f5
TI
3036 struct snd_pcm_file *pcm_file;
3037 struct snd_pcm_substream *substream;
3038 struct snd_pcm_runtime *runtime;
1da177e4
LT
3039 snd_pcm_sframes_t result;
3040 unsigned long i;
3041 void __user **bufs;
3042 snd_pcm_uframes_t frames;
3043
ee0b3e67 3044 pcm_file = iocb->ki_filp->private_data;
1da177e4 3045 substream = pcm_file->substream;
7eaa943c
TI
3046 if (PCM_RUNTIME_CHECK(substream))
3047 return -ENXIO;
1da177e4 3048 runtime = substream->runtime;
7eaa943c
TI
3049 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
3050 return -EBADFD;
ee0b3e67 3051 if (nr_segs > 128 || nr_segs != runtime->channels ||
7eaa943c
TI
3052 !frame_aligned(runtime, iov->iov_len))
3053 return -EINVAL;
ee0b3e67
BP
3054 frames = bytes_to_samples(runtime, iov->iov_len);
3055 bufs = kmalloc(sizeof(void *) * nr_segs, GFP_KERNEL);
1da177e4
LT
3056 if (bufs == NULL)
3057 return -ENOMEM;
ee0b3e67
BP
3058 for (i = 0; i < nr_segs; ++i)
3059 bufs[i] = iov[i].iov_base;
1da177e4
LT
3060 result = snd_pcm_lib_writev(substream, bufs, frames);
3061 if (result > 0)
3062 result = frames_to_bytes(runtime, result);
3063 kfree(bufs);
1da177e4
LT
3064 return result;
3065}
3066
3067static unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait)
3068{
877211f5
TI
3069 struct snd_pcm_file *pcm_file;
3070 struct snd_pcm_substream *substream;
3071 struct snd_pcm_runtime *runtime;
1da177e4
LT
3072 unsigned int mask;
3073 snd_pcm_uframes_t avail;
3074
3075 pcm_file = file->private_data;
3076
3077 substream = pcm_file->substream;
7eaa943c
TI
3078 if (PCM_RUNTIME_CHECK(substream))
3079 return -ENXIO;
1da177e4
LT
3080 runtime = substream->runtime;
3081
3082 poll_wait(file, &runtime->sleep, wait);
3083
3084 snd_pcm_stream_lock_irq(substream);
3085 avail = snd_pcm_playback_avail(runtime);
3086 switch (runtime->status->state) {
3087 case SNDRV_PCM_STATE_RUNNING:
3088 case SNDRV_PCM_STATE_PREPARED:
3089 case SNDRV_PCM_STATE_PAUSED:
3090 if (avail >= runtime->control->avail_min) {
3091 mask = POLLOUT | POLLWRNORM;
3092 break;
3093 }
3094 /* Fall through */
3095 case SNDRV_PCM_STATE_DRAINING:
3096 mask = 0;
3097 break;
3098 default:
3099 mask = POLLOUT | POLLWRNORM | POLLERR;
3100 break;
3101 }
3102 snd_pcm_stream_unlock_irq(substream);
3103 return mask;
3104}
3105
3106static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
3107{
877211f5
TI
3108 struct snd_pcm_file *pcm_file;
3109 struct snd_pcm_substream *substream;
3110 struct snd_pcm_runtime *runtime;
1da177e4
LT
3111 unsigned int mask;
3112 snd_pcm_uframes_t avail;
3113
3114 pcm_file = file->private_data;
3115
3116 substream = pcm_file->substream;
7eaa943c
TI
3117 if (PCM_RUNTIME_CHECK(substream))
3118 return -ENXIO;
1da177e4
LT
3119 runtime = substream->runtime;
3120
3121 poll_wait(file, &runtime->sleep, wait);
3122
3123 snd_pcm_stream_lock_irq(substream);
3124 avail = snd_pcm_capture_avail(runtime);
3125 switch (runtime->status->state) {
3126 case SNDRV_PCM_STATE_RUNNING:
3127 case SNDRV_PCM_STATE_PREPARED:
3128 case SNDRV_PCM_STATE_PAUSED:
3129 if (avail >= runtime->control->avail_min) {
3130 mask = POLLIN | POLLRDNORM;
3131 break;
3132 }
3133 mask = 0;
3134 break;
3135 case SNDRV_PCM_STATE_DRAINING:
3136 if (avail > 0) {
3137 mask = POLLIN | POLLRDNORM;
3138 break;
3139 }
3140 /* Fall through */
3141 default:
3142 mask = POLLIN | POLLRDNORM | POLLERR;
3143 break;
3144 }
3145 snd_pcm_stream_unlock_irq(substream);
3146 return mask;
3147}
3148
3149/*
3150 * mmap support
3151 */
3152
3153/*
3154 * Only on coherent architectures, we can mmap the status and the control records
3155 * for effcient data transfer. On others, we have to use HWSYNC ioctl...
3156 */
3157#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA)
3158/*
3159 * mmap status record
3160 */
3ad5afcd
NP
3161static int snd_pcm_mmap_status_fault(struct vm_area_struct *area,
3162 struct vm_fault *vmf)
1da177e4 3163{
877211f5
TI
3164 struct snd_pcm_substream *substream = area->vm_private_data;
3165 struct snd_pcm_runtime *runtime;
1da177e4
LT
3166
3167 if (substream == NULL)
3ad5afcd 3168 return VM_FAULT_SIGBUS;
1da177e4 3169 runtime = substream->runtime;
3ad5afcd
NP
3170 vmf->page = virt_to_page(runtime->status);
3171 get_page(vmf->page);
3172 return 0;
1da177e4
LT
3173}
3174
f0f37e2f 3175static const struct vm_operations_struct snd_pcm_vm_ops_status =
1da177e4 3176{
3ad5afcd 3177 .fault = snd_pcm_mmap_status_fault,
1da177e4
LT
3178};
3179
877211f5 3180static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
1da177e4
LT
3181 struct vm_area_struct *area)
3182{
1da177e4
LT
3183 long size;
3184 if (!(area->vm_flags & VM_READ))
3185 return -EINVAL;
1da177e4 3186 size = area->vm_end - area->vm_start;
877211f5 3187 if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)))
1da177e4
LT
3188 return -EINVAL;
3189 area->vm_ops = &snd_pcm_vm_ops_status;
3190 area->vm_private_data = substream;
314e51b9 3191 area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
1da177e4
LT
3192 return 0;
3193}
3194
3195/*
3196 * mmap control record
3197 */
3ad5afcd
NP
3198static int snd_pcm_mmap_control_fault(struct vm_area_struct *area,
3199 struct vm_fault *vmf)
1da177e4 3200{
877211f5
TI
3201 struct snd_pcm_substream *substream = area->vm_private_data;
3202 struct snd_pcm_runtime *runtime;
1da177e4
LT
3203
3204 if (substream == NULL)
3ad5afcd 3205 return VM_FAULT_SIGBUS;
1da177e4 3206 runtime = substream->runtime;
3ad5afcd
NP
3207 vmf->page = virt_to_page(runtime->control);
3208 get_page(vmf->page);
3209 return 0;
1da177e4
LT
3210}
3211
f0f37e2f 3212static const struct vm_operations_struct snd_pcm_vm_ops_control =
1da177e4 3213{
3ad5afcd 3214 .fault = snd_pcm_mmap_control_fault,
1da177e4
LT
3215};
3216
877211f5 3217static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file,
1da177e4
LT
3218 struct vm_area_struct *area)
3219{
1da177e4
LT
3220 long size;
3221 if (!(area->vm_flags & VM_READ))
3222 return -EINVAL;
1da177e4 3223 size = area->vm_end - area->vm_start;
877211f5 3224 if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)))
1da177e4
LT
3225 return -EINVAL;
3226 area->vm_ops = &snd_pcm_vm_ops_control;
3227 area->vm_private_data = substream;
314e51b9 3228 area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
1da177e4
LT
3229 return 0;
3230}
3231#else /* ! coherent mmap */
3232/*
3233 * don't support mmap for status and control records.
3234 */
877211f5 3235static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
1da177e4
LT
3236 struct vm_area_struct *area)
3237{
3238 return -ENXIO;
3239}
877211f5 3240static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file,
1da177e4
LT
3241 struct vm_area_struct *area)
3242{
3243 return -ENXIO;
3244}
3245#endif /* coherent mmap */
3246
9eb4a067
TI
3247static inline struct page *
3248snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
3249{
3250 void *vaddr = substream->runtime->dma_area + ofs;
3251 return virt_to_page(vaddr);
3252}
3253
1da177e4 3254/*
3ad5afcd 3255 * fault callback for mmapping a RAM page
1da177e4 3256 */
3ad5afcd
NP
3257static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
3258 struct vm_fault *vmf)
1da177e4 3259{
877211f5
TI
3260 struct snd_pcm_substream *substream = area->vm_private_data;
3261 struct snd_pcm_runtime *runtime;
1da177e4
LT
3262 unsigned long offset;
3263 struct page * page;
1da177e4
LT
3264 size_t dma_bytes;
3265
3266 if (substream == NULL)
3ad5afcd 3267 return VM_FAULT_SIGBUS;
1da177e4 3268 runtime = substream->runtime;
3ad5afcd 3269 offset = vmf->pgoff << PAGE_SHIFT;
1da177e4
LT
3270 dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
3271 if (offset > dma_bytes - PAGE_SIZE)
3ad5afcd 3272 return VM_FAULT_SIGBUS;
9eb4a067 3273 if (substream->ops->page)
1da177e4 3274 page = substream->ops->page(substream, offset);
9eb4a067
TI
3275 else
3276 page = snd_pcm_default_page_ops(substream, offset);
3277 if (!page)
3278 return VM_FAULT_SIGBUS;
b5810039 3279 get_page(page);
3ad5afcd
NP
3280 vmf->page = page;
3281 return 0;
1da177e4
LT
3282}
3283
657b1989
TI
3284static const struct vm_operations_struct snd_pcm_vm_ops_data = {
3285 .open = snd_pcm_mmap_data_open,
3286 .close = snd_pcm_mmap_data_close,
3287};
3288
3289static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
1da177e4
LT
3290 .open = snd_pcm_mmap_data_open,
3291 .close = snd_pcm_mmap_data_close,
3ad5afcd 3292 .fault = snd_pcm_mmap_data_fault,
1da177e4
LT
3293};
3294
3295/*
3296 * mmap the DMA buffer on RAM
3297 */
18a2b962
TI
3298int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
3299 struct vm_area_struct *area)
1da177e4 3300{
314e51b9 3301 area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
a5606f85 3302#ifdef CONFIG_GENERIC_ALLOCATOR
05503214
NC
3303 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_IRAM) {
3304 area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
3305 return remap_pfn_range(area, area->vm_start,
3306 substream->dma_buffer.addr >> PAGE_SHIFT,
3307 area->vm_end - area->vm_start, area->vm_page_prot);
3308 }
a5606f85 3309#endif /* CONFIG_GENERIC_ALLOCATOR */
657b1989
TI
3310 if (!substream->ops->page &&
3311 substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
3312 return dma_mmap_coherent(substream->dma_buffer.dev.dev,
3313 area,
3314 substream->runtime->dma_area,
3315 substream->runtime->dma_addr,
3316 area->vm_end - area->vm_start);
657b1989
TI
3317 /* mmap with fault handler */
3318 area->vm_ops = &snd_pcm_vm_ops_data_fault;
1da177e4
LT
3319 return 0;
3320}
18a2b962 3321EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap);
1da177e4
LT
3322
3323/*
3324 * mmap the DMA buffer on I/O memory area
3325 */
3326#if SNDRV_PCM_INFO_MMAP_IOMEM
877211f5
TI
3327int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3328 struct vm_area_struct *area)
1da177e4 3329{
0fe09a45 3330 struct snd_pcm_runtime *runtime = substream->runtime;;
1da177e4 3331
1da177e4 3332 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
0fe09a45 3333 return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes);
1da177e4 3334}
e88e8ae6
TI
3335
3336EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
1da177e4
LT
3337#endif /* SNDRV_PCM_INFO_MMAP */
3338
3339/*
3340 * mmap DMA buffer
3341 */
877211f5 3342int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
1da177e4
LT
3343 struct vm_area_struct *area)
3344{
877211f5 3345 struct snd_pcm_runtime *runtime;
1da177e4
LT
3346 long size;
3347 unsigned long offset;
3348 size_t dma_bytes;
657b1989 3349 int err;
1da177e4
LT
3350
3351 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3352 if (!(area->vm_flags & (VM_WRITE|VM_READ)))
3353 return -EINVAL;
3354 } else {
3355 if (!(area->vm_flags & VM_READ))
3356 return -EINVAL;
3357 }
3358 runtime = substream->runtime;
1da177e4
LT
3359 if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
3360 return -EBADFD;
3361 if (!(runtime->info & SNDRV_PCM_INFO_MMAP))
3362 return -ENXIO;
3363 if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
3364 runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
3365 return -EINVAL;
3366 size = area->vm_end - area->vm_start;
3367 offset = area->vm_pgoff << PAGE_SHIFT;
3368 dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
3369 if ((size_t)size > dma_bytes)
3370 return -EINVAL;
3371 if (offset > dma_bytes - size)
3372 return -EINVAL;
3373
657b1989
TI
3374 area->vm_ops = &snd_pcm_vm_ops_data;
3375 area->vm_private_data = substream;
1da177e4 3376 if (substream->ops->mmap)
657b1989 3377 err = substream->ops->mmap(substream, area);
1da177e4 3378 else
18a2b962 3379 err = snd_pcm_lib_default_mmap(substream, area);
657b1989
TI
3380 if (!err)
3381 atomic_inc(&substream->mmap_count);
3382 return err;
1da177e4
LT
3383}
3384
e88e8ae6
TI
3385EXPORT_SYMBOL(snd_pcm_mmap_data);
3386
1da177e4
LT
3387static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
3388{
877211f5
TI
3389 struct snd_pcm_file * pcm_file;
3390 struct snd_pcm_substream *substream;
1da177e4
LT
3391 unsigned long offset;
3392
3393 pcm_file = file->private_data;
3394 substream = pcm_file->substream;
7eaa943c
TI
3395 if (PCM_RUNTIME_CHECK(substream))
3396 return -ENXIO;
1da177e4
LT
3397
3398 offset = area->vm_pgoff << PAGE_SHIFT;
3399 switch (offset) {
3400 case SNDRV_PCM_MMAP_OFFSET_STATUS:
548a648b 3401 if (pcm_file->no_compat_mmap)
1da177e4
LT
3402 return -ENXIO;
3403 return snd_pcm_mmap_status(substream, file, area);
3404 case SNDRV_PCM_MMAP_OFFSET_CONTROL:
548a648b 3405 if (pcm_file->no_compat_mmap)
1da177e4
LT
3406 return -ENXIO;
3407 return snd_pcm_mmap_control(substream, file, area);
3408 default:
3409 return snd_pcm_mmap_data(substream, file, area);
3410 }
3411 return 0;
3412}
3413
3414static int snd_pcm_fasync(int fd, struct file * file, int on)
3415{
877211f5
TI
3416 struct snd_pcm_file * pcm_file;
3417 struct snd_pcm_substream *substream;
3418 struct snd_pcm_runtime *runtime;
1da177e4
LT
3419
3420 pcm_file = file->private_data;
3421 substream = pcm_file->substream;
7eaa943c 3422 if (PCM_RUNTIME_CHECK(substream))
d05468b7 3423 return -ENXIO;
1da177e4 3424 runtime = substream->runtime;
d05468b7 3425 return fasync_helper(fd, file, on, &runtime->fasync);
1da177e4
LT
3426}
3427
3428/*
3429 * ioctl32 compat
3430 */
3431#ifdef CONFIG_COMPAT
3432#include "pcm_compat.c"
3433#else
3434#define snd_pcm_ioctl_compat NULL
3435#endif
3436
3437/*
3438 * To be removed helpers to keep binary compatibility
3439 */
3440
59d48582 3441#ifdef CONFIG_SND_SUPPORT_OLD_API
1da177e4
LT
3442#define __OLD_TO_NEW_MASK(x) ((x&7)|((x&0x07fffff8)<<5))
3443#define __NEW_TO_OLD_MASK(x) ((x&7)|((x&0xffffff00)>>5))
3444
877211f5
TI
3445static void snd_pcm_hw_convert_from_old_params(struct snd_pcm_hw_params *params,
3446 struct snd_pcm_hw_params_old *oparams)
1da177e4
LT
3447{
3448 unsigned int i;
3449
3450 memset(params, 0, sizeof(*params));
3451 params->flags = oparams->flags;
3452 for (i = 0; i < ARRAY_SIZE(oparams->masks); i++)
3453 params->masks[i].bits[0] = oparams->masks[i];
3454 memcpy(params->intervals, oparams->intervals, sizeof(oparams->intervals));
3455 params->rmask = __OLD_TO_NEW_MASK(oparams->rmask);
3456 params->cmask = __OLD_TO_NEW_MASK(oparams->cmask);
3457 params->info = oparams->info;
3458 params->msbits = oparams->msbits;
3459 params->rate_num = oparams->rate_num;
3460 params->rate_den = oparams->rate_den;
3461 params->fifo_size = oparams->fifo_size;
3462}
3463
877211f5
TI
3464static void snd_pcm_hw_convert_to_old_params(struct snd_pcm_hw_params_old *oparams,
3465 struct snd_pcm_hw_params *params)
1da177e4
LT
3466{
3467 unsigned int i;
3468
3469 memset(oparams, 0, sizeof(*oparams));
3470 oparams->flags = params->flags;
3471 for (i = 0; i < ARRAY_SIZE(oparams->masks); i++)
3472 oparams->masks[i] = params->masks[i].bits[0];
3473 memcpy(oparams->intervals, params->intervals, sizeof(oparams->intervals));
3474 oparams->rmask = __NEW_TO_OLD_MASK(params->rmask);
3475 oparams->cmask = __NEW_TO_OLD_MASK(params->cmask);
3476 oparams->info = params->info;
3477 oparams->msbits = params->msbits;
3478 oparams->rate_num = params->rate_num;
3479 oparams->rate_den = params->rate_den;
3480 oparams->fifo_size = params->fifo_size;
3481}
3482
877211f5
TI
3483static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream,
3484 struct snd_pcm_hw_params_old __user * _oparams)
1da177e4 3485{
877211f5
TI
3486 struct snd_pcm_hw_params *params;
3487 struct snd_pcm_hw_params_old *oparams = NULL;
1da177e4
LT
3488 int err;
3489
3490 params = kmalloc(sizeof(*params), GFP_KERNEL);
ef44a1ec
LZ
3491 if (!params)
3492 return -ENOMEM;
1da177e4 3493
ef44a1ec
LZ
3494 oparams = memdup_user(_oparams, sizeof(*oparams));
3495 if (IS_ERR(oparams)) {
3496 err = PTR_ERR(oparams);
1da177e4
LT
3497 goto out;
3498 }
3499 snd_pcm_hw_convert_from_old_params(params, oparams);
3500 err = snd_pcm_hw_refine(substream, params);
3501 snd_pcm_hw_convert_to_old_params(oparams, params);
3502 if (copy_to_user(_oparams, oparams, sizeof(*oparams))) {
3503 if (!err)
3504 err = -EFAULT;
3505 }
ef44a1ec
LZ
3506
3507 kfree(oparams);
1da177e4
LT
3508out:
3509 kfree(params);
1da177e4
LT
3510 return err;
3511}
3512
877211f5
TI
3513static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream,
3514 struct snd_pcm_hw_params_old __user * _oparams)
1da177e4 3515{
877211f5
TI
3516 struct snd_pcm_hw_params *params;
3517 struct snd_pcm_hw_params_old *oparams = NULL;
1da177e4
LT
3518 int err;
3519
3520 params = kmalloc(sizeof(*params), GFP_KERNEL);
ef44a1ec
LZ
3521 if (!params)
3522 return -ENOMEM;
3523
3524 oparams = memdup_user(_oparams, sizeof(*oparams));
3525 if (IS_ERR(oparams)) {
3526 err = PTR_ERR(oparams);
1da177e4
LT
3527 goto out;
3528 }
3529 snd_pcm_hw_convert_from_old_params(params, oparams);
3530 err = snd_pcm_hw_params(substream, params);
3531 snd_pcm_hw_convert_to_old_params(oparams, params);
3532 if (copy_to_user(_oparams, oparams, sizeof(*oparams))) {
3533 if (!err)
3534 err = -EFAULT;
3535 }
ef44a1ec
LZ
3536
3537 kfree(oparams);
1da177e4
LT
3538out:
3539 kfree(params);
1da177e4
LT
3540 return err;
3541}
59d48582 3542#endif /* CONFIG_SND_SUPPORT_OLD_API */
1da177e4 3543
7003609b 3544#ifndef CONFIG_MMU
55c63bd2
DG
3545static unsigned long snd_pcm_get_unmapped_area(struct file *file,
3546 unsigned long addr,
3547 unsigned long len,
3548 unsigned long pgoff,
3549 unsigned long flags)
3550{
3551 struct snd_pcm_file *pcm_file = file->private_data;
3552 struct snd_pcm_substream *substream = pcm_file->substream;
3553 struct snd_pcm_runtime *runtime = substream->runtime;
3554 unsigned long offset = pgoff << PAGE_SHIFT;
3555
3556 switch (offset) {
3557 case SNDRV_PCM_MMAP_OFFSET_STATUS:
3558 return (unsigned long)runtime->status;
3559 case SNDRV_PCM_MMAP_OFFSET_CONTROL:
3560 return (unsigned long)runtime->control;
3561 default:
3562 return (unsigned long)runtime->dma_area + offset;
3563 }
7003609b
CC
3564}
3565#else
55c63bd2 3566# define snd_pcm_get_unmapped_area NULL
7003609b
CC
3567#endif
3568
1da177e4
LT
3569/*
3570 * Register section
3571 */
3572
9c2e08c5 3573const struct file_operations snd_pcm_f_ops[2] = {
1da177e4 3574 {
2af677fc
CL
3575 .owner = THIS_MODULE,
3576 .write = snd_pcm_write,
ee0b3e67 3577 .aio_write = snd_pcm_aio_write,
f87135f5 3578 .open = snd_pcm_playback_open,
2af677fc 3579 .release = snd_pcm_release,
02f4865f 3580 .llseek = no_llseek,
2af677fc
CL
3581 .poll = snd_pcm_playback_poll,
3582 .unlocked_ioctl = snd_pcm_playback_ioctl,
3583 .compat_ioctl = snd_pcm_ioctl_compat,
3584 .mmap = snd_pcm_mmap,
3585 .fasync = snd_pcm_fasync,
55c63bd2 3586 .get_unmapped_area = snd_pcm_get_unmapped_area,
1da177e4
LT
3587 },
3588 {
2af677fc
CL
3589 .owner = THIS_MODULE,
3590 .read = snd_pcm_read,
ee0b3e67 3591 .aio_read = snd_pcm_aio_read,
f87135f5 3592 .open = snd_pcm_capture_open,
2af677fc 3593 .release = snd_pcm_release,
02f4865f 3594 .llseek = no_llseek,
2af677fc
CL
3595 .poll = snd_pcm_capture_poll,
3596 .unlocked_ioctl = snd_pcm_capture_ioctl,
3597 .compat_ioctl = snd_pcm_ioctl_compat,
3598 .mmap = snd_pcm_mmap,
3599 .fasync = snd_pcm_fasync,
55c63bd2 3600 .get_unmapped_area = snd_pcm_get_unmapped_area,
1da177e4
LT
3601 }
3602};