Merge tag 'pci-v3.15-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaa...
[deliverable/linux.git] / drivers / staging / android / ion / compat_ion.c
1 /*
2 * drivers/staging/android/ion/compat_ion.c
3 *
4 * Copyright (C) 2013 Google, Inc.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17 #include <linux/compat.h>
18 #include <linux/fs.h>
19 #include <linux/uaccess.h>
20
21 #include "ion.h"
22 #include "compat_ion.h"
23
24 /* See drivers/staging/android/uapi/ion.h for the definition of these structs */
25 struct compat_ion_allocation_data {
26 compat_size_t len;
27 compat_size_t align;
28 compat_uint_t heap_id_mask;
29 compat_uint_t flags;
30 compat_int_t handle;
31 };
32
33 struct compat_ion_custom_data {
34 compat_uint_t cmd;
35 compat_ulong_t arg;
36 };
37
38 struct compat_ion_handle_data {
39 compat_int_t handle;
40 };
41
42 #define COMPAT_ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \
43 struct compat_ion_allocation_data)
44 #define COMPAT_ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, \
45 struct compat_ion_handle_data)
46 #define COMPAT_ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, \
47 struct compat_ion_custom_data)
48
49 static int compat_get_ion_allocation_data(
50 struct compat_ion_allocation_data __user *data32,
51 struct ion_allocation_data __user *data)
52 {
53 compat_size_t s;
54 compat_uint_t u;
55 compat_int_t i;
56 int err;
57
58 err = get_user(s, &data32->len);
59 err |= put_user(s, &data->len);
60 err |= get_user(s, &data32->align);
61 err |= put_user(s, &data->align);
62 err |= get_user(u, &data32->heap_id_mask);
63 err |= put_user(u, &data->heap_id_mask);
64 err |= get_user(u, &data32->flags);
65 err |= put_user(u, &data->flags);
66 err |= get_user(i, &data32->handle);
67 err |= put_user(i, &data->handle);
68
69 return err;
70 }
71
72 static int compat_get_ion_handle_data(
73 struct compat_ion_handle_data __user *data32,
74 struct ion_handle_data __user *data)
75 {
76 compat_int_t i;
77 int err;
78
79 err = get_user(i, &data32->handle);
80 err |= put_user(i, &data->handle);
81
82 return err;
83 }
84
85 static int compat_put_ion_allocation_data(
86 struct compat_ion_allocation_data __user *data32,
87 struct ion_allocation_data __user *data)
88 {
89 compat_size_t s;
90 compat_uint_t u;
91 compat_int_t i;
92 int err;
93
94 err = get_user(s, &data->len);
95 err |= put_user(s, &data32->len);
96 err |= get_user(s, &data->align);
97 err |= put_user(s, &data32->align);
98 err |= get_user(u, &data->heap_id_mask);
99 err |= put_user(u, &data32->heap_id_mask);
100 err |= get_user(u, &data->flags);
101 err |= put_user(u, &data32->flags);
102 err |= get_user(i, &data->handle);
103 err |= put_user(i, &data32->handle);
104
105 return err;
106 }
107
108 static int compat_get_ion_custom_data(
109 struct compat_ion_custom_data __user *data32,
110 struct ion_custom_data __user *data)
111 {
112 compat_uint_t cmd;
113 compat_ulong_t arg;
114 int err;
115
116 err = get_user(cmd, &data32->cmd);
117 err |= put_user(cmd, &data->cmd);
118 err |= get_user(arg, &data32->arg);
119 err |= put_user(arg, &data->arg);
120
121 return err;
122 };
123
124 long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
125 {
126 long ret;
127
128 if (!filp->f_op || !filp->f_op->unlocked_ioctl)
129 return -ENOTTY;
130
131 switch (cmd) {
132 case COMPAT_ION_IOC_ALLOC:
133 {
134 struct compat_ion_allocation_data __user *data32;
135 struct ion_allocation_data __user *data;
136 int err;
137
138 data32 = compat_ptr(arg);
139 data = compat_alloc_user_space(sizeof(*data));
140 if (data == NULL)
141 return -EFAULT;
142
143 err = compat_get_ion_allocation_data(data32, data);
144 if (err)
145 return err;
146 ret = filp->f_op->unlocked_ioctl(filp, ION_IOC_ALLOC,
147 (unsigned long)data);
148 err = compat_put_ion_allocation_data(data32, data);
149 return ret ? ret : err;
150 }
151 case COMPAT_ION_IOC_FREE:
152 {
153 struct compat_ion_handle_data __user *data32;
154 struct ion_handle_data __user *data;
155 int err;
156
157 data32 = compat_ptr(arg);
158 data = compat_alloc_user_space(sizeof(*data));
159 if (data == NULL)
160 return -EFAULT;
161
162 err = compat_get_ion_handle_data(data32, data);
163 if (err)
164 return err;
165
166 return filp->f_op->unlocked_ioctl(filp, ION_IOC_FREE,
167 (unsigned long)data);
168 }
169 case COMPAT_ION_IOC_CUSTOM: {
170 struct compat_ion_custom_data __user *data32;
171 struct ion_custom_data __user *data;
172 int err;
173
174 data32 = compat_ptr(arg);
175 data = compat_alloc_user_space(sizeof(*data));
176 if (data == NULL)
177 return -EFAULT;
178
179 err = compat_get_ion_custom_data(data32, data);
180 if (err)
181 return err;
182
183 return filp->f_op->unlocked_ioctl(filp, ION_IOC_CUSTOM,
184 (unsigned long)data);
185 }
186 case ION_IOC_SHARE:
187 case ION_IOC_MAP:
188 case ION_IOC_IMPORT:
189 case ION_IOC_SYNC:
190 return filp->f_op->unlocked_ioctl(filp, cmd,
191 (unsigned long)compat_ptr(arg));
192 default:
193 return -ENOIOCTLCMD;
194 }
195 }
This page took 0.040281 seconds and 5 git commands to generate.