cregit-Linux how code gets into the kernel

Release 4.8 sound/drivers/dummy.c

Directory: sound/drivers
/*
 *  Dummy soundcard
 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/hrtimer.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/tlv.h>
#include <sound/pcm.h>
#include <sound/rawmidi.h>
#include <sound/info.h>
#include <sound/initval.h>

MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Dummy soundcard (/dev/null)");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");


#define MAX_PCM_DEVICES		4

#define MAX_PCM_SUBSTREAMS	128

#define MAX_MIDI_DEVICES	2

/* defaults */

#define MAX_BUFFER_SIZE		(64*1024)

#define MIN_PERIOD_SIZE		64

#define MAX_PERIOD_SIZE		MAX_BUFFER_SIZE

#define USE_FORMATS 		(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)

#define USE_RATE		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000

#define USE_RATE_MIN		5500

#define USE_RATE_MAX		48000

#define USE_CHANNELS_MIN 	1

#define USE_CHANNELS_MAX 	2

#define USE_PERIODS_MIN 	1

#define USE_PERIODS_MAX 	1024


static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	
/* Index 0-MAX */

static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	
/* ID for this card */

static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};

static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL};

static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};

static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
#ifdef CONFIG_HIGH_RES_TIMERS

static bool hrtimer = 1;
#endif

static bool fake_buffer = 1;

module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for dummy soundcard.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for dummy soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
module_param_array(model, charp, NULL, 0444);
MODULE_PARM_DESC(model, "Soundcard model.");
module_param_array(pcm_devs, int, NULL, 0444);
MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
module_param_array(pcm_substreams, int, NULL, 0444);
MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
//module_param_array(midi_devs, int, NULL, 0444);
//MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
module_param(fake_buffer, bool, 0444);
MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations.");
#ifdef CONFIG_HIGH_RES_TIMERS
module_param(hrtimer, bool, 0644);
MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source.");
#endif


static struct platform_device *devices[SNDRV_CARDS];


#define MIXER_ADDR_MASTER	0

#define MIXER_ADDR_LINE		1

#define MIXER_ADDR_MIC		2

#define MIXER_ADDR_SYNTH	3

#define MIXER_ADDR_CD		4

#define MIXER_ADDR_LAST		4


struct dummy_timer_ops {
	
int (*create)(struct snd_pcm_substream *);
	
void (*free)(struct snd_pcm_substream *);
	
int (*prepare)(struct snd_pcm_substream *);
	
int (*start)(struct snd_pcm_substream *);
	
int (*stop)(struct snd_pcm_substream *);
	
snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
};


#define get_dummy_ops(substream) \
	(*(const struct dummy_timer_ops **)(substream)->runtime->private_data)


struct dummy_model {
	
const char *name;
	
int (*playback_constraints)(struct snd_pcm_runtime *runtime);
	
int (*capture_constraints)(struct snd_pcm_runtime *runtime);
	
u64 formats;
	
size_t buffer_bytes_max;
	
size_t period_bytes_min;
	
size_t period_bytes_max;
	
unsigned int periods_min;
	
unsigned int periods_max;
	
unsigned int rates;
	
unsigned int rate_min;
	
unsigned int rate_max;
	
unsigned int channels_min;
	
unsigned int channels_max;
};


struct snd_dummy {
	
struct snd_card *card;
	
struct dummy_model *model;
	
struct snd_pcm *pcm;
	
struct snd_pcm_hardware pcm_hw;
	
spinlock_t mixer_lock;
	
int mixer_volume[MIXER_ADDR_LAST+1][2];
	
int capture_source[MIXER_ADDR_LAST+1][2];
	
int iobox;
	
struct snd_kcontrol *cd_volume_ctl;
	
struct snd_kcontrol *cd_switch_ctl;
};

/*
 * card models
 */


static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime) { int err; err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (err < 0) return err; err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX); if (err < 0) return err; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela57100.00%1100.00%
Total57100.00%1100.00%

static struct dummy_model model_emu10k1 = { .name = "emu10k1", .playback_constraints = emu10k1_playback_constraints, .buffer_bytes_max = 128 * 1024, }; static struct dummy_model model_rme9652 = { .name = "rme9652", .buffer_bytes_max = 26 * 64 * 1024, .formats = SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 26, .channels_max = 26, .periods_min = 2, .periods_max = 2, }; static struct dummy_model model_ice1712 = { .name = "ice1712", .buffer_bytes_max = 256 * 1024, .formats = SNDRV_PCM_FMTBIT_S32_LE, .channels_min = 10, .channels_max = 10, .periods_min = 1, .periods_max = 1024, }; static struct dummy_model model_uda1341 = { .name = "uda1341", .buffer_bytes_max = 16380, .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels_min = 2, .channels_max = 2, .periods_min = 2, .periods_max = 255, }; static struct dummy_model model_ac97 = { .name = "ac97", .formats = SNDRV_PCM_FMTBIT_S16_LE, .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_48000, .rate_min = 48000, .rate_max = 48000, }; static struct dummy_model model_ca0106 = { .name = "ca0106", .formats = SNDRV_PCM_FMTBIT_S16_LE, .buffer_bytes_max = ((65536-64)*8), .period_bytes_max = (65536-64), .periods_min = 2, .periods_max = 8, .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000, .rate_min = 48000, .rate_max = 192000, }; static struct dummy_model *dummy_models[] = { &model_emu10k1, &model_rme9652, &model_ice1712, &model_uda1341, &model_ac97, &model_ca0106, NULL }; /* * system timer interface */ struct dummy_systimer_pcm { /* ops must be the first item */ const struct dummy_timer_ops *timer_ops; spinlock_t lock; struct timer_list timer; unsigned long base_time; unsigned int frac_pos; /* fractional sample position (based HZ) */ unsigned int frac_period_rest; unsigned int frac_buffer_size; /* buffer_size * HZ */ unsigned int frac_period_size; /* period_size * HZ */ unsigned int rate; int elapsed; struct snd_pcm_substream *substream; };
static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm) { mod_timer(&dpcm->timer, jiffies + (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate); }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai3389.19%266.67%
roman kollarroman kollar410.81%133.33%
Total37100.00%3100.00%


static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm) { unsigned long delta; delta = jiffies - dpcm->base_time; if (!delta) return; dpcm->base_time += delta; delta *= dpcm->rate; dpcm->frac_pos += delta; while (dpcm->frac_pos >= dpcm->frac_buffer_size) dpcm->frac_pos -= dpcm->frac_buffer_size; while (dpcm->frac_period_rest <= delta) { dpcm->elapsed++; dpcm->frac_period_rest += dpcm->frac_period_size; } dpcm->frac_period_rest -= delta; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai94100.00%2100.00%
Total94100.00%2100.00%


static int dummy_systimer_start(struct snd_pcm_substream *substream) { struct dummy_systimer_pcm *dpcm = substream->runtime->private_data; spin_lock(&dpcm->lock); dpcm->base_time = jiffies; dummy_systimer_rearm(dpcm); spin_unlock(&dpcm->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai4076.92%480.00%
jaroslav kyselajaroslav kysela1223.08%120.00%
Total52100.00%5100.00%


static int dummy_systimer_stop(struct snd_pcm_substream *substream) { struct dummy_systimer_pcm *dpcm = substream->runtime->private_data; spin_lock(&dpcm->lock); del_timer(&dpcm->timer); spin_unlock(&dpcm->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela2755.10%233.33%
takashi iwaitakashi iwai2244.90%466.67%
Total49100.00%6100.00%


static int dummy_systimer_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct dummy_systimer_pcm *dpcm = runtime->private_data; dpcm->frac_pos = 0; dpcm->rate = runtime->rate; dpcm->frac_buffer_size = runtime->buffer_size * HZ; dpcm->frac_period_size = runtime->period_size * HZ; dpcm->frac_period_rest = dpcm->frac_period_size; dpcm->elapsed = 0; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela4353.75%233.33%
takashi iwaitakashi iwai3746.25%466.67%
Total80100.00%6100.00%


static void dummy_systimer_callback(unsigned long data) { struct dummy_systimer_pcm *dpcm = (struct dummy_systimer_pcm *)data; unsigned long flags; int elapsed = 0; spin_lock_irqsave(&dpcm->lock, flags); dummy_systimer_update(dpcm); dummy_systimer_rearm(dpcm); elapsed = dpcm->elapsed; dpcm->elapsed = 0; spin_unlock_irqrestore(&dpcm->lock, flags); if (elapsed) snd_pcm_period_elapsed(dpcm->substream); }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai5464.29%675.00%
jaroslav kyselajaroslav kysela3035.71%225.00%
Total84100.00%8100.00%


static snd_pcm_uframes_t dummy_systimer_pointer(struct snd_pcm_substream *substream) { struct dummy_systimer_pcm *dpcm = substream->runtime->private_data; snd_pcm_uframes_t pos; spin_lock(&dpcm->lock); dummy_systimer_update(dpcm); pos = dpcm->frac_pos / HZ; spin_unlock(&dpcm->lock); return pos; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai3561.40%457.14%
jaroslav kyselajaroslav kysela2035.09%228.57%
ahmet inanahmet inan23.51%114.29%
Total57100.00%7100.00%


static int dummy_systimer_create(struct snd_pcm_substream *substream) { struct dummy_systimer_pcm *dpcm; dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); if (!dpcm) return -ENOMEM; substream->runtime->private_data = dpcm; setup_timer(&dpcm->timer, dummy_systimer_callback, (unsigned long) dpcm); spin_lock_init(&dpcm->lock); dpcm->substream = substream; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai7189.87%240.00%
roman kollarroman kollar56.33%120.00%
jaroslav kyselajaroslav kysela33.80%240.00%
Total79100.00%5100.00%


static void dummy_systimer_free(struct snd_pcm_substream *substream) { kfree(substream->runtime->private_data); }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai20100.00%1100.00%
Total20100.00%1100.00%

static const struct dummy_timer_ops dummy_systimer_ops = { .create = dummy_systimer_create, .free = dummy_systimer_free, .prepare = dummy_systimer_prepare, .start = dummy_systimer_start, .stop = dummy_systimer_stop, .pointer = dummy_systimer_pointer, }; #ifdef CONFIG_HIGH_RES_TIMERS /* * hrtimer interface */ struct dummy_hrtimer_pcm { /* ops must be the first item */ const struct dummy_timer_ops *timer_ops; ktime_t base_time; ktime_t period_time; atomic_t running; struct hrtimer timer; struct tasklet_struct tasklet; struct snd_pcm_substream *substream; };
static void dummy_hrtimer_pcm_elapsed(unsigned long priv) { struct dummy_hrtimer_pcm *dpcm = (struct dummy_hrtimer_pcm *)priv; if (atomic_read(&dpcm->running)) snd_pcm_period_elapsed(dpcm->substream); }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai39100.00%1100.00%
Total39100.00%1100.00%


static enum hrtimer_restart dummy_hrtimer_callback(struct hrtimer *timer) { struct dummy_hrtimer_pcm *dpcm; dpcm = container_of(timer, struct dummy_hrtimer_pcm, timer); if (!atomic_read(&dpcm->running)) return HRTIMER_NORESTART; tasklet_schedule(&dpcm->tasklet); hrtimer_forward_now(timer, dpcm->period_time); return HRTIMER_RESTART; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai63100.00%1100.00%
Total63100.00%1100.00%


static int dummy_hrtimer_start(struct snd_pcm_substream *substream) { struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data; dpcm->base_time = hrtimer_cb_get_time(&dpcm->timer); hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL); atomic_set(&dpcm->running, 1); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai61100.00%1100.00%
Total61100.00%1100.00%


static int dummy_hrtimer_stop(struct snd_pcm_substream *substream) { struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data; atomic_set(&dpcm->running, 0); hrtimer_cancel(&dpcm->timer); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai43100.00%1100.00%
Total43100.00%1100.00%


static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm) { hrtimer_cancel(&dpcm->timer); tasklet_kill(&dpcm->tasklet); }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai28100.00%2100.00%
Total28100.00%2100.00%


static snd_pcm_uframes_t dummy_hrtimer_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct dummy_hrtimer_pcm *dpcm = runtime->private_data; u64 delta; u32 pos; delta = ktime_us_delta(hrtimer_cb_get_time(&dpcm->timer), dpcm->base_time); delta = div_u64(delta * runtime->rate + 999999, 1000000); div_u64_rem(delta, runtime->buffer_size, &pos); return pos; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai82100.00%1100.00%
Total82100.00%1100.00%


static int dummy_hrtimer_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct dummy_hrtimer_pcm *dpcm = runtime->private_data; unsigned int period, rate; long sec; unsigned long nsecs; dummy_hrtimer_sync(dpcm); period = runtime->period_size; rate = runtime->rate; sec = period / rate; period %= rate; nsecs = div_u64((u64)period * 1000000000UL + rate - 1, rate); dpcm->period_time = ktime_set(sec, nsecs); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai101100.00%1100.00%
Total101100.00%1100.00%


static int dummy_hrtimer_create(struct snd_pcm_substream *substream) { struct dummy_hrtimer_pcm *dpcm; dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); if (!dpcm) return -ENOMEM; substream->runtime->private_data = dpcm; hrtimer_init(&dpcm->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); dpcm->timer.function = dummy_hrtimer_callback; dpcm->substream = substream; atomic_set(&dpcm->running, 0); tasklet_init(&dpcm->tasklet, dummy_hrtimer_pcm_elapsed, (unsigned long)dpcm); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai101100.00%1100.00%
Total101100.00%1100.00%


static void dummy_hrtimer_free(struct snd_pcm_substream *substream) { struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data; dummy_hrtimer_sync(dpcm); kfree(dpcm); }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai32100.00%1100.00%
Total32100.00%1100.00%

static const struct dummy_timer_ops dummy_hrtimer_ops = { .create = dummy_hrtimer_create, .free = dummy_hrtimer_free, .prepare = dummy_hrtimer_prepare, .start = dummy_hrtimer_start, .stop = dummy_hrtimer_stop, .pointer = dummy_hrtimer_pointer, }; #endif /* CONFIG_HIGH_RES_TIMERS */ /* * PCM interface */
static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: return get_dummy_ops(substream)->start(substream); case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: return get_dummy_ops(substream)->stop(substream); } return -EINVAL; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai58100.00%2100.00%
Total58100.00%2100.00%


static int dummy_pcm_prepare(struct snd_pcm_substream *substream) { return get_dummy_ops(substream)->prepare(substream); }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai22100.00%2100.00%
Total22100.00%2100.00%


static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream) { return get_dummy_ops(substream)->pointer(substream); }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai22100.00%2100.00%
Total22100.00%2100.00%

static struct snd_pcm_hardware dummy_pcm_hardware = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID), .formats = USE_FORMATS, .rates = USE_RATE, .rate_min = USE_RATE_MIN, .rate_max = USE_RATE_MAX, .channels_min = USE_CHANNELS_MIN, .channels_max = USE_CHANNELS_MAX, .buffer_bytes_max = MAX_BUFFER_SIZE, .period_bytes_min = MIN_PERIOD_SIZE, .period_bytes_max = MAX_PERIOD_SIZE, .periods_min = USE_PERIODS_MIN, .periods_max = USE_PERIODS_MAX, .fifo_size = 0, };
static int dummy_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { if (fake_buffer) { /* runtime->dma_bytes has to be set manually to allow mmap */ substream->runtime->dma_bytes = params_buffer_bytes(hw_params); return 0; } return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai2654.17%375.00%
jaroslav kyselajaroslav kysela2245.83%125.00%
Total48100.00%4100.00%


static int dummy_pcm_hw_free(struct snd_pcm_substream *substream) { if (fake_buffer) return 0; return snd_pcm_lib_free_pages(substream); }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai1354.17%480.00%
jaroslav kyselajaroslav kysela1145.83%120.00%
Total24100.00%5100.00%


static int dummy_pcm_open(struct snd_pcm_substream *substream) { struct snd_dummy *dummy = snd_pcm_substream_chip(substream); struct dummy_model *model = dummy->model; struct snd_pcm_runtime *runtime = substream->runtime; const struct dummy_timer_ops *ops; int err; ops = &dummy_systimer_ops; #ifdef CONFIG_HIGH_RES_TIMERS if (hrtimer) ops = &dummy_hrtimer_ops; #endif err = ops->create(substream); if (err < 0) return err; get_dummy_ops(substream) = ops; runtime->hw = dummy->pcm_hw; if (substream->pcm->device & 1) { runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED; runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED; } if (substream->pcm->device & 2) runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID); if (model == NULL) return 0; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (model->playback_constraints) err = model->playback_constraints(substream->runtime); } else { if (model->capture_constraints) err = model->capture_constraints(substream->runtime); } if (err < 0) { get_dummy_ops(substream)->free(substream); return err; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
jaroslav kyselajaroslav kysela13959.91%450.00%
takashi iwaitakashi iwai9340.09%450.00%
Total232100.00%8100.00%


static int dummy_pcm_close(struct snd_pcm_substream *substream) { get_dummy_ops(substream)->free(substream); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai1250.00%375.00%
jaroslav kyselajaroslav kysela1250.00%125.00%
Total24100.00%4100.00%

/* * dummy buffer handling */ static void *dummy_page[2];
static void free_fake_buffer(void) { if (fake_buffer) { int i; for (i = 0; i < 2; i++) if (dummy_page[i]) { free_page((unsigned long)dummy_page[i]); dummy_page[i] = NULL; } } }

Contributors

PersonTokensPropCommitsCommitProp
takashi iwaitakashi iwai58100.00%1100.00%
Total58100.00%1100.00%


static int alloc_fake_buffer(void) { int i; if (!fake_buffer) return 0; for (i = 0; i < 2; i++) { dummy_page[i] = (void *)get_zeroed_page(GFP_KERNEL);