tbm_module: make tbm_module_bufmgr_bo_alloc_with_format function
[platform/core/uifw/libtbm.git] / src / tbm_module.c
1 /**************************************************************************
2
3 libtbm
4
5 Copyright 2012-2021 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: SooChan Lim <sc1.lim@samsung.com>
8          Changyeon Lee <cyeon.lee@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 #include "config.h"
33
34 #include "tbm_bufmgr_int.h"
35 #include "tbm_bufmgr_backend.h"
36 #include "tbm_drm_helper.h"
37
38 #define PREFIX_LIB    "libtbm_"
39 #define SUFFIX_LIB    ".so"
40 #define DEFAULT_LIB   PREFIX_LIB"default"SUFFIX_LIB
41
42 /* values to indicate unspecified fields in XF86ModReqInfo. */
43 #define MAJOR_UNSPEC      0xFF
44 #define MINOR_UNSPEC      0xFF
45 #define PATCH_UNSPEC      0xFFFF
46 #define ABI_VERS_UNSPEC   0xFFFFFFFF
47
48 #define MODULE_VERSION_NUMERIC(maj, min, patch) \
49                         ((((maj) & 0xFF) << 24) | (((min) & 0xFF) << 16) | (patch & 0xFFFF))
50 #define GET_MODULE_MAJOR_VERSION(vers)    (((vers) >> 24) & 0xFF)
51 #define GET_MODULE_MINOR_VERSION(vers)    (((vers) >> 16) & 0xFF)
52 #define GET_MODULE_PATCHLEVEL(vers)    ((vers) & 0xFFFF)
53
54 /* LCOV_EXCL_START */
55
56 static int
57 _tbm_backend_load_hal_tbm(tbm_module *module)
58 {
59         hal_tbm_backend *hal_backend = NULL;
60         hal_tbm_bufmgr *hal_bufmgr;
61         hal_tbm_error ret = HAL_TBM_ERROR_NONE;
62         hal_tbm_fd auth_drm_fd = -1;
63
64         hal_backend = hal_tbm_get_backend(&ret);
65         if (hal_backend == NULL || ret != HAL_TBM_ERROR_NONE) {
66                 TBM_ERR("get backend fail");
67                 return 0;
68         }
69
70         hal_bufmgr = hal_tbm_backend_get_bufmgr(hal_backend, &ret);
71         if (hal_bufmgr == NULL || ret != HAL_TBM_ERROR_NONE) {
72                 TBM_ERR("get hal_bufmgr fail");
73                 goto get_backend_fail;
74         }
75
76         if (hal_tbm_backend_has_drm_device(hal_backend, &ret)) {
77                 auth_drm_fd = hal_tbm_backend_get_master_drm_fd(hal_backend, &ret);
78                 if (auth_drm_fd < 0) {
79                         TBM_INFO("tbm_backend has no master drm_fd.");
80
81                         auth_drm_fd = tbm_drm_helper_get_master_fd();
82                         if (auth_drm_fd < 0) {
83                                 TBM_INFO("libtbm requests an authenticated drm_fd to a process(display server).");
84                                 if (!tbm_drm_helper_get_auth_info(&auth_drm_fd, NULL, NULL)) {
85                                         TBM_ERR("get auth drm_fd fail");
86                                         goto get_backend_fail;
87                                 }
88                         } else {
89                                 TBM_INFO("libtbm gets a master drm_fd from libtdm via tbm_drm_helper.");
90                         }
91
92                         TBM_INFO("libtbm sends a master drm_fd as an authentiated drm_fd to tbm_backend.");
93                         ret = hal_tbm_backend_set_authenticated_drm_fd(hal_backend, auth_drm_fd);
94                         if (ret != HAL_TBM_ERROR_NONE) {
95                                 TBM_ERR("hal_tbm_backend_set_authenticated_drm_fd failed.");
96                                 goto get_backend_fail;
97                         }
98                 } else {
99                         TBM_INFO("tbm_backend has a master drm_fd.");
100
101                         tbm_drm_helper_set_tbm_master_fd(auth_drm_fd);
102                 }
103                 tbm_drm_helper_set_fd(auth_drm_fd);
104         }
105
106         module->hal_backend = hal_backend;
107         module->hal_bufmgr = hal_bufmgr;
108
109         module->use_hal_tbm = 1;
110
111         TBM_INFO("use HAL-TBM_API");
112
113         return 1;
114
115 get_backend_fail:
116         if (auth_drm_fd >= 0)
117                 close(auth_drm_fd);
118         hal_tbm_put_backend(hal_backend);
119         return 0;
120 }
121
122 static int
123 _check_version(TBMModuleVersionInfo *data)
124 {
125         int backend_module_major, backend_module_minor;
126         int tbm_backend_major, tbm_backend_minor;
127
128         backend_module_major = GET_ABI_MAJOR(data->abiversion);
129         backend_module_minor = GET_ABI_MINOR(data->abiversion);
130
131         TBM_DBG("TBM module %s: vendor=\"%s\" ABI=%d,%d\n",
132             data->modname ? data->modname : "UNKNOWN!",
133             data->vendor ? data->vendor : "UNKNOWN!", backend_module_major, backend_module_minor);
134
135         tbm_backend_major = GET_ABI_MAJOR(TBM_ABI_VERSION);
136         tbm_backend_minor = GET_ABI_MINOR(TBM_ABI_VERSION);
137
138         TBM_DBG("TBM ABI version %d.%d\n",
139             tbm_backend_major, tbm_backend_minor);
140
141         if (backend_module_major != tbm_backend_major) {
142                 TBM_ERR("TBM module ABI major ver(%d) doesn't match the TBM's ver(%d)\n",
143                         backend_module_major, tbm_backend_major);
144                 return 0;
145         } else if (backend_module_minor > tbm_backend_minor) {
146                 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
147                         backend_module_minor, tbm_backend_minor);
148                 return 0;
149         }
150
151         return 1;
152 }
153
154 static int
155 _tbm_backend_check_bufmgr_func(tbm_backend_bufmgr_func *bufmgr_func)
156 {
157         TBM_RETURN_VAL_IF_FAIL(bufmgr_func, 0); /* mandatory symbol */
158         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_capabilities, 0); /* mandatory symbol */
159         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_bind_native_display, 0); /* mandatory symbol */
160         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_supported_formats, 0); /* mandatory symbol */
161         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_get_plane_data, 0); /* mandatory symbol */
162         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, 0); /* mandatory symbol */
163         if (!bufmgr_func->bufmgr_alloc_bo_with_format)
164                 TBM_DBG("No bufmgr_func->bufmgr_alloc_bo_with_format.");
165         TBM_RETURN_VAL_IF_FAIL(bufmgr_func->bufmgr_import_fd, 0); /* mandatory symbol */
166         if (!bufmgr_func->bufmgr_import_key)
167                 TBM_DBG("No bufmgr_func->bo_export_key.");
168
169         return 1;
170 }
171
172 static int
173 _tbm_backend_check_bufmgr_bo(tbm_backend_bo_func *bo_func)
174 {
175         TBM_RETURN_VAL_IF_FAIL(bo_func, 0); /* mandatory symbol */
176         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_free, 0); /* mandatory symbol */
177         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_size, 0); /* mandatory symbol */
178         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_memory_types, 0); /* mandatory symbol */
179         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_get_handle, 0); /* mandatory symbol */
180         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_map, 0); /* mandatory symbol */
181         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_unmap, 0); /* mandatory symbol */
182         if (!bo_func->bo_lock)
183                 TBM_DBG("No bo_func->bo_lock.");
184         if (!bo_func->bo_unlock)
185                 TBM_DBG("No bo_func->bo_unlock.");
186         TBM_RETURN_VAL_IF_FAIL(bo_func->bo_export_fd, 0); /* mandatory symbol */
187         if (!bo_func->bo_export_key)
188                 TBM_INFO("No bo_func->bo_export_key.");
189
190         return 1;
191 }
192
193 static int
194 _tbm_backend_load_module(tbm_module *module, const char *file)
195 {
196         char path[PATH_MAX] = {0, };
197         void *module_data = NULL;
198         tbm_backend_module *backend_module_data = NULL;
199         tbm_backend_bufmgr_data *bufmgr_data = NULL;
200         int backend_module_major, backend_module_minor;
201         int tbm_backend_major, tbm_backend_minor;
202         tbm_error_e error;
203
204         snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
205
206         module_data = dlopen(path, RTLD_LAZY);
207         if (!module_data) {
208                 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
209                 return 0;
210         }
211
212         backend_module_data = dlsym(module_data, "tbm_backend_module_data");
213         if (!backend_module_data) {
214                 TBM_ERR("Error: module does not have data object.\n");
215                 goto err;
216         }
217
218         tbm_backend_major = GET_ABI_MAJOR(TBM_BACKEND_ABI_LATEST_VERSION);
219         tbm_backend_minor = GET_ABI_MINOR(TBM_BACKEND_ABI_LATEST_VERSION);
220         TBM_INFO("TBM Backend ABI version %d.%d\n", tbm_backend_major, tbm_backend_minor);
221
222         backend_module_major = GET_ABI_MAJOR(backend_module_data->abi_version);
223         backend_module_minor = GET_ABI_MINOR(backend_module_data->abi_version);
224
225         TBM_INFO("TBM module %s: vendor=\"%s\" Backend ABI version=%d.%d\n",
226             backend_module_data->name ? backend_module_data->name : "UNKNOWN!",
227             backend_module_data->vendor ? backend_module_data->vendor : "UNKNOWN!",
228                 backend_module_major, backend_module_minor);
229
230         if (backend_module_major > tbm_backend_major) {
231                 TBM_ERR("TBM module ABI major ver(%d) is newer than the TBM's ver(%d)\n",
232                         backend_module_major, tbm_backend_major);
233                 goto err;
234         } else if (backend_module_minor > tbm_backend_minor) {
235                 TBM_ERR("TBM module ABI minor ver(%d) is newer than the TBM's ver(%d)\n",
236                         backend_module_minor, tbm_backend_minor);
237                 goto err;
238         }
239
240         if (!backend_module_data->init) {
241                 TBM_ERR("Error: module does not supply init symbol.\n");
242                 goto err;
243         }
244
245         if (!backend_module_data->deinit)       {
246                 TBM_ERR("Error: module does not supply deinit symbol.\n");
247                 goto err;
248         }
249
250         bufmgr_data = backend_module_data->init((tbm_bufmgr)module, &error);
251         if (!bufmgr_data) {
252                 TBM_ERR("Fail to init module(%s)\n", file);
253                 goto err;
254         }
255
256         /* check the mandatory symbols of the backend module */
257         if (!_tbm_backend_check_bufmgr_func(module->bufmgr_func)) {
258                 TBM_ERR("Fail to check the bufmgr_func symboles.");
259                 goto err;
260         }
261
262         if (!_tbm_backend_check_bufmgr_bo(module->bo_func)) {
263                 TBM_ERR("Fail to check the bufmgr_bo symboles.");
264                 goto err;
265         }
266
267         module->module_data = module_data;
268         module->backend_module_data = backend_module_data;
269         module->bufmgr_data = bufmgr_data;
270
271         TBM_INFO("Success to load module(%s)\n", file);
272
273         return 1;
274
275 err:
276         if (bufmgr_data)
277                 module->backend_module_data->deinit(bufmgr_data);
278         if (module_data)
279                 dlclose(module_data);
280
281         return 0;
282 }
283
284 static int
285 _tbm_backend_load_bufmgr_module(tbm_module *module, int fd, const char *file)
286 {
287         char path[PATH_MAX] = {0, };
288         TBMModuleVersionInfo *vers;
289         TBMModuleData *initdata;
290         ModuleInitProc init;
291         void *module_data;
292
293         snprintf(path, sizeof(path), BUFMGR_MODULE_DIR "/%s", file);
294
295         module_data = dlopen(path, RTLD_LAZY);
296         if (!module_data) {
297                 TBM_ERR("failed to load module: %s(%s)\n", dlerror(), file);
298                 return 0;
299         }
300
301         initdata = dlsym(module_data, "tbmModuleData");
302         if (!initdata) {
303                 TBM_ERR("Error: module does not have data object.\n");
304                 goto err;
305         }
306
307         vers = initdata->vers;
308         if (!vers) {
309                 TBM_ERR("Error: module does not supply version information.\n");
310                 goto err;
311         }
312
313         init = initdata->init;
314         if (!init) {
315                 TBM_ERR("Error: module does not supply init symbol.\n");
316                 goto err;
317         }
318
319         if (!_check_version(vers)) {
320                 TBM_ERR("Fail to check version.\n");
321                 goto err;
322         }
323
324         if (!init((tbm_bufmgr)module, fd)) {
325                 TBM_ERR("Fail to init module(%s)\n", file);
326                 goto err;
327         }
328
329         if (!module->backend || !module->backend->priv) {
330                 TBM_ERR("Error: module(%s) wrong operation. Check backend or backend's priv.\n", file);
331                 goto err;
332         }
333
334         module->module_data = module_data;
335
336         TBM_DBG("Success to load module(%s)\n", file);
337
338         return 1;
339
340 err:
341         dlclose(module_data);
342         return 0;
343 }
344
345 /* LCOV_EXCL_STOP */
346
347 tbm_module *
348 tbm_module_load(int fd)
349 {
350         tbm_module *module;
351         struct dirent **namelist;
352         int ret = 0, n;
353
354         module = calloc(1, sizeof(struct _tbm_module));
355         if (!module) {
356                 TBM_ERR("fail to allocate the memory");
357                 return NULL;
358         }
359
360         /* try to load the hal-tbm backend module */
361         ret = _tbm_backend_load_hal_tbm(module);
362         if (ret) {
363                 module->type = TBM_MODULE_TYPE_HAL_TBM;
364                 goto done;
365         }
366
367         /* try to load the new backend module */
368         ret = _tbm_backend_load_module(module, DEFAULT_LIB);
369         if (ret) {
370                 module->type = TBM_MODULE_TYPE_TBM_BACKEND;
371                 goto done;
372         }
373
374         /* try to load the old(deprecated) backend mdoule */
375         ret = _tbm_backend_load_bufmgr_module(module, fd, DEFAULT_LIB);
376         if (ret) {
377                 module->type = TBM_MODULE_TYPE_BUFMGR_BACKEND;
378                 return module;
379         }
380
381         /* load backend_module from configured path */
382         n = scandir(BUFMGR_MODULE_DIR, &namelist, 0, alphasort);
383         if (n < 0) {
384                 TBM_ERR("no files : %s\n", BUFMGR_MODULE_DIR);
385                 tbm_module_unload(module);
386                 return NULL;
387         }
388
389         while (n--) {
390                 if (!ret && strstr(namelist[n]->d_name, PREFIX_LIB)) {
391                         const char *p = strstr(namelist[n]->d_name, SUFFIX_LIB);
392
393                         if (p && !strcmp(p, SUFFIX_LIB)) {
394                                 ret = _tbm_backend_load_module(module, namelist[n]->d_name);
395                                 if (ret)
396                                         module->type = TBM_MODULE_TYPE_TBM_BACKEND;
397                                 else {
398                                         ret = _tbm_backend_load_bufmgr_module(module, fd, namelist[n]->d_name);
399                                         module->type = TBM_MODULE_TYPE_BUFMGR_BACKEND;
400                                 }
401                         }
402                 }
403
404                 free(namelist[n]);
405         }
406
407         free(namelist);
408
409         if (!ret) {
410                 free(module);
411                 module = NULL;
412         }
413
414 done:
415         return module;
416 }
417
418 void
419 tbm_module_unload(tbm_module *module)
420 {
421         switch (module->type) {
422         case TBM_MODULE_TYPE_HAL_TBM:
423                 if (module->auth_wl_socket_created) {
424                         tbm_drm_helper_wl_auth_server_deinit();
425                         close(module->auth_fd);
426                 }
427                 tbm_drm_helper_unset_tbm_master_fd();
428                 tbm_drm_helper_unset_fd();
429
430                 hal_tbm_put_backend(module->hal_backend);
431                 module->hal_backend = NULL;
432                 module->hal_bufmgr = NULL;
433                 module->use_hal_tbm = 0;
434                 break;
435         case TBM_MODULE_TYPE_TBM_BACKEND:
436                 module->backend_module_data->deinit(module->bufmgr_data);
437                 module->bo_func = NULL;
438                 module->bufmgr_func = NULL;
439                 module->bufmgr_data = NULL;
440                 module->backend_module_data = NULL;
441
442                 dlclose(module->module_data);
443                 break;
444         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
445                 module->backend->bufmgr_deinit(module->backend->priv);
446                 module->backend->priv = NULL;
447                 tbm_backend_free(module->backend);
448                 module->backend = NULL;
449
450                 dlclose(module->module_data);
451                 break;
452         default:
453                 TBM_ERR("Wrong module type:%d", module->type);
454                 break;
455         }
456
457         free(module);
458 }
459
460 int
461 tbm_module_bufmgr_get_capabilities(tbm_module *module, tbm_error_e *error)
462 {
463         int capabilities = 0;
464
465         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, TBM_BUFMGR_CAPABILITY_NONE, *error, TBM_ERROR_INVALID_PARAMETER);
466
467         switch (module->type) {
468         case TBM_MODULE_TYPE_HAL_TBM:
469                 capabilities = hal_tbm_bufmgr_get_capabilities(module->hal_bufmgr, (hal_tbm_error *)error);
470                 break;
471         case TBM_MODULE_TYPE_TBM_BACKEND:
472                 capabilities = module->bufmgr_func->bufmgr_get_capabilities(module->bufmgr_data, error);
473                 break;
474         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
475                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 7.0.");
476                 TBM_ERR("Do not support at tbm_bufmgr_backend.");
477                 *error = TBM_ERROR_NOT_SUPPORTED;
478                 break;
479         default:
480                 TBM_ERR("Wrong module type:%d", module->type);
481                 *error = TBM_ERROR_INVALID_OPERATION;
482                 break;
483         }
484
485         return capabilities;
486 }
487
488 tbm_backend_bo_data *
489 tbm_module_bufmgr_bo_alloc(tbm_module *module, tbm_bo bo, int size, int flags, tbm_error_e *error)
490 {
491         tbm_backend_bo_data *bo_data = NULL;
492         tbm_backend_bufmgr_func *bufmgr_func = NULL;
493         tbm_bufmgr_backend backend = NULL;
494
495         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
496
497         switch (module->type) {
498         case TBM_MODULE_TYPE_HAL_TBM:
499                 bo_data = (tbm_backend_bo_data *)hal_tbm_bufmgr_alloc_bo(module->hal_bufmgr, size, flags, (hal_tbm_error *)error);
500                 break;
501         case TBM_MODULE_TYPE_TBM_BACKEND:
502                 bufmgr_func = module->bufmgr_func;
503                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr_func, NULL, *error, TBM_ERROR_INVALID_OPERATION);
504                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr_func->bufmgr_alloc_bo, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
505
506                 bo_data = module->bufmgr_func->bufmgr_alloc_bo(module->bufmgr_data, (unsigned int)size, flags, error);
507                 break;
508         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
509                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 7.0.");
510                 backend = module->backend;
511                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend, NULL, *error, TBM_ERROR_INVALID_OPERATION);
512                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(backend->bo_alloc, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
513
514                 bo_data = (void *)module->backend->bo_alloc(bo, size, flags);
515                 *error = TBM_ERROR_NONE;
516                 break;
517         default:
518                 TBM_ERR("Wrong module type:%d", module->type);
519                 *error = TBM_ERROR_INVALID_OPERATION;
520                 break;
521         }
522
523         return bo_data;
524 }
525
526 tbm_backend_bo_data *
527 tbm_module_bufmgr_bo_alloc_with_format(tbm_module *module, int format, int bo_idx, int width,
528                                                 int height, int bpp, tbm_bo_memory_type flags, tbm_error_e *error)
529 {
530         tbm_backend_bo_data *bo_data = NULL;
531         tbm_backend_bufmgr_func *bufmgr_func = NULL;
532
533         TBM_RETURN_VAL_SET_ERR_IF_FAIL(module, NULL, *error, TBM_ERROR_INVALID_PARAMETER);
534
535         switch (module->type) {
536         case TBM_MODULE_TYPE_HAL_TBM:
537                 bo_data = (tbm_backend_bo_data *)hal_tbm_bufmgr_alloc_bo_with_format(module->hal_bufmgr,
538                                                                                         format, bo_idx, width, height, bpp,
539                                                                                         (hal_tbm_bo_memory_type)flags, (hal_tbm_error *)error);
540                 break;
541         case TBM_MODULE_TYPE_TBM_BACKEND:
542                 bufmgr_func = module->bufmgr_func;
543                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr_func, NULL, *error, TBM_ERROR_INVALID_OPERATION);
544                 TBM_RETURN_VAL_SET_ERR_IF_FAIL(bufmgr_func->bufmgr_alloc_bo_with_format, NULL, *error, TBM_ERROR_NOT_SUPPORTED);
545
546                 bo_data = bufmgr_func->bufmgr_alloc_bo_with_format(module->bufmgr_data, format, bo_idx, width, height, flags, error);
547                 break;
548         case TBM_MODULE_TYPE_BUFMGR_BACKEND:
549                 TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 7.0.");
550                 TBM_ERR("error: not supported tbm_bo_alloc_with_format.");
551
552                 *error = TBM_ERROR_NOT_SUPPORTED;
553                 break;
554         default:
555                 TBM_ERR("Wrong module type:%d", module->type);
556                 *error = TBM_ERROR_INVALID_OPERATION;
557                 break;
558         }
559
560         return bo_data;
561 }