2019-05-27 15:55:05 +09:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
2005-04-17 07:20:36 +09:00
|
|
|
#ifndef __SOUND_PCM_H
|
|
|
|
#define __SOUND_PCM_H
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Digital Audio (PCM) abstract layer
|
2007-10-15 16:50:19 +09:00
|
|
|
* Copyright (c) by Jaroslav Kysela <perex@perex.cz>
|
2005-04-17 07:20:36 +09:00
|
|
|
* Abramo Bagnara <abramo@alsa-project.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sound/asound.h>
|
|
|
|
#include <sound/memalloc.h>
|
2008-07-30 20:46:40 +09:00
|
|
|
#include <sound/minors.h>
|
2005-04-17 07:20:36 +09:00
|
|
|
#include <linux/poll.h>
|
2006-10-21 04:17:02 +09:00
|
|
|
#include <linux/mm.h>
|
2005-04-17 07:20:36 +09:00
|
|
|
#include <linux/bitops.h>
|
2011-08-25 22:35:03 +09:00
|
|
|
#include <linux/pm_qos.h>
|
ALSA: pcm: More fine-grained PCM link locking
We have currently two global locks, a rwlock and a rwsem, that are
used for managing linking the PCM streams. Due to these global locks,
once when a linked stream is used, the lock granularity suffers a
lot.
This patch attempts to eliminate the former global lock for atomic
ops. The latter rwsem needs remaining because of the loosy way of the
loop calls in snd_pcm_action_nonatomic(), as well as for avoiding the
deadlock at linking. However, these are used far rarely, actually
only by two actions (prepare and reset), where both are no timing
critical ones. So this can be still seen as a good improvement.
The basic strategy to eliminate the rwlock is to assure group->lock at
adding or removing a stream to / from the group. Since we already
takes the group lock whenever taking the all substream locks under the
group, this shouldn't be a big problem. The reference to group
pointer in snd_pcm_substream object is protected by the stream lock
itself.
However, there are still pitfalls: a race window at re-locking and the
lifecycle of group object. The former is a small race window for
dereferencing the substream group object opened while snd_pcm_action()
performs re-locking to avoid ABBA deadlocks. This includes the unlink
of group during that window, too. And the latter is the kfree
performed after all streams are removed from the group while it's
still dereferenced.
For addressing these corner cases, two new tricks are introduced:
- After re-locking, the group assigned to the stream is checked again;
if the group is changed, we retry the whole procedure.
- Introduce a refcount to snd_pcm_group object, so that it's freed
only when it's empty and really no one refers to it.
(Some readers might wonder why not RCU for the latter. RCU in this
case would cost more than refcounting, unfortunately. We take the
group lock sooner or later, hence the performance improvement by RCU
would be negligible. Meanwhile, because we need to deal with
schedulable context depending on the pcm->nonatomic flag, it'll become
dynamic RCU/SRCU switch, and the grace period may become too long.)
Along with these changes, there are a significant amount of code
refactoring. The complex group re-lock & ref code is factored out to
snd_pcm_stream_group_ref() function, for example.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-01-13 17:50:33 +09:00
|
|
|
#include <linux/refcount.h>
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
#define snd_pcm_substream_chip(substream) ((substream)->private_data)
|
|
|
|
#define snd_pcm_chip(pcm) ((pcm)->private_data)
|
|
|
|
|
2017-05-12 18:44:03 +09:00
|
|
|
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
|
2012-10-03 02:01:25 +09:00
|
|
|
#include <sound/pcm_oss.h>
|
2005-04-17 07:20:36 +09:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Hardware (lowlevel) section
|
|
|
|
*/
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_hardware {
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int info; /* SNDRV_PCM_INFO_* */
|
|
|
|
u64 formats; /* SNDRV_PCM_FMTBIT_* */
|
|
|
|
unsigned int rates; /* SNDRV_PCM_RATE_* */
|
|
|
|
unsigned int rate_min; /* min rate */
|
|
|
|
unsigned int rate_max; /* max rate */
|
|
|
|
unsigned int channels_min; /* min channels */
|
|
|
|
unsigned int channels_max; /* max channels */
|
|
|
|
size_t buffer_bytes_max; /* max buffer size */
|
|
|
|
size_t period_bytes_min; /* min period size */
|
|
|
|
size_t period_bytes_max; /* max period size */
|
|
|
|
unsigned int periods_min; /* min # of periods */
|
|
|
|
unsigned int periods_max; /* max # of periods */
|
|
|
|
size_t fifo_size; /* fifo size in bytes */
|
2005-11-17 21:59:38 +09:00
|
|
|
};
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2018-04-24 21:06:11 +09:00
|
|
|
struct snd_pcm_status64;
|
2006-12-07 16:22:50 +09:00
|
|
|
struct snd_pcm_substream;
|
|
|
|
|
2015-02-14 06:14:03 +09:00
|
|
|
struct snd_pcm_audio_tstamp_config; /* definitions further down */
|
|
|
|
struct snd_pcm_audio_tstamp_report;
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_ops {
|
|
|
|
int (*open)(struct snd_pcm_substream *substream);
|
|
|
|
int (*close)(struct snd_pcm_substream *substream);
|
|
|
|
int (*ioctl)(struct snd_pcm_substream * substream,
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int cmd, void *arg);
|
2005-11-17 21:59:38 +09:00
|
|
|
int (*hw_params)(struct snd_pcm_substream *substream,
|
|
|
|
struct snd_pcm_hw_params *params);
|
|
|
|
int (*hw_free)(struct snd_pcm_substream *substream);
|
|
|
|
int (*prepare)(struct snd_pcm_substream *substream);
|
|
|
|
int (*trigger)(struct snd_pcm_substream *substream, int cmd);
|
ALSA: pcm: Add the support for sync-stop operation
The standard programming model of a PCM sound driver is to process
snd_pcm_period_elapsed() from an interrupt handler. When a running
stream is stopped, PCM core calls the trigger-STOP PCM ops, sets the
stream state to SETUP, and moves on to the next step. This is
performed in an atomic manner -- this could be called from the interrupt
context, after all.
The problem is that, if the stream goes further and reaches to the
CLOSE state immediately, the stream might be still being processed in
snd_pcm_period_elapsed() in the interrupt context, and hits a NULL
dereference. Such a crash happens because of the atomic operation,
and we can't wait until the stream-stop finishes.
For addressing such a problem, this commit adds a new PCM ops,
sync_stop. This gets called at the appropriate places that need a
sync with the stream-stop, i.e. at hw_params, prepare and hw_free.
Some drivers already have a similar mechanism implemented locally, and
we'll refactor the code later.
Link: https://lore.kernel.org/r/20191117085308.23915-7-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-11-17 17:53:06 +09:00
|
|
|
int (*sync_stop)(struct snd_pcm_substream *substream);
|
2005-11-17 21:59:38 +09:00
|
|
|
snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *substream);
|
2015-02-14 06:14:06 +09:00
|
|
|
int (*get_time_info)(struct snd_pcm_substream *substream,
|
2018-04-24 21:06:08 +09:00
|
|
|
struct timespec64 *system_ts, struct timespec64 *audio_ts,
|
2015-02-14 06:14:06 +09:00
|
|
|
struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
|
|
|
|
struct snd_pcm_audio_tstamp_report *audio_tstamp_report);
|
ALSA: pcm: Introduce copy_user, copy_kernel and fill_silence ops
For supporting the explicit in-kernel copy of PCM buffer data, and
also for further code refactoring, three new PCM ops, copy_user,
copy_kernel and fill_silence, are introduced. The old copy and
silence ops will be deprecated and removed later once when all callers
are converted.
The copy_kernel ops is the new one, and it's supposed to transfer the
PCM data from the given kernel buffer to the hardware ring-buffer (or
vice-versa depending on the stream direction), while the copy_user ops
is equivalent with the former copy ops, to transfer the data from the
user-space buffer.
The major difference of the new copy_* and fill_silence ops from the
previous ops is that the new ops take bytes instead of frames for size
and position arguments. It has two merits: first, it allows the
callback implementation often simpler (just call directly memcpy() &
co), and second, it may unify the implementations of both interleaved
and non-interleaved cases, as we'll see in the later patch.
As of this stage, copy_kernel ops isn't referred yet, but only
copy_user is used.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-05-11 03:02:35 +09:00
|
|
|
int (*fill_silence)(struct snd_pcm_substream *substream, int channel,
|
|
|
|
unsigned long pos, unsigned long bytes);
|
|
|
|
int (*copy_user)(struct snd_pcm_substream *substream, int channel,
|
|
|
|
unsigned long pos, void __user *buf,
|
|
|
|
unsigned long bytes);
|
|
|
|
int (*copy_kernel)(struct snd_pcm_substream *substream, int channel,
|
|
|
|
unsigned long pos, void *buf, unsigned long bytes);
|
2005-11-17 21:59:38 +09:00
|
|
|
struct page *(*page)(struct snd_pcm_substream *substream,
|
|
|
|
unsigned long offset);
|
|
|
|
int (*mmap)(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
|
|
|
|
int (*ack)(struct snd_pcm_substream *substream);
|
|
|
|
};
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2008-07-30 20:46:40 +09:00
|
|
|
#if defined(CONFIG_SND_DYNAMIC_MINORS)
|
|
|
|
#define SNDRV_PCM_DEVICES (SNDRV_OS_MINORS-2)
|
|
|
|
#else
|
|
|
|
#define SNDRV_PCM_DEVICES 8
|
|
|
|
#endif
|
2008-08-01 20:36:04 +09:00
|
|
|
|
2005-04-17 07:20:36 +09:00
|
|
|
#define SNDRV_PCM_IOCTL1_RESET 0
|
2017-06-14 19:30:03 +09:00
|
|
|
/* 1 is absent slot. */
|
2005-04-17 07:20:36 +09:00
|
|
|
#define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2
|
2017-06-14 19:30:04 +09:00
|
|
|
/* 3 is absent slot. */
|
2009-04-27 16:44:40 +09:00
|
|
|
#define SNDRV_PCM_IOCTL1_FIFO_SIZE 4
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
#define SNDRV_PCM_TRIGGER_STOP 0
|
|
|
|
#define SNDRV_PCM_TRIGGER_START 1
|
|
|
|
#define SNDRV_PCM_TRIGGER_PAUSE_PUSH 3
|
|
|
|
#define SNDRV_PCM_TRIGGER_PAUSE_RELEASE 4
|
|
|
|
#define SNDRV_PCM_TRIGGER_SUSPEND 5
|
|
|
|
#define SNDRV_PCM_TRIGGER_RESUME 6
|
2014-12-31 23:09:54 +09:00
|
|
|
#define SNDRV_PCM_TRIGGER_DRAIN 7
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
#define SNDRV_PCM_POS_XRUN ((snd_pcm_uframes_t)-1)
|
|
|
|
|
|
|
|
/* If you change this don't forget to change rates[] table in pcm_native.c */
|
2022-11-21 20:00:44 +09:00
|
|
|
#define SNDRV_PCM_RATE_5512 (1U<<0) /* 5512Hz */
|
|
|
|
#define SNDRV_PCM_RATE_8000 (1U<<1) /* 8000Hz */
|
|
|
|
#define SNDRV_PCM_RATE_11025 (1U<<2) /* 11025Hz */
|
|
|
|
#define SNDRV_PCM_RATE_16000 (1U<<3) /* 16000Hz */
|
|
|
|
#define SNDRV_PCM_RATE_22050 (1U<<4) /* 22050Hz */
|
|
|
|
#define SNDRV_PCM_RATE_32000 (1U<<5) /* 32000Hz */
|
|
|
|
#define SNDRV_PCM_RATE_44100 (1U<<6) /* 44100Hz */
|
|
|
|
#define SNDRV_PCM_RATE_48000 (1U<<7) /* 48000Hz */
|
|
|
|
#define SNDRV_PCM_RATE_64000 (1U<<8) /* 64000Hz */
|
|
|
|
#define SNDRV_PCM_RATE_88200 (1U<<9) /* 88200Hz */
|
|
|
|
#define SNDRV_PCM_RATE_96000 (1U<<10) /* 96000Hz */
|
|
|
|
#define SNDRV_PCM_RATE_176400 (1U<<11) /* 176400Hz */
|
|
|
|
#define SNDRV_PCM_RATE_192000 (1U<<12) /* 192000Hz */
|
|
|
|
#define SNDRV_PCM_RATE_352800 (1U<<13) /* 352800Hz */
|
|
|
|
#define SNDRV_PCM_RATE_384000 (1U<<14) /* 384000Hz */
|
|
|
|
|
|
|
|
#define SNDRV_PCM_RATE_CONTINUOUS (1U<<30) /* continuous range */
|
|
|
|
#define SNDRV_PCM_RATE_KNOT (1U<<31) /* supports more non-continuos rates */
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
#define SNDRV_PCM_RATE_8000_44100 (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
|
|
|
|
SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|\
|
|
|
|
SNDRV_PCM_RATE_32000|SNDRV_PCM_RATE_44100)
|
|
|
|
#define SNDRV_PCM_RATE_8000_48000 (SNDRV_PCM_RATE_8000_44100|SNDRV_PCM_RATE_48000)
|
|
|
|
#define SNDRV_PCM_RATE_8000_96000 (SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_64000|\
|
|
|
|
SNDRV_PCM_RATE_88200|SNDRV_PCM_RATE_96000)
|
|
|
|
#define SNDRV_PCM_RATE_8000_192000 (SNDRV_PCM_RATE_8000_96000|SNDRV_PCM_RATE_176400|\
|
|
|
|
SNDRV_PCM_RATE_192000)
|
2019-08-22 18:56:50 +09:00
|
|
|
#define SNDRV_PCM_RATE_8000_384000 (SNDRV_PCM_RATE_8000_192000|\
|
|
|
|
SNDRV_PCM_RATE_352800|\
|
|
|
|
SNDRV_PCM_RATE_384000)
|
2011-02-14 19:00:47 +09:00
|
|
|
#define _SNDRV_PCM_FMTBIT(fmt) (1ULL << (__force int)SNDRV_PCM_FORMAT_##fmt)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S8 _SNDRV_PCM_FMTBIT(S8)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U8 _SNDRV_PCM_FMTBIT(U8)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S16_LE _SNDRV_PCM_FMTBIT(S16_LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S16_BE _SNDRV_PCM_FMTBIT(S16_BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U16_LE _SNDRV_PCM_FMTBIT(U16_LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U16_BE _SNDRV_PCM_FMTBIT(U16_BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S24_LE _SNDRV_PCM_FMTBIT(S24_LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S24_BE _SNDRV_PCM_FMTBIT(S24_BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U24_LE _SNDRV_PCM_FMTBIT(U24_LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U24_BE _SNDRV_PCM_FMTBIT(U24_BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S32_LE _SNDRV_PCM_FMTBIT(S32_LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S32_BE _SNDRV_PCM_FMTBIT(S32_BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U32_LE _SNDRV_PCM_FMTBIT(U32_LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U32_BE _SNDRV_PCM_FMTBIT(U32_BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_FLOAT_LE _SNDRV_PCM_FMTBIT(FLOAT_LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_FLOAT_BE _SNDRV_PCM_FMTBIT(FLOAT_BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_FLOAT64_LE _SNDRV_PCM_FMTBIT(FLOAT64_LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_FLOAT64_BE _SNDRV_PCM_FMTBIT(FLOAT64_BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE _SNDRV_PCM_FMTBIT(IEC958_SUBFRAME_LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE _SNDRV_PCM_FMTBIT(IEC958_SUBFRAME_BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_MU_LAW _SNDRV_PCM_FMTBIT(MU_LAW)
|
|
|
|
#define SNDRV_PCM_FMTBIT_A_LAW _SNDRV_PCM_FMTBIT(A_LAW)
|
|
|
|
#define SNDRV_PCM_FMTBIT_IMA_ADPCM _SNDRV_PCM_FMTBIT(IMA_ADPCM)
|
|
|
|
#define SNDRV_PCM_FMTBIT_MPEG _SNDRV_PCM_FMTBIT(MPEG)
|
|
|
|
#define SNDRV_PCM_FMTBIT_GSM _SNDRV_PCM_FMTBIT(GSM)
|
2017-11-28 07:33:29 +09:00
|
|
|
#define SNDRV_PCM_FMTBIT_S20_LE _SNDRV_PCM_FMTBIT(S20_LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U20_LE _SNDRV_PCM_FMTBIT(U20_LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S20_BE _SNDRV_PCM_FMTBIT(S20_BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U20_BE _SNDRV_PCM_FMTBIT(U20_BE)
|
2011-02-14 19:00:47 +09:00
|
|
|
#define SNDRV_PCM_FMTBIT_SPECIAL _SNDRV_PCM_FMTBIT(SPECIAL)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S24_3LE _SNDRV_PCM_FMTBIT(S24_3LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U24_3LE _SNDRV_PCM_FMTBIT(U24_3LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S24_3BE _SNDRV_PCM_FMTBIT(S24_3BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U24_3BE _SNDRV_PCM_FMTBIT(U24_3BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S20_3LE _SNDRV_PCM_FMTBIT(S20_3LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U20_3LE _SNDRV_PCM_FMTBIT(U20_3LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S20_3BE _SNDRV_PCM_FMTBIT(S20_3BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U20_3BE _SNDRV_PCM_FMTBIT(U20_3BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S18_3LE _SNDRV_PCM_FMTBIT(S18_3LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U18_3LE _SNDRV_PCM_FMTBIT(U18_3LE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_S18_3BE _SNDRV_PCM_FMTBIT(S18_3BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_U18_3BE _SNDRV_PCM_FMTBIT(U18_3BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_G723_24 _SNDRV_PCM_FMTBIT(G723_24)
|
|
|
|
#define SNDRV_PCM_FMTBIT_G723_24_1B _SNDRV_PCM_FMTBIT(G723_24_1B)
|
|
|
|
#define SNDRV_PCM_FMTBIT_G723_40 _SNDRV_PCM_FMTBIT(G723_40)
|
|
|
|
#define SNDRV_PCM_FMTBIT_G723_40_1B _SNDRV_PCM_FMTBIT(G723_40_1B)
|
2013-04-17 01:01:36 +09:00
|
|
|
#define SNDRV_PCM_FMTBIT_DSD_U8 _SNDRV_PCM_FMTBIT(DSD_U8)
|
|
|
|
#define SNDRV_PCM_FMTBIT_DSD_U16_LE _SNDRV_PCM_FMTBIT(DSD_U16_LE)
|
2014-09-05 17:47:56 +09:00
|
|
|
#define SNDRV_PCM_FMTBIT_DSD_U32_LE _SNDRV_PCM_FMTBIT(DSD_U32_LE)
|
2014-11-21 23:04:46 +09:00
|
|
|
#define SNDRV_PCM_FMTBIT_DSD_U16_BE _SNDRV_PCM_FMTBIT(DSD_U16_BE)
|
|
|
|
#define SNDRV_PCM_FMTBIT_DSD_U32_BE _SNDRV_PCM_FMTBIT(DSD_U32_BE)
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
#ifdef SNDRV_LITTLE_ENDIAN
|
|
|
|
#define SNDRV_PCM_FMTBIT_S16 SNDRV_PCM_FMTBIT_S16_LE
|
|
|
|
#define SNDRV_PCM_FMTBIT_U16 SNDRV_PCM_FMTBIT_U16_LE
|
|
|
|
#define SNDRV_PCM_FMTBIT_S24 SNDRV_PCM_FMTBIT_S24_LE
|
|
|
|
#define SNDRV_PCM_FMTBIT_U24 SNDRV_PCM_FMTBIT_U24_LE
|
|
|
|
#define SNDRV_PCM_FMTBIT_S32 SNDRV_PCM_FMTBIT_S32_LE
|
|
|
|
#define SNDRV_PCM_FMTBIT_U32 SNDRV_PCM_FMTBIT_U32_LE
|
|
|
|
#define SNDRV_PCM_FMTBIT_FLOAT SNDRV_PCM_FMTBIT_FLOAT_LE
|
|
|
|
#define SNDRV_PCM_FMTBIT_FLOAT64 SNDRV_PCM_FMTBIT_FLOAT64_LE
|
|
|
|
#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE
|
2017-11-28 07:33:29 +09:00
|
|
|
#define SNDRV_PCM_FMTBIT_S20 SNDRV_PCM_FMTBIT_S20_LE
|
|
|
|
#define SNDRV_PCM_FMTBIT_U20 SNDRV_PCM_FMTBIT_U20_LE
|
2005-04-17 07:20:36 +09:00
|
|
|
#endif
|
|
|
|
#ifdef SNDRV_BIG_ENDIAN
|
|
|
|
#define SNDRV_PCM_FMTBIT_S16 SNDRV_PCM_FMTBIT_S16_BE
|
|
|
|
#define SNDRV_PCM_FMTBIT_U16 SNDRV_PCM_FMTBIT_U16_BE
|
|
|
|
#define SNDRV_PCM_FMTBIT_S24 SNDRV_PCM_FMTBIT_S24_BE
|
|
|
|
#define SNDRV_PCM_FMTBIT_U24 SNDRV_PCM_FMTBIT_U24_BE
|
|
|
|
#define SNDRV_PCM_FMTBIT_S32 SNDRV_PCM_FMTBIT_S32_BE
|
|
|
|
#define SNDRV_PCM_FMTBIT_U32 SNDRV_PCM_FMTBIT_U32_BE
|
|
|
|
#define SNDRV_PCM_FMTBIT_FLOAT SNDRV_PCM_FMTBIT_FLOAT_BE
|
|
|
|
#define SNDRV_PCM_FMTBIT_FLOAT64 SNDRV_PCM_FMTBIT_FLOAT64_BE
|
|
|
|
#define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE
|
2017-11-28 07:33:29 +09:00
|
|
|
#define SNDRV_PCM_FMTBIT_S20 SNDRV_PCM_FMTBIT_S20_BE
|
|
|
|
#define SNDRV_PCM_FMTBIT_U20 SNDRV_PCM_FMTBIT_U20_BE
|
2005-04-17 07:20:36 +09:00
|
|
|
#endif
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_file {
|
|
|
|
struct snd_pcm_substream *substream;
|
2006-07-31 23:51:51 +09:00
|
|
|
int no_compat_mmap;
|
ALSA: pcm: Add an ioctl to specify the supported protocol version
We have an ioctl to inform the PCM protocol version the running kernel
supports, but there is no way to know which protocol version the
user-space can understand. This lack of information caused headaches
in the past when we tried to extend the ABI. For example, because we
couldn't guarantee the validity of the reserved bytes, we had to
introduce a new ioctl SNDRV_PCM_IOCTL_STATUS_EXT for assigning a few
new fields in the formerly reserved bits. If we could know that it's
a new alsa-lib, we could assume the availability of the new fields,
thus we could have reused the existing SNDRV_PCM_IOCTL_STATUS.
In order to improve the ABI extensibility, this patch adds a new ioctl
for user-space to inform its supporting protocol version to the
kernel. By reporting the supported protocol from user-space, the
kernel can judge which feature should be provided and which not.
With the addition of the new ioctl, the PCM protocol version is bumped
to 2.0.14, too. User-space checks the kernel protocol version via
SNDRV_PCM_INFO_PVERSION, then it sets the supported version back via
SNDRV_PCM_INFO_USER_PVERSION.
Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2017-06-20 06:11:54 +09:00
|
|
|
unsigned int user_pversion; /* supported protocol version */
|
2005-04-17 07:20:36 +09:00
|
|
|
};
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_hw_rule;
|
|
|
|
typedef int (*snd_pcm_hw_rule_func_t)(struct snd_pcm_hw_params *params,
|
|
|
|
struct snd_pcm_hw_rule *rule);
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_hw_rule {
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int cond;
|
|
|
|
int var;
|
|
|
|
int deps[4];
|
2015-04-27 19:20:28 +09:00
|
|
|
|
|
|
|
snd_pcm_hw_rule_func_t func;
|
2005-04-17 07:20:36 +09:00
|
|
|
void *private;
|
|
|
|
};
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_hw_constraints {
|
|
|
|
struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK -
|
2005-04-17 07:20:36 +09:00
|
|
|
SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
|
2005-04-17 07:20:36 +09:00
|
|
|
SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
|
|
|
|
unsigned int rules_num;
|
|
|
|
unsigned int rules_all;
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_hw_rule *rules;
|
|
|
|
};
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline struct snd_mask *constrs_mask(struct snd_pcm_hw_constraints *constrs,
|
|
|
|
snd_pcm_hw_param_t var)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
return &constrs->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
|
|
|
|
}
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline struct snd_interval *constrs_interval(struct snd_pcm_hw_constraints *constrs,
|
|
|
|
snd_pcm_hw_param_t var)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
return &constrs->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
|
|
|
|
}
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_ratnum {
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int num;
|
|
|
|
unsigned int den_min, den_max, den_step;
|
2005-11-17 21:59:38 +09:00
|
|
|
};
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_ratden {
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int num_min, num_max, num_step;
|
|
|
|
unsigned int den;
|
2005-11-17 21:59:38 +09:00
|
|
|
};
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_hw_constraint_ratnums {
|
2005-04-17 07:20:36 +09:00
|
|
|
int nrats;
|
2015-10-28 19:37:53 +09:00
|
|
|
const struct snd_ratnum *rats;
|
2005-11-17 21:59:38 +09:00
|
|
|
};
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_hw_constraint_ratdens {
|
2005-04-17 07:20:36 +09:00
|
|
|
int nrats;
|
2015-10-28 19:37:53 +09:00
|
|
|
const struct snd_ratden *rats;
|
2005-11-17 21:59:38 +09:00
|
|
|
};
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_hw_constraint_list {
|
2012-03-15 04:48:43 +09:00
|
|
|
const unsigned int *list;
|
2015-04-27 19:20:29 +09:00
|
|
|
unsigned int count;
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int mask;
|
2005-11-17 21:59:38 +09:00
|
|
|
};
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2015-01-28 23:16:06 +09:00
|
|
|
struct snd_pcm_hw_constraint_ranges {
|
|
|
|
unsigned int count;
|
|
|
|
const struct snd_interval *ranges;
|
|
|
|
unsigned int mask;
|
|
|
|
};
|
|
|
|
|
2015-02-14 06:14:03 +09:00
|
|
|
/*
|
|
|
|
* userspace-provided audio timestamp config to kernel,
|
|
|
|
* structure is for internal use only and filled with dedicated unpack routine
|
|
|
|
*/
|
|
|
|
struct snd_pcm_audio_tstamp_config {
|
|
|
|
/* 5 of max 16 bits used */
|
|
|
|
u32 type_requested:4;
|
|
|
|
u32 report_delay:1; /* add total delay to A/D or D/A */
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline void snd_pcm_unpack_audio_tstamp_config(__u32 data,
|
|
|
|
struct snd_pcm_audio_tstamp_config *config)
|
|
|
|
{
|
|
|
|
config->type_requested = data & 0xF;
|
|
|
|
config->report_delay = (data >> 4) & 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* kernel-provided audio timestamp report to user-space
|
|
|
|
* structure is for internal use only and read by dedicated pack routine
|
|
|
|
*/
|
|
|
|
struct snd_pcm_audio_tstamp_report {
|
|
|
|
/* 6 of max 16 bits used for bit-fields */
|
|
|
|
|
|
|
|
/* for backwards compatibility */
|
|
|
|
u32 valid:1;
|
|
|
|
|
|
|
|
/* actual type if hardware could not support requested timestamp */
|
|
|
|
u32 actual_type:4;
|
|
|
|
|
|
|
|
/* accuracy represented in ns units */
|
|
|
|
u32 accuracy_report:1; /* 0 if accuracy unknown, 1 if accuracy field is valid */
|
|
|
|
u32 accuracy; /* up to 4.29s, will be packed in separate field */
|
|
|
|
};
|
|
|
|
|
|
|
|
static inline void snd_pcm_pack_audio_tstamp_report(__u32 *data, __u32 *accuracy,
|
|
|
|
const struct snd_pcm_audio_tstamp_report *report)
|
|
|
|
{
|
|
|
|
u32 tmp;
|
|
|
|
|
|
|
|
tmp = report->accuracy_report;
|
|
|
|
tmp <<= 4;
|
|
|
|
tmp |= report->actual_type;
|
|
|
|
tmp <<= 1;
|
|
|
|
tmp |= report->valid;
|
|
|
|
|
|
|
|
*data &= 0xffff; /* zero-clear MSBs */
|
|
|
|
*data |= (tmp << 16);
|
|
|
|
*accuracy = report->accuracy;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_runtime {
|
2005-04-17 07:20:36 +09:00
|
|
|
/* -- Status -- */
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_substream *trigger_master;
|
2018-04-24 21:06:08 +09:00
|
|
|
struct timespec64 trigger_tstamp; /* trigger timestamp */
|
2015-02-07 06:55:51 +09:00
|
|
|
bool trigger_tstamp_latched; /* trigger timestamp latched in low-level driver/hardware */
|
2005-04-17 07:20:36 +09:00
|
|
|
int overrange;
|
|
|
|
snd_pcm_uframes_t avail_max;
|
|
|
|
snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
|
2010-01-27 01:08:24 +09:00
|
|
|
snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */
|
2009-04-10 19:28:58 +09:00
|
|
|
unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */
|
2010-08-18 21:16:54 +09:00
|
|
|
unsigned long hw_ptr_buffer_jiffies; /* buffer time in jiffies */
|
2008-10-13 10:07:14 +09:00
|
|
|
snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */
|
2012-10-23 06:42:14 +09:00
|
|
|
u64 hw_ptr_wrap; /* offset for hw_ptr due to boundary wrap-around */
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
/* -- HW params -- */
|
|
|
|
snd_pcm_access_t access; /* access mode */
|
|
|
|
snd_pcm_format_t format; /* SNDRV_PCM_FORMAT_* */
|
|
|
|
snd_pcm_subformat_t subformat; /* subformat */
|
|
|
|
unsigned int rate; /* rate in Hz */
|
|
|
|
unsigned int channels; /* channels */
|
|
|
|
snd_pcm_uframes_t period_size; /* period size */
|
|
|
|
unsigned int periods; /* periods */
|
|
|
|
snd_pcm_uframes_t buffer_size; /* buffer size */
|
|
|
|
snd_pcm_uframes_t min_align; /* Min alignment for the format */
|
|
|
|
size_t byte_align;
|
|
|
|
unsigned int frame_bits;
|
|
|
|
unsigned int sample_bits;
|
|
|
|
unsigned int info;
|
|
|
|
unsigned int rate_num;
|
|
|
|
unsigned int rate_den;
|
2010-11-15 18:46:23 +09:00
|
|
|
unsigned int no_period_wakeup: 1;
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
/* -- SW params -- */
|
2005-11-17 21:59:38 +09:00
|
|
|
int tstamp_mode; /* mmap timestamp is updated */
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int period_step;
|
|
|
|
snd_pcm_uframes_t start_threshold;
|
|
|
|
snd_pcm_uframes_t stop_threshold;
|
|
|
|
snd_pcm_uframes_t silence_threshold; /* Silence filling happens when
|
|
|
|
noise is nearest than this */
|
|
|
|
snd_pcm_uframes_t silence_size; /* Silence filling size */
|
|
|
|
snd_pcm_uframes_t boundary; /* pointers wrap point */
|
|
|
|
|
|
|
|
snd_pcm_uframes_t silence_start; /* starting pointer to silence area */
|
|
|
|
snd_pcm_uframes_t silence_filled; /* size filled with silence */
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
union snd_pcm_sync_id sync; /* hardware synchronization ID */
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
/* -- mmap -- */
|
2007-09-11 07:35:06 +09:00
|
|
|
struct snd_pcm_mmap_status *status;
|
|
|
|
struct snd_pcm_mmap_control *control;
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
/* -- locking / scheduling -- */
|
2010-06-27 07:13:20 +09:00
|
|
|
snd_pcm_uframes_t twake; /* do transfer (!poll) wakeup if non-zero */
|
2010-01-21 18:32:15 +09:00
|
|
|
wait_queue_head_t sleep; /* poll sleep */
|
|
|
|
wait_queue_head_t tsleep; /* transfer sleep */
|
2005-04-17 07:20:36 +09:00
|
|
|
struct fasync_struct *fasync;
|
ALSA: pcm: Add the support for sync-stop operation
The standard programming model of a PCM sound driver is to process
snd_pcm_period_elapsed() from an interrupt handler. When a running
stream is stopped, PCM core calls the trigger-STOP PCM ops, sets the
stream state to SETUP, and moves on to the next step. This is
performed in an atomic manner -- this could be called from the interrupt
context, after all.
The problem is that, if the stream goes further and reaches to the
CLOSE state immediately, the stream might be still being processed in
snd_pcm_period_elapsed() in the interrupt context, and hits a NULL
dereference. Such a crash happens because of the atomic operation,
and we can't wait until the stream-stop finishes.
For addressing such a problem, this commit adds a new PCM ops,
sync_stop. This gets called at the appropriate places that need a
sync with the stream-stop, i.e. at hw_params, prepare and hw_free.
Some drivers already have a similar mechanism implemented locally, and
we'll refactor the code later.
Link: https://lore.kernel.org/r/20191117085308.23915-7-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-11-17 17:53:06 +09:00
|
|
|
bool stop_operating; /* sync_stop will be called */
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
/* -- private section -- */
|
|
|
|
void *private_data;
|
2005-11-17 21:59:38 +09:00
|
|
|
void (*private_free)(struct snd_pcm_runtime *runtime);
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
/* -- hardware description -- */
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_hardware hw;
|
|
|
|
struct snd_pcm_hw_constraints hw_constraints;
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
/* -- timer -- */
|
|
|
|
unsigned int timer_resolution; /* timer resolution */
|
2007-12-13 18:19:42 +09:00
|
|
|
int tstamp_type; /* timestamp type */
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
/* -- DMA -- */
|
|
|
|
unsigned char *dma_area; /* DMA area */
|
|
|
|
dma_addr_t dma_addr; /* physical bus address (not accessible from main CPU) */
|
|
|
|
size_t dma_bytes; /* size of DMA area */
|
|
|
|
|
|
|
|
struct snd_dma_buffer *dma_buffer_p; /* allocated buffer */
|
ALSA: pcm: Introduce managed buffer allocation mode
This patch adds the support for the feature to automatically allocate
and free PCM buffers, so called "managed buffer allocation" mode.
It's set up via new PCM helpers, snd_pcm_set_managed_buffer() and
snd_pcm_set_managed_buffer_all(), both of which correspond to the
existing preallocator helpers, snd_pcm_lib_preallocate_pages() and
snd_pcm_lib_preallocate_pages_for_all(). When the new helper is used,
it not only performs the pre-allocation of buffers, but also it
manages to call snd_pcm_lib_malloc_pages() before the PCM hw_params
ops and snd_lib_pcm_free() after the PCM hw_free ops inside PCM core,
respectively. This allows drivers to drop the explicit calls of the
memory allocation / release functions, and it will be a good amount of
code reduction in the end of this patch series.
When the PCM substream is set to the managed buffer allocation mode,
the managed_buffer_alloc flag is set in the substream object. Since
some drivers want to know when a buffer is newly allocated or
re-allocated at hw_params callback (e.g. want to set up the additional
stuff for the given buffer only at allocation time), now PCM core
turns on buffer_changed flag when the buffer has changed.
The standard conversions to use the new API will be straightforward:
- Replace snd_pcm_lib_preallocate*() calls with the corresponding
snd_pcm_set_managed_buffer*(); the arguments should be unchanged
- Drop superfluous snd_pcm_lib_malloc() and snd_pcm_lib_free() calls;
the check of snd_pcm_lib_malloc() returns should be replaced with
the check of runtime->buffer_changed flag.
- If hw_params or hw_free becomes empty, drop them from PCM ops
Link: https://lore.kernel.org/r/20191117085308.23915-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-11-17 17:53:01 +09:00
|
|
|
unsigned int buffer_changed:1; /* buffer allocation changed; set only in managed mode */
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2015-02-14 06:14:03 +09:00
|
|
|
/* -- audio timestamp config -- */
|
|
|
|
struct snd_pcm_audio_tstamp_config audio_tstamp_config;
|
|
|
|
struct snd_pcm_audio_tstamp_report audio_tstamp_report;
|
2018-04-24 21:06:08 +09:00
|
|
|
struct timespec64 driver_tstamp;
|
2015-02-14 06:14:03 +09:00
|
|
|
|
2017-05-12 18:44:03 +09:00
|
|
|
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
|
2005-04-17 07:20:36 +09:00
|
|
|
/* -- OSS things -- */
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_oss_runtime oss;
|
2005-04-17 07:20:36 +09:00
|
|
|
#endif
|
2022-03-29 00:30:06 +09:00
|
|
|
#ifndef __GENKSYMS__
|
|
|
|
struct mutex buffer_mutex; /* protect for buffer changes */
|
This is the 5.10.110 stable release
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmJQLWwACgkQONu9yGCS
aT4R2BAAr/cGnf2/BQ6+zNPW+LlfGn75803yd+oWNL8WzjNiQGrTsQavE1jL0LXP
45iPxvY6eOlP9oEoJGYyNYhzQfUM92Unysa/KemB/xUBsb2If0ZdWk1WB9Lnw0xq
m65kACXovbcg4LsZGpgCv7ln1ykogo+bNMES9P6CLxwKR/DMKUeJxbRNKE/AkD5l
DxF7IJEP+YRbKAtoLM2Xj4KdjVSfRIfs+Pf0A1t43GqAw6tt3beqmzeCwDzuzz5a
DHpXS6PeJjTZOjz4LkuBSbyK5cKGFv1C6o7JVjWSZhDyI5E4OLdNDpNKqcjsXAN+
wMqS1eh4gYUBXmPE44BGwkkugPyaR0/KHUebfkFZG2/H/8DfvrGqlbvsGSFNXxsV
jH2/AV/rOxAFeM/U0c1I4Ve42MU18kdf1MRBo0Dq5xSoN9HFQhNp+HE5jpppgsvi
FYpMqZoQzH31GIjOq7g0zLdj4NTBrkO9dh7kbpH0Xay1yBmigvD2PA4qpsL1+VMI
v73Iq/RJVGUJFAeiYFjn9IGs9EsiKNG08v9uoKS+1m1VLrpVdgwtzo+RjJ/E51Mt
Nk4WK94MyoivkRFKulDasv9yBWdcZCfljc91271UCKCERlyO/bmsTqhffeATGGRh
N/7oxa71BHvxp0VYqvKD6xFUs+jFt9DQmIX7Pl1/yLpaz+sN0no=
=31mv
-----END PGP SIGNATURE-----
Merge 5.10.110 into android12-5.10-lts
Changes in 5.10.110
swiotlb: fix info leak with DMA_FROM_DEVICE
USB: serial: pl2303: add IBM device IDs
USB: serial: simple: add Nokia phone driver
hv: utils: add PTP_1588_CLOCK to Kconfig to fix build
netdevice: add the case if dev is NULL
HID: logitech-dj: add new lightspeed receiver id
xfrm: fix tunnel model fragmentation behavior
ARM: mstar: Select HAVE_ARM_ARCH_TIMER
virtio_console: break out of buf poll on remove
vdpa/mlx5: should verify CTRL_VQ feature exists for MQ
tools/virtio: fix virtio_test execution
ethernet: sun: Free the coherent when failing in probing
gpio: Revert regression in sysfs-gpio (gpiolib.c)
spi: Fix invalid sgs value
net:mcf8390: Use platform_get_irq() to get the interrupt
Revert "gpio: Revert regression in sysfs-gpio (gpiolib.c)"
spi: Fix erroneous sgs value with min_t()
Input: zinitix - do not report shadow fingers
af_key: add __GFP_ZERO flag for compose_sadb_supported in function pfkey_register
net: dsa: microchip: add spi_device_id tables
locking/lockdep: Avoid potential access of invalid memory in lock_class
iommu/iova: Improve 32-bit free space estimate
tpm: fix reference counting for struct tpm_chip
virtio-blk: Use blk_validate_block_size() to validate block size
USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c
xhci: fix garbage USBSTS being logged in some cases
xhci: fix runtime PM imbalance in USB2 resume
xhci: make xhci_handshake timeout for xhci_reset() adjustable
xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx()
mei: me: add Alder Lake N device id.
mei: avoid iterator usage outside of list_for_each_entry
coresight: Fix TRCCONFIGR.QE sysfs interface
iio: afe: rescale: use s64 for temporary scale calculations
iio: inkern: apply consumer scale on IIO_VAL_INT cases
iio: inkern: apply consumer scale when no channel scale is available
iio: inkern: make a best effort on offset calculation
greybus: svc: fix an error handling bug in gb_svc_hello()
clk: uniphier: Fix fixed-rate initialization
ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE
KEYS: fix length validation in keyctl_pkey_params_get_2()
Documentation: add link to stable release candidate tree
Documentation: update stable tree link
firmware: stratix10-svc: add missing callback parameter on RSU
HID: intel-ish-hid: Use dma_alloc_coherent for firmware update
SUNRPC: avoid race between mod_timer() and del_timer_sync()
NFSD: prevent underflow in nfssvc_decode_writeargs()
NFSD: prevent integer overflow on 32 bit systems
f2fs: fix to unlock page correctly in error path of is_alive()
f2fs: quota: fix loop condition at f2fs_quota_sync()
f2fs: fix to do sanity check on .cp_pack_total_block_count
remoteproc: Fix count check in rproc_coredump_write()
pinctrl: samsung: drop pin banks references on error paths
spi: mxic: Fix the transmit path
mtd: rawnand: protect access to rawnand devices while in suspend
can: ems_usb: ems_usb_start_xmit(): fix double dev_kfree_skb() in error path
jffs2: fix use-after-free in jffs2_clear_xattr_subsystem
jffs2: fix memory leak in jffs2_do_mount_fs
jffs2: fix memory leak in jffs2_scan_medium
mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node
mm: invalidate hwpoison page cache page in fault path
mempolicy: mbind_range() set_policy() after vma_merge()
scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands
qed: display VF trust config
qed: validate and restrict untrusted VFs vlan promisc mode
riscv: Fix fill_callchain return value
riscv: Increase stack size under KASAN
Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads"
cifs: prevent bad output lengths in smb2_ioctl_query_info()
cifs: fix NULL ptr dereference in smb2_ioctl_query_info()
ALSA: cs4236: fix an incorrect NULL check on list iterator
ALSA: hda: Avoid unsol event during RPM suspending
ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
ALSA: hda/realtek: Fix audio regression on Mi Notebook Pro 2020
mm: madvise: skip unmapped vma holes passed to process_madvise
mm: madvise: return correct bytes advised with process_madvise
Revert "mm: madvise: skip unmapped vma holes passed to process_madvise"
mm,hwpoison: unmap poisoned page before invalidation
mm/kmemleak: reset tag when compare object pointer
dm integrity: set journal entry unused when shrinking device
drbd: fix potential silent data corruption
can: isotp: sanitize CAN ID checks in isotp_bind()
powerpc/kvm: Fix kvm_use_magic_page
udp: call udp_encap_enable for v6 sockets when enabling encap
arm64: signal: nofpsimd: Do not allocate fp/simd context when not available
arm64: dts: ti: k3-am65: Fix gic-v3 compatible regs
arm64: dts: ti: k3-j721e: Fix gic-v3 compatible regs
arm64: dts: ti: k3-j7200: Fix gic-v3 compatible regs
ACPI: properties: Consistently return -ENOENT if there are no more references
coredump: Also dump first pages of non-executable ELF libraries
ext4: fix ext4_fc_stats trace point
ext4: fix fs corruption when tring to remove a non-empty directory with IO error
drivers: hamradio: 6pack: fix UAF bug caused by mod_timer()
mailbox: tegra-hsp: Flush whole channel
block: limit request dispatch loop duration
block: don't merge across cgroup boundaries if blkcg is enabled
drm/edid: check basic audio support on CEA extension block
video: fbdev: sm712fb: Fix crash in smtcfb_read()
video: fbdev: atari: Atari 2 bpp (STe) palette bugfix
ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
ARM: dts: exynos: add missing HDMI supplies on SMDK5250
ARM: dts: exynos: add missing HDMI supplies on SMDK5420
mgag200 fix memmapsl configuration in GCTL6 register
carl9170: fix missing bit-wise or operator for tx_params
pstore: Don't use semaphores in always-atomic-context code
thermal: int340x: Increase bitmap size
lib/raid6/test: fix multiple definition linking error
exec: Force single empty string when argv is empty
crypto: rsa-pkcs1pad - only allow with rsa
crypto: rsa-pkcs1pad - correctly get hash from source scatterlist
crypto: rsa-pkcs1pad - restore signature length check
crypto: rsa-pkcs1pad - fix buffer overread in pkcs1pad_verify_complete()
bcache: fixup multiple threads crash
DEC: Limit PMAX memory probing to R3k systems
media: gpio-ir-tx: fix transmit with long spaces on Orange Pi PC
media: davinci: vpif: fix unbalanced runtime PM get
media: davinci: vpif: fix unbalanced runtime PM enable
xtensa: fix stop_machine_cpuslocked call in patch_text
xtensa: fix xtensa_wsr always writing 0
brcmfmac: firmware: Allocate space for default boardrev in nvram
brcmfmac: pcie: Release firmwares in the brcmf_pcie_setup error path
brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio
brcmfmac: pcie: Fix crashes due to early IRQs
drm/i915/opregion: check port number bounds for SWSCI display power state
drm/i915/gem: add missing boundary check in vm_access
PCI: pciehp: Clear cmd_busy bit in polling mode
PCI: xgene: Revert "PCI: xgene: Fix IB window setup"
regulator: qcom_smd: fix for_each_child.cocci warnings
selinux: check return value of sel_make_avc_files
hwrng: cavium - Check health status while reading random data
hwrng: cavium - HW_RANDOM_CAVIUM should depend on ARCH_THUNDER
crypto: sun8i-ss - really disable hash on A80
crypto: authenc - Fix sleep in atomic context in decrypt_tail
crypto: mxs-dcp - Fix scatterlist processing
thermal: int340x: Check for NULL after calling kmemdup()
spi: tegra114: Add missing IRQ check in tegra_spi_probe
arm64/mm: avoid fixmap race condition when create pud mapping
selftests/x86: Add validity check and allow field splitting
crypto: rockchip - ECB does not need IV
audit: log AUDIT_TIME_* records only from rules
EVM: fix the evm= __setup handler return value
crypto: ccree - don't attempt 0 len DMA mappings
spi: pxa2xx-pci: Balance reference count for PCI DMA device
hwmon: (pmbus) Add mutex to regulator ops
hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING
nvme: cleanup __nvme_check_ids
block: don't delete queue kobject before its children
PM: hibernate: fix __setup handler error handling
PM: suspend: fix return value of __setup handler
spi: spi-zynqmp-gqspi: Handle error for dma_set_mask
hwrng: atmel - disable trng on failure path
crypto: sun8i-ss - call finalize with bh disabled
crypto: sun8i-ce - call finalize with bh disabled
crypto: amlogic - call finalize with bh disabled
crypto: vmx - add missing dependencies
clocksource/drivers/timer-ti-dm: Fix regression from errata i940 fix
clocksource/drivers/exynos_mct: Refactor resources allocation
clocksource/drivers/exynos_mct: Handle DTS with higher number of interrupts
clocksource/drivers/timer-microchip-pit64b: Use notrace
clocksource/drivers/timer-of: Check return value of of_iomap in timer_of_base_init()
ACPI: APEI: fix return value of __setup handlers
crypto: ccp - ccp_dmaengine_unregister release dma channels
crypto: ccree - Fix use after free in cc_cipher_exit()
vfio: platform: simplify device removal
amba: Make the remove callback return void
hwrng: nomadik - Change clk_disable to clk_disable_unprepare
hwmon: (pmbus) Add Vin unit off handling
clocksource: acpi_pm: fix return value of __setup handler
io_uring: terminate manual loop iterator loop correctly for non-vecs
watch_queue: Fix NULL dereference in error cleanup
watch_queue: Actually free the watch
f2fs: fix to enable ATGC correctly via gc_idle sysfs interface
sched/debug: Remove mpol_get/put and task_lock/unlock from sched_show_numa
sched/core: Export pelt_thermal_tp
rseq: Optimise rseq_get_rseq_cs() and clear_rseq_cs()
rseq: Remove broken uapi field layout on 32-bit little endian
perf/core: Fix address filter parser for multiple filters
perf/x86/intel/pt: Fix address filter config for 32-bit kernel
f2fs: fix missing free nid in f2fs_handle_failed_inode
nfsd: more robust allocation failure handling in nfsd_file_cache_init
f2fs: fix to avoid potential deadlock
btrfs: fix unexpected error path when reflinking an inline extent
f2fs: compress: remove unneeded read when rewrite whole cluster
f2fs: fix compressed file start atomic write may cause data corruption
selftests, x86: fix how check_cc.sh is being invoked
kunit: make kunit_test_timeout compatible with comment
media: staging: media: zoran: fix usage of vb2_dma_contig_set_max_seg_size
media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across ioctls
media: mtk-vcodec: potential dereference of null pointer
media: bttv: fix WARNING regression on tunerless devices
ASoC: xilinx: xlnx_formatter_pcm: Handle sysclk setting
ASoC: generic: simple-card-utils: remove useless assignment
media: coda: Fix missing put_device() call in coda_get_vdoa_data
media: meson: vdec: potential dereference of null pointer
media: hantro: Fix overfill bottom register field name
media: aspeed: Correct value for h-total-pixels
video: fbdev: matroxfb: set maxvram of vbG200eW to the same as vbG200 to avoid black screen
video: fbdev: controlfb: Fix set but not used warnings
video: fbdev: controlfb: Fix COMPILE_TEST build
video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe()
video: fbdev: atmel_lcdfb: fix an error code in atmel_lcdfb_probe()
video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name()
firmware: qcom: scm: Remove reassignment to desc following initializer
ARM: dts: qcom: ipq4019: fix sleep clock
soc: qcom: rpmpd: Check for null return of devm_kcalloc
soc: qcom: ocmem: Fix missing put_device() call in of_get_ocmem
soc: qcom: aoss: remove spurious IRQF_ONESHOT flags
arm64: dts: qcom: sdm845: fix microphone bias properties and values
arm64: dts: qcom: sm8150: Correct TCS configuration for apps rsc
firmware: ti_sci: Fix compilation failure when CONFIG_TI_SCI_PROTOCOL is not defined
soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe
ARM: dts: sun8i: v3s: Move the csi1 block to follow address order
ARM: dts: imx: Add missing LVDS decoder on M53Menlo
media: video/hdmi: handle short reads of hdmi info frame.
media: em28xx: initialize refcount before kref_get
media: usb: go7007: s2250-board: fix leak in probe()
media: cedrus: H265: Fix neighbour info buffer size
media: cedrus: h264: Fix neighbour info buffer size
ASoC: codecs: wcd934x: fix return value of wcd934x_rx_hph_mode_put
uaccess: fix nios2 and microblaze get_user_8()
ASoC: rt5663: check the return value of devm_kzalloc() in rt5663_parse_dp()
ASoC: ti: davinci-i2s: Add check for clk_enable()
ALSA: spi: Add check for clk_enable()
arm64: dts: ns2: Fix spi-cpol and spi-cpha property
arm64: dts: broadcom: Fix sata nodename
printk: fix return value of printk.devkmsg __setup handler
ASoC: mxs-saif: Handle errors for clk_enable
ASoC: atmel_ssc_dai: Handle errors for clk_enable
ASoC: dwc-i2s: Handle errors for clk_enable
ASoC: soc-compress: prevent the potentially use of null pointer
memory: emif: Add check for setup_interrupts
memory: emif: check the pointer temp in get_device_details()
ALSA: firewire-lib: fix uninitialized flag for AV/C deferred transaction
arm64: dts: rockchip: Fix SDIO regulator supply properties on rk3399-firefly
m68k: coldfire/device.c: only build for MCF_EDMA when h/w macros are defined
media: stk1160: If start stream fails, return buffers with VB2_BUF_STATE_QUEUED
media: vidtv: Check for null return of vzalloc
ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe
ASoC: wm8350: Handle error for wm8350_register_irq
ASoC: fsi: Add check for clk_enable
video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of
media: saa7134: convert list_for_each to entry variant
media: saa7134: fix incorrect use to determine if list is empty
ivtv: fix incorrect device_caps for ivtvfb
ASoC: rockchip: i2s: Use devm_platform_get_and_ioremap_resource()
ASoC: rockchip: i2s: Fix missing clk_disable_unprepare() in rockchip_i2s_probe
ASoC: SOF: Add missing of_node_put() in imx8m_probe
ASoC: dmaengine: do not use a NULL prepare_slave_config() callback
ASoC: mxs: Fix error handling in mxs_sgtl5000_probe
ASoC: fsl_spdif: Disable TX clock when stop
ASoC: imx-es8328: Fix error return code in imx_es8328_probe()
ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in msm8916_wcd_digital_probe
mmc: davinci_mmc: Handle error for clk_enable
ASoC: atmel: sam9x5_wm8731: use devm_snd_soc_register_card()
ASoC: atmel: Fix error handling in sam9x5_wm8731_driver_probe
ASoC: msm8916-wcd-analog: Fix error handling in pm8916_wcd_analog_spmi_probe
ASoC: codecs: wcd934x: Add missing of_node_put() in wcd934x_codec_parse_data
ARM: configs: multi_v5_defconfig: re-enable CONFIG_V4L_PLATFORM_DRIVERS
drm/meson: osd_afbcd: Add an exit callback to struct meson_afbcd_ops
drm/bridge: Fix free wrong object in sii8620_init_rcp_input_dev
drm/bridge: Add missing pm_runtime_disable() in __dw_mipi_dsi_probe
drm/bridge: nwl-dsi: Fix PM disable depth imbalance in nwl_dsi_probe
drm: bridge: adv7511: Fix ADV7535 HPD enablement
ath10k: fix memory overwrite of the WoWLAN wakeup packet pattern
drm/panfrost: Check for error num after setting mask
libbpf: Fix possible NULL pointer dereference when destroying skeleton
udmabuf: validate ubuf->pagecount
Bluetooth: hci_serdev: call init_rwsem() before p->open()
mtd: onenand: Check for error irq
mtd: rawnand: gpmi: fix controller timings setting
drm/edid: Don't clear formats if using deep color
ionic: fix type complaint in ionic_dev_cmd_clean()
drm/nouveau/acr: Fix undefined behavior in nvkm_acr_hsfw_load_bl()
drm/amd/display: Fix a NULL pointer dereference in amdgpu_dm_connector_add_common_modes()
drm/amd/pm: return -ENOTSUPP if there is no get_dpm_ultimate_freq function
ath9k_htc: fix uninit value bugs
RDMA/core: Set MR type in ib_reg_user_mr
KVM: PPC: Fix vmx/vsx mixup in mmio emulation
i40e: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
i40e: respect metadata on XSK Rx to skb
power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe
ray_cs: Check ioremap return value
powerpc: dts: t1040rdb: fix ports names for Seville Ethernet switch
KVM: PPC: Book3S HV: Check return value of kvmppc_radix_init
powerpc/perf: Don't use perf_hw_context for trace IMC PMU
mt76: mt7915: use proper aid value in mt7915_mcu_wtbl_generic_tlv in sta mode
mt76: mt7915: use proper aid value in mt7915_mcu_sta_basic_tlv
mt76: mt7603: check sta_rates pointer in mt7603_sta_rate_tbl_update
mt76: mt7615: check sta_rates pointer in mt7615_sta_rate_tbl_update
net: dsa: mv88e6xxx: Enable port policy support on 6097
scripts/dtc: Call pkg-config POSIXly correct
livepatch: Fix build failure on 32 bits processors
PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
drm/bridge: dw-hdmi: use safe format when first in bridge chain
power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init
HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports
iommu/ipmmu-vmsa: Check for error num after setting mask
drm/amd/pm: enable pm sysfs write for one VF mode
drm/amd/display: Add affected crtcs to atomic state for dsc mst unplug
IB/cma: Allow XRC INI QPs to set their local ACK timeout
dax: make sure inodes are flushed before destroy cache
iwlwifi: Fix -EIO error code that is never returned
iwlwifi: mvm: Fix an error code in iwl_mvm_up()
drm/msm/dp: populate connector of struct dp_panel
drm/msm/dpu: add DSPP blocks teardown
drm/msm/dpu: fix dp audio condition
dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS
scsi: pm8001: Fix command initialization in pm80XX_send_read_log()
scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req()
scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config()
scsi: pm8001: Fix le32 values handling in pm80xx_set_sas_protocol_timer_config()
scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update()
scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req()
scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()
scsi: pm8001: Fix NCQ NON DATA command task initialization
scsi: pm8001: Fix NCQ NON DATA command completion handling
scsi: pm8001: Fix abort all task initialization
RDMA/mlx5: Fix the flow of a miss in the allocation of a cache ODP MR
drm/amd/display: Remove vupdate_int_entry definition
TOMOYO: fix __setup handlers return values
ext2: correct max file size computing
drm/tegra: Fix reference leak in tegra_dsi_ganged_probe
power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong false return
scsi: hisi_sas: Change permission of parameter prot_mask
drm/bridge: cdns-dsi: Make sure to to create proper aliases for dt
bpf, arm64: Call build_prologue() first in first JIT pass
bpf, arm64: Feed byte-offset into bpf line info
gpu: host1x: Fix a memory leak in 'host1x_remove()'
libbpf: Skip forward declaration when counting duplicated type names
powerpc/mm/numa: skip NUMA_NO_NODE onlining in parse_numa_properties()
powerpc/Makefile: Don't pass -mcpu=powerpc64 when building 32-bit
KVM: x86: Fix emulation in writing cr8
KVM: x86/emulator: Defer not-present segment check in __load_segment_descriptor()
hv_balloon: rate-limit "Unhandled message" warning
i2c: xiic: Make bus names unique
power: supply: wm8350-power: Handle error for wm8350_register_irq
power: supply: wm8350-power: Add missing free in free_charger_irq
IB/hfi1: Allow larger MTU without AIP
PCI: Reduce warnings on possible RW1C corruption
net: axienet: fix RX ring refill allocation failure handling
mips: DEC: honor CONFIG_MIPS_FP_SUPPORT=n
powerpc/sysdev: fix incorrect use to determine if list is empty
mfd: mc13xxx: Add check for mc13xxx_irq_request
libbpf: Unmap rings when umem deleted
selftests/bpf: Make test_lwt_ip_encap more stable and faster
platform/x86: huawei-wmi: check the return value of device_create_file()
powerpc: 8xx: fix a return value error in mpc8xx_pic_init
vxcan: enable local echo for sent CAN frames
ath10k: Fix error handling in ath10k_setup_msa_resources
mips: cdmm: Fix refcount leak in mips_cdmm_phys_base
MIPS: RB532: fix return value of __setup handler
MIPS: pgalloc: fix memory leak caused by pgd_free()
mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init
RDMA/mlx5: Fix memory leak in error flow for subscribe event routine
bpf, sockmap: Fix memleak in tcp_bpf_sendmsg while sk msg is full
bpf, sockmap: Fix more uncharged while msg has more_data
bpf, sockmap: Fix double uncharge the mem of sk_msg
samples/bpf, xdpsock: Fix race when running for fix duration of time
USB: storage: ums-realtek: fix error code in rts51x_read_mem()
can: isotp: return -EADDRNOTAVAIL when reading from unbound socket
can: isotp: support MSG_TRUNC flag when reading from socket
bareudp: use ipv6_mod_enabled to check if IPv6 enabled
selftests/bpf: Fix error reporting from sock_fields programs
Bluetooth: call hci_le_conn_failed with hdev lock in hci_le_conn_failed
Bluetooth: btmtksdio: Fix kernel oops in btmtksdio_interrupt
ipv4: Fix route lookups when handling ICMP redirects and PMTU updates
af_netlink: Fix shift out of bounds in group mask calculation
i2c: meson: Fix wrong speed use from probe
i2c: mux: demux-pinctrl: do not deactivate a master that is not active
selftests/bpf/test_lirc_mode2.sh: Exit with proper code
PCI: Avoid broken MSI on SB600 USB devices
net: bcmgenet: Use stronger register read/writes to assure ordering
tcp: ensure PMTU updates are processed during fastopen
openvswitch: always update flow key after nat
tipc: fix the timer expires after interval 100ms
mfd: asic3: Add missing iounmap() on error asic3_mfd_probe
mxser: fix xmit_buf leak in activate when LSR == 0xff
pwm: lpc18xx-sct: Initialize driver data and hardware before pwmchip_add()
fsi: aspeed: convert to devm_platform_ioremap_resource
fsi: Aspeed: Fix a potential double free
misc: alcor_pci: Fix an error handling path
cpufreq: qcom-cpufreq-nvmem: fix reading of PVS Valid fuse
soundwire: intel: fix wrong register name in intel_shim_wake
clk: qcom: ipq8074: fix PCI-E clock oops
iio: mma8452: Fix probe failing when an i2c_device_id is used
staging:iio:adc:ad7280a: Fix handing of device address bit reversing.
pinctrl: renesas: r8a77470: Reduce size for narrow VIN1 channel
pinctrl: renesas: checker: Fix miscalculation of number of states
clk: qcom: ipq8074: Use floor ops for SDCC1 clock
phy: dphy: Correct lpx parameter and its derivatives(ta_{get,go,sure})
serial: 8250_mid: Balance reference count for PCI DMA device
serial: 8250_lpss: Balance reference count for PCI DMA device
NFS: Use of mapping_set_error() results in spurious errors
serial: 8250: Fix race condition in RTS-after-send handling
iio: adc: Add check for devm_request_threaded_irq
habanalabs: Add check for pci_enable_device
NFS: Return valid errors from nfs2/3_decode_dirent()
dma-debug: fix return value of __setup handlers
clk: imx7d: Remove audio_mclk_root_clk
clk: at91: sama7g5: fix parents of PDMCs' GCLK
clk: qcom: clk-rcg2: Update logic to calculate D value for RCG
clk: qcom: clk-rcg2: Update the frac table for pixel clock
dmaengine: hisi_dma: fix MSI allocate fail when reload hisi_dma
remoteproc: qcom: Fix missing of_node_put in adsp_alloc_memory_region
remoteproc: qcom_wcnss: Add missing of_node_put() in wcnss_alloc_memory_region
remoteproc: qcom_q6v5_mss: Fix some leaks in q6v5_alloc_memory_region
nvdimm/region: Fix default alignment for small regions
clk: actions: Terminate clk_div_table with sentinel element
clk: loongson1: Terminate clk_div_table with sentinel element
clk: clps711x: Terminate clk_div_table with sentinel element
clk: tegra: tegra124-emc: Fix missing put_device() call in emc_ensure_emc_driver
NFS: remove unneeded check in decode_devicenotify_args()
staging: mt7621-dts: fix LEDs and pinctrl on GB-PC1 devicetree
staging: mt7621-dts: fix formatting
staging: mt7621-dts: fix pinctrl properties for ethernet
staging: mt7621-dts: fix GB-PC2 devicetree
pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init
pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback
pinctrl: mediatek: paris: Fix "argument" argument type for mtk_pinconf_get()
pinctrl: mediatek: paris: Fix pingroup pin config state readback
pinctrl: mediatek: paris: Skip custom extra pin config dump for virtual GPIOs
pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe
pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe
tty: hvc: fix return value of __setup handler
kgdboc: fix return value of __setup handler
serial: 8250: fix XOFF/XON sending when DMA is used
kgdbts: fix return value of __setup handler
firmware: google: Properly state IOMEM dependency
driver core: dd: fix return value of __setup handler
jfs: fix divide error in dbNextAG
netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options
NFSv4.1: don't retry BIND_CONN_TO_SESSION on session error
kdb: Fix the putarea helper function
clk: qcom: gcc-msm8994: Fix gpll4 width
clk: Initialize orphan req_rate
xen: fix is_xen_pmu()
net: enetc: report software timestamping via SO_TIMESTAMPING
net: hns3: fix bug when PF set the duplicate MAC address for VFs
net: phy: broadcom: Fix brcm_fet_config_init()
selftests: test_vxlan_under_vrf: Fix broken test case
qlcnic: dcb: default to returning -EOPNOTSUPP
net/x25: Fix null-ptr-deref caused by x25_disconnect
NFSv4/pNFS: Fix another issue with a list iterator pointing to the head
net: dsa: bcm_sf2_cfp: fix an incorrect NULL check on list iterator
fs: fd tables have to be multiples of BITS_PER_LONG
lib/test: use after free in register_test_dev_kmod()
fs: fix fd table size alignment properly
LSM: general protection fault in legacy_parse_param
regulator: rpi-panel: Handle I2C errors/timing to the Atmel
gcc-plugins/stackleak: Exactly match strings instead of prefixes
pinctrl: npcm: Fix broken references to chip->parent_device
block, bfq: don't move oom_bfqq
selinux: use correct type for context length
selinux: allow FIOCLEX and FIONCLEX with policy capability
loop: use sysfs_emit() in the sysfs xxx show()
Fix incorrect type in assignment of ipv6 port for audit
irqchip/qcom-pdc: Fix broken locking
irqchip/nvic: Release nvic_base upon failure
fs/binfmt_elf: Fix AT_PHDR for unusual ELF files
bfq: fix use-after-free in bfq_dispatch_request
ACPICA: Avoid walking the ACPI Namespace if it is not there
lib/raid6/test/Makefile: Use $(pound) instead of \# for Make 4.3
Revert "Revert "block, bfq: honor already-setup queue merges""
ACPI/APEI: Limit printable size of BERT table data
PM: core: keep irq flags in device_pm_check_callbacks()
parisc: Fix handling off probe non-access faults
nvme-tcp: lockdep: annotate in-kernel sockets
spi: tegra20: Use of_device_get_match_data()
locking/lockdep: Iterate lock_classes directly when reading lockdep files
ext4: correct cluster len and clusters changed accounting in ext4_mb_mark_bb
ext4: fix ext4_mb_mark_bb() with flex_bg with fast_commit
ext4: don't BUG if someone dirty pages without asking ext4 first
f2fs: fix to do sanity check on curseg->alloc_type
NFSD: Fix nfsd_breaker_owns_lease() return values
f2fs: compress: fix to print raw data size in error path of lz4 decompression
ntfs: add sanity check on allocation size
media: staging: media: zoran: move videodev alloc
media: staging: media: zoran: calculate the right buffer number for zoran_reap_stat_com
media: staging: media: zoran: fix various V4L2 compliance errors
media: ir_toy: free before error exiting
video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow
video: fbdev: w100fb: Reset global state
video: fbdev: cirrusfb: check pixclock to avoid divide by zero
video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit
ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960
ARM: dts: bcm2837: Add the missing L1/L2 cache information
ASoC: madera: Add dependencies on MFD
media: atomisp_gmin_platform: Add DMI quirk to not turn AXP ELDO2 regulator off on some boards
media: atomisp: fix dummy_ptr check to avoid duplicate active_bo
ARM: ftrace: avoid redundant loads or clobbering IP
ARM: dts: imx7: Use audio_mclk_post_div instead audio_mclk_root_clk
arm64: defconfig: build imx-sdma as a module
video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of snprintf()
video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead of snprintf()
video: fbdev: udlfb: replace snprintf in show functions with sysfs_emit
ARM: dts: bcm2711: Add the missing L1/L2 cache information
ASoC: soc-core: skip zero num_dai component in searching dai name
media: cx88-mpeg: clear interrupt status register before streaming video
uaccess: fix type mismatch warnings from access_ok()
lib/test_lockup: fix kernel pointer check for separate address spaces
ARM: tegra: tamonten: Fix I2C3 pad setting
ARM: mmp: Fix failure to remove sram device
video: fbdev: sm712fb: Fix crash in smtcfb_write()
media: Revert "media: em28xx: add missing em28xx_close_extension"
media: hdpvr: initialize dev->worker at hdpvr_register_videodev
mmc: host: Return an error when ->enable_sdio_irq() ops is missing
media: atomisp: fix bad usage at error handling logic
ALSA: hda/realtek: Add alc256-samsung-headphone fixup
KVM: x86/mmu: Check for present SPTE when clearing dirty bit in TDP MMU
powerpc/kasan: Fix early region not updated correctly
powerpc/lib/sstep: Fix 'sthcx' instruction
powerpc/lib/sstep: Fix build errors with newer binutils
powerpc: Fix build errors with newer binutils
scsi: qla2xxx: Fix stuck session in gpdb
scsi: qla2xxx: Fix scheduling while atomic
scsi: qla2xxx: Fix wrong FDMI data for 64G adapter
scsi: qla2xxx: Fix warning for missing error code
scsi: qla2xxx: Fix device reconnect in loop topology
scsi: qla2xxx: Add devids and conditionals for 28xx
scsi: qla2xxx: Check for firmware dump already collected
scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair()
scsi: qla2xxx: Fix disk failure to rediscover
scsi: qla2xxx: Fix incorrect reporting of task management failure
scsi: qla2xxx: Fix hang due to session stuck
scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests
scsi: qla2xxx: Fix N2N inconsistent PLOGI
scsi: qla2xxx: Reduce false trigger to login
scsi: qla2xxx: Use correct feature type field during RFF_ID processing
platform: chrome: Split trace include file
KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated
KVM: Prevent module exit until all VMs are freed
KVM: x86: fix sending PV IPI
KVM: SVM: fix panic on out-of-bounds guest IRQ
ASoC: SOF: Intel: Fix NULL ptr dereference when ENOMEM
ubifs: rename_whiteout: Fix double free for whiteout_ui->data
ubifs: Fix deadlock in concurrent rename whiteout and inode writeback
ubifs: Add missing iput if do_tmpfile() failed in rename whiteout
ubifs: setflags: Make dirtied_ino_d 8 bytes aligned
ubifs: Fix read out-of-bounds in ubifs_wbuf_write_nolock()
ubifs: Fix to add refcount once page is set private
ubifs: rename_whiteout: correct old_dir size computing
wireguard: queueing: use CFI-safe ptr_ring cleanup function
wireguard: socket: free skb in send6 when ipv6 is disabled
wireguard: socket: ignore v6 endpoints when ipv6 is disabled
XArray: Fix xas_create_range() when multi-order entry present
can: mcba_usb: mcba_usb_start_xmit(): fix double dev_kfree_skb in error path
can: mcba_usb: properly check endpoint type
can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix return of error value
XArray: Update the LRU list in xas_split()
rtc: check if __rtc_read_time was successful
gfs2: Make sure FITRIM minlen is rounded up to fs block size
net: hns3: fix software vlan talbe of vlan 0 inconsistent with hardware
rxrpc: Fix call timer start racing with call destruction
mailbox: imx: fix wakeup failure from freeze mode
crypto: arm/aes-neonbs-cbc - Select generic cbc and aes
watch_queue: Free the page array when watch_queue is dismantled
pinctrl: pinconf-generic: Print arguments for bias-pull-*
watchdog: rti-wdt: Add missing pm_runtime_disable() in probe function
pinctrl: nuvoton: npcm7xx: Rename DS() macro to DSTR()
pinctrl: nuvoton: npcm7xx: Use %zu printk format for ARRAY_SIZE()
ASoC: mediatek: mt6358: add missing EXPORT_SYMBOLs
ubi: Fix race condition between ctrl_cdev_ioctl and ubi_cdev_ioctl
ARM: iop32x: offset IRQ numbers by 1
io_uring: fix memory leak of uid in files registration
riscv module: remove (NOLOAD)
ACPI: CPPC: Avoid out of bounds access when parsing _CPC data
platform/chrome: cros_ec_typec: Check for EC device
can: isotp: restore accidentally removed MSG_PEEK feature
proc: bootconfig: Add null pointer check
staging: mt7621-dts: fix pinctrl-0 items to be size-1 items on ethernet
ASoC: soc-compress: Change the check for codec_dai
batman-adv: Check ptr for NULL before reducing its refcnt
mm/mmap: return 1 from stack_guard_gap __setup() handler
ARM: 9187/1: JIVE: fix return value of __setup handler
mm/memcontrol: return 1 from cgroup.memory __setup() handler
mm/usercopy: return 1 from hardened_usercopy __setup() handler
bpf: Adjust BPF stack helper functions to accommodate skip > 0
bpf: Fix comment for helper bpf_current_task_under_cgroup()
dt-bindings: mtd: nand-controller: Fix the reg property description
dt-bindings: mtd: nand-controller: Fix a comment in the examples
dt-bindings: spi: mxic: The interrupt property is not mandatory
ubi: fastmap: Return error code if memory allocation fails in add_aeb()
ASoC: topology: Allow TLV control to be either read or write
ARM: dts: spear1340: Update serial node properties
ARM: dts: spear13xx: Update SPI dma properties
um: Fix uml_mconsole stop/go
docs: sysctl/kernel: add missing bit to panic_print
openvswitch: Fixed nd target mask field in the flow dump.
KVM: x86/mmu: do compare-and-exchange of gPTE via the user address
can: m_can: m_can_tx_handler(): fix use after free of skb
can: usb_8dev: usb_8dev_start_xmit(): fix double dev_kfree_skb() in error path
coredump: Snapshot the vmas in do_coredump
coredump: Remove the WARN_ON in dump_vma_snapshot
coredump/elf: Pass coredump_params into fill_note_info
coredump: Use the vma snapshot in fill_files_note
arm64: Do not defer reserve_crashkernel() for platforms with no DMA memory zones
PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"
Linux 5.10.110
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I12fbe227793dd40c0582588e1700cf88cafd0ac6
2022-04-19 00:41:18 +09:00
|
|
|
atomic_t buffer_accessing; /* >0: in r/w operation, <0: blocked */
|
2022-03-29 00:30:06 +09:00
|
|
|
#endif
|
2005-04-17 07:20:36 +09:00
|
|
|
};
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_group { /* keep linked substreams */
|
2005-04-17 07:20:36 +09:00
|
|
|
spinlock_t lock;
|
2014-08-29 22:32:29 +09:00
|
|
|
struct mutex mutex;
|
2005-04-17 07:20:36 +09:00
|
|
|
struct list_head substreams;
|
ALSA: pcm: More fine-grained PCM link locking
We have currently two global locks, a rwlock and a rwsem, that are
used for managing linking the PCM streams. Due to these global locks,
once when a linked stream is used, the lock granularity suffers a
lot.
This patch attempts to eliminate the former global lock for atomic
ops. The latter rwsem needs remaining because of the loosy way of the
loop calls in snd_pcm_action_nonatomic(), as well as for avoiding the
deadlock at linking. However, these are used far rarely, actually
only by two actions (prepare and reset), where both are no timing
critical ones. So this can be still seen as a good improvement.
The basic strategy to eliminate the rwlock is to assure group->lock at
adding or removing a stream to / from the group. Since we already
takes the group lock whenever taking the all substream locks under the
group, this shouldn't be a big problem. The reference to group
pointer in snd_pcm_substream object is protected by the stream lock
itself.
However, there are still pitfalls: a race window at re-locking and the
lifecycle of group object. The former is a small race window for
dereferencing the substream group object opened while snd_pcm_action()
performs re-locking to avoid ABBA deadlocks. This includes the unlink
of group during that window, too. And the latter is the kfree
performed after all streams are removed from the group while it's
still dereferenced.
For addressing these corner cases, two new tricks are introduced:
- After re-locking, the group assigned to the stream is checked again;
if the group is changed, we retry the whole procedure.
- Introduce a refcount to snd_pcm_group object, so that it's freed
only when it's empty and really no one refers to it.
(Some readers might wonder why not RCU for the latter. RCU in this
case would cost more than refcounting, unfortunately. We take the
group lock sooner or later, hence the performance improvement by RCU
would be negligible. Meanwhile, because we need to deal with
schedulable context depending on the pcm->nonatomic flag, it'll become
dynamic RCU/SRCU switch, and the grace period may become too long.)
Along with these changes, there are a significant amount of code
refactoring. The complex group re-lock & ref code is factored out to
snd_pcm_stream_group_ref() function, for example.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-01-13 17:50:33 +09:00
|
|
|
refcount_t refs;
|
2005-11-17 21:59:38 +09:00
|
|
|
};
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2009-11-10 18:13:30 +09:00
|
|
|
struct pid;
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_substream {
|
|
|
|
struct snd_pcm *pcm;
|
|
|
|
struct snd_pcm_str *pstr;
|
2005-04-17 07:20:36 +09:00
|
|
|
void *private_data; /* copied from pcm->private_data */
|
|
|
|
int number;
|
|
|
|
char name[32]; /* substream name */
|
|
|
|
int stream; /* stream (direction) */
|
2011-08-25 22:35:12 +09:00
|
|
|
struct pm_qos_request latency_pm_qos_req; /* pm_qos request */
|
2005-04-17 07:20:36 +09:00
|
|
|
size_t buffer_bytes_max; /* limit ring buffer size */
|
|
|
|
struct snd_dma_buffer dma_buffer;
|
|
|
|
size_t dma_max;
|
|
|
|
/* -- hardware operations -- */
|
2013-05-24 22:18:10 +09:00
|
|
|
const struct snd_pcm_ops *ops;
|
2005-04-17 07:20:36 +09:00
|
|
|
/* -- runtime information -- */
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_runtime *runtime;
|
2005-04-17 07:20:36 +09:00
|
|
|
/* -- timer section -- */
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_timer *timer; /* timer */
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned timer_running: 1; /* time is running */
|
2018-07-06 21:50:36 +09:00
|
|
|
long wait_time; /* time in ms for R/W to wait for avail */
|
2005-04-17 07:20:36 +09:00
|
|
|
/* -- next substream -- */
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_substream *next;
|
2005-04-17 07:20:36 +09:00
|
|
|
/* -- linked substreams -- */
|
|
|
|
struct list_head link_list; /* linked list member */
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_group self_group; /* fake group for non linked substream (with substream lock inside) */
|
|
|
|
struct snd_pcm_group *group; /* pointer to current group */
|
2005-04-17 07:20:36 +09:00
|
|
|
/* -- assigned files -- */
|
2006-04-28 22:13:41 +09:00
|
|
|
int ref_count;
|
2006-04-28 22:13:41 +09:00
|
|
|
atomic_t mmap_count;
|
2006-04-28 22:13:41 +09:00
|
|
|
unsigned int f_flags;
|
2006-03-27 23:40:49 +09:00
|
|
|
void (*pcm_release)(struct snd_pcm_substream *);
|
2009-11-10 18:13:30 +09:00
|
|
|
struct pid *pid;
|
2017-05-12 18:44:03 +09:00
|
|
|
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
|
2005-04-17 07:20:36 +09:00
|
|
|
/* -- OSS things -- */
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_oss_substream oss;
|
2005-04-17 07:20:36 +09:00
|
|
|
#endif
|
2006-04-25 19:56:04 +09:00
|
|
|
#ifdef CONFIG_SND_VERBOSE_PROCFS
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_info_entry *proc_root;
|
2014-11-04 22:02:40 +09:00
|
|
|
#endif /* CONFIG_SND_VERBOSE_PROCFS */
|
2005-04-17 07:20:36 +09:00
|
|
|
/* misc flags */
|
2006-03-27 23:40:49 +09:00
|
|
|
unsigned int hw_opened: 1;
|
ALSA: pcm: Introduce managed buffer allocation mode
This patch adds the support for the feature to automatically allocate
and free PCM buffers, so called "managed buffer allocation" mode.
It's set up via new PCM helpers, snd_pcm_set_managed_buffer() and
snd_pcm_set_managed_buffer_all(), both of which correspond to the
existing preallocator helpers, snd_pcm_lib_preallocate_pages() and
snd_pcm_lib_preallocate_pages_for_all(). When the new helper is used,
it not only performs the pre-allocation of buffers, but also it
manages to call snd_pcm_lib_malloc_pages() before the PCM hw_params
ops and snd_lib_pcm_free() after the PCM hw_free ops inside PCM core,
respectively. This allows drivers to drop the explicit calls of the
memory allocation / release functions, and it will be a good amount of
code reduction in the end of this patch series.
When the PCM substream is set to the managed buffer allocation mode,
the managed_buffer_alloc flag is set in the substream object. Since
some drivers want to know when a buffer is newly allocated or
re-allocated at hw_params callback (e.g. want to set up the additional
stuff for the given buffer only at allocation time), now PCM core
turns on buffer_changed flag when the buffer has changed.
The standard conversions to use the new API will be straightforward:
- Replace snd_pcm_lib_preallocate*() calls with the corresponding
snd_pcm_set_managed_buffer*(); the arguments should be unchanged
- Drop superfluous snd_pcm_lib_malloc() and snd_pcm_lib_free() calls;
the check of snd_pcm_lib_malloc() returns should be replaced with
the check of runtime->buffer_changed flag.
- If hw_params or hw_free becomes empty, drop them from PCM ops
Link: https://lore.kernel.org/r/20191117085308.23915-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-11-17 17:53:01 +09:00
|
|
|
unsigned int managed_buffer_alloc:1;
|
2005-04-17 07:20:36 +09:00
|
|
|
};
|
|
|
|
|
2006-04-28 22:13:41 +09:00
|
|
|
#define SUBSTREAM_BUSY(substream) ((substream)->ref_count > 0)
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_str {
|
2005-04-17 07:20:36 +09:00
|
|
|
int stream; /* stream (direction) */
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm *pcm;
|
2005-04-17 07:20:36 +09:00
|
|
|
/* -- substreams -- */
|
|
|
|
unsigned int substream_count;
|
|
|
|
unsigned int substream_opened;
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_substream *substream;
|
2017-05-12 18:44:03 +09:00
|
|
|
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
|
2005-04-17 07:20:36 +09:00
|
|
|
/* -- OSS things -- */
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_oss_stream oss;
|
2005-04-17 07:20:36 +09:00
|
|
|
#endif
|
2006-04-25 19:56:04 +09:00
|
|
|
#ifdef CONFIG_SND_VERBOSE_PROCFS
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_info_entry *proc_root;
|
2006-04-25 19:56:04 +09:00
|
|
|
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int xrun_debug; /* 0 = disabled, 1 = verbose, 2 = stacktrace */
|
|
|
|
#endif
|
2006-04-25 19:56:04 +09:00
|
|
|
#endif
|
2012-07-28 01:27:00 +09:00
|
|
|
struct snd_kcontrol *chmap_kctl; /* channel-mapping controls */
|
2015-01-30 01:32:26 +09:00
|
|
|
struct device dev;
|
2005-04-17 07:20:36 +09:00
|
|
|
};
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm {
|
|
|
|
struct snd_card *card;
|
2005-11-20 22:06:59 +09:00
|
|
|
struct list_head list;
|
2008-07-30 20:46:40 +09:00
|
|
|
int device; /* device number */
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int info_flags;
|
|
|
|
unsigned short dev_class;
|
|
|
|
unsigned short dev_subclass;
|
|
|
|
char id[64];
|
|
|
|
char name[80];
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_str streams[2];
|
2006-01-17 00:29:08 +09:00
|
|
|
struct mutex open_mutex;
|
2005-04-17 07:20:36 +09:00
|
|
|
wait_queue_head_t open_wait;
|
|
|
|
void *private_data;
|
2005-11-17 21:59:38 +09:00
|
|
|
void (*private_free) (struct snd_pcm *pcm);
|
2012-02-09 05:33:31 +09:00
|
|
|
bool internal; /* pcm is for internal use only */
|
2014-08-29 22:32:29 +09:00
|
|
|
bool nonatomic; /* whole PCM operations are in non-atomic context */
|
2019-01-11 23:58:39 +09:00
|
|
|
bool no_device_suspend; /* don't invoke device PM suspend */
|
2017-05-12 18:44:03 +09:00
|
|
|
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_oss oss;
|
2005-04-17 07:20:36 +09:00
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Registering
|
|
|
|
*/
|
|
|
|
|
2007-02-12 17:55:28 +09:00
|
|
|
extern const struct file_operations snd_pcm_f_ops[2];
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2009-02-05 21:01:54 +09:00
|
|
|
int snd_pcm_new(struct snd_card *card, const char *id, int device,
|
2005-04-17 07:20:36 +09:00
|
|
|
int playback_count, int capture_count,
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm **rpcm);
|
2012-02-09 05:33:31 +09:00
|
|
|
int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
|
|
|
|
int playback_count, int capture_count,
|
|
|
|
struct snd_pcm **rpcm);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count);
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2017-05-12 18:35:17 +09:00
|
|
|
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
|
|
|
|
struct snd_pcm_notify {
|
|
|
|
int (*n_register) (struct snd_pcm * pcm);
|
|
|
|
int (*n_disconnect) (struct snd_pcm * pcm);
|
|
|
|
int (*n_unregister) (struct snd_pcm * pcm);
|
|
|
|
struct list_head list;
|
|
|
|
};
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree);
|
2017-05-12 18:35:17 +09:00
|
|
|
#endif
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Native I/O
|
|
|
|
*/
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info);
|
|
|
|
int snd_pcm_info_user(struct snd_pcm_substream *substream,
|
|
|
|
struct snd_pcm_info __user *info);
|
2018-04-24 21:06:11 +09:00
|
|
|
int snd_pcm_status64(struct snd_pcm_substream *substream,
|
|
|
|
struct snd_pcm_status64 *status);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_start(struct snd_pcm_substream *substream);
|
2011-02-14 19:00:47 +09:00
|
|
|
int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_drain_done(struct snd_pcm_substream *substream);
|
2014-11-08 01:08:28 +09:00
|
|
|
int snd_pcm_stop_xrun(struct snd_pcm_substream *substream);
|
2005-04-17 07:20:36 +09:00
|
|
|
#ifdef CONFIG_PM
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_suspend_all(struct snd_pcm *pcm);
|
2017-02-05 16:58:46 +09:00
|
|
|
#else
|
|
|
|
static inline int snd_pcm_suspend_all(struct snd_pcm *pcm)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2005-04-17 07:20:36 +09:00
|
|
|
#endif
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg);
|
2006-03-27 23:40:49 +09:00
|
|
|
int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, struct file *file,
|
|
|
|
struct snd_pcm_substream **rsubstream);
|
2005-11-17 21:59:38 +09:00
|
|
|
void snd_pcm_release_substream(struct snd_pcm_substream *substream);
|
2006-03-27 23:40:49 +09:00
|
|
|
int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, struct file *file,
|
|
|
|
struct snd_pcm_substream **rsubstream);
|
|
|
|
void snd_pcm_detach_substream(struct snd_pcm_substream *substream);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, struct vm_area_struct *area);
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2011-07-23 09:36:25 +09:00
|
|
|
|
|
|
|
#ifdef CONFIG_SND_DEBUG
|
|
|
|
void snd_pcm_debug_name(struct snd_pcm_substream *substream,
|
|
|
|
char *name, size_t len);
|
|
|
|
#else
|
|
|
|
static inline void
|
|
|
|
snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size)
|
|
|
|
{
|
|
|
|
*buf = 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2005-04-17 07:20:36 +09:00
|
|
|
/*
|
|
|
|
* PCM library
|
|
|
|
*/
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_stream_linked - Check whether the substream is linked with others
|
|
|
|
* @substream: substream to check
|
|
|
|
*
|
|
|
|
* Returns true if the given substream is being linked with others.
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline int snd_pcm_stream_linked(struct snd_pcm_substream *substream)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
return substream->group != &substream->self_group;
|
|
|
|
}
|
|
|
|
|
2014-09-01 18:19:37 +09:00
|
|
|
void snd_pcm_stream_lock(struct snd_pcm_substream *substream);
|
|
|
|
void snd_pcm_stream_unlock(struct snd_pcm_substream *substream);
|
|
|
|
void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream);
|
|
|
|
void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream);
|
|
|
|
unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream);
|
2014-10-30 23:02:50 +09:00
|
|
|
|
|
|
|
/**
|
|
|
|
* snd_pcm_stream_lock_irqsave - Lock the PCM stream
|
|
|
|
* @substream: PCM substream
|
|
|
|
* @flags: irq flags
|
|
|
|
*
|
|
|
|
* This locks the PCM stream like snd_pcm_stream_lock() but with the local
|
|
|
|
* IRQ (only when nonatomic is false). In nonatomic case, this is identical
|
|
|
|
* as snd_pcm_stream_lock().
|
|
|
|
*/
|
2014-09-01 18:19:37 +09:00
|
|
|
#define snd_pcm_stream_lock_irqsave(substream, flags) \
|
|
|
|
do { \
|
|
|
|
typecheck(unsigned long, flags); \
|
|
|
|
flags = _snd_pcm_stream_lock_irqsave(substream); \
|
|
|
|
} while (0)
|
|
|
|
void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
|
|
|
|
unsigned long flags);
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_group_for_each_entry - iterate over the linked substreams
|
|
|
|
* @s: the iterator
|
|
|
|
* @substream: the substream
|
|
|
|
*
|
|
|
|
* Iterate over the all linked substreams to the given @substream.
|
|
|
|
* When @substream isn't linked with any others, this gives returns @substream
|
|
|
|
* itself once.
|
|
|
|
*/
|
2007-02-22 20:52:53 +09:00
|
|
|
#define snd_pcm_group_for_each_entry(s, substream) \
|
|
|
|
list_for_each_entry(s, &substream->group->substreams, link_list)
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2020-02-17 17:28:19 +09:00
|
|
|
#define for_each_pcm_streams(stream) \
|
|
|
|
for (stream = SNDRV_PCM_STREAM_PLAYBACK; \
|
|
|
|
stream <= SNDRV_PCM_STREAM_LAST; \
|
|
|
|
stream++)
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_running - Check whether the substream is in a running state
|
|
|
|
* @substream: substream to check
|
|
|
|
*
|
|
|
|
* Returns true if the given substream is in the state RUNNING, or in the
|
|
|
|
* state DRAINING for playback.
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline int snd_pcm_running(struct snd_pcm_substream *substream)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
|
|
|
|
(substream->runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
|
|
|
|
substream->stream == SNDRV_PCM_STREAM_PLAYBACK));
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* bytes_to_samples - Unit conversion of the size from bytes to samples
|
|
|
|
* @runtime: PCM runtime instance
|
|
|
|
* @size: size in bytes
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline ssize_t bytes_to_samples(struct snd_pcm_runtime *runtime, ssize_t size)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
return size * 8 / runtime->sample_bits;
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* bytes_to_frames - Unit conversion of the size from bytes to frames
|
|
|
|
* @runtime: PCM runtime instance
|
|
|
|
* @size: size in bytes
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline snd_pcm_sframes_t bytes_to_frames(struct snd_pcm_runtime *runtime, ssize_t size)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
return size * 8 / runtime->frame_bits;
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* samples_to_bytes - Unit conversion of the size from samples to bytes
|
|
|
|
* @runtime: PCM runtime instance
|
|
|
|
* @size: size in samples
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline ssize_t samples_to_bytes(struct snd_pcm_runtime *runtime, ssize_t size)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
return size * runtime->sample_bits / 8;
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* frames_to_bytes - Unit conversion of the size from frames to bytes
|
|
|
|
* @runtime: PCM runtime instance
|
|
|
|
* @size: size in frames
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline ssize_t frames_to_bytes(struct snd_pcm_runtime *runtime, snd_pcm_sframes_t size)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
return size * runtime->frame_bits / 8;
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* frame_aligned - Check whether the byte size is aligned to frames
|
|
|
|
* @runtime: PCM runtime instance
|
|
|
|
* @bytes: size in bytes
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline int frame_aligned(struct snd_pcm_runtime *runtime, ssize_t bytes)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
return bytes % runtime->byte_align == 0;
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_lib_buffer_bytes - Get the buffer size of the current PCM in bytes
|
|
|
|
* @substream: PCM substream
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline size_t snd_pcm_lib_buffer_bytes(struct snd_pcm_substream *substream)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
2005-04-17 07:20:36 +09:00
|
|
|
return frames_to_bytes(runtime, runtime->buffer_size);
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_lib_period_bytes - Get the period size of the current PCM in bytes
|
|
|
|
* @substream: PCM substream
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline size_t snd_pcm_lib_period_bytes(struct snd_pcm_substream *substream)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
2005-04-17 07:20:36 +09:00
|
|
|
return frames_to_bytes(runtime, runtime->period_size);
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_playback_avail - Get the available (writable) space for playback
|
|
|
|
* @runtime: PCM runtime instance
|
|
|
|
*
|
|
|
|
* Result is between 0 ... (boundary - 1)
|
2005-04-17 07:20:36 +09:00
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *runtime)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
snd_pcm_sframes_t avail = runtime->status->hw_ptr + runtime->buffer_size - runtime->control->appl_ptr;
|
|
|
|
if (avail < 0)
|
|
|
|
avail += runtime->boundary;
|
|
|
|
else if ((snd_pcm_uframes_t) avail >= runtime->boundary)
|
|
|
|
avail -= runtime->boundary;
|
|
|
|
return avail;
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
2019-03-14 04:06:48 +09:00
|
|
|
* snd_pcm_capture_avail - Get the available (readable) space for capture
|
2014-10-30 23:02:50 +09:00
|
|
|
* @runtime: PCM runtime instance
|
|
|
|
*
|
|
|
|
* Result is between 0 ... (boundary - 1)
|
2005-04-17 07:20:36 +09:00
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *runtime)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
snd_pcm_sframes_t avail = runtime->status->hw_ptr - runtime->control->appl_ptr;
|
|
|
|
if (avail < 0)
|
|
|
|
avail += runtime->boundary;
|
|
|
|
return avail;
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_playback_hw_avail - Get the queued space for playback
|
|
|
|
* @runtime: PCM runtime instance
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(struct snd_pcm_runtime *runtime)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
return runtime->buffer_size - snd_pcm_playback_avail(runtime);
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_capture_hw_avail - Get the free space for capture
|
|
|
|
* @runtime: PCM runtime instance
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(struct snd_pcm_runtime *runtime)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
return runtime->buffer_size - snd_pcm_capture_avail(runtime);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* snd_pcm_playback_ready - check whether the playback buffer is available
|
|
|
|
* @substream: the pcm substream instance
|
|
|
|
*
|
|
|
|
* Checks whether enough free space is available on the playback buffer.
|
|
|
|
*
|
2013-03-12 06:05:14 +09:00
|
|
|
* Return: Non-zero if available, or zero if not.
|
2005-04-17 07:20:36 +09:00
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline int snd_pcm_playback_ready(struct snd_pcm_substream *substream)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
2005-04-17 07:20:36 +09:00
|
|
|
return snd_pcm_playback_avail(runtime) >= runtime->control->avail_min;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* snd_pcm_capture_ready - check whether the capture buffer is available
|
|
|
|
* @substream: the pcm substream instance
|
|
|
|
*
|
|
|
|
* Checks whether enough capture data is available on the capture buffer.
|
|
|
|
*
|
2013-03-12 06:05:14 +09:00
|
|
|
* Return: Non-zero if available, or zero if not.
|
2005-04-17 07:20:36 +09:00
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline int snd_pcm_capture_ready(struct snd_pcm_substream *substream)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
2005-04-17 07:20:36 +09:00
|
|
|
return snd_pcm_capture_avail(runtime) >= runtime->control->avail_min;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* snd_pcm_playback_data - check whether any data exists on the playback buffer
|
|
|
|
* @substream: the pcm substream instance
|
|
|
|
*
|
2013-03-12 06:05:14 +09:00
|
|
|
* Checks whether any data exists on the playback buffer.
|
2005-04-17 07:20:36 +09:00
|
|
|
*
|
2013-03-12 06:05:14 +09:00
|
|
|
* Return: Non-zero if any data exists, or zero if not. If stop_threshold
|
|
|
|
* is bigger or equal to boundary, then this function returns always non-zero.
|
2005-04-17 07:20:36 +09:00
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline int snd_pcm_playback_data(struct snd_pcm_substream *substream)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
2005-04-17 07:20:36 +09:00
|
|
|
|
|
|
|
if (runtime->stop_threshold >= runtime->boundary)
|
|
|
|
return 1;
|
|
|
|
return snd_pcm_playback_avail(runtime) < runtime->buffer_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* snd_pcm_playback_empty - check whether the playback buffer is empty
|
|
|
|
* @substream: the pcm substream instance
|
|
|
|
*
|
|
|
|
* Checks whether the playback buffer is empty.
|
|
|
|
*
|
2013-03-12 06:05:14 +09:00
|
|
|
* Return: Non-zero if empty, or zero if not.
|
2005-04-17 07:20:36 +09:00
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline int snd_pcm_playback_empty(struct snd_pcm_substream *substream)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
2005-04-17 07:20:36 +09:00
|
|
|
return snd_pcm_playback_avail(runtime) >= runtime->buffer_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* snd_pcm_capture_empty - check whether the capture buffer is empty
|
|
|
|
* @substream: the pcm substream instance
|
|
|
|
*
|
|
|
|
* Checks whether the capture buffer is empty.
|
|
|
|
*
|
2013-03-12 06:05:14 +09:00
|
|
|
* Return: Non-zero if empty, or zero if not.
|
2005-04-17 07:20:36 +09:00
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline int snd_pcm_capture_empty(struct snd_pcm_substream *substream)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
2005-04-17 07:20:36 +09:00
|
|
|
return snd_pcm_capture_avail(runtime) == 0;
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_trigger_done - Mark the master substream
|
|
|
|
* @substream: the pcm substream instance
|
|
|
|
* @master: the linked master substream
|
|
|
|
*
|
|
|
|
* When multiple substreams of the same card are linked and the hardware
|
|
|
|
* supports the single-shot operation, the driver calls this in the loop
|
|
|
|
* in snd_pcm_group_for_each_entry() for marking the substream as "done".
|
|
|
|
* Then most of trigger operations are performed only to the given master
|
|
|
|
* substream.
|
|
|
|
*
|
|
|
|
* The trigger_master mark is cleared at timestamp updates at the end
|
|
|
|
* of trigger operations.
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline void snd_pcm_trigger_done(struct snd_pcm_substream *substream,
|
|
|
|
struct snd_pcm_substream *master)
|
2005-04-17 07:20:36 +09:00
|
|
|
{
|
|
|
|
substream->runtime->trigger_master = master;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int hw_is_mask(int var)
|
|
|
|
{
|
|
|
|
return var >= SNDRV_PCM_HW_PARAM_FIRST_MASK &&
|
|
|
|
var <= SNDRV_PCM_HW_PARAM_LAST_MASK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int hw_is_interval(int var)
|
|
|
|
{
|
|
|
|
return var >= SNDRV_PCM_HW_PARAM_FIRST_INTERVAL &&
|
|
|
|
var <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL;
|
|
|
|
}
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline struct snd_mask *hw_param_mask(struct snd_pcm_hw_params *params,
|
2005-04-17 07:20:36 +09:00
|
|
|
snd_pcm_hw_param_t var)
|
|
|
|
{
|
|
|
|
return ¶ms->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
|
|
|
|
}
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline struct snd_interval *hw_param_interval(struct snd_pcm_hw_params *params,
|
2005-04-17 07:20:36 +09:00
|
|
|
snd_pcm_hw_param_t var)
|
|
|
|
{
|
|
|
|
return ¶ms->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
|
|
|
|
}
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline const struct snd_mask *hw_param_mask_c(const struct snd_pcm_hw_params *params,
|
2005-04-17 07:20:36 +09:00
|
|
|
snd_pcm_hw_param_t var)
|
|
|
|
{
|
2007-09-11 07:33:48 +09:00
|
|
|
return ¶ms->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
|
2005-04-17 07:20:36 +09:00
|
|
|
}
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline const struct snd_interval *hw_param_interval_c(const struct snd_pcm_hw_params *params,
|
2005-04-17 07:20:36 +09:00
|
|
|
snd_pcm_hw_param_t var)
|
|
|
|
{
|
2007-09-11 07:33:48 +09:00
|
|
|
return ¶ms->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
|
2005-04-17 07:20:36 +09:00
|
|
|
}
|
|
|
|
|
2014-10-30 23:06:13 +09:00
|
|
|
/**
|
|
|
|
* params_channels - Get the number of channels from the hw params
|
|
|
|
* @p: hw params
|
|
|
|
*/
|
|
|
|
static inline unsigned int params_channels(const struct snd_pcm_hw_params *p)
|
|
|
|
{
|
|
|
|
return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_CHANNELS)->min;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-12-30 03:41:40 +09:00
|
|
|
* params_rate - Get the sample rate from the hw params
|
2014-10-30 23:06:13 +09:00
|
|
|
* @p: hw params
|
|
|
|
*/
|
|
|
|
static inline unsigned int params_rate(const struct snd_pcm_hw_params *p)
|
|
|
|
{
|
|
|
|
return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_RATE)->min;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-12-30 03:41:40 +09:00
|
|
|
* params_period_size - Get the period size (in frames) from the hw params
|
2014-10-30 23:06:13 +09:00
|
|
|
* @p: hw params
|
|
|
|
*/
|
|
|
|
static inline unsigned int params_period_size(const struct snd_pcm_hw_params *p)
|
|
|
|
{
|
|
|
|
return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-12-30 03:41:40 +09:00
|
|
|
* params_periods - Get the number of periods from the hw params
|
2014-10-30 23:06:13 +09:00
|
|
|
* @p: hw params
|
|
|
|
*/
|
|
|
|
static inline unsigned int params_periods(const struct snd_pcm_hw_params *p)
|
|
|
|
{
|
|
|
|
return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIODS)->min;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-12-30 03:41:40 +09:00
|
|
|
* params_buffer_size - Get the buffer size (in frames) from the hw params
|
2014-10-30 23:06:13 +09:00
|
|
|
* @p: hw params
|
|
|
|
*/
|
|
|
|
static inline unsigned int params_buffer_size(const struct snd_pcm_hw_params *p)
|
|
|
|
{
|
|
|
|
return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_BUFFER_SIZE)->min;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-12-30 03:41:40 +09:00
|
|
|
* params_buffer_bytes - Get the buffer size (in bytes) from the hw params
|
2014-10-30 23:06:13 +09:00
|
|
|
* @p: hw params
|
|
|
|
*/
|
|
|
|
static inline unsigned int params_buffer_bytes(const struct snd_pcm_hw_params *p)
|
|
|
|
{
|
|
|
|
return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min;
|
|
|
|
}
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v);
|
2012-03-15 04:48:43 +09:00
|
|
|
int snd_interval_list(struct snd_interval *i, unsigned int count,
|
|
|
|
const unsigned int *list, unsigned int mask);
|
2015-01-28 23:16:06 +09:00
|
|
|
int snd_interval_ranges(struct snd_interval *i, unsigned int count,
|
|
|
|
const struct snd_interval *list, unsigned int mask);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_interval_ratnum(struct snd_interval *i,
|
2015-10-28 19:37:53 +09:00
|
|
|
unsigned int rats_count, const struct snd_ratnum *rats,
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int *nump, unsigned int *denp);
|
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params);
|
|
|
|
void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var);
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_hw_refine(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params);
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
|
2005-04-17 07:20:36 +09:00
|
|
|
u_int64_t mask);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int min, unsigned int max);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var);
|
|
|
|
int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int cond,
|
|
|
|
snd_pcm_hw_param_t var,
|
2012-07-05 20:15:01 +09:00
|
|
|
const struct snd_pcm_hw_constraint_list *l);
|
2015-01-28 23:16:06 +09:00
|
|
|
int snd_pcm_hw_constraint_ranges(struct snd_pcm_runtime *runtime,
|
|
|
|
unsigned int cond,
|
|
|
|
snd_pcm_hw_param_t var,
|
|
|
|
const struct snd_pcm_hw_constraint_ranges *r);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime,
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int cond,
|
|
|
|
snd_pcm_hw_param_t var,
|
2015-10-28 19:37:53 +09:00
|
|
|
const struct snd_pcm_hw_constraint_ratnums *r);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime,
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int cond,
|
|
|
|
snd_pcm_hw_param_t var,
|
2015-10-28 19:37:53 +09:00
|
|
|
const struct snd_pcm_hw_constraint_ratdens *r);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime,
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int cond,
|
|
|
|
unsigned int width,
|
|
|
|
unsigned int msbits);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int cond,
|
|
|
|
snd_pcm_hw_param_t var,
|
|
|
|
unsigned long step);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int cond,
|
|
|
|
snd_pcm_hw_param_t var);
|
2011-09-17 06:03:02 +09:00
|
|
|
int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime,
|
|
|
|
unsigned int base_rate);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime,
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int cond,
|
|
|
|
int var,
|
|
|
|
snd_pcm_hw_rule_func_t func, void *private,
|
|
|
|
int dep, ...);
|
|
|
|
|
2015-10-18 22:39:16 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_hw_constraint_single() - Constrain parameter to a single value
|
|
|
|
* @runtime: PCM runtime instance
|
|
|
|
* @var: The hw_params variable to constrain
|
|
|
|
* @val: The value to constrain to
|
|
|
|
*
|
|
|
|
* Return: Positive if the value is changed, zero if it's not changed, or a
|
|
|
|
* negative error code.
|
|
|
|
*/
|
|
|
|
static inline int snd_pcm_hw_constraint_single(
|
|
|
|
struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
|
|
|
|
unsigned int val)
|
|
|
|
{
|
|
|
|
return snd_pcm_hw_constraint_minmax(runtime, var, val, val);
|
|
|
|
}
|
|
|
|
|
2005-04-17 07:20:36 +09:00
|
|
|
int snd_pcm_format_signed(snd_pcm_format_t format);
|
|
|
|
int snd_pcm_format_unsigned(snd_pcm_format_t format);
|
|
|
|
int snd_pcm_format_linear(snd_pcm_format_t format);
|
|
|
|
int snd_pcm_format_little_endian(snd_pcm_format_t format);
|
|
|
|
int snd_pcm_format_big_endian(snd_pcm_format_t format);
|
2017-05-15 00:38:44 +09:00
|
|
|
#if 0 /* just for kernel-doc */
|
2005-09-09 22:05:33 +09:00
|
|
|
/**
|
2005-05-18 23:25:46 +09:00
|
|
|
* snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian
|
|
|
|
* @format: the format to check
|
|
|
|
*
|
2013-03-12 06:05:14 +09:00
|
|
|
* Return: 1 if the given PCM format is CPU-endian, 0 if
|
2005-05-18 23:25:46 +09:00
|
|
|
* opposite, or a negative error code if endian not specified.
|
|
|
|
*/
|
[ALSA] Remove superfluous PCI ID definitions
CS46xx driver,EMU10K1/EMU10K2 driver,PCM Midlevel,Trident driver
YMFPCI driver,BT87x driver,CMIPCI driver,CS4281 driver
ENS1370/1+ driver,ES1938 driver,ES1968 driver,Intel8x0 driver
Intel8x0-modem driver,Maestro3 driver,RME32 driver,RME96 driver
SonicVibes driver,VIA82xx driver,ALI5451 driver,ICE1712 driver
ICE1724 driver,NM256 driver,RME HDSP driver,RME9652 driver
Remove superfluous PCI ID definitions.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2005-09-07 21:08:11 +09:00
|
|
|
int snd_pcm_format_cpu_endian(snd_pcm_format_t format);
|
2005-09-09 22:05:33 +09:00
|
|
|
#endif /* DocBook */
|
2005-05-18 23:25:46 +09:00
|
|
|
#ifdef SNDRV_LITTLE_ENDIAN
|
2005-09-10 05:10:17 +09:00
|
|
|
#define snd_pcm_format_cpu_endian(format) snd_pcm_format_little_endian(format)
|
2005-05-18 23:25:46 +09:00
|
|
|
#else
|
2005-09-10 05:10:17 +09:00
|
|
|
#define snd_pcm_format_cpu_endian(format) snd_pcm_format_big_endian(format)
|
2005-05-18 23:25:46 +09:00
|
|
|
#endif
|
2005-04-17 07:20:36 +09:00
|
|
|
int snd_pcm_format_width(snd_pcm_format_t format); /* in bits */
|
|
|
|
int snd_pcm_format_physical_width(snd_pcm_format_t format); /* in bits */
|
2005-05-18 23:25:46 +09:00
|
|
|
ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples);
|
2005-04-17 07:20:36 +09:00
|
|
|
const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format);
|
|
|
|
int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int frames);
|
|
|
|
|
2013-05-24 22:18:10 +09:00
|
|
|
void snd_pcm_set_ops(struct snd_pcm * pcm, int direction,
|
|
|
|
const struct snd_pcm_ops *ops);
|
2005-11-17 21:59:38 +09:00
|
|
|
void snd_pcm_set_sync(struct snd_pcm_substream *substream);
|
|
|
|
int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
|
2005-04-17 07:20:36 +09:00
|
|
|
unsigned int cmd, void *arg);
|
2005-11-17 21:59:38 +09:00
|
|
|
void snd_pcm_period_elapsed(struct snd_pcm_substream *substream);
|
2017-05-25 05:36:23 +09:00
|
|
|
snd_pcm_sframes_t __snd_pcm_lib_xfer(struct snd_pcm_substream *substream,
|
2017-05-21 16:35:21 +09:00
|
|
|
void *buf, bool interleaved,
|
2017-05-25 01:23:20 +09:00
|
|
|
snd_pcm_uframes_t frames, bool in_kernel);
|
2017-05-21 16:35:21 +09:00
|
|
|
|
|
|
|
static inline snd_pcm_sframes_t
|
|
|
|
snd_pcm_lib_write(struct snd_pcm_substream *substream,
|
|
|
|
const void __user *buf, snd_pcm_uframes_t frames)
|
|
|
|
{
|
2018-07-26 06:00:54 +09:00
|
|
|
return __snd_pcm_lib_xfer(substream, (void __force *)buf, true, frames, false);
|
2017-05-21 16:35:21 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline snd_pcm_sframes_t
|
|
|
|
snd_pcm_lib_read(struct snd_pcm_substream *substream,
|
|
|
|
void __user *buf, snd_pcm_uframes_t frames)
|
|
|
|
{
|
2018-07-26 06:00:54 +09:00
|
|
|
return __snd_pcm_lib_xfer(substream, (void __force *)buf, true, frames, false);
|
2017-05-21 16:35:21 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline snd_pcm_sframes_t
|
|
|
|
snd_pcm_lib_writev(struct snd_pcm_substream *substream,
|
|
|
|
void __user **bufs, snd_pcm_uframes_t frames)
|
|
|
|
{
|
2017-05-25 01:23:20 +09:00
|
|
|
return __snd_pcm_lib_xfer(substream, (void *)bufs, false, frames, false);
|
2017-05-21 16:35:21 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline snd_pcm_sframes_t
|
|
|
|
snd_pcm_lib_readv(struct snd_pcm_substream *substream,
|
|
|
|
void __user **bufs, snd_pcm_uframes_t frames)
|
|
|
|
{
|
2017-05-25 01:23:20 +09:00
|
|
|
return __snd_pcm_lib_xfer(substream, (void *)bufs, false, frames, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline snd_pcm_sframes_t
|
|
|
|
snd_pcm_kernel_write(struct snd_pcm_substream *substream,
|
|
|
|
const void *buf, snd_pcm_uframes_t frames)
|
|
|
|
{
|
|
|
|
return __snd_pcm_lib_xfer(substream, (void *)buf, true, frames, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline snd_pcm_sframes_t
|
|
|
|
snd_pcm_kernel_read(struct snd_pcm_substream *substream,
|
|
|
|
void *buf, snd_pcm_uframes_t frames)
|
|
|
|
{
|
|
|
|
return __snd_pcm_lib_xfer(substream, buf, true, frames, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline snd_pcm_sframes_t
|
|
|
|
snd_pcm_kernel_writev(struct snd_pcm_substream *substream,
|
|
|
|
void **bufs, snd_pcm_uframes_t frames)
|
|
|
|
{
|
|
|
|
return __snd_pcm_lib_xfer(substream, bufs, false, frames, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline snd_pcm_sframes_t
|
|
|
|
snd_pcm_kernel_readv(struct snd_pcm_substream *substream,
|
|
|
|
void **bufs, snd_pcm_uframes_t frames)
|
|
|
|
{
|
|
|
|
return __snd_pcm_lib_xfer(substream, bufs, false, frames, true);
|
2017-05-21 16:35:21 +09:00
|
|
|
}
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2020-03-05 14:11:41 +09:00
|
|
|
int snd_pcm_hw_limit_rates(struct snd_pcm_hardware *hw);
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
|
|
|
|
{
|
|
|
|
return snd_pcm_hw_limit_rates(&runtime->hw);
|
|
|
|
}
|
|
|
|
|
2007-08-14 00:40:54 +09:00
|
|
|
unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate);
|
2012-06-16 00:35:28 +09:00
|
|
|
unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit);
|
2014-01-11 18:24:43 +09:00
|
|
|
unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a,
|
|
|
|
unsigned int rates_b);
|
2016-01-15 17:13:10 +09:00
|
|
|
unsigned int snd_pcm_rate_range_to_bits(unsigned int rate_min,
|
|
|
|
unsigned int rate_max);
|
2005-04-17 07:20:36 +09:00
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_set_runtime_buffer - Set the PCM runtime buffer
|
|
|
|
* @substream: PCM substream to set
|
|
|
|
* @bufp: the buffer information, NULL to clear
|
|
|
|
*
|
|
|
|
* Copy the buffer information to runtime->dma_buffer when @bufp is non-NULL.
|
|
|
|
* Otherwise it clears the current buffer information.
|
|
|
|
*/
|
2005-11-17 21:59:38 +09:00
|
|
|
static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream,
|
2005-04-17 07:20:36 +09:00
|
|
|
struct snd_dma_buffer *bufp)
|
|
|
|
{
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_runtime *runtime = substream->runtime;
|
2005-04-17 07:20:36 +09:00
|
|
|
if (bufp) {
|
|
|
|
runtime->dma_buffer_p = bufp;
|
|
|
|
runtime->dma_area = bufp->area;
|
|
|
|
runtime->dma_addr = bufp->addr;
|
|
|
|
runtime->dma_bytes = bufp->bytes;
|
|
|
|
} else {
|
|
|
|
runtime->dma_buffer_p = NULL;
|
|
|
|
runtime->dma_area = NULL;
|
|
|
|
runtime->dma_addr = 0;
|
|
|
|
runtime->dma_bytes = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
2018-04-24 21:06:08 +09:00
|
|
|
* snd_pcm_gettime - Fill the timespec64 depending on the timestamp mode
|
2014-10-30 23:02:50 +09:00
|
|
|
* @runtime: PCM runtime instance
|
2018-04-24 21:06:08 +09:00
|
|
|
* @tv: timespec64 to fill
|
2014-10-30 23:02:50 +09:00
|
|
|
*/
|
2007-12-13 18:19:42 +09:00
|
|
|
static inline void snd_pcm_gettime(struct snd_pcm_runtime *runtime,
|
2018-04-24 21:06:08 +09:00
|
|
|
struct timespec64 *tv)
|
2007-12-13 18:19:42 +09:00
|
|
|
{
|
2014-07-08 23:51:49 +09:00
|
|
|
switch (runtime->tstamp_type) {
|
|
|
|
case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC:
|
2018-04-24 21:06:08 +09:00
|
|
|
ktime_get_ts64(tv);
|
2014-07-08 23:51:49 +09:00
|
|
|
break;
|
|
|
|
case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW:
|
2018-04-24 21:06:08 +09:00
|
|
|
ktime_get_raw_ts64(tv);
|
2014-07-08 23:51:49 +09:00
|
|
|
break;
|
|
|
|
default:
|
2018-04-24 21:06:08 +09:00
|
|
|
ktime_get_real_ts64(tv);
|
2014-07-08 23:51:49 +09:00
|
|
|
break;
|
|
|
|
}
|
2007-12-13 18:19:42 +09:00
|
|
|
}
|
|
|
|
|
2005-04-17 07:20:36 +09:00
|
|
|
/*
|
|
|
|
* Memory
|
|
|
|
*/
|
|
|
|
|
2019-02-05 00:42:24 +09:00
|
|
|
void snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream);
|
|
|
|
void snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm);
|
|
|
|
void snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream,
|
2005-04-17 07:20:36 +09:00
|
|
|
int type, struct device *data,
|
|
|
|
size_t size, size_t max);
|
2019-02-05 00:42:24 +09:00
|
|
|
void snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
|
2005-04-17 07:20:36 +09:00
|
|
|
int type, void *data,
|
|
|
|
size_t size, size_t max);
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size);
|
|
|
|
int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);
|
2005-04-17 07:20:36 +09:00
|
|
|
|
ALSA: pcm: Introduce managed buffer allocation mode
This patch adds the support for the feature to automatically allocate
and free PCM buffers, so called "managed buffer allocation" mode.
It's set up via new PCM helpers, snd_pcm_set_managed_buffer() and
snd_pcm_set_managed_buffer_all(), both of which correspond to the
existing preallocator helpers, snd_pcm_lib_preallocate_pages() and
snd_pcm_lib_preallocate_pages_for_all(). When the new helper is used,
it not only performs the pre-allocation of buffers, but also it
manages to call snd_pcm_lib_malloc_pages() before the PCM hw_params
ops and snd_lib_pcm_free() after the PCM hw_free ops inside PCM core,
respectively. This allows drivers to drop the explicit calls of the
memory allocation / release functions, and it will be a good amount of
code reduction in the end of this patch series.
When the PCM substream is set to the managed buffer allocation mode,
the managed_buffer_alloc flag is set in the substream object. Since
some drivers want to know when a buffer is newly allocated or
re-allocated at hw_params callback (e.g. want to set up the additional
stuff for the given buffer only at allocation time), now PCM core
turns on buffer_changed flag when the buffer has changed.
The standard conversions to use the new API will be straightforward:
- Replace snd_pcm_lib_preallocate*() calls with the corresponding
snd_pcm_set_managed_buffer*(); the arguments should be unchanged
- Drop superfluous snd_pcm_lib_malloc() and snd_pcm_lib_free() calls;
the check of snd_pcm_lib_malloc() returns should be replaced with
the check of runtime->buffer_changed flag.
- If hw_params or hw_free becomes empty, drop them from PCM ops
Link: https://lore.kernel.org/r/20191117085308.23915-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2019-11-17 17:53:01 +09:00
|
|
|
void snd_pcm_set_managed_buffer(struct snd_pcm_substream *substream, int type,
|
|
|
|
struct device *data, size_t size, size_t max);
|
|
|
|
void snd_pcm_set_managed_buffer_all(struct snd_pcm *pcm, int type,
|
|
|
|
struct device *data,
|
|
|
|
size_t size, size_t max);
|
|
|
|
|
2009-12-18 17:29:00 +09:00
|
|
|
int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
|
|
|
|
size_t size, gfp_t gfp_flags);
|
|
|
|
int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream);
|
|
|
|
struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
|
|
|
|
unsigned long offset);
|
|
|
|
/**
|
|
|
|
* snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer
|
|
|
|
* @substream: the substream to allocate the buffer to
|
|
|
|
* @size: the requested buffer size, in bytes
|
|
|
|
*
|
|
|
|
* Allocates the PCM substream buffer using vmalloc(), i.e., the memory is
|
|
|
|
* contiguous in kernel virtual space, but not in physical memory. Use this
|
|
|
|
* if the buffer is accessed by kernel code but not by device DMA.
|
|
|
|
*
|
2013-03-12 06:05:14 +09:00
|
|
|
* Return: 1 if the buffer was changed, 0 if not changed, or a negative error
|
2009-12-18 17:29:00 +09:00
|
|
|
* code.
|
|
|
|
*/
|
2014-10-30 21:45:58 +09:00
|
|
|
static inline int snd_pcm_lib_alloc_vmalloc_buffer
|
|
|
|
(struct snd_pcm_substream *substream, size_t size)
|
|
|
|
{
|
|
|
|
return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size,
|
|
|
|
GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
|
|
|
|
}
|
|
|
|
|
2009-12-18 17:29:00 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_lib_alloc_vmalloc_32_buffer - allocate 32-bit-addressable buffer
|
|
|
|
* @substream: the substream to allocate the buffer to
|
|
|
|
* @size: the requested buffer size, in bytes
|
|
|
|
*
|
|
|
|
* This function works like snd_pcm_lib_alloc_vmalloc_buffer(), but uses
|
|
|
|
* vmalloc_32(), i.e., the pages are allocated from 32-bit-addressable memory.
|
2013-03-12 06:05:14 +09:00
|
|
|
*
|
|
|
|
* Return: 1 if the buffer was changed, 0 if not changed, or a negative error
|
|
|
|
* code.
|
2009-12-18 17:29:00 +09:00
|
|
|
*/
|
2014-10-30 21:45:58 +09:00
|
|
|
static inline int snd_pcm_lib_alloc_vmalloc_32_buffer
|
|
|
|
(struct snd_pcm_substream *substream, size_t size)
|
|
|
|
{
|
|
|
|
return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size,
|
|
|
|
GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
|
|
|
|
}
|
2009-12-18 17:29:00 +09:00
|
|
|
|
2012-09-21 12:29:12 +09:00
|
|
|
#define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p)
|
|
|
|
|
2008-06-17 23:39:06 +09:00
|
|
|
#ifdef CONFIG_SND_DMA_SGBUF
|
2008-08-21 20:00:13 +09:00
|
|
|
/*
|
|
|
|
* SG-buffer handling
|
|
|
|
*/
|
|
|
|
#define snd_pcm_substream_sgbuf(substream) \
|
2012-09-21 12:29:12 +09:00
|
|
|
snd_pcm_get_dma_buf(substream)->private_data
|
|
|
|
#endif /* SND_DMA_SGBUF */
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_sgbuf_get_addr - Get the DMA address at the corresponding offset
|
|
|
|
* @substream: PCM substream
|
|
|
|
* @ofs: byte offset
|
|
|
|
*/
|
2008-06-17 23:39:06 +09:00
|
|
|
static inline dma_addr_t
|
|
|
|
snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
|
|
|
|
{
|
2012-09-21 12:29:12 +09:00
|
|
|
return snd_sgbuf_get_addr(snd_pcm_get_dma_buf(substream), ofs);
|
2008-06-17 23:39:06 +09:00
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_sgbuf_get_ptr - Get the virtual address at the corresponding offset
|
|
|
|
* @substream: PCM substream
|
|
|
|
* @ofs: byte offset
|
|
|
|
*/
|
2008-06-17 23:39:06 +09:00
|
|
|
static inline void *
|
|
|
|
snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
|
|
|
|
{
|
2012-09-21 12:29:12 +09:00
|
|
|
return snd_sgbuf_get_ptr(snd_pcm_get_dma_buf(substream), ofs);
|
2008-06-17 23:39:06 +09:00
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
2020-10-24 01:33:35 +09:00
|
|
|
* snd_pcm_sgbuf_get_chunk_size - Compute the max size that fits within the
|
|
|
|
* contig. page from the given size
|
2014-10-30 23:02:50 +09:00
|
|
|
* @substream: PCM substream
|
|
|
|
* @ofs: byte offset
|
|
|
|
* @size: byte size to examine
|
|
|
|
*/
|
2012-09-21 12:29:12 +09:00
|
|
|
static inline unsigned int
|
|
|
|
snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
|
|
|
|
unsigned int ofs, unsigned int size)
|
|
|
|
{
|
|
|
|
return snd_sgbuf_get_chunk_size(snd_pcm_get_dma_buf(substream), ofs, size);
|
|
|
|
}
|
2008-06-17 23:39:06 +09:00
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_mmap_data_open - increase the mmap counter
|
|
|
|
* @area: VMA
|
|
|
|
*
|
|
|
|
* PCM mmap callback should handle this counter properly
|
|
|
|
*/
|
2005-04-17 07:20:36 +09:00
|
|
|
static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
|
|
|
|
{
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
|
2006-04-28 22:13:41 +09:00
|
|
|
atomic_inc(&substream->mmap_count);
|
2005-04-17 07:20:36 +09:00
|
|
|
}
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_mmap_data_close - decrease the mmap counter
|
|
|
|
* @area: VMA
|
|
|
|
*
|
|
|
|
* PCM mmap callback should handle this counter properly
|
|
|
|
*/
|
2005-04-17 07:20:36 +09:00
|
|
|
static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area)
|
|
|
|
{
|
2005-11-17 21:59:38 +09:00
|
|
|
struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
|
2006-04-28 22:13:41 +09:00
|
|
|
atomic_dec(&substream->mmap_count);
|
2005-04-17 07:20:36 +09:00
|
|
|
}
|
|
|
|
|
2011-09-29 00:12:59 +09:00
|
|
|
int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
|
|
|
|
struct vm_area_struct *area);
|
2005-04-17 07:20:36 +09:00
|
|
|
/* mmap for io-memory area */
|
|
|
|
#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA)
|
|
|
|
#define SNDRV_PCM_INFO_MMAP_IOMEM SNDRV_PCM_INFO_MMAP
|
2005-11-17 21:59:38 +09:00
|
|
|
int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_struct *area);
|
2005-04-17 07:20:36 +09:00
|
|
|
#else
|
|
|
|
#define SNDRV_PCM_INFO_MMAP_IOMEM 0
|
|
|
|
#define snd_pcm_lib_mmap_iomem NULL
|
|
|
|
#endif
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer
|
|
|
|
* @dma: DMA number
|
|
|
|
* @max: pointer to store the max size
|
|
|
|
*/
|
2005-04-17 07:20:36 +09:00
|
|
|
static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
|
|
|
|
{
|
|
|
|
*max = dma < 4 ? 64 * 1024 : 128 * 1024;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Misc
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define SNDRV_PCM_DEFAULT_CON_SPDIF (IEC958_AES0_CON_EMPHASIS_NONE|\
|
|
|
|
(IEC958_AES1_CON_ORIGINAL<<8)|\
|
|
|
|
(IEC958_AES1_CON_PCM_CODER<<8)|\
|
|
|
|
(IEC958_AES3_CON_FS_48000<<24))
|
|
|
|
|
2009-09-08 21:26:51 +09:00
|
|
|
const char *snd_pcm_format_name(snd_pcm_format_t format);
|
|
|
|
|
2012-05-24 22:26:03 +09:00
|
|
|
/**
|
2012-08-19 09:43:05 +09:00
|
|
|
* snd_pcm_stream_str - Get a string naming the direction of a stream
|
|
|
|
* @substream: the pcm substream instance
|
2013-03-12 06:05:14 +09:00
|
|
|
*
|
|
|
|
* Return: A string naming the direction of the stream.
|
2012-05-24 22:26:03 +09:00
|
|
|
*/
|
|
|
|
static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream)
|
|
|
|
{
|
|
|
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
|
|
|
return "Playback";
|
|
|
|
else
|
|
|
|
return "Capture";
|
|
|
|
}
|
|
|
|
|
2012-07-28 01:27:00 +09:00
|
|
|
/*
|
|
|
|
* PCM channel-mapping control API
|
|
|
|
*/
|
|
|
|
/* array element of channel maps */
|
|
|
|
struct snd_pcm_chmap_elem {
|
|
|
|
unsigned char channels;
|
|
|
|
unsigned char map[15];
|
|
|
|
};
|
|
|
|
|
|
|
|
/* channel map information; retrieved via snd_kcontrol_chip() */
|
|
|
|
struct snd_pcm_chmap {
|
|
|
|
struct snd_pcm *pcm; /* assigned PCM instance */
|
|
|
|
int stream; /* PLAYBACK or CAPTURE */
|
|
|
|
struct snd_kcontrol *kctl;
|
|
|
|
const struct snd_pcm_chmap_elem *chmap;
|
|
|
|
unsigned int max_channels;
|
|
|
|
unsigned int channel_mask; /* optional: active channels bitmask */
|
|
|
|
void *private_data; /* optional: private data pointer */
|
|
|
|
};
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* snd_pcm_chmap_substream - get the PCM substream assigned to the given chmap info
|
|
|
|
* @info: chmap information
|
|
|
|
* @idx: the substream number index
|
|
|
|
*/
|
2012-07-28 01:27:00 +09:00
|
|
|
static inline struct snd_pcm_substream *
|
|
|
|
snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx)
|
|
|
|
{
|
|
|
|
struct snd_pcm_substream *s;
|
|
|
|
for (s = info->pcm->streams[info->stream].substream; s; s = s->next)
|
|
|
|
if (s->number == idx)
|
|
|
|
return s;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ALSA-standard channel maps (RL/RR prior to C/LFE) */
|
|
|
|
extern const struct snd_pcm_chmap_elem snd_pcm_std_chmaps[];
|
|
|
|
/* Other world's standard channel maps (C/LFE prior to RL/RR) */
|
|
|
|
extern const struct snd_pcm_chmap_elem snd_pcm_alt_chmaps[];
|
|
|
|
|
|
|
|
/* bit masks to be passed to snd_pcm_chmap.channel_mask field */
|
|
|
|
#define SND_PCM_CHMAP_MASK_24 ((1U << 2) | (1U << 4))
|
|
|
|
#define SND_PCM_CHMAP_MASK_246 (SND_PCM_CHMAP_MASK_24 | (1U << 6))
|
|
|
|
#define SND_PCM_CHMAP_MASK_2468 (SND_PCM_CHMAP_MASK_246 | (1U << 8))
|
|
|
|
|
|
|
|
int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
|
|
|
|
const struct snd_pcm_chmap_elem *chmap,
|
|
|
|
int max_channels,
|
|
|
|
unsigned long private_value,
|
|
|
|
struct snd_pcm_chmap **info_ret);
|
|
|
|
|
2014-10-30 23:02:50 +09:00
|
|
|
/**
|
|
|
|
* pcm_format_to_bits - Strong-typed conversion of pcm_format to bitwise
|
|
|
|
* @pcm_format: PCM format
|
|
|
|
*/
|
2013-04-23 08:00:41 +09:00
|
|
|
static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format)
|
|
|
|
{
|
|
|
|
return 1ULL << (__force int) pcm_format;
|
|
|
|
}
|
|
|
|
|
2020-02-07 01:39:39 +09:00
|
|
|
/**
|
|
|
|
* pcm_for_each_format - helper to iterate for each format type
|
|
|
|
* @f: the iterator variable in snd_pcm_format_t type
|
|
|
|
*/
|
|
|
|
#define pcm_for_each_format(f) \
|
|
|
|
for ((f) = SNDRV_PCM_FORMAT_FIRST; \
|
|
|
|
(__force int)(f) <= (__force int)SNDRV_PCM_FORMAT_LAST; \
|
|
|
|
(f) = (__force snd_pcm_format_t)((__force int)(f) + 1))
|
|
|
|
|
2014-02-05 02:19:48 +09:00
|
|
|
/* printk helpers */
|
|
|
|
#define pcm_err(pcm, fmt, args...) \
|
|
|
|
dev_err((pcm)->card->dev, fmt, ##args)
|
|
|
|
#define pcm_warn(pcm, fmt, args...) \
|
|
|
|
dev_warn((pcm)->card->dev, fmt, ##args)
|
|
|
|
#define pcm_dbg(pcm, fmt, args...) \
|
|
|
|
dev_dbg((pcm)->card->dev, fmt, ##args)
|
|
|
|
|
2018-04-24 21:06:11 +09:00
|
|
|
struct snd_pcm_status64 {
|
|
|
|
snd_pcm_state_t state; /* stream state */
|
|
|
|
u8 rsvd[4];
|
|
|
|
s64 trigger_tstamp_sec; /* time when stream was started/stopped/paused */
|
|
|
|
s64 trigger_tstamp_nsec;
|
|
|
|
s64 tstamp_sec; /* reference timestamp */
|
|
|
|
s64 tstamp_nsec;
|
|
|
|
snd_pcm_uframes_t appl_ptr; /* appl ptr */
|
|
|
|
snd_pcm_uframes_t hw_ptr; /* hw ptr */
|
|
|
|
snd_pcm_sframes_t delay; /* current delay in frames */
|
|
|
|
snd_pcm_uframes_t avail; /* number of frames available */
|
|
|
|
snd_pcm_uframes_t avail_max; /* max frames available on hw since last status */
|
|
|
|
snd_pcm_uframes_t overrange; /* count of ADC (capture) overrange detections from last status */
|
|
|
|
snd_pcm_state_t suspended_state; /* suspended stream state */
|
|
|
|
__u32 audio_tstamp_data; /* needed for 64-bit alignment, used for configs/report to/from userspace */
|
|
|
|
s64 audio_tstamp_sec; /* sample counter, wall clock, PHC or on-demand sync'ed */
|
|
|
|
s64 audio_tstamp_nsec;
|
|
|
|
s64 driver_tstamp_sec; /* useful in case reference system tstamp is reported with delay */
|
|
|
|
s64 driver_tstamp_nsec;
|
|
|
|
__u32 audio_tstamp_accuracy; /* in ns units, only valid if indicated in audio_tstamp_data */
|
|
|
|
unsigned char reserved[52-4*sizeof(s64)]; /* must be filled with zero */
|
|
|
|
};
|
|
|
|
|
|
|
|
#define SNDRV_PCM_IOCTL_STATUS64 _IOR('A', 0x20, struct snd_pcm_status64)
|
|
|
|
#define SNDRV_PCM_IOCTL_STATUS_EXT64 _IOWR('A', 0x24, struct snd_pcm_status64)
|
|
|
|
|
|
|
|
struct snd_pcm_status32 {
|
2020-02-01 00:22:14 +09:00
|
|
|
snd_pcm_state_t state; /* stream state */
|
2018-04-24 21:06:11 +09:00
|
|
|
s32 trigger_tstamp_sec; /* time when stream was started/stopped/paused */
|
|
|
|
s32 trigger_tstamp_nsec;
|
|
|
|
s32 tstamp_sec; /* reference timestamp */
|
|
|
|
s32 tstamp_nsec;
|
|
|
|
u32 appl_ptr; /* appl ptr */
|
|
|
|
u32 hw_ptr; /* hw ptr */
|
|
|
|
s32 delay; /* current delay in frames */
|
|
|
|
u32 avail; /* number of frames available */
|
|
|
|
u32 avail_max; /* max frames available on hw since last status */
|
|
|
|
u32 overrange; /* count of ADC (capture) overrange detections from last status */
|
2020-02-01 00:22:14 +09:00
|
|
|
snd_pcm_state_t suspended_state; /* suspended stream state */
|
2018-04-24 21:06:11 +09:00
|
|
|
u32 audio_tstamp_data; /* needed for 64-bit alignment, used for configs/report to/from userspace */
|
|
|
|
s32 audio_tstamp_sec; /* sample counter, wall clock, PHC or on-demand sync'ed */
|
|
|
|
s32 audio_tstamp_nsec;
|
|
|
|
s32 driver_tstamp_sec; /* useful in case reference system tstamp is reported with delay */
|
|
|
|
s32 driver_tstamp_nsec;
|
|
|
|
u32 audio_tstamp_accuracy; /* in ns units, only valid if indicated in audio_tstamp_data */
|
|
|
|
unsigned char reserved[52-4*sizeof(s32)]; /* must be filled with zero */
|
|
|
|
};
|
|
|
|
|
|
|
|
#define SNDRV_PCM_IOCTL_STATUS32 _IOR('A', 0x20, struct snd_pcm_status32)
|
|
|
|
#define SNDRV_PCM_IOCTL_STATUS_EXT32 _IOWR('A', 0x24, struct snd_pcm_status32)
|
|
|
|
|
2005-04-17 07:20:36 +09:00
|
|
|
#endif /* __SOUND_PCM_H */
|