14a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin/*
24a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *  ion.c
34a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *
44a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin * Memory Allocator functions for ion
54a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *
64a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *   Copyright 2011 Google, Inc
74a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *
84a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *  Licensed under the Apache License, Version 2.0 (the "License");
94a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *  you may not use this file except in compliance with the License.
104a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *  You may obtain a copy of the License at
114a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *
124a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *      http://www.apache.org/licenses/LICENSE-2.0
134a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *
144a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *  Unless required by applicable law or agreed to in writing, software
154a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *  distributed under the License is distributed on an "AS IS" BASIS,
164a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
174a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *  See the License for the specific language governing permissions and
184a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin *  limitations under the License.
194a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin */
204a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin#include <errno.h>
214a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin#include <fcntl.h>
224a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin#include <stdio.h>
234a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin#include <sys/ioctl.h>
244a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin#include <sys/mman.h>
254a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin#include <sys/types.h>
264a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
274a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin#define LOG_TAG "ion"
284a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin#include <cutils/log.h>
294a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
3080fba10a860e6c7900367a6a9dfd9bbbe5ef2cd2Rebecca Schultz Zavin#include "linux_ion.h"
3180fba10a860e6c7900367a6a9dfd9bbbe5ef2cd2Rebecca Schultz Zavin#include "omap_ion.h"
324a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin#include "ion.h"
334a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
344a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavinint ion_open()
354a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin{
364a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        int fd = open("/dev/ion", O_RDWR);
374a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        if (fd < 0)
384a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                ALOGE("open /dev/ion failed!\n");
394a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        return fd;
404a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin}
414a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
424a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavinint ion_close(int fd)
434a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin{
444a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        return close(fd);
454a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin}
464a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
474a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavinstatic int ion_ioctl(int fd, int req, void *arg)
484a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin{
494a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        int ret = ioctl(fd, req, arg);
504a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        if (ret < 0) {
514a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                ALOGE("ioctl %d failed with code %d: %s\n", req,
524a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                       ret, strerror(errno));
534a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                return -errno;
544a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        }
554a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        return ret;
564a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin}
574a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
584a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavinint ion_alloc(int fd, size_t len, size_t align, unsigned int flags,
594a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin              struct ion_handle **handle)
604a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin{
614a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        int ret;
624a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        struct ion_allocation_data data = {
634a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .len = len,
644a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .align = align,
654a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .flags = flags,
664a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        };
674a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
684a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        ret = ion_ioctl(fd, ION_IOC_ALLOC, &data);
694a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        if (ret < 0)
704a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                return ret;
714a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        *handle = data.handle;
724a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        return ret;
734a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin}
744a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
754a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavinint ion_alloc_tiler(int fd, size_t w, size_t h, int fmt, unsigned int flags,
764a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin            struct ion_handle **handle, size_t *stride)
774a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin{
784a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        int ret;
794a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        struct omap_ion_tiler_alloc_data alloc_data = {
804a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .w = w,
814a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .h = h,
824a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .fmt = fmt,
834a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .flags = flags,
844a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        };
854a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
864a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        struct ion_custom_data custom_data = {
874a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .cmd = OMAP_ION_TILER_ALLOC,
884a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .arg = (unsigned long)(&alloc_data),
894a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        };
904a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
914a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        ret = ion_ioctl(fd, ION_IOC_CUSTOM, &custom_data);
924a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        if (ret < 0)
934a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                return ret;
944a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        *stride = alloc_data.stride;
954a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        *handle = alloc_data.handle;
964a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        return ret;
974a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin}
984a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
994a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavinint ion_free(int fd, struct ion_handle *handle)
1004a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin{
1014a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        struct ion_handle_data data = {
1024a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .handle = handle,
1034a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        };
1044a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        return ion_ioctl(fd, ION_IOC_FREE, &data);
1054a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin}
1064a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
1074a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavinint ion_map(int fd, struct ion_handle *handle, size_t length, int prot,
1084a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin            int flags, off_t offset, unsigned char **ptr, int *map_fd)
1094a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin{
1104a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        struct ion_fd_data data = {
1114a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .handle = handle,
1124a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        };
1134a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        int ret = ion_ioctl(fd, ION_IOC_MAP, &data);
1144a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        if (ret < 0)
1154a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                return ret;
1164a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        *map_fd = data.fd;
1174a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        if (*map_fd < 0) {
1184a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                ALOGE("map ioctl returned negative fd\n");
1194a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                return -EINVAL;
1204a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        }
1214a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        *ptr = mmap(NULL, length, prot, flags, *map_fd, offset);
1224a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        if (*ptr == MAP_FAILED) {
1234a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                ALOGE("mmap failed: %s\n", strerror(errno));
1244a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                return -errno;
1254a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        }
1264a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        return ret;
1274a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin}
1284a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
1294a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavinint ion_share(int fd, struct ion_handle *handle, int *share_fd)
1304a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin{
1314a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        int map_fd;
1324a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        struct ion_fd_data data = {
1334a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .handle = handle,
1344a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        };
1354a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        int ret = ion_ioctl(fd, ION_IOC_SHARE, &data);
1364a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        if (ret < 0)
1374a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                return ret;
1384a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        *share_fd = data.fd;
1394a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        if (*share_fd < 0) {
1404a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                ALOGE("map ioctl returned negative fd\n");
1414a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                return -EINVAL;
1424a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        }
1434a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        return ret;
1444a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin}
1454a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin
1464a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavinint ion_import(int fd, int share_fd, struct ion_handle **handle)
1474a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin{
1484a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        struct ion_fd_data data = {
1494a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                .fd = share_fd,
1504a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        };
1514a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        int ret = ion_ioctl(fd, ION_IOC_IMPORT, &data);
1524a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        if (ret < 0)
1534a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin                return ret;
1544a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        *handle = data.handle;
1554a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin        return ret;
1564a35937fcb950ccd05af56c49214b88e393233e3Rebecca Schultz Zavin}
157