]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/android/ion/compat_ion.c
staging: android: ion: Remove duplicate ION_IOC_MAP
[karo-tx-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_handle_data {
34         compat_int_t handle;
35 };
36
37 #define COMPAT_ION_IOC_ALLOC    _IOWR(ION_IOC_MAGIC, 0, \
38                                       struct compat_ion_allocation_data)
39 #define COMPAT_ION_IOC_FREE     _IOWR(ION_IOC_MAGIC, 1, \
40                                       struct compat_ion_handle_data)
41
42 static int compat_get_ion_allocation_data(
43                         struct compat_ion_allocation_data __user *data32,
44                         struct ion_allocation_data __user *data)
45 {
46         compat_size_t s;
47         compat_uint_t u;
48         compat_int_t i;
49         int err;
50
51         err = get_user(s, &data32->len);
52         err |= put_user(s, &data->len);
53         err |= get_user(s, &data32->align);
54         err |= put_user(s, &data->align);
55         err |= get_user(u, &data32->heap_id_mask);
56         err |= put_user(u, &data->heap_id_mask);
57         err |= get_user(u, &data32->flags);
58         err |= put_user(u, &data->flags);
59         err |= get_user(i, &data32->handle);
60         err |= put_user(i, &data->handle);
61
62         return err;
63 }
64
65 static int compat_get_ion_handle_data(
66                         struct compat_ion_handle_data __user *data32,
67                         struct ion_handle_data __user *data)
68 {
69         compat_int_t i;
70         int err;
71
72         err = get_user(i, &data32->handle);
73         err |= put_user(i, &data->handle);
74
75         return err;
76 }
77
78 static int compat_put_ion_allocation_data(
79                         struct compat_ion_allocation_data __user *data32,
80                         struct ion_allocation_data __user *data)
81 {
82         compat_size_t s;
83         compat_uint_t u;
84         compat_int_t i;
85         int err;
86
87         err = get_user(s, &data->len);
88         err |= put_user(s, &data32->len);
89         err |= get_user(s, &data->align);
90         err |= put_user(s, &data32->align);
91         err |= get_user(u, &data->heap_id_mask);
92         err |= put_user(u, &data32->heap_id_mask);
93         err |= get_user(u, &data->flags);
94         err |= put_user(u, &data32->flags);
95         err |= get_user(i, &data->handle);
96         err |= put_user(i, &data32->handle);
97
98         return err;
99 }
100
101 long compat_ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
102 {
103         long ret;
104
105         if (!filp->f_op->unlocked_ioctl)
106                 return -ENOTTY;
107
108         switch (cmd) {
109         case COMPAT_ION_IOC_ALLOC:
110         {
111                 struct compat_ion_allocation_data __user *data32;
112                 struct ion_allocation_data __user *data;
113                 int err;
114
115                 data32 = compat_ptr(arg);
116                 data = compat_alloc_user_space(sizeof(*data));
117                 if (!data)
118                         return -EFAULT;
119
120                 err = compat_get_ion_allocation_data(data32, data);
121                 if (err)
122                         return err;
123                 ret = filp->f_op->unlocked_ioctl(filp, ION_IOC_ALLOC,
124                                                         (unsigned long)data);
125                 err = compat_put_ion_allocation_data(data32, data);
126                 return ret ? ret : err;
127         }
128         case COMPAT_ION_IOC_FREE:
129         {
130                 struct compat_ion_handle_data __user *data32;
131                 struct ion_handle_data __user *data;
132                 int err;
133
134                 data32 = compat_ptr(arg);
135                 data = compat_alloc_user_space(sizeof(*data));
136                 if (!data)
137                         return -EFAULT;
138
139                 err = compat_get_ion_handle_data(data32, data);
140                 if (err)
141                         return err;
142
143                 return filp->f_op->unlocked_ioctl(filp, ION_IOC_FREE,
144                                                         (unsigned long)data);
145         }
146         case ION_IOC_SHARE:
147                 return filp->f_op->unlocked_ioctl(filp, cmd,
148                                                 (unsigned long)compat_ptr(arg));
149         default:
150                 return -ENOIOCTLCMD;
151         }
152 }