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