On Fri, 30 Sep 2016 14:43:27 +0200, Subhransu S. Prusty wrote: > > From: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx> > > Report size of data burst before updating the hw_ptr, e.g. while DMA > operations are on-going. > > This can help fix two issues with stale data discussed many times over > on the alsa-devel mailing list (refilling/reading ring buffer too late > during capture or rewinding too close to the hw_ptr during playback) > > This patch only reports the maximum burst of data and does not provide > hooks to negotiate its size. This might be useful to lower power or > reduce latency, but isn't typically supported by fixed-function DMA > hardware. This needs to be discussed rather from the actual demand. From the API change POV, the only (and the biggest) question is whether hw_params is the best API. It looks feasible, so far, but someone else might have a better idea. Let's see. Takashi > > The use of IOCTL1 is not really required but keep for symmetry with > existing code used to retried fifo_size > > Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@xxxxxxxxxxxxxxx> > Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@xxxxxxxxx> > --- > include/sound/pcm.h | 2 ++ > include/uapi/sound/asound.h | 5 +++-- > sound/core/pcm_lib.c | 20 ++++++++++++++++++++ > sound/core/pcm_native.c | 7 +++++++ > 4 files changed, 32 insertions(+), 2 deletions(-) > > diff --git a/include/sound/pcm.h b/include/sound/pcm.h > index 1accb8b..8c9d80a 100644 > --- a/include/sound/pcm.h > +++ b/include/sound/pcm.h > @@ -56,6 +56,7 @@ struct snd_pcm_hardware { > unsigned int periods_min; /* min # of periods */ > unsigned int periods_max; /* max # of periods */ > size_t fifo_size; /* fifo size in bytes */ > + unsigned int max_inflight_bytes;/* hw_ptr precision/fuzziness, e.g. due to DMA transfers */ > }; > > struct snd_pcm_substream; > @@ -105,6 +106,7 @@ struct snd_pcm_ops { > #define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2 > #define SNDRV_PCM_IOCTL1_GSTATE 3 > #define SNDRV_PCM_IOCTL1_FIFO_SIZE 4 > +#define SNDRV_PCM_IOCTL1_MAX_INFLIGHT_BYTES 5 > > #define SNDRV_PCM_TRIGGER_STOP 0 > #define SNDRV_PCM_TRIGGER_START 1 > diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h > index 6828ed2..5f539d7 100644 > --- a/include/uapi/sound/asound.h > +++ b/include/uapi/sound/asound.h > @@ -392,8 +392,9 @@ struct snd_pcm_hw_params { > unsigned int msbits; /* R: used most significant bits */ > unsigned int rate_num; /* R: rate numerator */ > unsigned int rate_den; /* R: rate denominator */ > - snd_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames */ > - unsigned char reserved[64]; /* reserved for future */ > + snd_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames, indicates buffering after hw_ptr updates */ > + unsigned int max_inflight_bytes;/* R: typically DMA burst in bytes, indicates buffering before hw_ptr updates */ > + unsigned char reserved[60]; /* reserved for future */ > }; > > enum { > diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c > index 1656ca9..06b44ed 100644 > --- a/sound/core/pcm_lib.c > +++ b/sound/core/pcm_lib.c > @@ -1827,6 +1827,23 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream, > return 0; > } > > +static int snd_pcm_lib_ioctl_max_inflight_bytes( > + struct snd_pcm_substream *substream, > + void *arg) > +{ > + struct snd_pcm_hw_params *params = arg; > + > + params->max_inflight_bytes = substream->runtime->hw.max_inflight_bytes; > + /* > + * Sanity check that max_inflight_bytes isn't larger than buffer_size, > + * couldn't think of any other checks > + */ > + if (params->max_inflight_bytes > substream->runtime->buffer_size) > + params->max_inflight_bytes = substream->runtime->buffer_size; > + > + return 0; > +} > + > /** > * snd_pcm_lib_ioctl - a generic PCM ioctl callback > * @substream: the pcm substream instance > @@ -1850,6 +1867,9 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream, > return snd_pcm_lib_ioctl_channel_info(substream, arg); > case SNDRV_PCM_IOCTL1_FIFO_SIZE: > return snd_pcm_lib_ioctl_fifo_size(substream, arg); > + case SNDRV_PCM_IOCTL1_MAX_INFLIGHT_BYTES: > + return snd_pcm_lib_ioctl_max_inflight_bytes(substream, arg); > + > } > return -ENXIO; > } > diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c > index 1965d83..a29b5af 100644 > --- a/sound/core/pcm_native.c > +++ b/sound/core/pcm_native.c > @@ -292,6 +292,7 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, > > params->info = 0; > params->fifo_size = 0; > + params->max_inflight_bytes = 0; > if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_SAMPLE_BITS)) > params->msbits = 0; > if (params->rmask & (1 << SNDRV_PCM_HW_PARAM_RATE)) { > @@ -449,6 +450,12 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, > return changed; > } > } > + if (!params->max_inflight_bytes) { > + changed = substream->ops->ioctl(substream, > + SNDRV_PCM_IOCTL1_MAX_INFLIGHT_BYTES, params); > + if (changed < 0) > + return changed; > + } > params->rmask = 0; > return 0; > } > -- > 1.9.1 > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel