Root/sound/core/pcm_native.c

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

Archive Download this file



interactive