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