218 lines
6.2 KiB
C
218 lines
6.2 KiB
C
|
/*
|
||
|
* Copyright (C) 2013 Google, Inc.
|
||
|
*
|
||
|
* This software is licensed under the terms of the GNU General Public
|
||
|
* License version 2, as published by the Free Software Foundation, and
|
||
|
* may be copied, distributed, and modified under those terms.
|
||
|
*
|
||
|
* 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.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <linux/uaccess.h>
|
||
|
#include <video/adf.h>
|
||
|
|
||
|
#include "adf_fops.h"
|
||
|
#include "adf_fops32.h"
|
||
|
|
||
|
long adf_compat_post_config(struct file *file,
|
||
|
struct adf_post_config32 __user *arg)
|
||
|
{
|
||
|
struct adf_post_config32 cfg32;
|
||
|
struct adf_post_config __user *cfg;
|
||
|
int ret;
|
||
|
|
||
|
if (copy_from_user(&cfg32, arg, sizeof(cfg32)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
cfg = compat_alloc_user_space(sizeof(*cfg));
|
||
|
if (!access_ok(VERIFY_WRITE, cfg, sizeof(*cfg)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
if (put_user(cfg32.n_interfaces, &cfg->n_interfaces) ||
|
||
|
put_user(compat_ptr(cfg32.interfaces),
|
||
|
&cfg->interfaces) ||
|
||
|
put_user(cfg32.n_bufs, &cfg->n_bufs) ||
|
||
|
put_user(compat_ptr(cfg32.bufs), &cfg->bufs) ||
|
||
|
put_user(cfg32.custom_data_size,
|
||
|
&cfg->custom_data_size) ||
|
||
|
put_user(compat_ptr(cfg32.custom_data),
|
||
|
&cfg->custom_data))
|
||
|
return -EFAULT;
|
||
|
|
||
|
ret = adf_file_ioctl(file, ADF_POST_CONFIG, (unsigned long)cfg);
|
||
|
if (ret < 0)
|
||
|
return ret;
|
||
|
|
||
|
if (copy_in_user(&arg->complete_fence, &cfg->complete_fence,
|
||
|
sizeof(cfg->complete_fence)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
long adf_compat_get_device_data(struct file *file,
|
||
|
struct adf_device_data32 __user *arg)
|
||
|
{
|
||
|
struct adf_device_data32 data32;
|
||
|
struct adf_device_data __user *data;
|
||
|
int ret;
|
||
|
|
||
|
if (copy_from_user(&data32, arg, sizeof(data32)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
data = compat_alloc_user_space(sizeof(*data));
|
||
|
if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
if (put_user(data32.n_attachments, &data->n_attachments) ||
|
||
|
put_user(compat_ptr(data32.attachments),
|
||
|
&data->attachments) ||
|
||
|
put_user(data32.n_allowed_attachments,
|
||
|
&data->n_allowed_attachments) ||
|
||
|
put_user(compat_ptr(data32.allowed_attachments),
|
||
|
&data->allowed_attachments) ||
|
||
|
put_user(data32.custom_data_size,
|
||
|
&data->custom_data_size) ||
|
||
|
put_user(compat_ptr(data32.custom_data),
|
||
|
&data->custom_data))
|
||
|
return -EFAULT;
|
||
|
|
||
|
ret = adf_file_ioctl(file, ADF_GET_DEVICE_DATA, (unsigned long)data);
|
||
|
if (ret < 0)
|
||
|
return ret;
|
||
|
|
||
|
if (copy_in_user(arg->name, data->name, sizeof(arg->name)) ||
|
||
|
copy_in_user(&arg->n_attachments, &data->n_attachments,
|
||
|
sizeof(arg->n_attachments)) ||
|
||
|
copy_in_user(&arg->n_allowed_attachments,
|
||
|
&data->n_allowed_attachments,
|
||
|
sizeof(arg->n_allowed_attachments)) ||
|
||
|
copy_in_user(&arg->custom_data_size,
|
||
|
&data->custom_data_size,
|
||
|
sizeof(arg->custom_data_size)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
long adf_compat_get_interface_data(struct file *file,
|
||
|
struct adf_interface_data32 __user *arg)
|
||
|
{
|
||
|
struct adf_interface_data32 data32;
|
||
|
struct adf_interface_data __user *data;
|
||
|
int ret;
|
||
|
|
||
|
if (copy_from_user(&data32, arg, sizeof(data32)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
data = compat_alloc_user_space(sizeof(*data));
|
||
|
if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
if (put_user(data32.n_available_modes, &data->n_available_modes) ||
|
||
|
put_user(compat_ptr(data32.available_modes),
|
||
|
&data->available_modes) ||
|
||
|
put_user(data32.custom_data_size,
|
||
|
&data->custom_data_size) ||
|
||
|
put_user(compat_ptr(data32.custom_data),
|
||
|
&data->custom_data))
|
||
|
return -EFAULT;
|
||
|
|
||
|
ret = adf_file_ioctl(file, ADF_GET_INTERFACE_DATA, (unsigned long)data);
|
||
|
if (ret < 0)
|
||
|
return ret;
|
||
|
|
||
|
if (copy_in_user(arg->name, data->name, sizeof(arg->name)) ||
|
||
|
copy_in_user(&arg->type, &data->type,
|
||
|
sizeof(arg->type)) ||
|
||
|
copy_in_user(&arg->id, &data->id, sizeof(arg->id)) ||
|
||
|
copy_in_user(&arg->flags, &data->flags,
|
||
|
sizeof(arg->flags)) ||
|
||
|
copy_in_user(&arg->dpms_state, &data->dpms_state,
|
||
|
sizeof(arg->dpms_state)) ||
|
||
|
copy_in_user(&arg->hotplug_detect,
|
||
|
&data->hotplug_detect,
|
||
|
sizeof(arg->hotplug_detect)) ||
|
||
|
copy_in_user(&arg->width_mm, &data->width_mm,
|
||
|
sizeof(arg->width_mm)) ||
|
||
|
copy_in_user(&arg->height_mm, &data->height_mm,
|
||
|
sizeof(arg->height_mm)) ||
|
||
|
copy_in_user(&arg->current_mode, &data->current_mode,
|
||
|
sizeof(arg->current_mode)) ||
|
||
|
copy_in_user(&arg->n_available_modes,
|
||
|
&data->n_available_modes,
|
||
|
sizeof(arg->n_available_modes)) ||
|
||
|
copy_in_user(&arg->custom_data_size,
|
||
|
&data->custom_data_size,
|
||
|
sizeof(arg->custom_data_size)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
long adf_compat_get_overlay_engine_data(struct file *file,
|
||
|
struct adf_overlay_engine_data32 __user *arg)
|
||
|
{
|
||
|
struct adf_overlay_engine_data32 data32;
|
||
|
struct adf_overlay_engine_data __user *data;
|
||
|
int ret;
|
||
|
|
||
|
if (copy_from_user(&data32, arg, sizeof(data32)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
data = compat_alloc_user_space(sizeof(*data));
|
||
|
if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
if (put_user(data32.n_supported_formats, &data->n_supported_formats) ||
|
||
|
put_user(compat_ptr(data32.supported_formats),
|
||
|
&data->supported_formats) ||
|
||
|
put_user(data32.custom_data_size,
|
||
|
&data->custom_data_size) ||
|
||
|
put_user(compat_ptr(data32.custom_data),
|
||
|
&data->custom_data))
|
||
|
return -EFAULT;
|
||
|
|
||
|
ret = adf_file_ioctl(file, ADF_GET_OVERLAY_ENGINE_DATA,
|
||
|
(unsigned long)data);
|
||
|
if (ret < 0)
|
||
|
return ret;
|
||
|
|
||
|
if (copy_in_user(arg->name, data->name, sizeof(arg->name)) ||
|
||
|
copy_in_user(&arg->n_supported_formats,
|
||
|
&data->n_supported_formats,
|
||
|
sizeof(arg->n_supported_formats)) ||
|
||
|
copy_in_user(&arg->custom_data_size,
|
||
|
&data->custom_data_size,
|
||
|
sizeof(arg->custom_data_size)))
|
||
|
return -EFAULT;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
long adf_file_compat_ioctl(struct file *file, unsigned int cmd,
|
||
|
unsigned long arg)
|
||
|
{
|
||
|
switch (cmd) {
|
||
|
case ADF_POST_CONFIG32:
|
||
|
return adf_compat_post_config(file, compat_ptr(arg));
|
||
|
|
||
|
case ADF_GET_DEVICE_DATA32:
|
||
|
return adf_compat_get_device_data(file, compat_ptr(arg));
|
||
|
|
||
|
case ADF_GET_INTERFACE_DATA32:
|
||
|
return adf_compat_get_interface_data(file, compat_ptr(arg));
|
||
|
|
||
|
case ADF_GET_OVERLAY_ENGINE_DATA32:
|
||
|
return adf_compat_get_overlay_engine_data(file,
|
||
|
compat_ptr(arg));
|
||
|
|
||
|
default:
|
||
|
return adf_file_ioctl(file, cmd, arg);
|
||
|
}
|
||
|
}
|