Home | History | Annotate | Download | only in ion
      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 
     13 void 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 
     30 void 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 
     46 int 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 
    139 err_fd_data:
    140 err_mmap:
    141 	/* in case of error: close the buffer fd */
    142 	if (buffer_fd)
    143 		close(buffer_fd);
    144 
    145 err_query:
    146 err_heap:
    147 err_alloc:
    148 	/* In case of error: close the ion client fd */
    149 	if (ionfd)
    150 		close(ionfd);
    151 
    152 	return -1;
    153 }
    154 
    155 int 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 
    188 err_mmap:
    189 	if (buffd)
    190 		close(buffd);
    191 
    192 err_buffd:
    193 	return -1;
    194 }
    195 
    196 void 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 
    211 int 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 
    236 int 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