LCOV - code coverage report
Current view: top level - sound/core - pcm_native.c (source / functions) Hit Total Coverage
Test: Real Lines: 5 1391 0.4 %
Date: 2020-10-17 15:46:43 Functions: 0 126 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

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

Generated by: LCOV version 1.14