1 /*
2 * ion.c
3 *
4 * Memory Allocator functions for ion
5 *
6 * Copyright 2011 Google, Inc
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <sys/ioctl.h>
24 #include <sys/mman.h>
25 #include <sys/types.h>
26
27 #define LOG_TAG "ion"
28 #include <cutils/log.h>
29
30 #include "linux_ion.h"
31 #include "omap_ion.h"
32 #include "ion.h"
33
ion_open()34 int ion_open()
35 {
36 int fd = open("/dev/ion", O_RDWR);
37 if (fd < 0)
38 ALOGE("open /dev/ion failed!\n");
39 return fd;
40 }
41
ion_close(int fd)42 int ion_close(int fd)
43 {
44 return close(fd);
45 }
46
ion_ioctl(int fd,int req,void * arg)47 static int ion_ioctl(int fd, int req, void *arg)
48 {
49 int ret = ioctl(fd, req, arg);
50 if (ret < 0) {
51 ALOGE("ioctl %d failed with code %d: %s\n", req,
52 ret, strerror(errno));
53 return -errno;
54 }
55 return ret;
56 }
57
ion_alloc(int fd,size_t len,size_t align,unsigned int flags,struct ion_handle ** handle)58 int ion_alloc(int fd, size_t len, size_t align, unsigned int flags,
59 struct ion_handle **handle)
60 {
61 int ret;
62 struct ion_allocation_data data = {
63 .len = len,
64 .align = align,
65 .flags = flags,
66 };
67
68 ret = ion_ioctl(fd, ION_IOC_ALLOC, &data);
69 if (ret < 0)
70 return ret;
71 *handle = data.handle;
72 return ret;
73 }
74
ion_alloc_tiler(int fd,size_t w,size_t h,int fmt,unsigned int flags,struct ion_handle ** handle,size_t * stride)75 int ion_alloc_tiler(int fd, size_t w, size_t h, int fmt, unsigned int flags,
76 struct ion_handle **handle, size_t *stride)
77 {
78 int ret;
79 struct omap_ion_tiler_alloc_data alloc_data = {
80 .w = w,
81 .h = h,
82 .fmt = fmt,
83 .flags = flags,
84 };
85
86 struct ion_custom_data custom_data = {
87 .cmd = OMAP_ION_TILER_ALLOC,
88 .arg = (unsigned long)(&alloc_data),
89 };
90
91 ret = ion_ioctl(fd, ION_IOC_CUSTOM, &custom_data);
92 if (ret < 0)
93 return ret;
94 *stride = alloc_data.stride;
95 *handle = alloc_data.handle;
96 return ret;
97 }
98
ion_free(int fd,struct ion_handle * handle)99 int ion_free(int fd, struct ion_handle *handle)
100 {
101 struct ion_handle_data data = {
102 .handle = handle,
103 };
104 return ion_ioctl(fd, ION_IOC_FREE, &data);
105 }
106
ion_map(int fd,struct ion_handle * handle,size_t length,int prot,int flags,off_t offset,unsigned char ** ptr,int * map_fd)107 int ion_map(int fd, struct ion_handle *handle, size_t length, int prot,
108 int flags, off_t offset, unsigned char **ptr, int *map_fd)
109 {
110 struct ion_fd_data data = {
111 .handle = handle,
112 };
113 int ret = ion_ioctl(fd, ION_IOC_MAP, &data);
114 if (ret < 0)
115 return ret;
116 *map_fd = data.fd;
117 if (*map_fd < 0) {
118 ALOGE("map ioctl returned negative fd\n");
119 return -EINVAL;
120 }
121 *ptr = mmap(NULL, length, prot, flags, *map_fd, offset);
122 if (*ptr == MAP_FAILED) {
123 ALOGE("mmap failed: %s\n", strerror(errno));
124 return -errno;
125 }
126 return ret;
127 }
128
ion_share(int fd,struct ion_handle * handle,int * share_fd)129 int ion_share(int fd, struct ion_handle *handle, int *share_fd)
130 {
131 int map_fd;
132 struct ion_fd_data data = {
133 .handle = handle,
134 };
135 int ret = ion_ioctl(fd, ION_IOC_SHARE, &data);
136 if (ret < 0)
137 return ret;
138 *share_fd = data.fd;
139 if (*share_fd < 0) {
140 ALOGE("map ioctl returned negative fd\n");
141 return -EINVAL;
142 }
143 return ret;
144 }
145
ion_import(int fd,int share_fd,struct ion_handle ** handle)146 int ion_import(int fd, int share_fd, struct ion_handle **handle)
147 {
148 struct ion_fd_data data = {
149 .fd = share_fd,
150 };
151 int ret = ion_ioctl(fd, ION_IOC_IMPORT, &data);
152 if (ret < 0)
153 return ret;
154 *handle = data.handle;
155 return ret;
156 }
157