1363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/*
2363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Copyright 2008 The Android Open Source Project
3363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger *
4363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be
5363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * found in the LICENSE file.
6363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */
7363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
8363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/*
9363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Implementation of the user-space ashmem API for devices, which have our
10363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
11363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * used by the simulator.
12363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */
13363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <android/ashmem.h>
15363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
16363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <unistd.h>
17363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <string.h>
18363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <sys/types.h>
19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <sys/stat.h>
20363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <sys/ioctl.h>
21363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <fcntl.h>
22363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
23363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <linux/ashmem.h>
24363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
25363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#define ASHMEM_DEVICE   "/dev/ashmem"
26363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
27363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger/*
28363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * ashmem_create_region - creates a new ashmem region and returns the file
29363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * descriptor, or <0 on error
30363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger *
31363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * `name' is an optional label to give the region (visible in /proc/pid/maps)
32363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * `size' is the size of the region, in page-aligned bytes
33363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger */
34363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint ashmem_create_region(const char *name, size_t size)
35363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger{
36363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    int fd, ret;
37363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
38363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    fd = open(ASHMEM_DEVICE, O_RDWR);
39363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    if (fd < 0)
40363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        return fd;
41363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
42363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    if (name) {
43363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        char buf[ASHMEM_NAME_LEN];
44363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
45363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        strlcpy(buf, name, sizeof(buf));
46363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        ret = ioctl(fd, ASHMEM_SET_NAME, buf);
47363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        if (ret < 0)
48363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            goto error;
49363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    }
50363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
51363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    ret = ioctl(fd, ASHMEM_SET_SIZE, size);
52363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    if (ret < 0)
53363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        goto error;
54363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
55363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    return fd;
56363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
57363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergererror:
58363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    close(fd);
59363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    return ret;
60363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
61363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
62363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint ashmem_set_prot_region(int fd, int prot)
63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger{
64363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    return ioctl(fd, ASHMEM_SET_PROT_MASK, prot);
65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
66363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
67363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint ashmem_pin_region(int fd, size_t offset, size_t len)
68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger{
69363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    struct ashmem_pin pin = { offset, len };
70363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    return ioctl(fd, ASHMEM_PIN, &pin);
71363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
72363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
73363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint ashmem_unpin_region(int fd, size_t offset, size_t len)
74363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger{
75363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    struct ashmem_pin pin = { offset, len };
76363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    return ioctl(fd, ASHMEM_UNPIN, &pin);
77363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
78363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
79363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint ashmem_get_size_region(int fd)
80363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger{
81363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger  return ioctl(fd, ASHMEM_GET_SIZE, NULL);
82363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}
83096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
84096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergerint ashmem_purge_all_caches(int fd)
85096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger{
86096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger  return ioctl(fd, ASHMEM_PURGE_ALL_CACHES, NULL);
87096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
88