2 * drivers/staging/android/ion/compat_ion.c
4 * Copyright (C) 2013 Google, Inc.
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.
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.
17 #include <linux/compat.h>
19 #include <linux/uaccess.h>
22 #include "compat_ion.h"
24 /* See drivers/staging/android/uapi/ion.h for the definition of these structs */
25 struct compat_ion_allocation_data
{
28 compat_uint_t heap_id_mask
;
33 struct compat_ion_custom_data
{
38 struct compat_ion_handle_data
{
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)
49 static int compat_get_ion_allocation_data(
50 struct compat_ion_allocation_data __user
*data32
,
51 struct ion_allocation_data __user
*data
)
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
);
72 static int compat_get_ion_handle_data(
73 struct compat_ion_handle_data __user
*data32
,
74 struct ion_handle_data __user
*data
)
79 err
= get_user(i
, &data32
->handle
);
80 err
|= put_user(i
, &data
->handle
);
85 static int compat_put_ion_allocation_data(
86 struct compat_ion_allocation_data __user
*data32
,
87 struct ion_allocation_data __user
*data
)
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
);
108 static int compat_get_ion_custom_data(
109 struct compat_ion_custom_data __user
*data32
,
110 struct ion_custom_data __user
*data
)
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
);
124 long compat_ion_ioctl(struct file
*filp
, unsigned int cmd
, unsigned long arg
)
128 if (!filp
->f_op
|| !filp
->f_op
->unlocked_ioctl
)
132 case COMPAT_ION_IOC_ALLOC
:
134 struct compat_ion_allocation_data __user
*data32
;
135 struct ion_allocation_data __user
*data
;
138 data32
= compat_ptr(arg
);
139 data
= compat_alloc_user_space(sizeof(*data
));
143 err
= compat_get_ion_allocation_data(data32
, data
);
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
;
151 case COMPAT_ION_IOC_FREE
:
153 struct compat_ion_handle_data __user
*data32
;
154 struct ion_handle_data __user
*data
;
157 data32
= compat_ptr(arg
);
158 data
= compat_alloc_user_space(sizeof(*data
));
162 err
= compat_get_ion_handle_data(data32
, data
);
166 return filp
->f_op
->unlocked_ioctl(filp
, ION_IOC_FREE
,
167 (unsigned long)data
);
169 case COMPAT_ION_IOC_CUSTOM
: {
170 struct compat_ion_custom_data __user
*data32
;
171 struct ion_custom_data __user
*data
;
174 data32
= compat_ptr(arg
);
175 data
= compat_alloc_user_space(sizeof(*data
));
179 err
= compat_get_ion_custom_data(data32
, data
);
183 return filp
->f_op
->unlocked_ioctl(filp
, ION_IOC_CUSTOM
,
184 (unsigned long)data
);
190 return filp
->f_op
->unlocked_ioctl(filp
, cmd
,
191 (unsigned long)compat_ptr(arg
));