⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcm_compat.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *   32bit -> 64bit ioctl wrapper for PCM API *   Copyright (c) by Takashi Iwai <tiwai@suse.de> * *   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 * *//* This file included from pcm_native.c */#include <linux/compat.h>static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,				      s32 __user *src){	snd_pcm_sframes_t delay;	mm_segment_t fs;	int err;	fs = snd_enter_user();	err = snd_pcm_delay(substream, &delay);	snd_leave_user(fs);	if (err < 0)		return err;	if (put_user(delay, src))		return -EFAULT;	return err;}static int snd_pcm_ioctl_rewind_compat(struct snd_pcm_substream *substream,				       u32 __user *src){	snd_pcm_uframes_t frames;	int err;	if (get_user(frames, src))		return -EFAULT;	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)		err = snd_pcm_playback_rewind(substream, frames);	else		err = snd_pcm_capture_rewind(substream, frames);	if (put_user(err, src))		return -EFAULT;	return err < 0 ? err : 0;}static int snd_pcm_ioctl_forward_compat(struct snd_pcm_substream *substream,				       u32 __user *src){	snd_pcm_uframes_t frames;	int err;	if (get_user(frames, src))		return -EFAULT;	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)		err = snd_pcm_playback_forward(substream, frames);	else		err = snd_pcm_capture_forward(substream, frames);	if (put_user(err, src))		return -EFAULT;	return err < 0 ? err : 0;}struct snd_pcm_hw_params32 {	u32 flags;	struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; /* this must be identical */	struct snd_mask mres[5];	/* reserved masks */	struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];	struct snd_interval ires[9];	/* reserved intervals */	u32 rmask;	u32 cmask;	u32 info;	u32 msbits;	u32 rate_num;	u32 rate_den;	u32 fifo_size;	unsigned char reserved[64];};struct snd_pcm_sw_params32 {	s32 tstamp_mode;	u32 period_step;	u32 sleep_min;	u32 avail_min;	u32 xfer_align;	u32 start_threshold;	u32 stop_threshold;	u32 silence_threshold;	u32 silence_size;	u32 boundary;	unsigned char reserved[64];};/* recalcuate the boundary within 32bit */static snd_pcm_uframes_t recalculate_boundary(struct snd_pcm_runtime *runtime){	snd_pcm_uframes_t boundary;	if (! runtime->buffer_size)		return 0;	boundary = runtime->buffer_size;	while (boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)		boundary *= 2;	return boundary;}static int snd_pcm_ioctl_sw_params_compat(struct snd_pcm_substream *substream,					  struct snd_pcm_sw_params32 __user *src){	struct snd_pcm_sw_params params;	snd_pcm_uframes_t boundary;	int err;	memset(&params, 0, sizeof(params));	if (get_user(params.tstamp_mode, &src->tstamp_mode) ||	    get_user(params.period_step, &src->period_step) ||	    get_user(params.sleep_min, &src->sleep_min) ||	    get_user(params.avail_min, &src->avail_min) ||	    get_user(params.xfer_align, &src->xfer_align) ||	    get_user(params.start_threshold, &src->start_threshold) ||	    get_user(params.stop_threshold, &src->stop_threshold) ||	    get_user(params.silence_threshold, &src->silence_threshold) ||	    get_user(params.silence_size, &src->silence_size))		return -EFAULT;	/*	 * Check silent_size parameter.  Since we have 64bit boundary,	 * silence_size must be compared with the 32bit boundary.	 */	boundary = recalculate_boundary(substream->runtime);	if (boundary && params.silence_size >= boundary)		params.silence_size = substream->runtime->boundary;	err = snd_pcm_sw_params(substream, &params);	if (err < 0)		return err;	if (boundary && put_user(boundary, &src->boundary))		return -EFAULT;	return err;}struct snd_pcm_channel_info32 {	u32 channel;	u32 offset;	u32 first;	u32 step;};static int snd_pcm_ioctl_channel_info_compat(struct snd_pcm_substream *substream,					     struct snd_pcm_channel_info32 __user *src){	struct snd_pcm_channel_info info;	int err;	if (get_user(info.channel, &src->channel) ||	    get_user(info.offset, &src->offset) ||	    get_user(info.first, &src->first) ||	    get_user(info.step, &src->step))		return -EFAULT;	err = snd_pcm_channel_info(substream, &info);	if (err < 0)		return err;	if (put_user(info.channel, &src->channel) ||	    put_user(info.offset, &src->offset) ||	    put_user(info.first, &src->first) ||	    put_user(info.step, &src->step))		return -EFAULT;	return err;}struct snd_pcm_status32 {	s32 state;	struct compat_timespec trigger_tstamp;	struct compat_timespec tstamp;	u32 appl_ptr;	u32 hw_ptr;	s32 delay;	u32 avail;	u32 avail_max;	u32 overrange;	s32 suspended_state;	unsigned char reserved[60];} __attribute__((packed));static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,				      struct snd_pcm_status32 __user *src){	struct snd_pcm_status status;	int err;	err = snd_pcm_status(substream, &status);	if (err < 0)		return err;	if (put_user(status.state, &src->state) ||	    put_user(status.trigger_tstamp.tv_sec, &src->trigger_tstamp.tv_sec) ||	    put_user(status.trigger_tstamp.tv_nsec, &src->trigger_tstamp.tv_nsec) ||	    put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) ||	    put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) ||	    put_user(status.appl_ptr, &src->appl_ptr) ||	    put_user(status.hw_ptr, &src->hw_ptr) ||	    put_user(status.delay, &src->delay) ||	    put_user(status.avail, &src->avail) ||	    put_user(status.avail_max, &src->avail_max) ||	    put_user(status.overrange, &src->overrange) ||	    put_user(status.suspended_state, &src->suspended_state))		return -EFAULT;	return err;}/* both for HW_PARAMS and HW_REFINE */static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,					  int refine, 					  struct snd_pcm_hw_params32 __user *data32){	struct snd_pcm_hw_params *data;	struct snd_pcm_runtime *runtime;	int err;	if (! (runtime = substream->runtime))		return -ENOTTY;	data = kmalloc(sizeof(*data), GFP_KERNEL);	if (data == NULL)		return -ENOMEM;	/* only fifo_size is different, so just copy all */	if (copy_from_user(data, data32, sizeof(*data32))) {		err = -EFAULT;		goto error;	}	if (refine)		err = snd_pcm_hw_refine(substream, data);	else		err = snd_pcm_hw_params(substream, data);	if (err < 0)		goto error;	if (copy_to_user(data32, data, sizeof(*data32)) ||	    put_user(data->fifo_size, &data32->fifo_size)) {		err = -EFAULT;		goto error;	}	if (! refine) {		unsigned int new_boundary = recalculate_boundary(runtime);		if (new_boundary)			runtime->boundary = new_boundary;	} error:	kfree(data);	return err;}/* */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -