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