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 const char *hal_common_get_backend_library_name(enum hal_module module)
41 struct __hal_module_info *info = NULL;
43 /* Check parameter whether is valid or not */
44 if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
45 _E("Invalid parameter of HAL module (%d)\n", module);
49 info = _hal_api_conf_get_module_info(module);
51 _E("Failed to get HAL module(%d) information\n", module);
55 #if defined(__aarch64__)
56 library_name = info->library_name_64bit;
58 library_name = info->library_name;
62 _E("%s backend library name is NULL\n", info->module_name);
69 const char *hal_common_get_backend_symbol_name(enum hal_module module)
71 struct __hal_module_info *info = NULL;
73 /* Check parameter whether is valid or not */
74 if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
75 _E("Invalid paramer of HAL module (%d)\n", module);
79 info = _hal_api_conf_get_module_info(module);
81 _E("Failed to get HAL module(%d) information\n", module);
85 if (!info->symbol_name) {
86 _E("%s backend library name is NULL\n", info->module_name);
90 return info->symbol_name;
94 int hal_common_get_backend(enum hal_module module, void **data)
96 struct __hal_module_info *info = NULL;
99 const char *library_name, *symbol_name;
102 /* Check parameter whether is valid or not */
103 if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
104 _E("Invalid parameter of HAL module (%d)\n", module);
105 return TIZEN_ERROR_INVALID_PARAMETER;
108 G_LOCK(hal_common_lock);
110 info = _hal_api_conf_get_module_info(module);
112 _E("Failed to get HAL module(%d) information\n", module);
113 ret = TIZEN_ERROR_UNKNOWN;
117 if (info->usage_count == 0) {
119 * Load HAL backend library at first loading time
120 * when usage_count is 0.
122 library_name = hal_common_get_backend_library_name(module);
124 _E("%s: Failed to get backend library name\n",
126 ret = TIZEN_ERROR_INVALID_PARAMETER;
130 handle = dlopen(library_name, RTLD_LAZY);
132 _E("%s: Failed to load shared library (%s)\n",
133 info->module_name, dlerror());
134 ret = TIZEN_ERROR_INVALID_PARAMETER;
138 symbol_name = hal_common_get_backend_symbol_name(module);
140 _E("%s: Failed to get backend symbol name\n",
142 ret = TIZEN_ERROR_INVALID_PARAMETER;
146 backend = dlsym(handle, symbol_name);
148 _E("%s: Failed to find backend data (%s)\n",
149 info->module_name, dlerror());
150 ret = TIZEN_ERROR_INVALID_PARAMETER;
154 info->library_backend = backend;
155 info->library_handle = handle;
158 * Re-use the already loaded HAL backend instance
159 * when usage_count is larger than 0.
161 backend = info->library_backend;
164 /* Check HAL ABI Version */
165 ret = hal_common_check_backend_abi_version(module, backend->abi_version);
167 _E("%s: Failed to check ABI version\n",
169 ret = TIZEN_ERROR_INVALID_PARAMETER;
173 /* Get the backend module data */
174 if (!backend->init) {
175 _E("%s: hal_backend->init() is NULL\n",
177 ret = TIZEN_ERROR_INVALID_PARAMETER;
181 ret = backend->init(data);
183 _E("%s: Failed to initialize backend: name(%s)/vendor(%s)\n",
184 info->module_name, backend->name, backend->vendor);
185 ret = TIZEN_ERROR_INVALID_PARAMETER;
189 _I("%s: Get HAL backend: name(%s)/vendor(%s)\n",
190 info->module_name, backend->name, backend->vendor);
194 G_UNLOCK(hal_common_lock);
195 return TIZEN_ERROR_NONE;
200 G_UNLOCK(hal_common_lock);
205 int hal_common_put_backend(enum hal_module module, void *data)
207 struct __hal_module_info *info = NULL;
208 hal_backend *backend = NULL;
212 /* Check parameter whether is valid or not */
213 if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
214 _E("Invalid parameter of HAL module (%d)\n", module);
215 return TIZEN_ERROR_INVALID_PARAMETER;
218 G_LOCK(hal_common_lock);
220 info = _hal_api_conf_get_module_info(module);
222 _E("Failed to get HAL module(%d) information\n", module);
223 ret = TIZEN_ERROR_UNKNOWN;
227 backend = info->library_backend;
228 handle = info->library_handle;
230 if (!backend || info->usage_count == 0) {
231 _I("%s: Already fully put for HAL module\n", info->module_name);
232 ret = TIZEN_ERROR_NONE;
237 if (info->usage_count > 0) {
238 ret = TIZEN_ERROR_NONE;
243 ret = backend->exit(data);
245 _E("%s: Failed to exit backend: name(%s)/vendor(%s)\n",
246 info->module_name, backend->name, backend->vendor);
247 ret = TIZEN_ERROR_INVALID_PARAMETER;
252 _I("%s: Put HAL backend: name(%s)/vendor(%s)\n",
253 info->module_name, backend->name, backend->vendor);
258 info->library_backend = NULL;
259 info->library_handle = NULL;
262 G_UNLOCK(hal_common_lock);
267 int hal_common_check_backend_abi_version(enum hal_module module,
268 enum hal_abi_version abi_version)
270 struct __hal_module_info *info = NULL;
273 /* Check parameter whether is valid or not */
274 if (module <= HAL_MODULE_UNKNOWN || module >= HAL_MODULE_END) {
275 _E("Invalid paramer of HAL module(%d)\n", module);
276 return TIZEN_ERROR_INVALID_PARAMETER;
279 if (abi_version <= HAL_ABI_VERSION_UNKNOWN
280 || abi_version >= HAL_ABI_VERSION_END) {
281 _E("Invalid paramer of HAL ABI version(%d) for HAL module(%d)\n",
282 abi_version, module);
283 return TIZEN_ERROR_INVALID_PARAMETER;
286 info = _hal_api_conf_get_module_info(module);
288 _E("Failed to get HAL module(%d) information\n", module);
289 return TIZEN_ERROR_UNKNOWN;
292 /* Check abi_version whether is supported or not */
293 if (!info->hal_api) {
294 _E("%s: Doesn't support HAL API\n", info->module_name);
295 return TIZEN_ERROR_INVALID_PARAMETER;
298 if (!info->num_abi_versions
299 || !info->abi_versions) {
300 _E("%s: Doesn't have the ABI version information\n",
302 return TIZEN_ERROR_INVALID_PARAMETER;
305 g_platform_curr_abi_version = _hal_api_conf_get_platform_abi_version();
306 for (i = 0; i < info->num_abi_versions; i++) {
307 struct hal_abi_version_match *data
308 = &info->abi_versions[i];
310 if (g_platform_curr_abi_version != data->platform_abi_version)
313 if (data->backend_min_abi_version <= HAL_ABI_VERSION_UNKNOWN ||
314 data->backend_min_abi_version >= HAL_ABI_VERSION_END) {
315 _E("%s: abi_versions[%d].backend_min_abi_version(%d) is invalid\n",
316 info->module_name, i, data->backend_min_abi_version);
317 return TIZEN_ERROR_INVALID_PARAMETER;
320 if (abi_version <= data->platform_abi_version
321 && abi_version >= data->backend_min_abi_version)
322 return TIZEN_ERROR_NONE;
324 _E("%s: \'%s\' doesn't support \'%s\'\n",
326 hal_abi_version_str[g_platform_curr_abi_version],
327 hal_abi_version_str[abi_version]);
328 _E("%s: Must use ABI versions from \'%s\' to \'%s\'\n",
330 hal_abi_version_str[data->backend_min_abi_version],
331 hal_abi_version_str[data->platform_abi_version]);
334 return TIZEN_ERROR_INVALID_PARAMETER;