1/* 2 * Copyright (C) 2013 Google, Inc. 3 * 4 * This software is licensed under the terms of the GNU General Public 5 * License version 2, as published by the Free Software Foundation, and 6 * may be copied, distributed, and modified under those terms. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 */ 14 15#include <linux/uaccess.h> 16#include <video/adf.h> 17 18#include "adf_fops.h" 19#include "adf_fops32.h" 20 21long adf_compat_post_config(struct file *file, 22 struct adf_post_config32 __user *arg) 23{ 24 struct adf_post_config32 cfg32; 25 struct adf_post_config __user *cfg; 26 int ret; 27 28 if (copy_from_user(&cfg32, arg, sizeof(cfg32))) 29 return -EFAULT; 30 31 cfg = compat_alloc_user_space(sizeof(*cfg)); 32 if (!access_ok(VERIFY_WRITE, cfg, sizeof(*cfg))) 33 return -EFAULT; 34 35 if (put_user(cfg32.n_interfaces, &cfg->n_interfaces) || 36 put_user(compat_ptr(cfg32.interfaces), 37 &cfg->interfaces) || 38 put_user(cfg32.n_bufs, &cfg->n_bufs) || 39 put_user(compat_ptr(cfg32.bufs), &cfg->bufs) || 40 put_user(cfg32.custom_data_size, 41 &cfg->custom_data_size) || 42 put_user(compat_ptr(cfg32.custom_data), 43 &cfg->custom_data)) 44 return -EFAULT; 45 46 ret = adf_file_ioctl(file, ADF_POST_CONFIG, (unsigned long)cfg); 47 if (ret < 0) 48 return ret; 49 50 if (copy_in_user(&arg->complete_fence, &cfg->complete_fence, 51 sizeof(cfg->complete_fence))) 52 return -EFAULT; 53 54 return 0; 55} 56 57long adf_compat_get_device_data(struct file *file, 58 struct adf_device_data32 __user *arg) 59{ 60 struct adf_device_data32 data32; 61 struct adf_device_data __user *data; 62 int ret; 63 64 if (copy_from_user(&data32, arg, sizeof(data32))) 65 return -EFAULT; 66 67 data = compat_alloc_user_space(sizeof(*data)); 68 if (!access_ok(VERIFY_WRITE, data, sizeof(*data))) 69 return -EFAULT; 70 71 if (put_user(data32.n_attachments, &data->n_attachments) || 72 put_user(compat_ptr(data32.attachments), 73 &data->attachments) || 74 put_user(data32.n_allowed_attachments, 75 &data->n_allowed_attachments) || 76 put_user(compat_ptr(data32.allowed_attachments), 77 &data->allowed_attachments) || 78 put_user(data32.custom_data_size, 79 &data->custom_data_size) || 80 put_user(compat_ptr(data32.custom_data), 81 &data->custom_data)) 82 return -EFAULT; 83 84 ret = adf_file_ioctl(file, ADF_GET_DEVICE_DATA, (unsigned long)data); 85 if (ret < 0) 86 return ret; 87 88 if (copy_in_user(arg->name, data->name, sizeof(arg->name)) || 89 copy_in_user(&arg->n_attachments, &data->n_attachments, 90 sizeof(arg->n_attachments)) || 91 copy_in_user(&arg->n_allowed_attachments, 92 &data->n_allowed_attachments, 93 sizeof(arg->n_allowed_attachments)) || 94 copy_in_user(&arg->custom_data_size, 95 &data->custom_data_size, 96 sizeof(arg->custom_data_size))) 97 return -EFAULT; 98 99 return 0; 100} 101 102long adf_compat_get_interface_data(struct file *file, 103 struct adf_interface_data32 __user *arg) 104{ 105 struct adf_interface_data32 data32; 106 struct adf_interface_data __user *data; 107 int ret; 108 109 if (copy_from_user(&data32, arg, sizeof(data32))) 110 return -EFAULT; 111 112 data = compat_alloc_user_space(sizeof(*data)); 113 if (!access_ok(VERIFY_WRITE, data, sizeof(*data))) 114 return -EFAULT; 115 116 if (put_user(data32.n_available_modes, &data->n_available_modes) || 117 put_user(compat_ptr(data32.available_modes), 118 &data->available_modes) || 119 put_user(data32.custom_data_size, 120 &data->custom_data_size) || 121 put_user(compat_ptr(data32.custom_data), 122 &data->custom_data)) 123 return -EFAULT; 124 125 ret = adf_file_ioctl(file, ADF_GET_INTERFACE_DATA, (unsigned long)data); 126 if (ret < 0) 127 return ret; 128 129 if (copy_in_user(arg->name, data->name, sizeof(arg->name)) || 130 copy_in_user(&arg->type, &data->type, 131 sizeof(arg->type)) || 132 copy_in_user(&arg->id, &data->id, sizeof(arg->id)) || 133 copy_in_user(&arg->flags, &data->flags, 134 sizeof(arg->flags)) || 135 copy_in_user(&arg->dpms_state, &data->dpms_state, 136 sizeof(arg->dpms_state)) || 137 copy_in_user(&arg->hotplug_detect, 138 &data->hotplug_detect, 139 sizeof(arg->hotplug_detect)) || 140 copy_in_user(&arg->width_mm, &data->width_mm, 141 sizeof(arg->width_mm)) || 142 copy_in_user(&arg->height_mm, &data->height_mm, 143 sizeof(arg->height_mm)) || 144 copy_in_user(&arg->current_mode, &data->current_mode, 145 sizeof(arg->current_mode)) || 146 copy_in_user(&arg->n_available_modes, 147 &data->n_available_modes, 148 sizeof(arg->n_available_modes)) || 149 copy_in_user(&arg->custom_data_size, 150 &data->custom_data_size, 151 sizeof(arg->custom_data_size))) 152 return -EFAULT; 153 154 return 0; 155} 156 157long adf_compat_get_overlay_engine_data(struct file *file, 158 struct adf_overlay_engine_data32 __user *arg) 159{ 160 struct adf_overlay_engine_data32 data32; 161 struct adf_overlay_engine_data __user *data; 162 int ret; 163 164 if (copy_from_user(&data32, arg, sizeof(data32))) 165 return -EFAULT; 166 167 data = compat_alloc_user_space(sizeof(*data)); 168 if (!access_ok(VERIFY_WRITE, data, sizeof(*data))) 169 return -EFAULT; 170 171 if (put_user(data32.n_supported_formats, &data->n_supported_formats) || 172 put_user(compat_ptr(data32.supported_formats), 173 &data->supported_formats) || 174 put_user(data32.custom_data_size, 175 &data->custom_data_size) || 176 put_user(compat_ptr(data32.custom_data), 177 &data->custom_data)) 178 return -EFAULT; 179 180 ret = adf_file_ioctl(file, ADF_GET_OVERLAY_ENGINE_DATA, 181 (unsigned long)data); 182 if (ret < 0) 183 return ret; 184 185 if (copy_in_user(arg->name, data->name, sizeof(arg->name)) || 186 copy_in_user(&arg->n_supported_formats, 187 &data->n_supported_formats, 188 sizeof(arg->n_supported_formats)) || 189 copy_in_user(&arg->custom_data_size, 190 &data->custom_data_size, 191 sizeof(arg->custom_data_size))) 192 return -EFAULT; 193 194 return 0; 195} 196 197long adf_file_compat_ioctl(struct file *file, unsigned int cmd, 198 unsigned long arg) 199{ 200 switch (cmd) { 201 case ADF_POST_CONFIG32: 202 return adf_compat_post_config(file, compat_ptr(arg)); 203 204 case ADF_GET_DEVICE_DATA32: 205 return adf_compat_get_device_data(file, compat_ptr(arg)); 206 207 case ADF_GET_INTERFACE_DATA32: 208 return adf_compat_get_interface_data(file, compat_ptr(arg)); 209 210 case ADF_GET_OVERLAY_ENGINE_DATA32: 211 return adf_compat_get_overlay_engine_data(file, 212 compat_ptr(arg)); 213 214 default: 215 return adf_file_ioctl(file, cmd, arg); 216 } 217} 218