4 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
25 #include <glib-object.h>
28 #include "hal-api-conf.h"
31 #define EXPORT __attribute__ ((visibility("default")))
34 static enum hal_abi_version g_platform_curr_abi_version;
35 G_LOCK_DEFINE_STATIC(hal_common_lock);
38 int hal_common_get_backend_library_name(enum hal_module module, char *name, int size)
40 const char *library_name = NULL;
41 struct __hal_module_info *info = NULL;
45 /* Check parameter whether is valid or not */
46 if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
47 _E("Invalid parameter of HAL module (%d)\n", module);
48 return TIZEN_ERROR_INVALID_PARAMETER;
51 if (_hal_api_conf_init())
52 return TIZEN_ERROR_UNKNOWN;
54 info = _hal_api_conf_get_module_info(module, NULL);
56 _E("Failed to get HAL module(%d) information\n", module);
57 ret = TIZEN_ERROR_UNKNOWN;
61 library_name = get_backend_library_name(info);
63 _E("%s backend library name is NULL\n", info->module_name);
64 ret = TIZEN_ERROR_NONE;
68 len_library_name = strlen(library_name);
69 if (!name || (len_library_name + 1 > size)) {
70 ret = TIZEN_ERROR_UNKNOWN;
74 strncpy(name, library_name, len_library_name);
75 name[len_library_name] = '\0';
77 ret = TIZEN_ERROR_NONE;
85 int hal_common_get_backend_symbol_name(enum hal_module module, char *name, int size)
87 struct __hal_module_info *info = NULL;
88 char *symbol_name = NULL;
92 /* Check parameter whether is valid or not */
93 if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
94 _E("Invalid paramer of HAL module (%d)\n", module);
95 return TIZEN_ERROR_INVALID_PARAMETER;
98 if (_hal_api_conf_init())
99 return TIZEN_ERROR_UNKNOWN;
101 info = _hal_api_conf_get_module_info(module, NULL);
103 _E("Failed to get HAL module(%d) information\n", module);
104 ret = TIZEN_ERROR_UNKNOWN;
107 symbol_name = info->symbol_name;
109 _E("%s backend symbol name is NULL\n", info->module_name);
110 ret = TIZEN_ERROR_NONE;
114 len_symbol_name = strlen(symbol_name);
115 if (!name || (len_symbol_name + 1 > size)) {
116 ret = TIZEN_ERROR_UNKNOWN;
120 strncpy(name, symbol_name, len_symbol_name);
121 name[len_symbol_name] = '\0';
123 ret = TIZEN_ERROR_NONE;
125 _hal_api_conf_exit();
130 static int __get_backend(enum hal_module module, void **data, const char *library_name)
132 struct __hal_module_info *info = NULL;
134 hal_backend *backend;
135 const char *symbol_name = NULL;
136 const char *backend_library_name = NULL;
139 /* Check parameter whether is valid or not */
140 if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
141 _E("Invalid parameter of HAL module (%d)\n", module);
142 return TIZEN_ERROR_INVALID_PARAMETER;
145 G_LOCK(hal_common_lock);
147 if (_hal_api_conf_init()) {
148 ret = TIZEN_ERROR_UNKNOWN;
152 info = _hal_api_conf_get_module_info(module, library_name);
155 _E("Failed to get HAL module(%d) information\n", module);
157 _E("Failed to get HAL module(%d) information (%s)\n",
158 module, library_name);
159 ret = TIZEN_ERROR_UNKNOWN;
163 if (info->usage_count == 0) {
165 * Load HAL backend library at first loading time
166 * when usage_count is 0.
168 backend_library_name = get_backend_library_name(info);
169 if (!backend_library_name) {
170 _E("%s: Failed to get backend library name\n",
172 ret = TIZEN_ERROR_INVALID_PARAMETER;
176 ret = access(backend_library_name, F_OK);
178 _E("%s: Failed to find backend library (%s)\n",
179 info->module_name, backend_library_name);
180 ret = TIZEN_ERROR_INVALID_PARAMETER;
184 handle = dlopen(backend_library_name, RTLD_LAZY);
186 _E("%s: Failed to load backend library (%s)\n",
187 info->module_name, dlerror());
188 ret = TIZEN_ERROR_INVALID_PARAMETER;
192 symbol_name = info->symbol_name;
194 _E("%s: Failed to get backend symbol name\n",
196 ret = TIZEN_ERROR_INVALID_PARAMETER;
200 backend = dlsym(handle, symbol_name);
202 _E("%s: Failed to find backend data (%s)\n",
203 info->module_name, dlerror());
204 ret = TIZEN_ERROR_INVALID_PARAMETER;
208 info->library_backend = backend;
209 info->library_handle = handle;
212 * Re-use the already loaded HAL backend instance
213 * when usage_count is larger than 0.
215 backend = info->library_backend;
218 /* Check HAL ABI Version */
219 ret = hal_common_check_backend_abi_version(module, backend->abi_version);
221 _E("%s: Failed to check ABI version\n",
223 ret = TIZEN_ERROR_INVALID_PARAMETER;
227 /* Get the backend module data */
228 if (!backend->init) {
229 _E("%s: hal_backend->init() is NULL\n",
231 ret = TIZEN_ERROR_INVALID_PARAMETER;
235 ret = backend->init(data);
237 _E("%s: Failed to initialize backend: name(%s)/vendor(%s)\n",
238 info->module_name, backend->name, backend->vendor);
239 ret = TIZEN_ERROR_INVALID_PARAMETER;
245 _I("%s: Get HAL backend: name(%s)/vendor(%s)/library(%s)/count(%d)\n",
246 info->module_name, backend->name, backend->vendor,
247 backend_library_name, info->usage_count);
249 G_UNLOCK(hal_common_lock);
250 return TIZEN_ERROR_NONE;
253 _hal_api_conf_exit();
256 G_UNLOCK(hal_common_lock);
260 static int __put_backend(enum hal_module module, void *data, const char *library_name)
262 struct __hal_module_info *info = NULL;
263 hal_backend *backend = NULL;
267 /* Check parameter whether is valid or not */
268 if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
269 _E("Invalid parameter of HAL module (%d)\n", module);
270 return TIZEN_ERROR_INVALID_PARAMETER;
273 G_LOCK(hal_common_lock);
275 info = _hal_api_conf_get_module_info(module, library_name);
277 _E("Failed to get HAL module(%d) information\n", module);
278 ret = TIZEN_ERROR_UNKNOWN;
282 backend = info->library_backend;
283 handle = info->library_handle;
285 if (!backend || info->usage_count == 0) {
286 _I("%s: Already fully put for HAL module\n", info->module_name);
287 ret = TIZEN_ERROR_NONE;
292 if (info->usage_count > 0) {
293 ret = TIZEN_ERROR_NONE;
298 ret = backend->exit(data);
300 _E("%s: Failed to exit backend: name(%s)/vendor(%s)\n",
301 info->module_name, backend->name, backend->vendor);
302 ret = TIZEN_ERROR_INVALID_PARAMETER;
307 _I("%s: Put HAL backend: name(%s)/vendor(%s)/library(%s)/count(%d)\n",
308 info->module_name, backend->name, backend->vendor,
309 get_backend_library_name(info), info->usage_count);
314 info->library_backend = NULL;
315 info->library_handle = NULL;
317 _hal_api_conf_exit();
319 ret = TIZEN_ERROR_NONE;
322 G_UNLOCK(hal_common_lock);
327 int hal_common_get_backend(enum hal_module module, void **data)
329 return __get_backend(module, data, NULL);
333 int hal_common_put_backend(enum hal_module module, void *data)
335 return __put_backend(module, data, NULL);
339 int hal_common_get_backend_with_library_name(enum hal_module module,
340 void **data, const char *library_name)
342 return __get_backend(module, data, library_name);
346 int hal_common_put_backend_with_library_name(enum hal_module module,
347 void *data, const char *library_name)
349 return __put_backend(module, data, library_name);
353 int hal_common_check_backend_abi_version(enum hal_module module,
354 enum hal_abi_version abi_version)
356 struct __hal_module_info *info = NULL;
360 /* Check parameter whether is valid or not */
361 if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
362 _E("Invalid paramer of HAL module(%d)\n", module);
363 return TIZEN_ERROR_INVALID_PARAMETER;
366 if (abi_version <= HAL_ABI_VERSION_UNKNOWN
367 || abi_version >= HAL_ABI_VERSION_END) {
368 _E("Invalid paramer of HAL ABI version(%d) for HAL module(%d)\n",
369 abi_version, module);
370 return TIZEN_ERROR_INVALID_PARAMETER;
373 if (_hal_api_conf_init())
374 return TIZEN_ERROR_UNKNOWN;
376 info = _hal_api_conf_get_module_info(module, NULL);
378 _E("Failed to get HAL module(%d) information\n", module);
379 ret = TIZEN_ERROR_UNKNOWN;
383 /* Check abi_version whether is supported or not */
384 if (!info->hal_api) {
385 _E("%s: Doesn't support HAL API\n", info->module_name);
386 ret = TIZEN_ERROR_INVALID_PARAMETER;
390 if (!info->num_abi_versions
391 || !info->abi_versions) {
392 _E("%s: Doesn't have the ABI version information\n",
394 ret = TIZEN_ERROR_INVALID_PARAMETER;
398 g_platform_curr_abi_version = _hal_api_conf_get_platform_abi_version();
399 for (i = 0; i < info->num_abi_versions; i++) {
400 struct hal_abi_version_match *data
401 = &info->abi_versions[i];
403 if (g_platform_curr_abi_version != data->platform_abi_version)
406 if (data->backend_min_abi_version <= HAL_ABI_VERSION_UNKNOWN ||
407 data->backend_min_abi_version >= HAL_ABI_VERSION_END) {
408 _E("%s: abi_versions[%d].backend_min_abi_version(%d) is invalid\n",
409 info->module_name, i, data->backend_min_abi_version);
410 ret = TIZEN_ERROR_INVALID_PARAMETER;
414 if (abi_version <= data->platform_abi_version
415 && abi_version >= data->backend_min_abi_version) {
416 ret = TIZEN_ERROR_NONE;
420 _E("%s: \'%s\' doesn't support \'%s\'\n",
422 hal_abi_version_str[g_platform_curr_abi_version],
423 hal_abi_version_str[abi_version]);
424 _E("%s: Must use ABI versions from \'%s\' to \'%s\'\n",
426 hal_abi_version_str[data->backend_min_abi_version],
427 hal_abi_version_str[data->platform_abi_version]);
429 ret = TIZEN_ERROR_INVALID_PARAMETER;
432 _hal_api_conf_exit();