sound/core/oss/pcm_plugin.c

Source file repositories/reference/linux-study-clean/sound/core/oss/pcm_plugin.c

File Facts

System
Linux kernel
Corpus path
sound/core/oss/pcm_plugin.c
Extension
.c
Size
21538 bytes
Lines
767
Domain
Driver Families
Bucket
sound/core
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

while (plugin->next) {
			if (plugin->dst_frames)
				frames = plugin->dst_frames(plugin, frames);
			if ((snd_pcm_sframes_t)frames <= 0)
				return -ENXIO;
			plugin = plugin->next;
			err = snd_pcm_plugin_alloc(plugin, frames);
			if (err < 0)
				return err;
		}
	} else {
		struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
		while (plugin->prev) {
			if (plugin->src_frames)
				frames = plugin->src_frames(plugin, frames);
			if ((snd_pcm_sframes_t)frames <= 0)
				return -ENXIO;
			plugin = plugin->prev;
			err = snd_pcm_plugin_alloc(plugin, frames);
			if (err < 0)
				return err;
		}
	}
	return 0;
}


snd_pcm_sframes_t snd_pcm_plugin_client_channels(struct snd_pcm_plugin *plugin,
				       snd_pcm_uframes_t frames,
				       struct snd_pcm_plugin_channel **channels)
{
	*channels = plugin->buf_channels;
	return frames;
}

int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
			 const char *name,
			 struct snd_pcm_plugin_format *src_format,
			 struct snd_pcm_plugin_format *dst_format,
			 size_t extra,
			 struct snd_pcm_plugin **ret)
{
	struct snd_pcm_plugin *plugin;
	unsigned int channels;
	
	if (snd_BUG_ON(!plug))
		return -ENXIO;
	if (snd_BUG_ON(!src_format || !dst_format))
		return -ENXIO;
	plugin = kzalloc_flex(*plugin, extra_data, extra);
	if (plugin == NULL)
		return -ENOMEM;
	plugin->name = name;
	plugin->plug = plug;
	plugin->stream = snd_pcm_plug_stream(plug);
	plugin->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
	plugin->src_format = *src_format;
	plugin->src_width = snd_pcm_format_physical_width(src_format->format);
	snd_BUG_ON(plugin->src_width <= 0);
	plugin->dst_format = *dst_format;
	plugin->dst_width = snd_pcm_format_physical_width(dst_format->format);
	snd_BUG_ON(plugin->dst_width <= 0);
	if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK)
		channels = src_format->channels;
	else
		channels = dst_format->channels;
	plugin->buf_channels = kzalloc_objs(*plugin->buf_channels, channels);
	if (plugin->buf_channels == NULL) {
		snd_pcm_plugin_free(plugin);
		return -ENOMEM;
	}
	plugin->client_channels = snd_pcm_plugin_client_channels;
	*ret = plugin;
	return 0;
}

int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin)
{
	if (! plugin)
		return 0;
	if (plugin->private_free)
		plugin->private_free(plugin);
	kfree(plugin->buf_channels);
	kvfree(plugin->buf);
	kfree(plugin);
	return 0;
}

static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug,
					 snd_pcm_sframes_t frames,

Annotation

Implementation Notes