linux/sound/core/pcm_lib.c
<<
>>
Prefs
   1/*
   2 *  Digital Audio (PCM) abstract layer
   3 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   4 *                   Abramo Bagnara <abramo@alsa-project.org>
   5 *
   6 *
   7 *   This program is free software; you can redistribute it and/or modify
   8 *   it under the terms of the GNU General Public License as published by
   9 *   the Free Software Foundation; either version 2 of the License, or
  10 *   (at your option) any later version.
  11 *
  12 *   This program is distributed in the hope that it will be useful,
  13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 *   GNU General Public License for more details.
  16 *
  17 *   You should have received a copy of the GNU General Public License
  18 *   along with this program; if not, write to the Free Software
  19 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20 *
  21 */
  22
  23#include <linux/slab.h>
  24#include <linux/time.h>
  25#include <sound/core.h>
  26#include <sound/control.h>
  27#include <sound/info.h>
  28#include <sound/pcm.h>
  29#include <sound/pcm_params.h>
  30#include <sound/timer.h>
  31
  32/*
  33 * fill ring buffer with silence
  34 * runtime->silence_start: starting pointer to silence area
  35 * runtime->silence_filled: size filled with silence
  36 * runtime->silence_threshold: threshold from application
  37 * runtime->silence_size: maximal size from application
  38 *
  39 * when runtime->silence_size >= runtime->boundary - fill processed area with silence immediately
  40 */
  41void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr)
  42{
  43        struct snd_pcm_runtime *runtime = substream->runtime;
  44        snd_pcm_uframes_t frames, ofs, transfer;
  45
  46        if (runtime->silence_size < runtime->boundary) {
  47                snd_pcm_sframes_t noise_dist, n;
  48                if (runtime->silence_start != runtime->control->appl_ptr) {
  49                        n = runtime->control->appl_ptr - runtime->silence_start;
  50                        if (n < 0)
  51                                n += runtime->boundary;
  52                        if ((snd_pcm_uframes_t)n < runtime->silence_filled)
  53                                runtime->silence_filled -= n;
  54                        else
  55                                runtime->silence_filled = 0;
  56                        runtime->silence_start = runtime->control->appl_ptr;
  57                }
  58                if (runtime->silence_filled >= runtime->buffer_size)
  59                        return;
  60                noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled;
  61                if (noise_dist >= (snd_pcm_sframes_t) runtime->silence_threshold)
  62                        return;
  63                frames = runtime->silence_threshold - noise_dist;
  64                if (frames > runtime->silence_size)
  65                        frames = runtime->silence_size;
  66        } else {
  67                if (new_hw_ptr == ULONG_MAX) {  /* initialization */
  68                        snd_pcm_sframes_t avail = snd_pcm_playback_hw_avail(runtime);
  69                        runtime->silence_filled = avail > 0 ? avail : 0;
  70                        runtime->silence_start = (runtime->status->hw_ptr +
  71                                                  runtime->silence_filled) %
  72                                                 runtime->boundary;
  73                } else {
  74                        ofs = runtime->status->hw_ptr;
  75                        frames = new_hw_ptr - ofs;
  76                        if ((snd_pcm_sframes_t)frames < 0)
  77                                frames += runtime->boundary;
  78                        runtime->silence_filled -= frames;
  79                        if ((snd_pcm_sframes_t)runtime->silence_filled < 0) {
  80                                runtime->silence_filled = 0;
  81                                runtime->silence_start = new_hw_ptr;
  82                        } else {
  83                                runtime->silence_start = ofs;
  84                        }
  85                }
  86                frames = runtime->buffer_size - runtime->silence_filled;
  87        }
  88        snd_assert(frames <= runtime->buffer_size, return);
  89        if (frames == 0)
  90                return;
  91        ofs = runtime->silence_start % runtime->buffer_size;
  92        while (frames > 0) {
  93                transfer = ofs + frames > runtime->buffer_size ? runtime->buffer_size - ofs : frames;
  94                if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
  95                    runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
  96                        if (substream->ops->silence) {
  97                                int err;
  98                                err = substream->ops->silence(substream, -1, ofs, transfer);
  99                                snd_assert(err >= 0, );
 100                        } else {
 101                                char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, ofs);
 102                                snd_pcm_format_set_silence(runtime->format, hwbuf, transfer * runtime->channels);
 103                        }
 104                } else {
 105                        unsigned int c;
 106                        unsigned int channels = runtime->channels;
 107                        if (substream->ops->silence) {
 108                                for (c = 0; c < channels; ++c) {
 109                                        int err;
 110                                        err = substream->ops->silence(substream, c, ofs, transfer);
 111                                        snd_assert(err >= 0, );
 112                                }
 113                        } else {
 114                                size_t dma_csize = runtime->dma_bytes / channels;
 115                                for (c = 0; c < channels; ++c) {
 116                                        char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, ofs);
 117                                        snd_pcm_format_set_silence(runtime->format, hwbuf, transfer);
 118                                }
 119                        }
 120                }
 121                runtime->silence_filled += transfer;
 122                frames -= transfer;
 123                ofs = 0;
 124        }
 125}
 126
 127static void xrun(struct snd_pcm_substream *substream)
 128{
 129        snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
 130#ifdef CONFIG_SND_PCM_XRUN_DEBUG
 131        if (substream->pstr->xrun_debug) {
 132                snd_printd(KERN_DEBUG "XRUN: pcmC%dD%d%c\n",
 133                           substream->pcm->card->number,
 134                           substream->pcm->device,
 135                           substream->stream ? 'c' : 'p');
 136                if (substream->pstr->xrun_debug > 1)
 137                        dump_stack();
 138        }
 139#endif
 140}
 141
 142static inline snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream,
 143                                                          struct snd_pcm_runtime *runtime)
 144{
 145        snd_pcm_uframes_t pos;
 146
 147        if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
 148                snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
 149        pos = substream->ops->pointer(substream);
 150        if (pos == SNDRV_PCM_POS_XRUN)
 151                return pos; /* XRUN */
 152#ifdef CONFIG_SND_DEBUG
 153        if (pos >= runtime->buffer_size) {
 154                snd_printk(KERN_ERR  "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size);
 155        }
 156#endif
 157        pos -= pos % runtime->min_align;
 158        return pos;
 159}
 160
 161static inline int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream,
 162                                             struct snd_pcm_runtime *runtime)
 163{
 164        snd_pcm_uframes_t avail;
 165
 166        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 167                avail = snd_pcm_playback_avail(runtime);
 168        else
 169                avail = snd_pcm_capture_avail(runtime);
 170        if (avail > runtime->avail_max)
 171                runtime->avail_max = avail;
 172        if (avail >= runtime->stop_threshold) {
 173                if (substream->runtime->status->state == SNDRV_PCM_STATE_DRAINING)
 174                        snd_pcm_drain_done(substream);
 175                else
 176                        xrun(substream);
 177                return -EPIPE;
 178        }
 179        if (avail >= runtime->control->avail_min)
 180                wake_up(&runtime->sleep);
 181        return 0;
 182}
 183
 184static inline int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
 185{
 186        struct snd_pcm_runtime *runtime = substream->runtime;
 187        snd_pcm_uframes_t pos;
 188        snd_pcm_uframes_t new_hw_ptr, hw_ptr_interrupt;
 189        snd_pcm_sframes_t delta;
 190
 191        pos = snd_pcm_update_hw_ptr_pos(substream, runtime);
 192        if (pos == SNDRV_PCM_POS_XRUN) {
 193                xrun(substream);
 194                return -EPIPE;
 195        }
 196        if (runtime->period_size == runtime->buffer_size)
 197                goto __next_buf;
 198        new_hw_ptr = runtime->hw_ptr_base + pos;
 199        hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size;
 200
 201        delta = hw_ptr_interrupt - new_hw_ptr;
 202        if (delta > 0) {
 203                if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) {
 204#ifdef CONFIG_SND_PCM_XRUN_DEBUG
 205                        if (runtime->periods > 1 && substream->pstr->xrun_debug) {
 206                                snd_printd(KERN_ERR "Unexpected hw_pointer value [1] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2);
 207                                if (substream->pstr->xrun_debug > 1)
 208                                        dump_stack();
 209                        }
 210#endif
 211                        return 0;
 212                }
 213              __next_buf:
 214                runtime->hw_ptr_base += runtime->buffer_size;
 215                if (runtime->hw_ptr_base == runtime->boundary)
 216                        runtime->hw_ptr_base = 0;
 217                new_hw_ptr = runtime->hw_ptr_base + pos;
 218        }
 219
 220        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
 221            runtime->silence_size > 0)
 222                snd_pcm_playback_silence(substream, new_hw_ptr);
 223
 224        runtime->status->hw_ptr = new_hw_ptr;
 225        runtime->hw_ptr_interrupt = new_hw_ptr - new_hw_ptr % runtime->period_size;
 226
 227        return snd_pcm_update_hw_ptr_post(substream, runtime);
 228}
 229
 230/* CAUTION: call it with irq disabled */
 231int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
 232{
 233        struct snd_pcm_runtime *runtime = substream->runtime;
 234        snd_pcm_uframes_t pos;
 235        snd_pcm_uframes_t old_hw_ptr, new_hw_ptr;
 236        snd_pcm_sframes_t delta;
 237
 238        old_hw_ptr = runtime->status->hw_ptr;
 239        pos = snd_pcm_update_hw_ptr_pos(substream, runtime);
 240        if (pos == SNDRV_PCM_POS_XRUN) {
 241                xrun(substream);
 242                return -EPIPE;
 243        }
 244        new_hw_ptr = runtime->hw_ptr_base + pos;
 245
 246        delta = old_hw_ptr - new_hw_ptr;
 247        if (delta > 0) {
 248                if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) {
 249#ifdef CONFIG_SND_PCM_XRUN_DEBUG
 250                        if (runtime->periods > 2 && substream->pstr->xrun_debug) {
 251                                snd_printd(KERN_ERR "Unexpected hw_pointer value [2] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2);
 252                                if (substream->pstr->xrun_debug > 1)
 253                                        dump_stack();
 254                        }
 255#endif
 256                        return 0;
 257                }
 258                runtime->hw_ptr_base += runtime->buffer_size;
 259                if (runtime->hw_ptr_base == runtime->boundary)
 260                        runtime->hw_ptr_base = 0;
 261                new_hw_ptr = runtime->hw_ptr_base + pos;
 262        }
 263        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
 264            runtime->silence_size > 0)
 265                snd_pcm_playback_silence(substream, new_hw_ptr);
 266
 267        runtime->status->hw_ptr = new_hw_ptr;
 268
 269        return snd_pcm_update_hw_ptr_post(substream, runtime);
 270}
 271
 272/**
 273 * snd_pcm_set_ops - set the PCM operators
 274 * @pcm: the pcm instance
 275 * @direction: stream direction, SNDRV_PCM_STREAM_XXX
 276 * @ops: the operator table
 277 *
 278 * Sets the given PCM operators to the pcm instance.
 279 */
 280void snd_pcm_set_ops(struct snd_pcm *pcm, int direction, struct snd_pcm_ops *ops)
 281{
 282        struct snd_pcm_str *stream = &pcm->streams[direction];
 283        struct snd_pcm_substream *substream;
 284        
 285        for (substream = stream->substream; substream != NULL; substream = substream->next)
 286                substream->ops = ops;
 287}
 288
 289EXPORT_SYMBOL(snd_pcm_set_ops);
 290
 291/**
 292 * snd_pcm_sync - set the PCM sync id
 293 * @substream: the pcm substream
 294 *
 295 * Sets the PCM sync identifier for the card.
 296 */
 297void snd_pcm_set_sync(struct snd_pcm_substream *substream)
 298{
 299        struct snd_pcm_runtime *runtime = substream->runtime;
 300        
 301        runtime->sync.id32[0] = substream->pcm->card->number;
 302        runtime->sync.id32[1] = -1;
 303        runtime->sync.id32[2] = -1;
 304        runtime->sync.id32[3] = -1;
 305}
 306
 307EXPORT_SYMBOL(snd_pcm_set_sync);
 308
 309/*
 310 *  Standard ioctl routine
 311 */
 312
 313static inline unsigned int div32(unsigned int a, unsigned int b, 
 314                                 unsigned int *r)
 315{
 316        if (b == 0) {
 317                *r = 0;
 318                return UINT_MAX;
 319        }
 320        *r = a % b;
 321        return a / b;
 322}
 323
 324static inline unsigned int div_down(unsigned int a, unsigned int b)
 325{
 326        if (b == 0)
 327                return UINT_MAX;
 328        return a / b;
 329}
 330
 331static inline unsigned int div_up(unsigned int a, unsigned int b)
 332{
 333        unsigned int r;
 334        unsigned int q;
 335        if (b == 0)
 336                return UINT_MAX;
 337        q = div32(a, b, &r);
 338        if (r)
 339                ++q;
 340        return q;
 341}
 342
 343static inline unsigned int mul(unsigned int a, unsigned int b)
 344{
 345        if (a == 0)
 346                return 0;
 347        if (div_down(UINT_MAX, a) < b)
 348                return UINT_MAX;
 349        return a * b;
 350}
 351
 352static inline unsigned int muldiv32(unsigned int a, unsigned int b,
 353                                    unsigned int c, unsigned int *r)
 354{
 355        u_int64_t n = (u_int64_t) a * b;
 356        if (c == 0) {
 357                snd_assert(n > 0, );
 358                *r = 0;
 359                return UINT_MAX;
 360        }
 361        div64_32(&n, c, r);
 362        if (n >= UINT_MAX) {
 363                *r = 0;
 364                return UINT_MAX;
 365        }
 366        return n;
 367}
 368
 369/**
 370 * snd_interval_refine - refine the interval value of configurator
 371 * @i: the interval value to refine
 372 * @v: the interval value to refer to
 373 *
 374 * Refines the interval value with the reference value.
 375 * The interval is changed to the range satisfying both intervals.
 376 * The interval status (min, max, integer, etc.) are evaluated.
 377 *
 378 * Returns non-zero if the value is changed, zero if not changed.
 379 */
 380int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
 381{
 382        int changed = 0;
 383        snd_assert(!snd_interval_empty(i), return -EINVAL);
 384        if (i->min < v->min) {
 385                i->min = v->min;
 386                i->openmin = v->openmin;
 387                changed = 1;
 388        } else if (i->min == v->min && !i->openmin && v->openmin) {
 389                i->openmin = 1;
 390                changed = 1;
 391        }
 392        if (i->max > v->max) {
 393                i->max = v->max;
 394                i->openmax = v->openmax;
 395                changed = 1;
 396        } else if (i->max == v->max && !i->openmax && v->openmax) {
 397                i->openmax = 1;
 398                changed = 1;
 399        }
 400        if (!i->integer && v->integer) {
 401                i->integer = 1;
 402                changed = 1;
 403        }
 404        if (i->integer) {
 405                if (i->openmin) {
 406                        i->min++;
 407                        i->openmin = 0;
 408                }
 409                if (i->openmax) {
 410                        i->max--;
 411                        i->openmax = 0;
 412                }
 413        } else if (!i->openmin && !i->openmax && i->min == i->max)
 414                i->integer = 1;
 415        if (snd_interval_checkempty(i)) {
 416                snd_interval_none(i);
 417                return -EINVAL;
 418        }
 419        return changed;
 420}
 421
 422EXPORT_SYMBOL(snd_interval_refine);
 423
 424static int snd_interval_refine_first(struct snd_interval *i)
 425{
 426        snd_assert(!snd_interval_empty(i), return -EINVAL);
 427        if (snd_interval_single(i))
 428                return 0;
 429        i->max = i->min;
 430        i->openmax = i->openmin;
 431        if (i->openmax)
 432                i->max++;
 433        return 1;
 434}
 435
 436static int snd_interval_refine_last(struct snd_interval *i)
 437{
 438        snd_assert(!snd_interval_empty(i), return -EINVAL);
 439        if (snd_interval_single(i))
 440                return 0;
 441        i->min = i->max;
 442        i->openmin = i->openmax;
 443        if (i->openmin)
 444                i->min--;
 445        return 1;
 446}
 447
 448void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c)
 449{
 450        if (a->empty || b->empty) {
 451                snd_interval_none(c);
 452                return;
 453        }
 454        c->empty = 0;
 455        c->min = mul(a->min, b->min);
 456        c->openmin = (a->openmin || b->openmin);
 457        c->max = mul(a->max,  b->max);
 458        c->openmax = (a->openmax || b->openmax);
 459        c->integer = (a->integer && b->integer);
 460}
 461
 462/**
 463 * snd_interval_div - refine the interval value with division
 464 * @a: dividend
 465 * @b: divisor
 466 * @c: quotient
 467 *
 468 * c = a / b
 469 *
 470 * Returns non-zero if the value is changed, zero if not changed.
 471 */
 472void snd_interval_div(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c)
 473{
 474        unsigned int r;
 475        if (a->empty || b->empty) {
 476                snd_interval_none(c);
 477                return;
 478        }
 479        c->empty = 0;
 480        c->min = div32(a->min, b->max, &r);
 481        c->openmin = (r || a->openmin || b->openmax);
 482        if (b->min > 0) {
 483                c->max = div32(a->max, b->min, &r);
 484                if (r) {
 485                        c->max++;
 486                        c->openmax = 1;
 487                } else
 488                        c->openmax = (a->openmax || b->openmin);
 489        } else {
 490                c->max = UINT_MAX;
 491                c->openmax = 0;
 492        }
 493        c->integer = 0;
 494}
 495
 496/**
 497 * snd_interval_muldivk - refine the interval value
 498 * @a: dividend 1
 499 * @b: dividend 2
 500 * @k: divisor (as integer)
 501 * @c: result
 502  *
 503 * c = a * b / k
 504 *
 505 * Returns non-zero if the value is changed, zero if not changed.
 506 */
 507void snd_interval_muldivk(const struct snd_interval *a, const struct snd_interval *b,
 508                      unsigned int k, struct snd_interval *c)
 509{
 510        unsigned int r;
 511        if (a->empty || b->empty) {
 512                snd_interval_none(c);
 513                return;
 514        }
 515        c->empty = 0;
 516        c->min = muldiv32(a->min, b->min, k, &r);
 517        c->openmin = (r || a->openmin || b->openmin);
 518        c->max = muldiv32(a->max, b->max, k, &r);
 519        if (r) {
 520                c->max++;
 521                c->openmax = 1;
 522        } else
 523                c->openmax = (a->openmax || b->openmax);
 524        c->integer = 0;
 525}
 526
 527/**
 528 * snd_interval_mulkdiv - refine the interval value
 529 * @a: dividend 1
 530 * @k: dividend 2 (as integer)
 531 * @b: divisor
 532 * @c: result
 533 *
 534 * c = a * k / b
 535 *
 536 * Returns non-zero if the value is changed, zero if not changed.
 537 */
 538void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k,
 539                      const struct snd_interval *b, struct snd_interval *c)
 540{
 541        unsigned int r;
 542        if (a->empty || b->empty) {
 543                snd_interval_none(c);
 544                return;
 545        }
 546        c->empty = 0;
 547        c->min = muldiv32(a->min, k, b->max, &r);
 548        c->openmin = (r || a->openmin || b->openmax);
 549        if (b->min > 0) {
 550                c->max = muldiv32(a->max, k, b->min, &r);
 551                if (r) {
 552                        c->max++;
 553                        c->openmax = 1;
 554                } else
 555                        c->openmax = (a->openmax || b->openmin);
 556        } else {
 557                c->max = UINT_MAX;
 558                c->openmax = 0;
 559        }
 560        c->integer = 0;
 561}
 562
 563/* ---- */
 564
 565
 566/**
 567 * snd_interval_ratnum - refine the interval value
 568 * @i: interval to refine
 569 * @rats_count: number of ratnum_t 
 570 * @rats: ratnum_t array
 571 * @nump: pointer to store the resultant numerator
 572 * @denp: pointer to store the resultant denominator
 573 *
 574 * Returns non-zero if the value is changed, zero if not changed.
 575 */
 576int snd_interval_ratnum(struct snd_interval *i,
 577                        unsigned int rats_count, struct snd_ratnum *rats,
 578                        unsigned int *nump, unsigned int *denp)
 579{
 580        unsigned int best_num, best_diff, best_den;
 581        unsigned int k;
 582        struct snd_interval t;
 583        int err;
 584
 585        best_num = best_den = best_diff = 0;
 586        for (k = 0; k < rats_count; ++k) {
 587                unsigned int num = rats[k].num;
 588                unsigned int den;
 589                unsigned int q = i->min;
 590                int diff;
 591                if (q == 0)
 592                        q = 1;
 593                den = div_down(num, q);
 594                if (den < rats[k].den_min)
 595                        continue;
 596                if (den > rats[k].den_max)
 597                        den = rats[k].den_max;
 598                else {
 599                        unsigned int r;
 600                        r = (den - rats[k].den_min) % rats[k].den_step;
 601                        if (r != 0)
 602                                den -= r;
 603                }
 604                diff = num - q * den;
 605                if (best_num == 0 ||
 606                    diff * best_den < best_diff * den) {
 607                        best_diff = diff;
 608                        best_den = den;
 609                        best_num = num;
 610                }
 611        }
 612        if (best_den == 0) {
 613                i->empty = 1;
 614                return -EINVAL;
 615        }
 616        t.min = div_down(best_num, best_den);
 617        t.openmin = !!(best_num % best_den);
 618        
 619        best_num = best_den = best_diff = 0;
 620        for (k = 0; k < rats_count; ++k) {
 621                unsigned int num = rats[k].num;
 622                unsigned int den;
 623                unsigned int q = i->max;
 624                int diff;
 625                if (q == 0) {
 626                        i->empty = 1;
 627                        return -EINVAL;
 628                }
 629                den = div_up(num, q);
 630                if (den > rats[k].den_max)
 631                        continue;
 632                if (den < rats[k].den_min)
 633                        den = rats[k].den_min;
 634                else {
 635                        unsigned int r;
 636                        r = (den - rats[k].den_min) % rats[k].den_step;
 637                        if (r != 0)
 638                                den += rats[k].den_step - r;
 639                }
 640                diff = q * den - num;
 641                if (best_num == 0 ||
 642                    diff * best_den < best_diff * den) {
 643                        best_diff = diff;
 644                        best_den = den;
 645                        best_num = num;
 646                }
 647        }
 648        if (best_den == 0) {
 649                i->empty = 1;
 650                return -EINVAL;
 651        }
 652        t.max = div_up(best_num, best_den);
 653        t.openmax = !!(best_num % best_den);
 654        t.integer = 0;
 655        err = snd_interval_refine(i, &t);
 656        if (err < 0)
 657                return err;
 658
 659        if (snd_interval_single(i)) {
 660                if (nump)
 661                        *nump = best_num;
 662                if (denp)
 663                        *denp = best_den;
 664        }
 665        return err;
 666}
 667
 668EXPORT_SYMBOL(snd_interval_ratnum);
 669
 670/**
 671 * snd_interval_ratden - refine the interval value
 672 * @i: interval to refine
 673 * @rats_count: number of struct ratden
 674 * @rats: struct ratden array
 675 * @nump: pointer to store the resultant numerator
 676 * @denp: pointer to store the resultant denominator
 677 *
 678 * Returns non-zero if the value is changed, zero if not changed.
 679 */
 680static int snd_interval_ratden(struct snd_interval *i,
 681                               unsigned int rats_count, struct snd_ratden *rats,
 682                               unsigned int *nump, unsigned int *denp)
 683{
 684        unsigned int best_num, best_diff, best_den;
 685        unsigned int k;
 686        struct snd_interval t;
 687        int err;
 688
 689        best_num = best_den = best_diff = 0;
 690        for (k = 0; k < rats_count; ++k) {
 691                unsigned int num;
 692                unsigned int den = rats[k].den;
 693                unsigned int q = i->min;
 694                int diff;
 695                num = mul(q, den);
 696                if (num > rats[k].num_max)
 697                        continue;
 698                if (num < rats[k].num_min)
 699                        num = rats[k].num_max;
 700                else {
 701                        unsigned int r;
 702                        r = (num - rats[k].num_min) % rats[k].num_step;
 703                        if (r != 0)
 704                                num += rats[k].num_step - r;
 705                }
 706                diff = num - q * den;
 707                if (best_num == 0 ||
 708                    diff * best_den < best_diff * den) {
 709                        best_diff = diff;
 710                        best_den = den;
 711                        best_num = num;
 712                }
 713        }
 714        if (best_den == 0) {
 715                i->empty = 1;
 716                return -EINVAL;
 717        }
 718        t.min = div_down(best_num, best_den);
 719        t.openmin = !!(best_num % best_den);
 720        
 721        best_num = best_den = best_diff = 0;
 722        for (k = 0; k < rats_count; ++k) {
 723                unsigned int num;
 724                unsigned int den = rats[k].den;
 725                unsigned int q = i->max;
 726                int diff;
 727                num = mul(q, den);
 728                if (num < rats[k].num_min)
 729                        continue;
 730                if (num > rats[k].num_max)
 731                        num = rats[k].num_max;
 732                else {
 733                        unsigned int r;
 734                        r = (num - rats[k].num_min) % rats[k].num_step;
 735                        if (r != 0)
 736                                num -= r;
 737                }
 738                diff = q * den - num;
 739                if (best_num == 0 ||
 740                    diff * best_den < best_diff * den) {
 741                        best_diff = diff;
 742                        best_den = den;
 743                        best_num = num;
 744                }
 745        }
 746        if (best_den == 0) {
 747                i->empty = 1;
 748                return -EINVAL;
 749        }
 750        t.max = div_up(best_num, best_den);
 751        t.openmax = !!(best_num % best_den);
 752        t.integer = 0;
 753        err = snd_interval_refine(i, &t);
 754        if (err < 0)
 755                return err;
 756
 757        if (snd_interval_single(i)) {
 758                if (nump)
 759                        *nump = best_num;
 760                if (denp)
 761                        *denp = best_den;
 762        }
 763        return err;
 764}
 765
 766/**
 767 * snd_interval_list - refine the interval value from the list
 768 * @i: the interval value to refine
 769 * @count: the number of elements in the list
 770 * @list: the value list
 771 * @mask: the bit-mask to evaluate
 772 *
 773 * Refines the interval value from the list.
 774 * When mask is non-zero, only the elements corresponding to bit 1 are
 775 * evaluated.
 776 *
 777 * Returns non-zero if the value is changed, zero if not changed.
 778 */
 779int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask)
 780{
 781        unsigned int k;
 782        struct snd_interval list_range;
 783
 784        if (!count) {
 785                i->empty = 1;
 786                return -EINVAL;
 787        }
 788        snd_interval_any(&list_range);
 789        list_range.min = UINT_MAX;
 790        list_range.max = 0;
 791        for (k = 0; k < count; k++) {
 792                if (mask && !(mask & (1 << k)))
 793                        continue;
 794                if (!snd_interval_test(i, list[k]))
 795                        continue;
 796                list_range.min = min(list_range.min, list[k]);
 797                list_range.max = max(list_range.max, list[k]);
 798        }
 799        return snd_interval_refine(i, &list_range);
 800}
 801
 802EXPORT_SYMBOL(snd_interval_list);
 803
 804static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step)
 805{
 806        unsigned int n;
 807        int changed = 0;
 808        n = (i->min - min) % step;
 809        if (n != 0 || i->openmin) {
 810                i->min += step - n;
 811                changed = 1;
 812        }
 813        n = (i->max - min) % step;
 814        if (n != 0 || i->openmax) {
 815                i->max -= n;
 816                changed = 1;
 817        }
 818        if (snd_interval_checkempty(i)) {
 819                i->empty = 1;
 820                return -EINVAL;
 821        }
 822        return changed;
 823}
 824
 825/* Info constraints helpers */
 826
 827/**
 828 * snd_pcm_hw_rule_add - add the hw-constraint rule
 829 * @runtime: the pcm runtime instance
 830 * @cond: condition bits
 831 * @var: the variable to evaluate
 832 * @func: the evaluation function
 833 * @private: the private data pointer passed to function
 834 * @dep: the dependent variables
 835 *
 836 * Returns zero if successful, or a negative error code on failure.
 837 */
 838int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
 839                        int var,
 840                        snd_pcm_hw_rule_func_t func, void *private,
 841                        int dep, ...)
 842{
 843        struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
 844        struct snd_pcm_hw_rule *c;
 845        unsigned int k;
 846        va_list args;
 847        va_start(args, dep);
 848        if (constrs->rules_num >= constrs->rules_all) {
 849                struct snd_pcm_hw_rule *new;
 850                unsigned int new_rules = constrs->rules_all + 16;
 851                new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL);
 852                if (!new)
 853                        return -ENOMEM;
 854                if (constrs->rules) {
 855                        memcpy(new, constrs->rules,
 856                               constrs->rules_num * sizeof(*c));
 857                        kfree(constrs->rules);
 858                }
 859                constrs->rules = new;
 860                constrs->rules_all = new_rules;
 861        }
 862        c = &constrs->rules[constrs->rules_num];
 863        c->cond = cond;
 864        c->func = func;
 865        c->var = var;
 866        c->private = private;
 867        k = 0;
 868        while (1) {
 869                snd_assert(k < ARRAY_SIZE(c->deps), return -EINVAL);
 870                c->deps[k++] = dep;
 871                if (dep < 0)
 872                        break;
 873                dep = va_arg(args, int);
 874        }
 875        constrs->rules_num++;
 876        va_end(args);
 877        return 0;
 878}                                   
 879
 880EXPORT_SYMBOL(snd_pcm_hw_rule_add);
 881
 882/**
 883 * snd_pcm_hw_constraint_mask
 884 * @runtime: PCM runtime instance
 885 * @var: hw_params variable to apply the mask
 886 * @mask: the bitmap mask
 887 *
 888 * Apply the constraint of the given bitmap mask to a mask parameter.
 889 */
 890int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
 891                               u_int32_t mask)
 892{
 893        struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
 894        struct snd_mask *maskp = constrs_mask(constrs, var);
 895        *maskp->bits &= mask;
 896        memset(maskp->bits + 1, 0, (SNDRV_MASK_MAX-32) / 8); /* clear rest */
 897        if (*maskp->bits == 0)
 898                return -EINVAL;
 899        return 0;
 900}
 901
 902/**
 903 * snd_pcm_hw_constraint_mask64
 904 * @runtime: PCM runtime instance
 905 * @var: hw_params variable to apply the mask
 906 * @mask: the 64bit bitmap mask
 907 *
 908 * Apply the constraint of the given bitmap mask to a mask parameter.
 909 */
 910int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
 911                                 u_int64_t mask)
 912{
 913        struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
 914        struct snd_mask *maskp = constrs_mask(constrs, var);
 915        maskp->bits[0] &= (u_int32_t)mask;
 916        maskp->bits[1] &= (u_int32_t)(mask >> 32);
 917        memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
 918        if (! maskp->bits[0] && ! maskp->bits[1])
 919                return -EINVAL;
 920        return 0;
 921}
 922
 923/**
 924 * snd_pcm_hw_constraint_integer
 925 * @runtime: PCM runtime instance
 926 * @var: hw_params variable to apply the integer constraint
 927 *
 928 * Apply the constraint of integer to an interval parameter.
 929 */
 930int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var)
 931{
 932        struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
 933        return snd_interval_setinteger(constrs_interval(constrs, var));
 934}
 935
 936EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
 937
 938/**
 939 * snd_pcm_hw_constraint_minmax
 940 * @runtime: PCM runtime instance
 941 * @var: hw_params variable to apply the range
 942 * @min: the minimal value
 943 * @max: the maximal value
 944 * 
 945 * Apply the min/max range constraint to an interval parameter.
 946 */
 947int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
 948                                 unsigned int min, unsigned int max)
 949{
 950        struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
 951        struct snd_interval t;
 952        t.min = min;
 953        t.max = max;
 954        t.openmin = t.openmax = 0;
 955        t.integer = 0;
 956        return snd_interval_refine(constrs_interval(constrs, var), &t);
 957}
 958
 959EXPORT_SYMBOL(snd_pcm_hw_constraint_minmax);
 960
 961static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
 962                                struct snd_pcm_hw_rule *rule)
 963{
 964        struct snd_pcm_hw_constraint_list *list = rule->private;
 965        return snd_interval_list(hw_param_interval(params, rule->var), list->count, list->list, list->mask);
 966}               
 967
 968
 969/**
 970 * snd_pcm_hw_constraint_list
 971 * @runtime: PCM runtime instance
 972 * @cond: condition bits
 973 * @var: hw_params variable to apply the list constraint
 974 * @l: list
 975 * 
 976 * Apply the list of constraints to an interval parameter.
 977 */
 978int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
 979                               unsigned int cond,
 980                               snd_pcm_hw_param_t var,
 981                               struct snd_pcm_hw_constraint_list *l)
 982{
 983        return snd_pcm_hw_rule_add(runtime, cond, var,
 984                                   snd_pcm_hw_rule_list, l,
 985                                   var, -1);
 986}
 987
 988EXPORT_SYMBOL(snd_pcm_hw_constraint_list);
 989
 990static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
 991                                   struct snd_pcm_hw_rule *rule)
 992{
 993        struct snd_pcm_hw_constraint_ratnums *r = rule->private;
 994        unsigned int num = 0, den = 0;
 995        int err;
 996        err = snd_interval_ratnum(hw_param_interval(params, rule->var),
 997                                  r->nrats, r->rats, &num, &den);
 998        if (err >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) {
 999                params->rate_num = num;
1000                params->rate_den = den;
1001        }
1002        return err;
1003}
1004
1005/**
1006 * snd_pcm_hw_constraint_ratnums
1007 * @runtime: PCM runtime instance
1008 * @cond: condition bits
1009 * @var: hw_params variable to apply the ratnums constraint
1010 * @r: struct snd_ratnums constriants
1011 */
1012int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, 
1013                                  unsigned int cond,
1014                                  snd_pcm_hw_param_t var,
1015                                  struct snd_pcm_hw_constraint_ratnums *r)
1016{
1017        return snd_pcm_hw_rule_add(runtime, cond, var,
1018                                   snd_pcm_hw_rule_ratnums, r,
1019                                   var, -1);
1020}
1021
1022EXPORT_SYMBOL(snd_pcm_hw_constraint_ratnums);
1023
1024static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params,
1025                                   struct snd_pcm_hw_rule *rule)
1026{
1027        struct snd_pcm_hw_constraint_ratdens *r = rule->private;
1028        unsigned int num = 0, den = 0;
1029        int err = snd_interval_ratden(hw_param_interval(params, rule->var),
1030                                  r->nrats, r->rats, &num, &den);
1031        if (err >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) {
1032                params->rate_num = num;
1033                params->rate_den = den;
1034        }
1035        return err;
1036}
1037
1038/**
1039 * snd_pcm_hw_constraint_ratdens
1040 * @runtime: PCM runtime instance
1041 * @cond: condition bits
1042 * @var: hw_params variable to apply the ratdens constraint
1043 * @r: struct snd_ratdens constriants
1044 */
1045int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime, 
1046                                  unsigned int cond,
1047                                  snd_pcm_hw_param_t var,
1048                                  struct snd_pcm_hw_constraint_ratdens *r)
1049{
1050        return snd_pcm_hw_rule_add(runtime, cond, var,
1051                                   snd_pcm_hw_rule_ratdens, r,
1052                                   var, -1);
1053}
1054
1055EXPORT_SYMBOL(snd_pcm_hw_constraint_ratdens);
1056
1057static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params,
1058                                  struct snd_pcm_hw_rule *rule)
1059{
1060        unsigned int l = (unsigned long) rule->private;
1061        int width = l & 0xffff;
1062        unsigned int msbits = l >> 16;
1063        struct snd_interval *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
1064        if (snd_interval_single(i) && snd_interval_value(i) == width)
1065                params->msbits = msbits;
1066        return 0;
1067}
1068
1069/**
1070 * snd_pcm_hw_constraint_msbits
1071 * @runtime: PCM runtime instance
1072 * @cond: condition bits
1073 * @width: sample bits width
1074 * @msbits: msbits width
1075 */
1076int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, 
1077                                 unsigned int cond,
1078                                 unsigned int width,
1079                                 unsigned int msbits)
1080{
1081        unsigned long l = (msbits << 16) | width;
1082        return snd_pcm_hw_rule_add(runtime, cond, -1,
1083                                    snd_pcm_hw_rule_msbits,
1084                                    (void*) l,
1085                                    SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
1086}
1087
1088EXPORT_SYMBOL(snd_pcm_hw_constraint_msbits);
1089
1090static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params,
1091                                struct snd_pcm_hw_rule *rule)
1092{
1093        unsigned long step = (unsigned long) rule->private;
1094        return snd_interval_step(hw_param_interval(params, rule->var), 0, step);
1095}
1096
1097/**
1098 * snd_pcm_hw_constraint_step
1099 * @runtime: PCM runtime instance
1100 * @cond: condition bits
1101 * @var: hw_params variable to apply the step constraint
1102 * @step: step size
1103 */
1104int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
1105                               unsigned int cond,
1106                               snd_pcm_hw_param_t var,
1107                               unsigned long step)
1108{
1109        return snd_pcm_hw_rule_add(runtime, cond, var, 
1110                                   snd_pcm_hw_rule_step, (void *) step,
1111                                   var, -1);
1112}
1113
1114EXPORT_SYMBOL(snd_pcm_hw_constraint_step);
1115
1116static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
1117{
1118        static unsigned int pow2_sizes[] = {
1119                1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7,
1120                1<<8, 1<<9, 1<<10, 1<<11, 1<<12, 1<<13, 1<<14, 1<<15,
1121                1<<16, 1<<17, 1<<18, 1<<19, 1<<20, 1<<21, 1<<22, 1<<23,
1122                1<<24, 1<<25, 1<<26, 1<<27, 1<<28, 1<<29, 1<<30
1123        };
1124        return snd_interval_list(hw_param_interval(params, rule->var),
1125                                 ARRAY_SIZE(pow2_sizes), pow2_sizes, 0);
1126}               
1127
1128/**
1129 * snd_pcm_hw_constraint_pow2
1130 * @runtime: PCM runtime instance
1131 * @cond: condition bits
1132 * @var: hw_params variable to apply the power-of-2 constraint
1133 */
1134int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
1135                               unsigned int cond,
1136                               snd_pcm_hw_param_t var)
1137{
1138        return snd_pcm_hw_rule_add(runtime, cond, var, 
1139                                   snd_pcm_hw_rule_pow2, NULL,
1140                                   var, -1);
1141}
1142
1143EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2);
1144
1145static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
1146                                  snd_pcm_hw_param_t var)
1147{
1148        if (hw_is_mask(var)) {
1149                snd_mask_any(hw_param_mask(params, var));
1150                params->cmask |= 1 << var;
1151                params->rmask |= 1 << var;
1152                return;
1153        }
1154        if (hw_is_interval(var)) {
1155                snd_interval_any(hw_param_interval(params, var));
1156                params->cmask |= 1 << var;
1157                params->rmask |= 1 << var;
1158                return;
1159        }
1160        snd_BUG();
1161}
1162
1163void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
1164{
1165        unsigned int k;
1166        memset(params, 0, sizeof(*params));
1167        for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++)
1168                _snd_pcm_hw_param_any(params, k);
1169        for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++)
1170                _snd_pcm_hw_param_any(params, k);
1171        params->info = ~0U;
1172}
1173
1174EXPORT_SYMBOL(_snd_pcm_hw_params_any);
1175
1176/**
1177 * snd_pcm_hw_param_value
1178 * @params: the hw_params instance
1179 * @var: parameter to retrieve
1180 * @dir: pointer to the direction (-1,0,1) or NULL
1181 *
1182 * Return the value for field PAR if it's fixed in configuration space 
1183 *  defined by PARAMS. Return -EINVAL otherwise
1184 */
1185int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
1186                           snd_pcm_hw_param_t var, int *dir)
1187{
1188        if (hw_is_mask(var)) {
1189                const struct snd_mask *mask = hw_param_mask_c(params, var);
1190                if (!snd_mask_single(mask))
1191                        return -EINVAL;
1192                if (dir)
1193                        *dir = 0;
1194                return snd_mask_value(mask);
1195        }
1196        if (hw_is_interval(var)) {
1197                const struct snd_interval *i = hw_param_interval_c(params, var);
1198                if (!snd_interval_single(i))
1199                        return -EINVAL;
1200                if (dir)
1201                        *dir = i->openmin;
1202                return snd_interval_value(i);
1203        }
1204        return -EINVAL;
1205}
1206
1207EXPORT_SYMBOL(snd_pcm_hw_param_value);
1208
1209void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params,
1210                                snd_pcm_hw_param_t var)
1211{
1212        if (hw_is_mask(var)) {
1213                snd_mask_none(hw_param_mask(params, var));
1214                params->cmask |= 1 << var;
1215                params->rmask |= 1 << var;
1216        } else if (hw_is_interval(var)) {
1217                snd_interval_none(hw_param_interval(params, var));
1218                params->cmask |= 1 << var;
1219                params->rmask |= 1 << var;
1220        } else {
1221                snd_BUG();
1222        }
1223}
1224
1225EXPORT_SYMBOL(_snd_pcm_hw_param_setempty);
1226
1227static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1228                                   snd_pcm_hw_param_t var)
1229{
1230        int changed;
1231        if (hw_is_mask(var))
1232                changed = snd_mask_refine_first(hw_param_mask(params, var));
1233        else if (hw_is_interval(var))
1234                changed = snd_interval_refine_first(hw_param_interval(params, var));
1235        else
1236                return -EINVAL;
1237        if (changed) {
1238                params->cmask |= 1 << var;
1239                params->rmask |= 1 << var;
1240        }
1241        return changed;
1242}
1243
1244
1245/**
1246 * snd_pcm_hw_param_first
1247 * @pcm: PCM instance
1248 * @params: the hw_params instance
1249 * @var: parameter to retrieve
1250 * @dir: pointer to the direction (-1,0,1) or NULL
1251 *
1252 * Inside configuration space defined by PARAMS remove from PAR all 
1253 * values > minimum. Reduce configuration space accordingly.
1254 * Return the minimum.
1255 */
1256int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, 
1257                           struct snd_pcm_hw_params *params, 
1258                           snd_pcm_hw_param_t var, int *dir)
1259{
1260        int changed = _snd_pcm_hw_param_first(params, var);
1261        if (changed < 0)
1262                return changed;
1263        if (params->rmask) {
1264                int err = snd_pcm_hw_refine(pcm, params);
1265                snd_assert(err >= 0, return err);
1266        }
1267        return snd_pcm_hw_param_value(params, var, dir);
1268}
1269
1270EXPORT_SYMBOL(snd_pcm_hw_param_first);
1271
1272static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1273                                  snd_pcm_hw_param_t var)
1274{
1275        int changed;
1276        if (hw_is_mask(var))
1277                changed = snd_mask_refine_last(hw_param_mask(params, var));
1278        else if (hw_is_interval(var))
1279                changed = snd_interval_refine_last(hw_param_interval(params, var));
1280        else
1281                return -EINVAL;
1282        if (changed) {
1283                params->cmask |= 1 << var;
1284                params->rmask |= 1 << var;
1285        }
1286        return changed;
1287}
1288
1289
1290/**
1291 * snd_pcm_hw_param_last
1292 * @pcm: PCM instance
1293 * @params: the hw_params instance
1294 * @var: parameter to retrieve
1295 * @dir: pointer to the direction (-1,0,1) or NULL
1296 *
1297 * Inside configuration space defined by PARAMS remove from PAR all 
1298 * values < maximum. Reduce configuration space accordingly.
1299 * Return the maximum.
1300 */
1301int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, 
1302                          struct snd_pcm_hw_params *params,
1303                          snd_pcm_hw_param_t var, int *dir)
1304{
1305        int changed = _snd_pcm_hw_param_last(params, var);
1306        if (changed < 0)
1307                return changed;
1308        if (params->rmask) {
1309                int err = snd_pcm_hw_refine(pcm, params);
1310                snd_assert(err >= 0, return err);
1311        }
1312        return snd_pcm_hw_param_value(params, var, dir);
1313}
1314
1315EXPORT_SYMBOL(snd_pcm_hw_param_last);
1316
1317/**
1318 * snd_pcm_hw_param_choose
1319 * @pcm: PCM instance
1320 * @params: the hw_params instance
1321 *
1322 * Choose one configuration from configuration space defined by PARAMS
1323 * The configuration chosen is that obtained fixing in this order:
1324 * first access, first format, first subformat, min channels,
1325 * min rate, min period time, max buffer size, min tick time
1326 */
1327int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm,
1328                             struct snd_pcm_hw_params *params)
1329{
1330        static int vars[] = {
1331                SNDRV_PCM_HW_PARAM_ACCESS,
1332                SNDRV_PCM_HW_PARAM_FORMAT,
1333                SNDRV_PCM_HW_PARAM_SUBFORMAT,
1334                SNDRV_PCM_HW_PARAM_CHANNELS,
1335                SNDRV_PCM_HW_PARAM_RATE,
1336                SNDRV_PCM_HW_PARAM_PERIOD_TIME,
1337                SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
1338                SNDRV_PCM_HW_PARAM_TICK_TIME,
1339                -1
1340        };
1341        int err, *v;
1342
1343        for (v = vars; *v != -1; v++) {
1344                if (*v != SNDRV_PCM_HW_PARAM_BUFFER_SIZE)
1345                        err = snd_pcm_hw_param_first(pcm, params, *v, NULL);
1346                else
1347                        err = snd_pcm_hw_param_last(pcm, params, *v, NULL);
1348                snd_assert(err >= 0, return err);
1349        }
1350        return 0;
1351}
1352
1353static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
1354                                   void *arg)
1355{
1356        struct snd_pcm_runtime *runtime = substream->runtime;
1357        unsigned long flags;
1358        snd_pcm_stream_lock_irqsave(substream, flags);
1359        if (snd_pcm_running(substream) &&
1360            snd_pcm_update_hw_ptr(substream) >= 0)
1361                runtime->status->hw_ptr %= runtime->buffer_size;
1362        else
1363                runtime->status->hw_ptr = 0;
1364        snd_pcm_stream_unlock_irqrestore(substream, flags);
1365        return 0;
1366}
1367
1368static int snd_pcm_lib_ioctl_channel_info(struct snd_pcm_substream *substream,
1369                                          void *arg)
1370{
1371        struct snd_pcm_channel_info *info = arg;
1372        struct snd_pcm_runtime *runtime = substream->runtime;
1373        int width;
1374        if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) {
1375                info->offset = -1;
1376                return 0;
1377        }
1378        width = snd_pcm_format_physical_width(runtime->format);
1379        if (width < 0)
1380                return width;
1381        info->offset = 0;
1382        switch (runtime->access) {
1383        case SNDRV_PCM_ACCESS_MMAP_INTERLEAVED:
1384        case SNDRV_PCM_ACCESS_RW_INTERLEAVED:
1385                info->first = info->channel * width;
1386                info->step = runtime->channels * width;
1387                break;
1388        case SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED:
1389        case SNDRV_PCM_ACCESS_RW_NONINTERLEAVED:
1390        {
1391                size_t size = runtime->dma_bytes / runtime->channels;
1392                info->first = info->channel * size * 8;
1393                info->step = width;
1394                break;
1395        }
1396        default:
1397                snd_BUG();
1398                break;
1399        }
1400        return 0;
1401}
1402
1403/**
1404 * snd_pcm_lib_ioctl - a generic PCM ioctl callback
1405 * @substream: the pcm substream instance
1406 * @cmd: ioctl command
1407 * @arg: ioctl argument
1408 *
1409 * Processes the generic ioctl commands for PCM.
1410 * Can be passed as the ioctl callback for PCM ops.
1411 *
1412 * Returns zero if successful, or a negative error code on failure.
1413 */
1414int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
1415                      unsigned int cmd, void *arg)
1416{
1417        switch (cmd) {
1418        case SNDRV_PCM_IOCTL1_INFO:
1419                return 0;
1420        case SNDRV_PCM_IOCTL1_RESET:
1421                return snd_pcm_lib_ioctl_reset(substream, arg);
1422        case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
1423                return snd_pcm_lib_ioctl_channel_info(substream, arg);
1424        }
1425        return -ENXIO;
1426}
1427
1428EXPORT_SYMBOL(snd_pcm_lib_ioctl);
1429
1430/**
1431 * snd_pcm_period_elapsed - update the pcm status for the next period
1432 * @substream: the pcm substream instance
1433 *
1434 * This function is called from the interrupt handler when the
1435 * PCM has processed the period size.  It will update the current
1436 * pointer, wake up sleepers, etc.
1437 *
1438 * Even if more than one periods have elapsed since the last call, you
1439 * have to call this only once.
1440 */
1441void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
1442{
1443        struct snd_pcm_runtime *runtime;
1444        unsigned long flags;
1445
1446        snd_assert(substream != NULL, return);
1447        runtime = substream->runtime;
1448        snd_assert(runtime != NULL, return);
1449
1450        if (runtime->transfer_ack_begin)
1451                runtime->transfer_ack_begin(substream);
1452
1453        snd_pcm_stream_lock_irqsave(substream, flags);
1454        if (!snd_pcm_running(substream) ||
1455            snd_pcm_update_hw_ptr_interrupt(substream) < 0)
1456                goto _end;
1457
1458        if (substream->timer_running)
1459                snd_timer_interrupt(substream->timer, 1);
1460 _end:
1461        snd_pcm_stream_unlock_irqrestore(substream, flags);
1462        if (runtime->transfer_ack_end)
1463                runtime->transfer_ack_end(substream);
1464        kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
1465}
1466
1467EXPORT_SYMBOL(snd_pcm_period_elapsed);
1468
1469/*
1470 * Wait until avail_min data becomes available
1471 * Returns a negative error code if any error occurs during operation.
1472 * The available space is stored on availp.  When err = 0 and avail = 0
1473 * on the capture stream, it indicates the stream is in DRAINING state.
1474 */
1475static int wait_for_avail_min(struct snd_pcm_substream *substream,
1476                              snd_pcm_uframes_t *availp)
1477{
1478        struct snd_pcm_runtime *runtime = substream->runtime;
1479        int is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
1480        wait_queue_t wait;
1481        int err = 0;
1482        snd_pcm_uframes_t avail = 0;
1483        long tout;
1484
1485        init_waitqueue_entry(&wait, current);
1486        add_wait_queue(&runtime->sleep, &wait);
1487        for (;;) {
1488                if (signal_pending(current)) {
1489                        err = -ERESTARTSYS;
1490                        break;
1491                }
1492                set_current_state(TASK_INTERRUPTIBLE);
1493                snd_pcm_stream_unlock_irq(substream);
1494                tout = schedule_timeout(msecs_to_jiffies(10000));
1495                snd_pcm_stream_lock_irq(substream);
1496                switch (runtime->status->state) {
1497                case SNDRV_PCM_STATE_SUSPENDED:
1498                        err = -ESTRPIPE;
1499                        goto _endloop;
1500                case SNDRV_PCM_STATE_XRUN:
1501                        err = -EPIPE;
1502                        goto _endloop;
1503                case SNDRV_PCM_STATE_DRAINING:
1504                        if (is_playback)
1505                                err = -EPIPE;
1506                        else 
1507                                avail = 0; /* indicate draining */
1508                        goto _endloop;
1509                case SNDRV_PCM_STATE_OPEN:
1510                case SNDRV_PCM_STATE_SETUP:
1511                case SNDRV_PCM_STATE_DISCONNECTED:
1512                        err = -EBADFD;
1513                        goto _endloop;
1514                }
1515                if (!tout) {
1516                        snd_printd("%s write error (DMA or IRQ trouble?)\n",
1517                                   is_playback ? "playback" : "capture");
1518                        err = -EIO;
1519                        break;
1520                }
1521                if (is_playback)
1522                        avail = snd_pcm_playback_avail(runtime);
1523                else
1524                        avail = snd_pcm_capture_avail(runtime);
1525                if (avail >= runtime->control->avail_min)
1526                        break;
1527        }
1528 _endloop:
1529        remove_wait_queue(&runtime->sleep, &wait);
1530        *availp = avail;
1531        return err;
1532}
1533        
1534static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
1535                                      unsigned int hwoff,
1536                                      unsigned long data, unsigned int off,
1537                                      snd_pcm_uframes_t frames)
1538{
1539        struct snd_pcm_runtime *runtime = substream->runtime;
1540        int err;
1541        char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
1542        if (substream->ops->copy) {
1543                if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
1544                        return err;
1545        } else {
1546                char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
1547                snd_assert(runtime->dma_area, return -EFAULT);
1548                if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames)))
1549                        return -EFAULT;
1550        }
1551        return 0;
1552}
1553 
1554typedef int (*transfer_f)(struct snd_pcm_substream *substream, unsigned int hwoff,
1555                          unsigned long data, unsigned int off,
1556                          snd_pcm_uframes_t size);
1557
1558static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, 
1559                                            unsigned long data,
1560                                            snd_pcm_uframes_t size,
1561                                            int nonblock,
1562                                            transfer_f transfer)
1563{
1564        struct snd_pcm_runtime *runtime = substream->runtime;
1565        snd_pcm_uframes_t xfer = 0;
1566        snd_pcm_uframes_t offset = 0;
1567        int err = 0;
1568
1569        if (size == 0)
1570                return 0;
1571
1572        snd_pcm_stream_lock_irq(substream);
1573        switch (runtime->status->state) {
1574        case SNDRV_PCM_STATE_PREPARED:
1575        case SNDRV_PCM_STATE_RUNNING:
1576        case SNDRV_PCM_STATE_PAUSED:
1577                break;
1578        case SNDRV_PCM_STATE_XRUN:
1579                err = -EPIPE;
1580                goto _end_unlock;
1581        case SNDRV_PCM_STATE_SUSPENDED:
1582                err = -ESTRPIPE;
1583                goto _end_unlock;
1584        default:
1585                err = -EBADFD;
1586                goto _end_unlock;
1587        }
1588
1589        while (size > 0) {
1590                snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1591                snd_pcm_uframes_t avail;
1592                snd_pcm_uframes_t cont;
1593                if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
1594                        snd_pcm_update_hw_ptr(substream);
1595                avail = snd_pcm_playback_avail(runtime);
1596                if (!avail) {
1597                        if (nonblock) {
1598                                err = -EAGAIN;
1599                                goto _end_unlock;
1600                        }
1601                        err = wait_for_avail_min(substream, &avail);
1602                        if (err < 0)
1603                                goto _end_unlock;
1604                }
1605                frames = size > avail ? avail : size;
1606                cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
1607                if (frames > cont)
1608                        frames = cont;
1609                snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL);
1610                appl_ptr = runtime->control->appl_ptr;
1611                appl_ofs = appl_ptr % runtime->buffer_size;
1612                snd_pcm_stream_unlock_irq(substream);
1613                if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0)
1614                        goto _end;
1615                snd_pcm_stream_lock_irq(substream);
1616                switch (runtime->status->state) {
1617                case SNDRV_PCM_STATE_XRUN:
1618                        err = -EPIPE;
1619                        goto _end_unlock;
1620                case SNDRV_PCM_STATE_SUSPENDED:
1621                        err = -ESTRPIPE;
1622                        goto _end_unlock;
1623                default:
1624                        break;
1625                }
1626                appl_ptr += frames;
1627                if (appl_ptr >= runtime->boundary)
1628                        appl_ptr -= runtime->boundary;
1629                runtime->control->appl_ptr = appl_ptr;
1630                if (substream->ops->ack)
1631                        substream->ops->ack(substream);
1632
1633                offset += frames;
1634                size -= frames;
1635                xfer += frames;
1636                if (runtime->status->state == SNDRV_PCM_STATE_PREPARED &&
1637                    snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) {
1638                        err = snd_pcm_start(substream);
1639                        if (err < 0)
1640                                goto _end_unlock;
1641                }
1642        }
1643 _end_unlock:
1644        snd_pcm_stream_unlock_irq(substream);
1645 _end:
1646        return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
1647}
1648
1649snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size)
1650{
1651        struct snd_pcm_runtime *runtime;
1652        int nonblock;
1653
1654        snd_assert(substream != NULL, return -ENXIO);
1655        runtime = substream->runtime;
1656        snd_assert(runtime != NULL, return -ENXIO);
1657        snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL);
1658        if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1659                return -EBADFD;
1660
1661        nonblock = !!(substream->f_flags & O_NONBLOCK);
1662
1663        if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED &&
1664            runtime->channels > 1)
1665                return -EINVAL;
1666        return snd_pcm_lib_write1(substream, (unsigned long)buf, size, nonblock,
1667                                  snd_pcm_lib_write_transfer);
1668}
1669
1670EXPORT_SYMBOL(snd_pcm_lib_write);
1671
1672static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
1673                                       unsigned int hwoff,
1674                                       unsigned long data, unsigned int off,
1675                                       snd_pcm_uframes_t frames)
1676{
1677        struct snd_pcm_runtime *runtime = substream->runtime;
1678        int err;
1679        void __user **bufs = (void __user **)data;
1680        int channels = runtime->channels;
1681        int c;
1682        if (substream->ops->copy) {
1683                snd_assert(substream->ops->silence != NULL, return -EINVAL);
1684                for (c = 0; c < channels; ++c, ++bufs) {
1685                        if (*bufs == NULL) {
1686                                if ((err = substream->ops->silence(substream, c, hwoff, frames)) < 0)
1687                                        return err;
1688                        } else {
1689                                char __user *buf = *bufs + samples_to_bytes(runtime, off);
1690                                if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0)
1691                                        return err;
1692                        }
1693                }
1694        } else {
1695                /* default transfer behaviour */
1696                size_t dma_csize = runtime->dma_bytes / channels;
1697                snd_assert(runtime->dma_area, return -EFAULT);
1698                for (c = 0; c < channels; ++c, ++bufs) {
1699                        char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff);
1700                        if (*bufs == NULL) {
1701                                snd_pcm_format_set_silence(runtime->format, hwbuf, frames);
1702                        } else {
1703                                char __user *buf = *bufs + samples_to_bytes(runtime, off);
1704                                if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames)))
1705                                        return -EFAULT;
1706                        }
1707                }
1708        }
1709        return 0;
1710}
1711 
1712snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
1713                                     void __user **bufs,
1714                                     snd_pcm_uframes_t frames)
1715{
1716        struct snd_pcm_runtime *runtime;
1717        int nonblock;
1718
1719        snd_assert(substream != NULL, return -ENXIO);
1720        runtime = substream->runtime;
1721        snd_assert(runtime != NULL, return -ENXIO);
1722        snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL);
1723        if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1724                return -EBADFD;
1725
1726        nonblock = !!(substream->f_flags & O_NONBLOCK);
1727
1728        if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
1729                return -EINVAL;
1730        return snd_pcm_lib_write1(substream, (unsigned long)bufs, frames,
1731                                  nonblock, snd_pcm_lib_writev_transfer);
1732}
1733
1734EXPORT_SYMBOL(snd_pcm_lib_writev);
1735
1736static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, 
1737                                     unsigned int hwoff,
1738                                     unsigned long data, unsigned int off,
1739                                     snd_pcm_uframes_t frames)
1740{
1741        struct snd_pcm_runtime *runtime = substream->runtime;
1742        int err;
1743        char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
1744        if (substream->ops->copy) {
1745                if ((err = substream->ops->copy(substream, -1, hwoff, buf, frames)) < 0)
1746                        return err;
1747        } else {
1748                char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
1749                snd_assert(runtime->dma_area, return -EFAULT);
1750                if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames)))
1751                        return -EFAULT;
1752        }
1753        return 0;
1754}
1755
1756static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
1757                                           unsigned long data,
1758                                           snd_pcm_uframes_t size,
1759                                           int nonblock,
1760                                           transfer_f transfer)
1761{
1762        struct snd_pcm_runtime *runtime = substream->runtime;
1763        snd_pcm_uframes_t xfer = 0;
1764        snd_pcm_uframes_t offset = 0;
1765        int err = 0;
1766
1767        if (size == 0)
1768                return 0;
1769
1770        snd_pcm_stream_lock_irq(substream);
1771        switch (runtime->status->state) {
1772        case SNDRV_PCM_STATE_PREPARED:
1773                if (size >= runtime->start_threshold) {
1774                        err = snd_pcm_start(substream);
1775                        if (err < 0)
1776                                goto _end_unlock;
1777                }
1778                break;
1779        case SNDRV_PCM_STATE_DRAINING:
1780        case SNDRV_PCM_STATE_RUNNING:
1781        case SNDRV_PCM_STATE_PAUSED:
1782                break;
1783        case SNDRV_PCM_STATE_XRUN:
1784                err = -EPIPE;
1785                goto _end_unlock;
1786        case SNDRV_PCM_STATE_SUSPENDED:
1787                err = -ESTRPIPE;
1788                goto _end_unlock;
1789        default:
1790                err = -EBADFD;
1791                goto _end_unlock;
1792        }
1793
1794        while (size > 0) {
1795                snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1796                snd_pcm_uframes_t avail;
1797                snd_pcm_uframes_t cont;
1798                if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
1799                        snd_pcm_update_hw_ptr(substream);
1800                avail = snd_pcm_capture_avail(runtime);
1801                if (!avail) {
1802                        if (runtime->status->state ==
1803                            SNDRV_PCM_STATE_DRAINING) {
1804                                snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
1805                                goto _end_unlock;
1806                        }
1807                        if (nonblock) {
1808                                err = -EAGAIN;
1809                                goto _end_unlock;
1810                        }
1811                        err = wait_for_avail_min(substream, &avail);
1812                        if (err < 0)
1813                                goto _end_unlock;
1814                        if (!avail)
1815                                continue; /* draining */
1816                }
1817                frames = size > avail ? avail : size;
1818                cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
1819                if (frames > cont)
1820                        frames = cont;
1821                snd_assert(frames != 0, snd_pcm_stream_unlock_irq(substream); return -EINVAL);
1822                appl_ptr = runtime->control->appl_ptr;
1823                appl_ofs = appl_ptr % runtime->buffer_size;
1824                snd_pcm_stream_unlock_irq(substream);
1825                if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0)
1826                        goto _end;
1827                snd_pcm_stream_lock_irq(substream);
1828                switch (runtime->status->state) {
1829                case SNDRV_PCM_STATE_XRUN:
1830                        err = -EPIPE;
1831                        goto _end_unlock;
1832                case SNDRV_PCM_STATE_SUSPENDED:
1833                        err = -ESTRPIPE;
1834                        goto _end_unlock;
1835                default:
1836                        break;
1837                }
1838                appl_ptr += frames;
1839                if (appl_ptr >= runtime->boundary)
1840                        appl_ptr -= runtime->boundary;
1841                runtime->control->appl_ptr = appl_ptr;
1842                if (substream->ops->ack)
1843                        substream->ops->ack(substream);
1844
1845                offset += frames;
1846                size -= frames;
1847                xfer += frames;
1848        }
1849 _end_unlock:
1850        snd_pcm_stream_unlock_irq(substream);
1851 _end:
1852        return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
1853}
1854
1855snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __user *buf, snd_pcm_uframes_t size)
1856{
1857        struct snd_pcm_runtime *runtime;
1858        int nonblock;
1859        
1860        snd_assert(substream != NULL, return -ENXIO);
1861        runtime = substream->runtime;
1862        snd_assert(runtime != NULL, return -ENXIO);
1863        snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL);
1864        if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1865                return -EBADFD;
1866
1867        nonblock = !!(substream->f_flags & O_NONBLOCK);
1868        if (runtime->access != SNDRV_PCM_ACCESS_RW_INTERLEAVED)
1869                return -EINVAL;
1870        return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
1871}
1872
1873EXPORT_SYMBOL(snd_pcm_lib_read);
1874
1875static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
1876                                      unsigned int hwoff,
1877                                      unsigned long data, unsigned int off,
1878                                      snd_pcm_uframes_t frames)
1879{
1880        struct snd_pcm_runtime *runtime = substream->runtime;
1881        int err;
1882        void __user **bufs = (void __user **)data;
1883        int channels = runtime->channels;
1884        int c;
1885        if (substream->ops->copy) {
1886                for (c = 0; c < channels; ++c, ++bufs) {
1887                        char __user *buf;
1888                        if (*bufs == NULL)
1889                                continue;
1890                        buf = *bufs + samples_to_bytes(runtime, off);
1891                        if ((err = substream->ops->copy(substream, c, hwoff, buf, frames)) < 0)
1892                                return err;
1893                }
1894        } else {
1895                snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels;
1896                snd_assert(runtime->dma_area, return -EFAULT);
1897                for (c = 0; c < channels; ++c, ++bufs) {
1898                        char *hwbuf;
1899                        char __user *buf;
1900                        if (*bufs == NULL)
1901                                continue;
1902
1903                        hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff);
1904                        buf = *bufs + samples_to_bytes(runtime, off);
1905                        if (copy_to_user(buf, hwbuf, samples_to_bytes(runtime, frames)))
1906                                return -EFAULT;
1907                }
1908        }
1909        return 0;
1910}
1911 
1912snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
1913                                    void __user **bufs,
1914                                    snd_pcm_uframes_t frames)
1915{
1916        struct snd_pcm_runtime *runtime;
1917        int nonblock;
1918
1919        snd_assert(substream != NULL, return -ENXIO);
1920        runtime = substream->runtime;
1921        snd_assert(runtime != NULL, return -ENXIO);
1922        snd_assert(substream->ops->copy != NULL || runtime->dma_area != NULL, return -EINVAL);
1923        if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
1924                return -EBADFD;
1925
1926        nonblock = !!(substream->f_flags & O_NONBLOCK);
1927        if (runtime->access != SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
1928                return -EINVAL;
1929        return snd_pcm_lib_read1(substream, (unsigned long)bufs, frames, nonblock, snd_pcm_lib_readv_transfer);
1930}
1931
1932EXPORT_SYMBOL(snd_pcm_lib_readv);
1933