linux/tools/testing/selftests/android/ion/ionutils.c
<<
>>
Prefs
   1#include <stdio.h>
   2#include <string.h>
   3#include <unistd.h>
   4#include <fcntl.h>
   5#include <errno.h>
   6//#include <stdint.h>
   7#include <sys/ioctl.h>
   8#include <sys/mman.h>
   9#include "ionutils.h"
  10#include "ipcsocket.h"
  11
  12
  13void write_buffer(void *buffer, unsigned long len)
  14{
  15        int i;
  16        unsigned char *ptr = (unsigned char *)buffer;
  17
  18        if (!ptr) {
  19                fprintf(stderr, "<%s>: Invalid buffer...\n", __func__);
  20                return;
  21        }
  22
  23        printf("Fill buffer content:\n");
  24        memset(ptr, 0xfd, len);
  25        for (i = 0; i < len; i++)
  26                printf("0x%x ", ptr[i]);
  27        printf("\n");
  28}
  29
  30void read_buffer(void *buffer, unsigned long len)
  31{
  32        int i;
  33        unsigned char *ptr = (unsigned char *)buffer;
  34
  35        if (!ptr) {
  36                fprintf(stderr, "<%s>: Invalid buffer...\n", __func__);
  37                return;
  38        }
  39
  40        printf("Read buffer content:\n");
  41        for (i = 0; i < len; i++)
  42                printf("0x%x ", ptr[i]);
  43        printf("\n");
  44}
  45
  46int ion_export_buffer_fd(struct ion_buffer_info *ion_info)
  47{
  48        int i, ret, ionfd, buffer_fd;
  49        unsigned int heap_id;
  50        unsigned long maplen;
  51        unsigned char *map_buffer;
  52        struct ion_allocation_data alloc_data;
  53        struct ion_heap_query query;
  54        struct ion_heap_data heap_data[MAX_HEAP_COUNT];
  55
  56        if (!ion_info) {
  57                fprintf(stderr, "<%s>: Invalid ion info\n", __func__);
  58                return -1;
  59        }
  60
  61        /* Create an ION client */
  62        ionfd = open(ION_DEVICE, O_RDWR);
  63        if (ionfd < 0) {
  64                fprintf(stderr, "<%s>: Failed to open ion client: %s\n",
  65                        __func__, strerror(errno));
  66                return -1;
  67        }
  68
  69        memset(&query, 0, sizeof(query));
  70        query.cnt = MAX_HEAP_COUNT;
  71        query.heaps = (unsigned long int)&heap_data[0];
  72        /* Query ION heap_id_mask from ION heap */
  73        ret = ioctl(ionfd, ION_IOC_HEAP_QUERY, &query);
  74        if (ret < 0) {
  75                fprintf(stderr, "<%s>: Failed: ION_IOC_HEAP_QUERY: %s\n",
  76                        __func__, strerror(errno));
  77                goto err_query;
  78        }
  79
  80        heap_id = MAX_HEAP_COUNT + 1;
  81        for (i = 0; i < query.cnt; i++) {
  82                if (heap_data[i].type == ion_info->heap_type) {
  83                        printf("--------------------------------------\n");
  84                        printf("heap type: %d\n", heap_data[i].type);
  85                        printf("  heap id: %d\n", heap_data[i].heap_id);
  86                        printf("heap name: %s\n", heap_data[i].name);
  87                        printf("--------------------------------------\n");
  88                        heap_id = heap_data[i].heap_id;
  89                        break;
  90                }
  91        }
  92
  93        if (heap_id > MAX_HEAP_COUNT) {
  94                fprintf(stderr, "<%s>: ERROR: heap type does not exists\n",
  95                        __func__);
  96                goto err_heap;
  97        }
  98
  99        alloc_data.len = ion_info->heap_size;
 100        alloc_data.heap_id_mask = 1 << heap_id;
 101        alloc_data.flags = ion_info->flag_type;
 102
 103        /* Allocate memory for this ION client as per heap_type */
 104        ret = ioctl(ionfd, ION_IOC_ALLOC, &alloc_data);
 105        if (ret < 0) {
 106                fprintf(stderr, "<%s>: Failed: ION_IOC_ALLOC: %s\n",
 107                        __func__, strerror(errno));
 108                goto err_alloc;
 109        }
 110
 111        /* This will return a valid buffer fd */
 112        buffer_fd = alloc_data.fd;
 113        maplen = alloc_data.len;
 114
 115        if (buffer_fd < 0 || maplen <= 0) {
 116                fprintf(stderr, "<%s>: Invalid map data, fd: %d, len: %ld\n",
 117                        __func__, buffer_fd, maplen);
 118                goto err_fd_data;
 119        }
 120
 121        /* Create memory mapped buffer for the buffer fd */
 122        map_buffer = (unsigned char *)mmap(NULL, maplen, PROT_READ|PROT_WRITE,
 123                        MAP_SHARED, buffer_fd, 0);
 124        if (map_buffer == MAP_FAILED) {
 125                fprintf(stderr, "<%s>: Failed: mmap: %s\n",
 126                        __func__, strerror(errno));
 127                goto err_mmap;
 128        }
 129
 130        ion_info->ionfd = ionfd;
 131        ion_info->buffd = buffer_fd;
 132        ion_info->buffer = map_buffer;
 133        ion_info->buflen = maplen;
 134
 135        return 0;
 136
 137        munmap(map_buffer, maplen);
 138
 139err_fd_data:
 140err_mmap:
 141        /* in case of error: close the buffer fd */
 142        if (buffer_fd)
 143                close(buffer_fd);
 144
 145err_query:
 146err_heap:
 147err_alloc:
 148        /* In case of error: close the ion client fd */
 149        if (ionfd)
 150                close(ionfd);
 151
 152        return -1;
 153}
 154
 155int ion_import_buffer_fd(struct ion_buffer_info *ion_info)
 156{
 157        int buffd;
 158        unsigned char *map_buf;
 159        unsigned long map_len;
 160
 161        if (!ion_info) {
 162                fprintf(stderr, "<%s>: Invalid ion info\n", __func__);
 163                return -1;
 164        }
 165
 166        map_len = ion_info->buflen;
 167        buffd = ion_info->buffd;
 168
 169        if (buffd < 0 || map_len <= 0) {
 170                fprintf(stderr, "<%s>: Invalid map data, fd: %d, len: %ld\n",
 171                        __func__, buffd, map_len);
 172                goto err_buffd;
 173        }
 174
 175        map_buf = (unsigned char *)mmap(NULL, map_len, PROT_READ|PROT_WRITE,
 176                        MAP_SHARED, buffd, 0);
 177        if (map_buf == MAP_FAILED) {
 178                printf("<%s>: Failed - mmap: %s\n",
 179                        __func__, strerror(errno));
 180                goto err_mmap;
 181        }
 182
 183        ion_info->buffer = map_buf;
 184        ion_info->buflen = map_len;
 185
 186        return 0;
 187
 188err_mmap:
 189        if (buffd)
 190                close(buffd);
 191
 192err_buffd:
 193        return -1;
 194}
 195
 196void ion_close_buffer_fd(struct ion_buffer_info *ion_info)
 197{
 198        if (ion_info) {
 199                /* unmap the buffer properly in the end */
 200                munmap(ion_info->buffer, ion_info->buflen);
 201                /* close the buffer fd */
 202                if (ion_info->buffd > 0)
 203                        close(ion_info->buffd);
 204                /* Finally, close the client fd */
 205                if (ion_info->ionfd > 0)
 206                        close(ion_info->ionfd);
 207                printf("<%s>: buffer release successfully....\n", __func__);
 208        }
 209}
 210
 211int socket_send_fd(struct socket_info *info)
 212{
 213        int status;
 214        int fd, sockfd;
 215        struct socketdata skdata;
 216
 217        if (!info) {
 218                fprintf(stderr, "<%s>: Invalid socket info\n", __func__);
 219                return -1;
 220        }
 221
 222        sockfd = info->sockfd;
 223        fd = info->datafd;
 224        memset(&skdata, 0, sizeof(skdata));
 225        skdata.data = fd;
 226        skdata.len = sizeof(skdata.data);
 227        status = sendtosocket(sockfd, &skdata);
 228        if (status < 0) {
 229                fprintf(stderr, "<%s>: Failed: sendtosocket\n", __func__);
 230                return -1;
 231        }
 232
 233        return 0;
 234}
 235
 236int socket_receive_fd(struct socket_info *info)
 237{
 238        int status;
 239        int fd, sockfd;
 240        struct socketdata skdata;
 241
 242        if (!info) {
 243                fprintf(stderr, "<%s>: Invalid socket info\n", __func__);
 244                return -1;
 245        }
 246
 247        sockfd = info->sockfd;
 248        memset(&skdata, 0, sizeof(skdata));
 249        status = receivefromsocket(sockfd, &skdata);
 250        if (status < 0) {
 251                fprintf(stderr, "<%s>: Failed: receivefromsocket\n", __func__);
 252                return -1;
 253        }
 254
 255        fd = (int)skdata.data;
 256        info->datafd = fd;
 257
 258        return status;
 259}
 260