コード例 #1
0
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;
}
コード例 #2
0
static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
					 struct snd_pcm_sync_ptr32 __user *src)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	volatile struct snd_pcm_mmap_status *status;
	volatile struct snd_pcm_mmap_control *control;
	u32 sflags;
	struct snd_pcm_mmap_control scontrol;
	struct snd_pcm_mmap_status sstatus;
	snd_pcm_uframes_t boundary;
	int err;

	if (snd_BUG_ON(!runtime))
		return -EINVAL;

	if (get_user(sflags, &src->flags) ||
	    get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
	    get_user(scontrol.avail_min, &src->c.control.avail_min))
		return -EFAULT;
	if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
		err = snd_pcm_hwsync(substream);
		if (err < 0)
			return err;
	}
	status = runtime->status;
	control = runtime->control;
	boundary = recalculate_boundary(runtime);
	if (! boundary)
		boundary = 0x7fffffff;
	snd_pcm_stream_lock_irq(substream);
	/* FIXME: we should consider the boundary for the sync from app */
	if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
		control->appl_ptr = scontrol.appl_ptr;
	else
		scontrol.appl_ptr = control->appl_ptr % boundary;
	if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
		control->avail_min = scontrol.avail_min;
	else
		scontrol.avail_min = control->avail_min;
	sstatus.state = status->state;
	sstatus.hw_ptr = status->hw_ptr % boundary;
	sstatus.tstamp = status->tstamp;
	sstatus.suspended_state = status->suspended_state;
	sstatus.audio_tstamp = status->audio_tstamp;
	snd_pcm_stream_unlock_irq(substream);
	if (put_user(sstatus.state, &src->s.status.state) ||
	    put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
	    compat_put_timespec(&sstatus.tstamp, &src->s.status.tstamp) ||
	    put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
	    compat_put_timespec(&sstatus.audio_tstamp,
		    &src->s.status.audio_tstamp) ||
	    put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
	    put_user(scontrol.avail_min, &src->c.control.avail_min))
		return -EFAULT;

	return 0;
}
コード例 #3
0
ファイル: pcm32.c プロジェクト: idtek/linux-2.6.11
/* both for HW_PARAMS and HW_REFINE */
static int _snd_ioctl32_pcm_hw_params(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
    struct sndrv_pcm_hw_params32 __user *data32;
    struct sndrv_pcm_hw_params *data;
    snd_pcm_file_t *pcm_file;
    snd_pcm_substream_t *substream;
    snd_pcm_runtime_t *runtime;
    int err;

    if (sanity_check_pcm(file))
        return -ENOTTY;
    if (! (pcm_file = file->private_data))
        return -ENOTTY;
    if (! (substream = pcm_file->substream))
        return -ENOTTY;
    if (! (runtime = substream->runtime))
        return -ENOTTY;

    data32 = compat_ptr(arg);
    data = kmalloc(sizeof(*data), GFP_KERNEL);
    if (data == NULL)
        return -ENOMEM;
    if (copy_from_user(data, data32, sizeof(*data32))) {
        err = -EFAULT;
        goto error;
    }
    if (native_ctl == SNDRV_PCM_IOCTL_HW_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((u32)data->fifo_size, &data32->fifo_size)) {
        err = -EFAULT;
        goto error;
    }

    if (native_ctl == SNDRV_PCM_IOCTL_HW_PARAMS)
        recalculate_boundary(runtime);
error:
    kfree(data);
    return err;
}
コード例 #4
0
ファイル: pcm_compat.c プロジェクト: 020gzh/linux
/* 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)
		return -ENOMEM;

	/* only fifo_size (RO from userspace) 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;
}
コード例 #5
0
ファイル: pcm32.c プロジェクト: GodFox/magx_kernel_xpixl
static inline int _snd_ioctl32_pcm_hw_params(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
	struct sndrv_pcm_hw_params32 *data32;
	struct sndrv_pcm_hw_params *data;
	mm_segment_t oldseg;
	int err;

	data32 = kmalloc(sizeof(*data32), GFP_KERNEL);
	data = kmalloc(sizeof(*data), GFP_KERNEL);
	if (data32 == NULL || data == NULL) {
		err = -ENOMEM;
		goto __end;
	}
	if (copy_from_user(data32, (void __user *)arg, sizeof(*data32))) {
		err = -EFAULT;
		goto __end;
	}
	memset(data, 0, sizeof(*data));
	convert_from_32(pcm_hw_params, data, data32);
	oldseg = get_fs();
	set_fs(KERNEL_DS);
	err = file->f_op->ioctl(file->f_dentry->d_inode, file, native_ctl, (unsigned long)data);
	set_fs(oldseg);
	if (err < 0)
		goto __end;
	err = 0;
	convert_to_32(pcm_hw_params, data32, data);
	if (copy_to_user((void __user *)arg, data32, sizeof(*data32)))
		err = -EFAULT;
	else
		recalculate_boundary(file);
      __end:
      	if (data)
      		kfree(data);
      	if (data32)
      		kfree(data32);
	return err;
}
コード例 #6
0
	/* FIXME: need to check whether fop->ioctl is sane */
	if (! (pcm_file = file->private_data))
		return 0x7fffffffUL;
	if (! (substream = pcm_file->substream))
		return 0x7fffffffUL;
	if (! (runtime = substream->runtime))
		return 0x7fffffffUL;
	boundary = runtime->buffer_size;
	if (boundary == 0)
		return 0x7fffffffUL;
	while (boundary * 2 <= 0x7fffffffUL - runtime->buffer_size)
		boundary *= 2;
	return (u32)boundary;
}

DEFINE_ALSA_IOCTL1(pcm_sw_params, data.boundary = recalculate_boundary(file, data.boundary), data32.boundary = recalculate_boundary(file, data.boundary));

static inline int _snd_ioctl32_pcm_hw_params(unsigned int fd, unsigned int cmd, unsigned long arg, struct file *file, unsigned int native_ctl)
{
	struct sndrv_pcm_hw_params32 *data32;
	struct snd_pcm_hw_params *data;
	mm_segment_t oldseg;
	int err;

	data32 = kmalloc(sizeof(*data32), GFP_KERNEL);
	data = kmalloc(sizeof(*data), GFP_KERNEL);
	if (data32 == NULL || data == NULL) {
		err = -ENOMEM;
		goto __end;
	}
	if (copy_from_user(data32, (void __user *)arg, sizeof(*data32))) {